From 224ce89bce8186937e77bdbda572a650953f8c23 Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Wed, 19 Jul 2017 11:16:26 +0200 Subject: [PATCH] update sources to v12.1.1 --- Makefile | 4 +- ceph/.mailmap | 4 + ceph/.organizationmap | 4 + ceph/CMakeLists.txt | 25 +- ceph/PendingReleaseNotes | 28 + ceph/alpine/APKBUILD | 6 +- ceph/ceph.spec | 18 +- ceph/ceph.spec.in | 12 +- ceph/cmake/modules/Finddpdk.cmake | 2 +- ceph/cmake/modules/Findxfs.cmake | 6 +- ceph/cmake/modules/Findzfs.cmake | 28 + ceph/debian/ceph-base.dirs | 6 +- ceph/debian/ceph-base.install | 10 +- ceph/debian/ceph-base.maintscript | 4 +- ceph/debian/ceph-common.dirs | 2 +- ceph/debian/ceph-fuse.install | 2 +- ceph/debian/ceph-mon.install | 2 +- ceph/debian/ceph-osd.install | 14 +- ceph/debian/ceph-test.install | 14 +- ceph/debian/changelog | 6 + ceph/debian/control | 346 +- ceph/debian/copyright | 18 +- ceph/debian/libcephfs-dev.install | 2 +- ceph/debian/libcephfs2.install | 1 - ceph/debian/librados-dev.install | 4 +- ceph/debian/librados2.install | 2 +- ceph/debian/libradosstriper1.install | 1 - ceph/debian/python-cephfs.install | 2 +- ceph/debian/python-rados.install | 2 +- ceph/debian/python-rbd.install | 2 +- ceph/debian/python-rgw.install | 2 +- ceph/debian/python3-cephfs.install | 2 +- ceph/debian/python3-rados.install | 2 +- ceph/debian/python3-rbd.install | 2 +- ceph/debian/python3-rgw.install | 2 +- ceph/debian/radosgw.install | 2 +- ceph/debian/rules | 9 +- ceph/doc/cephfs/administration.rst | 22 +- ceph/doc/cephfs/experimental-features.rst | 35 +- ceph/doc/cephfs/mantle.rst | 1 - ceph/doc/changelog/v10.2.8.txt | 5435 ++++++++++ ceph/doc/changelog/v10.2.9.txt | 63 + ceph/doc/dev/erasure-coded-pool.rst | 8 +- ceph/doc/dev/index.rst | 61 +- ceph/doc/dev/object-store.rst | 3 + .../erasure_coding/developer_notes.rst | 4 +- ceph/doc/dev/osd_internals/osd_throttles.rst | 2 +- ceph/doc/dev/perf_histograms.rst | 54 +- ceph/doc/index.rst | 6 +- ceph/doc/install/manual-deployment.rst | 4 +- .../doc/install/manual-freebsd-deployment.rst | 7 +- ceph/doc/man/8/ceph-create-keys.rst | 6 +- ceph/doc/man/8/ceph-deploy.rst | 2 +- ceph/doc/man/8/ceph-osd.rst | 2 +- ceph/doc/man/8/rados.rst | 4 +- ceph/doc/mgr/administrator.rst | 11 +- ceph/doc/mgr/dashboard.rst | 48 +- ceph/doc/mgr/index.rst | 1 + ceph/doc/mgr/plugins.rst | 9 +- ceph/doc/mgr/restful.rst | 88 +- ceph/doc/mgr/zabbix.rst | 104 + ceph/doc/rados/configuration/ceph-conf.rst | 5 +- .../configuration/filestore-config-ref.rst | 15 +- .../filesystem-recommendations.rst | 43 +- .../rados/configuration/mon-lookup-dns.rst | 6 +- .../configuration/mon-osd-interaction.rst | 1 + .../configuration/network-config-ref.rst | 27 +- .../rados/configuration/osd-config-ref.rst | 7 - .../doc/rados/operations/erasure-code-isa.rst | 19 +- .../operations/erasure-code-jerasure.rst | 21 +- .../doc/rados/operations/erasure-code-lrc.rst | 33 +- .../rados/operations/erasure-code-shec.rst | 21 +- ceph/doc/rados/operations/erasure-code.rst | 8 +- ceph/doc/rados/operations/operating.rst | 6 +- .../doc/rados/operations/placement-groups.rst | 3 + ceph/doc/rados/operations/pools.rst | 10 +- ceph/doc/rados/operations/user-management.rst | 1 + .../rados/troubleshooting/log-and-debug.rst | 7 - .../troubleshooting/troubleshooting-osd.rst | 22 +- .../troubleshooting/troubleshooting-pg.rst | 2 +- ceph/doc/radosgw/index.rst | 2 + ceph/doc/release-notes.rst | 768 +- ceph/doc/releases.rst | 51 +- ceph/doc/start/hardware-recommendations.rst | 8 +- ceph/doc/start/index.rst | 6 +- ceph/doc/start/intro.rst | 87 +- ceph/doc/start/os-recommendations.rst | 63 +- ceph/doc/start/quick-ceph-deploy.rst | 325 +- ceph/doc/start/quick-common.rst | 15 +- ceph/doc/start/quick-rbd.rst | 5 + ceph/doc/start/quick-start-preflight.rst | 76 +- ceph/install-deps.sh | 1 + .../whitelist_wrongly_marked_down.yaml | 5 + .../ec-rados-plugin=isa-k=2-m=1.yaml | 2 +- .../ec-rados-plugin=jerasure-k=2-m=1.yaml | 2 +- .../ec-rados-plugin=jerasure-k=3-m=1.yaml | 2 +- .../ec-rados-plugin=lrc-k=4-m=2-l=3.yaml | 2 +- .../ec-rados-plugin=shec-k=4-m=3-c=2.yaml | 2 +- ceph/qa/objectstore/bluestore-comp.yaml | 5 + ceph/qa/objectstore/bluestore.yaml | 6 +- ceph/qa/objectstore/filestore-btrfs.yaml | 7 - ceph/qa/rgw_pool_type/ec-profile.yaml | 2 +- .../ceph-disk/basic/tasks/ceph-disk.yaml | 3 + .../overrides/whitelist_health.yaml | 9 + .../tasks/cephfs_scrub_tests.yaml | 2 + .../tasks/cfuse_workunit_quota.yaml | 6 - .../fs/thrash/overrides/whitelist_health.yaml | 8 + .../suites/fs/verify/validater/valgrind.yaml | 5 +- .../rbd_workunit_suites_fsstress_btrfs.yaml | 10 - .../powercycle/osd/tasks/radosbench.yaml | 28 +- .../rados/basic-luminous/scrub_test.yaml | 6 + .../rados/basic/tasks/rados_api_tests.yaml | 5 + .../rados/basic/tasks/rados_python.yaml | 5 + .../rados/basic/tasks/rados_stress_watch.yaml | 6 + .../suites/rados/basic/tasks/repair_test.yaml | 4 + ceph/qa/suites/rados/mgr/tasks/failover.yaml | 6 +- .../monthrash/thrashers/force-sync-many.yaml | 6 + .../rados/monthrash/thrashers/many.yaml | 3 + .../suites/rados/monthrash/thrashers/one.yaml | 5 + .../rados/monthrash/thrashers/sync-many.yaml | 3 + .../rados/monthrash/thrashers/sync.yaml | 3 + .../monthrash/workloads/rados_api_tests.yaml | 6 + .../workloads/rados_mon_workunits.yaml | 3 + .../multimon/tasks/mon_clock_no_skews.yaml | 2 + .../multimon/tasks/mon_clock_with_skews.yaml | 2 + .../rados/multimon/tasks/mon_recovery.yaml | 3 + .../objectstore/ceph_objectstore_tool.yaml | 6 + ceph/qa/suites/rados/rest/mgr-restful.yaml | 5 +- .../singleton-bluestore/all/cephtool.yaml | 5 + .../all/admin_socket_output.yaml | 4 + .../singleton-nomsgr/all/cache-fs-trunc.yaml | 3 + .../all/export-after-evict.yaml | 3 + .../singleton-nomsgr/all/full-tiering.yaml | 4 + .../singleton-nomsgr/all/health-warnings.yaml | 4 + .../all/multi-backfill-reject.yaml | 5 + .../singleton-nomsgr/all/valgrind-leaks.yaml | 9 +- .../rados/singleton/all/divergent_priors.yaml | 6 + .../singleton/all/divergent_priors2.yaml | 6 + .../rados/singleton/all/dump-stuck.yaml | 6 +- .../rados/singleton/all/ec-lost-unfound.yaml | 7 +- .../singleton/all/lost-unfound-delete.yaml | 7 +- .../rados/singleton/all/lost-unfound.yaml | 7 +- .../rados/singleton/all/mon-auth-caps.yaml | 14 + .../rados/singleton/all/mon-thrasher.yaml | 4 + .../rados/singleton/all/osd-backfill.yaml | 7 +- .../all/osd-recovery-incomplete.yaml | 7 +- .../rados/singleton/all/osd-recovery.yaml | 7 +- ceph/qa/suites/rados/singleton/all/peer.yaml | 6 +- .../all/pg-removal-interruption.yaml | 8 +- .../suites/rados/singleton/all/radostool.yaml | 2 + .../rados/singleton/all/random-eio.yaml | 39 + .../rados/singleton/all/rebuild-mondb.yaml | 7 +- .../suites/rados/singleton/all/reg11184.yaml | 8 +- .../singleton/all/resolve_stuck_peering.yaml | 6 + .../suites/rados/singleton/all/rest-api.yaml | 9 +- .../rados/singleton/all/thrash-eio.yaml | 43 + .../suites/rados/singleton/all/thrash-rados/+ | 0 .../all/{ => thrash-rados}/thrash-rados.yaml | 2 +- .../all/thrash-rados/thrashosds-health.yaml | 1 + .../thrash_cache_writeback_proxy_none.yaml | 6 +- .../all/watch-notify-same-primary.yaml | 7 +- .../thrashosds-health.yaml | 1 + .../thrashosds-health.yaml | 1 + .../thrashosds-health.yaml | 1 + .../thrashosds-health.yaml | 1 + .../thrashosds-health.yaml | 1 + .../thrash-luminous/thrashosds-health.yaml | 1 + .../rados/thrash/thrashosds-health.yaml | 1 + .../thrash/workloads/cache-agent-big.yaml | 2 +- .../workloads/cache-pool-snaps-readproxy.yaml | 6 +- .../thrash/workloads/cache-pool-snaps.yaml | 6 +- .../rados/thrash/workloads/cache-snaps.yaml | 6 +- .../suites/rados/thrash/workloads/cache.yaml | 6 +- .../1-jewel-install/jewel.yaml | 1 + .../jewel-x-singleton/6-finish-upgrade.yaml | 2 + .../8-workload/rbd-python.yaml | 1 - .../jewel-x-singleton/thrashosds-health.yaml | 1 + .../qa/suites/rados/verify/d-thrash/default/+ | 0 .../d-thrash/{ => default}/default.yaml | 0 .../d-thrash/default/thrashosds-health.yaml | 1 + .../rados/verify/tasks/mon_recovery.yaml | 7 + .../rados/verify/tasks/rados_api_tests.yaml | 6 + .../rados/verify/validater/valgrind.yaml | 6 +- ceph/qa/suites/rbd/basic/cachepool/small.yaml | 5 + .../basic/tasks/rbd_api_tests_old_format.yaml | 5 + .../rbd_python_api_tests_old_format.yaml | 4 + ceph/qa/suites/rbd/cli/pool/ec-data-pool.yaml | 5 +- .../suites/rbd/cli/pool/small-cache-pool.yaml | 5 + .../suites/rbd/librbd/pool/ec-data-pool.yaml | 2 +- .../rbd/librbd/pool/small-cache-pool.yaml | 5 + .../rbd/librbd/workloads/c_api_tests.yaml | 5 + .../workloads/c_api_tests_with_defaults.yaml | 5 + .../c_api_tests_with_journaling.yaml | 5 + .../workloads/dynamic_features_no_cache.yaml | 13 + ceph/qa/suites/rbd/nbd/thrashosds-health.yaml | 1 + .../workloads/devstack-tempest-gate.yaml | 15 + .../suites/rbd/qemu/pool/ec-cache-pool.yaml | 7 +- .../qa/suites/rbd/qemu/pool/ec-data-pool.yaml | 2 +- .../rbd/qemu/pool/small-cache-pool.yaml | 5 + .../suites/rbd/singleton/all/rbd_mirror.yaml | 3 + .../suites/rbd/thrash/thrashosds-health.yaml | 1 + .../rbd/thrash/workloads/rbd_api_tests.yaml | 5 + .../workloads/rbd_api_tests_copy_on_read.yaml | 3 + .../workloads/rbd_api_tests_journaling.yaml | 5 + .../workloads/rbd_api_tests_no_locking.yaml | 5 + .../rbd/valgrind/validator/memcheck.yaml | 4 +- .../rbd/valgrind/workloads/c_api_tests.yaml | 5 + .../workloads/c_api_tests_with_defaults.yaml | 5 + .../c_api_tests_with_journaling.yaml | 5 + .../valgrind/workloads/python_api_tests.yaml | 2 + .../python_api_tests_with_defaults.yaml | 2 + .../python_api_tests_with_journaling.yaml | 2 + .../rbd/valgrind/workloads/rbd_mirror.yaml | 5 + .../suites/rgw/hadoop-s3a/s3a-hadoop-v28.yaml | 31 + ceph/qa/suites/rgw/hadoop-s3a/s3a-hadoop.yaml | 29 + .../rgw/multisite/tasks/test_multi.yaml | 3 + ceph/qa/suites/rgw/multisite/valgrind.yaml | 6 +- .../suites/rgw/singleton/filestore-xfs.yaml | 1 - .../suites/rgw/thrash/thrashosds-health.yaml | 1 + .../suites/rgw/verify/tasks/rgw_s3tests.yaml | 4 +- .../qa/suites/rgw/verify/tasks/rgw_swift.yaml | 4 +- .../suites/rgw/verify/validater/valgrind.yaml | 6 +- .../tasks/cfuse_workunit_suites_fsstress.yaml | 1 - .../tasks/cfuse_workunit_suites_iozone.yaml | 1 - .../tasks/kclient_workunit_direct_io.yaml | 1 - .../tasks/libcephfs_interface_tests.yaml | 1 - .../smoke/basic/tasks/rados_cache_snaps.yaml | 7 +- .../smoke/basic/tasks/rados_python.yaml | 1 - .../basic/tasks/rbd_python_api_tests.yaml | 1 - .../tasks/rbd_workunit_suites_iozone.yaml | 1 - .../smoke/basic/tasks/rgw_ec_s3tests.yaml | 1 - .../parallel/0-cluster/start.yaml | 1 + .../1-hammer-jewel-install/hammer-jewel.yaml | 1 + .../parallel/6-workload/ec-rados-default.yaml | 2 +- .../7-upgrade-sequence/upgrade-all.yaml | 5 - .../7-upgrade-sequence/upgrade-by-daemon.yaml | 15 +- .../hammer-jewel-x/parallel/8-kraken.yaml | 1 - .../hammer-jewel-x/parallel/8-luminous.yaml | 1 + .../hammer-to-jewel.yaml | 1 + .../hammer-to-jewel.yaml | 1 + .../0-create-base-tier/create-ec-pool.yaml | 2 +- .../hammer-jewel-x/tiering/3-upgrade.yaml | 6 +- .../parallel/1-jewel-install/jewel.yaml | 1 + .../parallel/2-workload/cache-pool-snaps.yaml | 6 +- .../point-to-point-upgrade.yaml | 1 + .../ec-rados-plugin=jerasure-k=3-m=1.yaml | 2 +- .../stress-split/1-jewel-install/jewel.yaml | 1 + .../7-final-workload.yaml | 2 +- ceph/qa/tasks/ceph.py | 96 +- ceph/qa/tasks/ceph_deploy.py | 4 + ceph/qa/tasks/ceph_manager.py | 22 +- ceph/qa/tasks/ceph_test_case.py | 7 +- ceph/qa/tasks/cephfs/filesystem.py | 3 - ceph/qa/tasks/cephfs/test_auto_repair.py | 2 +- ceph/qa/tasks/cephfs/test_client_limits.py | 8 +- ceph/qa/tasks/cephfs/test_exports.py | 2 +- ceph/qa/tasks/cephfs/test_failover.py | 9 +- ceph/qa/tasks/cephfs/test_journal_repair.py | 1 - ceph/qa/tasks/cephfs/test_mantle.py | 1 - ceph/qa/tasks/cephfs/test_misc.py | 11 +- ceph/qa/tasks/cephfs/test_sessionmap.py | 1 - ceph/qa/tasks/cephfs/test_strays.py | 33 +- ceph/qa/tasks/divergent_priors2.py | 4 +- ceph/qa/tasks/dump_stuck.py | 5 +- ceph/qa/tasks/ec_lost_unfound.py | 2 +- ceph/qa/tasks/mds_thrash.py | 20 +- ceph/qa/tasks/mon_clock_skew_check.py | 231 +- ceph/qa/tasks/qemu.py | 15 +- ceph/qa/tasks/rados.py | 2 +- ceph/qa/tasks/radosbench.py | 45 +- ceph/qa/tasks/rbd_mirror.py | 2 +- ceph/qa/tasks/reg11184.py | 36 +- ceph/qa/tasks/rgw.py | 23 +- ceph/qa/tasks/s3a_hadoop.py | 341 + ceph/qa/tasks/swift.py | 263 + ceph/qa/tasks/thrashosds-health.yaml | 13 + ceph/qa/tasks/thrashosds.py | 2 + ceph/qa/tasks/util/rados.py | 4 +- ceph/qa/tasks/workunit.py | 8 +- ceph/qa/workunits/ceph-disk/ceph-disk-test.py | 23 +- ceph/qa/workunits/ceph-helpers.sh | 79 +- .../ceph-tests/ceph-admin-commands.sh | 1 + ceph/qa/workunits/cephtool/test.sh | 219 +- ceph/qa/workunits/mon/auth_caps.sh | 14 +- ceph/qa/workunits/mon/crush_ops.sh | 15 + ceph/qa/workunits/rados/load-gen-big.sh | 2 +- .../rados/load-gen-mix-small-long.sh | 2 +- ceph/qa/workunits/rados/load-gen-mix-small.sh | 2 +- ceph/qa/workunits/rados/load-gen-mix.sh | 2 +- .../qa/workunits/rados/load-gen-mostlyread.sh | 2 +- ceph/qa/workunits/rados/test.sh | 1 + ceph/qa/workunits/rados/test_alloc_hint.sh | 2 +- .../rados/test_envlibrados_for_rocksdb.sh | 2 +- .../workunits/rados/test_health_warnings.sh | 17 + ceph/qa/workunits/rados/test_rados_tool.sh | 2 +- ceph/qa/workunits/rbd/import_export.sh | 120 +- ceph/qa/workunits/rbd/krbd_data_pool.sh | 2 +- ceph/qa/workunits/rbd/run_devstack_tempest.sh | 6 + ceph/qa/workunits/rest/test-restful.sh | 4 +- ceph/qa/workunits/rest/test.py | 16 +- ceph/qa/workunits/rest/test_mgr_rest_api.py | 2 +- .../suites/cephfs_journal_tool_smoke.sh | 31 +- ceph/src/.git_version | 4 +- ceph/src/CMakeLists.txt | 1 + ceph/src/auth/RotatingKeyRing.cc | 4 +- ceph/src/auth/RotatingKeyRing.h | 2 +- ceph/src/auth/cephx/CephxClientHandler.cc | 2 +- ceph/src/ceph-create-keys | 30 +- ceph/src/ceph-disk/ceph_disk/main.py | 86 +- ceph/src/ceph-rest-api | 10 +- ceph/src/ceph.in | 56 +- ceph/src/ceph_mon.cc | 50 +- ceph/src/ceph_osd.cc | 2 + ceph/src/ceph_release | 2 +- ceph/src/cls/lock/cls_lock.cc | 28 - ceph/src/cls/lock/cls_lock_types.cc | 29 + ceph/src/cls/lock/cls_lock_types.h | 31 + ceph/src/cls/log/cls_log_client.cc | 4 +- ceph/src/cls/rgw/cls_rgw.cc | 4 +- ceph/src/common/BackTrace.h | 2 +- ceph/src/common/LogEntry.cc | 25 + ceph/src/common/LogEntry.h | 1 + ceph/src/common/Mutex.cc | 9 +- ceph/src/common/OpQueue.h | 9 +- ceph/src/common/PrioritizedQueue.h | 63 - ceph/src/common/Timer.cc | 16 +- ceph/src/common/Timer.h | 4 +- ceph/src/common/WeightedPriorityQueue.h | 50 - ceph/src/common/WorkQueue.h | 5 +- ceph/src/common/ceph_crypto.cc | 2 +- ceph/src/common/cohort_lru.h | 42 +- ceph/src/common/config.cc | 29 +- ceph/src/common/config_opts.h | 67 +- ceph/src/common/dns_resolve.cc | 86 +- ceph/src/common/dns_resolve.h | 12 +- ceph/src/common/fork_function.h | 161 + ceph/src/common/freebsd_errno.cc | 2 +- ceph/src/common/mClockPriorityQueue.h | 361 + ceph/src/compressor/zlib/CMakeLists.txt | 30 +- .../compressor/zlib/CompressionPluginZlib.h | 2 +- ceph/src/compressor/zlib/ZlibCompressor.cc | 4 +- ceph/src/compressor/zlib/ZlibCompressor.h | 4 +- ceph/src/crush/CrushCompiler.cc | 4 +- ceph/src/crush/CrushLocation.h | 2 +- ceph/src/crush/CrushTester.cc | 48 +- ceph/src/crush/CrushTester.h | 5 +- ceph/src/crush/CrushTreeDumper.h | 6 +- ceph/src/crush/CrushWrapper.cc | 115 +- ceph/src/crush/CrushWrapper.h | 81 +- ceph/src/crush/builder.c | 6 +- ceph/src/crush/crush.h | 8 +- ceph/src/crush/mapper.c | 6 +- ceph/src/erasure-code/ErasureCode.cc | 46 + ceph/src/erasure-code/ErasureCode.h | 14 +- ceph/src/erasure-code/ErasureCodeInterface.h | 18 +- ceph/src/erasure-code/isa/CMakeLists.txt | 2 - ceph/src/erasure-code/isa/ErasureCodeIsa.cc | 32 +- ceph/src/erasure-code/isa/ErasureCodeIsa.h | 13 +- .../jerasure/ErasureCodeJerasure.cc | 25 +- .../jerasure/ErasureCodeJerasure.h | 13 +- ceph/src/erasure-code/lrc/ErasureCodeLrc.cc | 95 +- ceph/src/erasure-code/lrc/ErasureCodeLrc.h | 25 +- ceph/src/erasure-code/shec/ErasureCodeShec.cc | 26 +- ceph/src/erasure-code/shec/ErasureCodeShec.h | 11 - ceph/src/global/global_init.cc | 2 +- ceph/src/include/Context.h | 6 +- ceph/src/include/ceph_fs.h | 2 +- ceph/src/include/health.h | 68 + ceph/src/include/rados/librados.h | 42 + ceph/src/include/rados/librados.hpp | 7 + ceph/src/include/scope_guard.h | 2 + ceph/src/include/stringify.h | 2 + ceph/src/include/types.h | 34 +- ceph/src/isa-l/CONTRIBUTING.md | 35 + ceph/src/isa-l/Doxyfile | 27 + ceph/src/isa-l/Makefile.am | 38 +- ceph/src/isa-l/Makefile.nmake | 54 +- ceph/src/isa-l/README.md | 54 +- ceph/src/isa-l/Release_notes.txt | 63 +- ceph/src/isa-l/configure.ac | 17 +- ceph/src/isa-l/crc/Makefile.am | 28 +- ceph/src/isa-l/crc/crc16_t10dif_01.asm | 6 + ceph/src/isa-l/crc/crc16_t10dif_by4.asm | 4 + ceph/src/isa-l/crc/crc16_t10dif_perf.c | 1 + ceph/src/isa-l/crc/crc32_ieee_01.asm | 5 + ceph/src/isa-l/crc/crc32_ieee_by4.asm | 4 + ceph/src/isa-l/crc/crc32_ieee_perf.c | 1 + ceph/src/isa-l/crc/crc32_iscsi_00.asm | 3 + ceph/src/isa-l/crc/crc32_iscsi_01.asm | 4 + ceph/src/isa-l/crc/crc32_iscsi_perf.c | 1 + ceph/src/isa-l/crc/crc64_base.c | 159 + ceph/src/isa-l/crc/crc64_ecma_norm_by8.asm | 583 ++ ceph/src/isa-l/crc/crc64_ecma_refl_by8.asm | 548 + ceph/src/isa-l/crc/crc64_example.c | 68 + ceph/src/isa-l/crc/crc64_funcs_perf.c | 109 + ceph/src/isa-l/crc/crc64_funcs_test.c | 290 + ceph/src/isa-l/crc/crc64_iso_norm_by8.asm | 581 ++ ceph/src/isa-l/crc/crc64_iso_refl_by8.asm | 544 + ceph/src/isa-l/crc/crc64_jones_norm_by8.asm | 581 ++ ceph/src/isa-l/crc/crc64_jones_refl_by8.asm | 544 + ceph/src/isa-l/crc/crc64_multibinary.asm | 89 + ceph/src/isa-l/crc/crc_base_aliases.c | 77 + ceph/src/isa-l/erasure_code/Makefile.am | 18 +- ceph/src/isa-l/erasure_code/ec_base.c | 12 + ceph/src/isa-l/erasure_code/ec_base_aliases.c | 61 + .../isa-l/erasure_code/ec_highlevel_func.c | 11 - ceph/src/isa-l/igzip/Makefile.am | 93 +- ceph/src/isa-l/igzip/bitbuf2.asm | 7 + ceph/src/isa-l/igzip/bitbuf2.h | 47 +- ceph/src/isa-l/igzip/crc32_gzip.asm | 4 +- ceph/src/isa-l/igzip/crc32_gzip_base.c | 106 + ceph/src/isa-l/igzip/crc_data.asm | 120 - ceph/src/isa-l/igzip/crc_utils_01.asm | 195 - ceph/src/isa-l/igzip/crc_utils_04.asm | 194 - ceph/src/isa-l/igzip/data_struct2.asm | 86 +- ceph/src/isa-l/igzip/encode_df.c | 36 + ceph/src/isa-l/igzip/encode_df.h | 21 + ceph/src/isa-l/igzip/encode_df_04.asm | 4 + ceph/src/isa-l/igzip/encode_df_asm.asm | 527 + ceph/src/isa-l/igzip/flatten_ll.c | 41 + ceph/src/isa-l/igzip/flatten_ll.h | 3 + .../igzip/generate_constant_block_header.c | 118 - .../isa-l/igzip/generate_custom_hufftables.c | 270 +- ceph/src/isa-l/igzip/heap_macros.asm | 69 + ceph/src/isa-l/igzip/huff_codes.c | 1681 ++- ceph/src/isa-l/igzip/huff_codes.h | 228 +- ceph/src/isa-l/igzip/huffman.asm | 90 +- ceph/src/isa-l/igzip/huffman.h | 75 +- ceph/src/isa-l/igzip/hufftables_c.c | 9146 ++++++++++++----- ceph/src/isa-l/igzip/igzip.c | 836 +- ceph/src/isa-l/igzip/igzip_base.c | 298 +- ceph/src/isa-l/igzip/igzip_base_aliases.c | 87 + ceph/src/isa-l/igzip/igzip_body.asm | 636 +- ceph/src/isa-l/igzip/igzip_body_01.asm | 1 - ceph/src/isa-l/igzip/igzip_body_02.asm | 7 + ceph/src/isa-l/igzip/igzip_body_04.asm | 1 - .../src/isa-l/igzip/igzip_buffer_utils_01.asm | 543 - .../src/isa-l/igzip/igzip_buffer_utils_04.asm | 552 - ceph/src/isa-l/igzip/igzip_check.c | 1285 --- ceph/src/isa-l/igzip/igzip_compare_types.asm | 50 +- .../igzip/igzip_decode_block_stateless.asm | 668 ++ .../igzip/igzip_decode_block_stateless_01.asm | 3 + .../igzip/igzip_decode_block_stateless_04.asm | 4 + ceph/src/isa-l/igzip/igzip_example.c | 19 +- ceph/src/isa-l/igzip/igzip_file_perf.c | 177 +- ceph/src/isa-l/igzip/igzip_finish.asm | 118 +- ceph/src/isa-l/igzip/igzip_fuzz_inflate.c | 104 + ceph/src/isa-l/igzip/igzip_hist_perf.c | 146 + ceph/src/isa-l/igzip/igzip_icf_base.c | 223 + ceph/src/isa-l/igzip/igzip_icf_body.asm | 513 + ceph/src/isa-l/igzip/igzip_icf_body_01.asm | 7 + ceph/src/isa-l/igzip/igzip_icf_body_02.asm | 7 + ...stateless_04.asm => igzip_icf_body_04.asm} | 2 +- ceph/src/isa-l/igzip/igzip_icf_finish.asm | 299 + ceph/src/isa-l/igzip/igzip_inflate.c | 1292 +++ .../isa-l/igzip/igzip_inflate_multibinary.asm | 51 + ceph/src/isa-l/igzip/igzip_inflate_perf.c | 116 +- ceph/src/isa-l/igzip/igzip_inflate_ref.c | 668 -- ceph/src/isa-l/igzip/igzip_inflate_ref.h | 150 - ceph/src/isa-l/igzip/igzip_inflate_test.c | 202 +- .../src/isa-l/igzip/igzip_level_buf_structs.h | 16 + ceph/src/isa-l/igzip/igzip_multibinary.asm | 48 +- ceph/src/isa-l/igzip/igzip_perf.c | 2 +- ceph/src/isa-l/igzip/igzip_rand_test.c | 855 +- .../isa-l/igzip/igzip_semi_dyn_file_perf.c | 342 + ceph/src/isa-l/igzip/igzip_stateless.asm | 644 -- ceph/src/isa-l/igzip/igzip_stateless_01.asm | 7 - ceph/src/isa-l/igzip/igzip_stateless_base.c | 151 - .../isa-l/igzip/igzip_stateless_file_perf.c | 126 +- .../isa-l/igzip/igzip_sync_flush_example.c | 4 +- .../isa-l/igzip/igzip_sync_flush_file_perf.c | 2 +- ceph/src/isa-l/igzip/igzip_sync_flush_perf.c | 2 +- .../isa-l/igzip/igzip_update_histogram.asm | 557 + .../isa-l/igzip/igzip_update_histogram_01.asm | 7 + .../isa-l/igzip/igzip_update_histogram_04.asm | 8 + ceph/src/isa-l/igzip/inflate_data_structs.asm | 117 + ceph/src/isa-l/igzip/inflate_std_vects.h | 1554 +++ ceph/src/isa-l/igzip/lz0a_const.asm | 24 +- ceph/src/isa-l/igzip/options.asm | 31 +- ceph/src/isa-l/igzip/proc_heap.asm | 97 + ceph/src/isa-l/igzip/proc_heap_base.c | 84 + ceph/src/isa-l/igzip/rfc1951_lookup.asm | 89 + ceph/src/isa-l/igzip/stdmac.asm | 184 +- ceph/src/isa-l/include/crc64.h | 277 + ceph/src/isa-l/include/igzip_lib.h | 477 +- ceph/src/isa-l/include/multibinary.asm | 48 +- ceph/src/isa-l/isa-l.def | 17 + ceph/src/isa-l/make.inc | 79 +- ceph/src/isa-l/raid/Makefile.am | 27 +- ceph/src/isa-l/raid/pq_gen_avx512.asm | 235 + ceph/src/isa-l/raid/pq_gen_perf.c | 4 +- ceph/src/isa-l/raid/raid_base_aliases.c | 50 + ceph/src/isa-l/raid/raid_multibinary.asm | 15 +- ceph/src/isa-l/raid/raid_multibinary_i32.asm | 58 + ceph/src/isa-l/raid/xor_gen_avx512.asm | 217 + ceph/src/isa-l/raid/xor_gen_perf.c | 4 +- ceph/src/isa-l/tools/iindent | 2 + ceph/src/jobs/alc.tp | 38 - ceph/src/jobs/alcdat/makedirs | 45 - ceph/src/jobs/alcdat/makedirs.big | 45 - ceph/src/jobs/alcdat/makedirs.tput | 46 - ceph/src/jobs/alcdat/makefiles.shared | 32 - ceph/src/jobs/alcdat/openshared | 32 - ceph/src/jobs/alcdat/ossh.include | 45 - ceph/src/jobs/alcdat/ossh.include.big | 46 - ceph/src/jobs/alcdat/ossh.lib | 45 - ceph/src/jobs/alcdat/ossh.lib.big | 46 - ceph/src/jobs/alcdat/striping | 48 - ceph/src/jobs/example | 56 - ceph/src/jobs/mds/log_striping | 36 - ceph/src/jobs/mds/makedir_lat | 33 - ceph/src/jobs/mds/makedirs | 39 - ceph/src/jobs/mds/opensshlib | 44 - ceph/src/jobs/meta1 | 19 - ceph/src/jobs/meta1.proc.sh | 14 - ceph/src/jobs/osd/ebofs | 48 - ceph/src/jobs/osd/mds_log | 42 - ceph/src/jobs/osd/osd_threads | 33 - ceph/src/jobs/osd/striping | 78 - ceph/src/jobs/osd/wr_lat2 | 44 - ceph/src/jobs/osd/write_sizes | 56 - ceph/src/jobs/rados/map_dist | 32 - ceph/src/jobs/rados/rep_lat | 43 - ceph/src/jobs/rados/wr_sizes | 40 - ceph/src/jobs/runjobsample | 26 - ceph/src/krbd.cc | 16 +- ceph/src/kv/RocksDBStore.cc | 54 +- ceph/src/kv/RocksDBStore.h | 2 + ceph/src/librados/RadosClient.cc | 59 +- ceph/src/librados/RadosClient.h | 11 + ceph/src/librados/librados.cc | 14 + .../libradosstriper/MultiAioCompletionImpl.cc | 10 + .../libradosstriper/MultiAioCompletionImpl.h | 3 + ceph/src/libradosstriper/RadosStriperImpl.cc | 354 +- ceph/src/libradosstriper/RadosStriperImpl.h | 221 +- ceph/src/libradosstriper/libradosstriper.cc | 3 +- ceph/src/librbd/ExclusiveLock.cc | 21 +- ceph/src/librbd/ImageCtx.cc | 2 +- ceph/src/librbd/ImageCtx.h | 4 +- .../exclusive_lock/PreReleaseRequest.cc | 9 +- ceph/src/librbd/image/RefreshRequest.cc | 13 +- ceph/src/librbd/io/ImageRequest.cc | 42 + ceph/src/librbd/io/ImageRequest.h | 25 + ceph/src/librbd/io/ImageRequestWQ.cc | 433 +- ceph/src/librbd/io/ImageRequestWQ.h | 83 +- ceph/src/librbd/io/Types.h | 6 + .../operation/DisableFeaturesRequest.cc | 9 +- .../librbd/operation/DisableFeaturesRequest.h | 2 + ceph/src/mds/CDir.cc | 52 +- ceph/src/mds/CInode.cc | 15 +- ceph/src/mds/FSMap.cc | 26 + ceph/src/mds/FSMap.h | 3 + ceph/src/mds/Locker.cc | 26 + ceph/src/mds/Locker.h | 1 + ceph/src/mds/MDBalancer.cc | 8 +- ceph/src/mds/MDBalancer.h | 5 +- ceph/src/mds/MDCache.cc | 129 +- ceph/src/mds/MDCache.h | 12 +- ceph/src/mds/MDSMap.cc | 74 + ceph/src/mds/MDSMap.h | 4 + ceph/src/mds/Migrator.cc | 86 +- ceph/src/mds/Server.cc | 44 +- ceph/src/mds/StrayManager.cc | 1 + ceph/src/mds/journal.cc | 2 +- ceph/src/messages/MDirUpdate.h | 15 +- ceph/src/messages/MMDSBeacon.h | 50 + ceph/src/messages/MMgrBeacon.h | 16 +- ceph/src/messages/MMgrOpen.h | 33 +- ceph/src/messages/MMgrReport.h | 30 +- ceph/src/messages/MMonElection.h | 28 +- ceph/src/messages/MMonHealthChecks.h | 47 + ceph/src/messages/MMonMgrReport.h | 26 +- ceph/src/messages/MOSDOp.h | 2 +- ceph/src/messages/MOSDOpReply.h | 1 + ceph/src/messages/MOSDPing.h | 46 +- ceph/src/messages/MServiceMap.h | 34 + ceph/src/mgr/ClusterState.cc | 31 +- ceph/src/mgr/ClusterState.h | 23 +- ceph/src/mgr/DaemonServer.cc | 299 +- ceph/src/mgr/DaemonServer.h | 12 + ceph/src/mgr/DaemonState.cc | 13 +- ceph/src/mgr/DaemonState.h | 13 +- ceph/src/mgr/Mgr.cc | 87 +- ceph/src/mgr/Mgr.h | 14 +- ceph/src/mgr/MgrClient.cc | 82 +- ceph/src/mgr/MgrClient.h | 15 + ceph/src/mgr/MgrCommands.h | 14 +- ceph/src/mgr/MgrStandby.cc | 28 +- ceph/src/mgr/MgrStandby.h | 5 - ceph/src/mgr/PyModules.cc | 99 +- ceph/src/mgr/PyModules.h | 23 +- ceph/src/mgr/PyState.cc | 69 +- ceph/src/mgr/ServiceMap.cc | 128 + ceph/src/mgr/ServiceMap.h | 89 + ceph/src/mon/CMakeLists.txt | 1 + ceph/src/mon/ConfigKeyService.h | 3 +- ceph/src/mon/DataHealthService.cc | 22 - ceph/src/mon/DataHealthService.h | 6 +- ceph/src/mon/Elector.cc | 13 +- ceph/src/mon/Elector.h | 5 +- ceph/src/mon/FSCommands.cc | 6 - ceph/src/mon/HealthMonitor.cc | 374 +- ceph/src/mon/HealthMonitor.h | 46 +- ceph/src/mon/LogMonitor.cc | 50 +- ceph/src/mon/MDSMonitor.cc | 67 +- ceph/src/mon/MgrMap.h | 54 +- ceph/src/mon/MgrMonitor.cc | 156 +- ceph/src/mon/MgrMonitor.h | 5 + ceph/src/mon/MgrStatMonitor.cc | 129 +- ceph/src/mon/MgrStatMonitor.h | 12 +- ceph/src/mon/MonClient.cc | 20 +- ceph/src/mon/MonCommands.h | 69 +- ceph/src/mon/MonMap.cc | 33 +- ceph/src/mon/MonMap.h | 30 +- ceph/src/mon/Monitor.cc | 560 +- ceph/src/mon/Monitor.h | 29 +- ceph/src/mon/MonmapMonitor.cc | 19 +- ceph/src/mon/OSDMonitor.cc | 996 +- ceph/src/mon/OSDMonitor.h | 4 +- ceph/src/mon/OldHealthMonitor.cc | 107 + ceph/src/mon/OldHealthMonitor.h | 66 + ceph/src/mon/PGMap.cc | 750 +- ceph/src/mon/PGMap.h | 7 + ceph/src/mon/PGMonitor.cc | 17 +- ceph/src/mon/Paxos.cc | 12 +- ceph/src/mon/PaxosService.cc | 25 +- ceph/src/mon/PaxosService.h | 23 +- ceph/src/mon/QuorumService.h | 3 +- ceph/src/mon/Session.h | 4 +- ceph/src/mon/health_check.h | 200 + ceph/src/mon/mon_types.h | 4 +- ceph/src/msg/Message.cc | 11 + ceph/src/msg/Message.h | 3 + ceph/src/msg/Messenger.h | 8 + ceph/src/msg/QueueStrategy.cc | 13 +- ceph/src/msg/QueueStrategy.h | 8 +- ceph/src/msg/async/AsyncConnection.cc | 8 +- ceph/src/msg/async/AsyncMessenger.cc | 9 + ceph/src/msg/async/AsyncMessenger.h | 1 + ceph/src/msg/async/PosixStack.cc | 2 +- ceph/src/msg/async/rdma/Infiniband.cc | 10 +- .../msg/async/rdma/RDMAConnectedSocketImpl.cc | 2 +- .../msg/async/rdma/RDMAServerSocketImpl.cc | 4 +- ceph/src/msg/async/rdma/RDMAStack.cc | 31 +- ceph/src/msg/async/rdma/RDMAStack.h | 14 +- ceph/src/msg/simple/Accepter.cc | 2 +- ceph/src/msg/simple/Pipe.cc | 6 +- ceph/src/msg/simple/SimpleMessenger.cc | 8 + ceph/src/msg/simple/SimpleMessenger.h | 1 + ceph/src/msg/xio/XioMessenger.h | 2 + ceph/src/os/CMakeLists.txt | 29 +- ceph/src/os/ObjectMap.h | 2 + ceph/src/os/ObjectStore.h | 14 +- .../src/os/bluestore/BitmapFreelistManager.cc | 1 + ceph/src/os/bluestore/BlueFS.cc | 11 + ceph/src/os/bluestore/BlueStore.cc | 698 +- ceph/src/os/bluestore/BlueStore.h | 72 +- ceph/src/os/bluestore/KernelDevice.cc | 57 +- ceph/src/os/bluestore/NVMEDevice.cc | 2 +- ceph/src/os/bluestore/NVMEDevice.h | 1 + ceph/src/os/filestore/CollectionIndex.h | 3 + ceph/src/os/filestore/DBObjectMap.h | 5 + ceph/src/os/filestore/FileJournal.cc | 39 +- ceph/src/os/filestore/FileStore.cc | 58 +- ceph/src/os/filestore/FileStore.h | 10 +- ceph/src/os/filestore/HashIndex.cc | 45 +- ceph/src/os/filestore/HashIndex.h | 41 +- ceph/src/os/filestore/IndexManager.cc | 12 +- .../src/os/filestore/JournalingObjectStore.cc | 3 + ceph/src/os/filestore/ZFSFileStoreBackend.cc | 6 +- ceph/src/os/fs/aio.cc | 39 +- ceph/src/os/fs/aio.h | 5 + ceph/src/os/kstore/KStore.cc | 3 +- ceph/src/os/kstore/KStore.h | 8 +- ceph/src/os/memstore/MemStore.cc | 8 +- ceph/src/os/memstore/MemStore.h | 6 +- ceph/src/osd/CMakeLists.txt | 5 +- ceph/src/osd/ECBackend.cc | 8 +- ceph/src/osd/ECBackend.h | 2 +- ceph/src/osd/ECTransaction.h | 6 +- ceph/src/osd/OSD.cc | 253 +- ceph/src/osd/OSD.h | 179 +- ceph/src/osd/OSDMap.cc | 485 +- ceph/src/osd/OSDMap.h | 41 +- ceph/src/osd/OSDMapMapping.cc | 3 + ceph/src/osd/PG.cc | 148 +- ceph/src/osd/PG.h | 15 +- ceph/src/osd/PGBackend.h | 12 +- ceph/src/osd/PGQueueable.cc | 35 + ceph/src/osd/PGQueueable.h | 148 + ceph/src/osd/PrimaryLogPG.cc | 333 +- ceph/src/osd/PrimaryLogPG.h | 11 +- ceph/src/osd/ReplicatedBackend.cc | 139 +- ceph/src/osd/ReplicatedBackend.h | 10 +- ceph/src/osd/mClockClientQueue.cc | 165 + ceph/src/osd/mClockClientQueue.h | 146 + ceph/src/osd/mClockOpClassQueue.cc | 123 + ceph/src/osd/mClockOpClassQueue.h | 153 + ceph/src/osd/osd_types.cc | 40 +- ceph/src/osd/osd_types.h | 14 +- ceph/src/osdc/Objecter.cc | 16 + ceph/src/osdc/Objecter.h | 6 +- ceph/src/pybind/ceph_rest_api.py | 2 +- ceph/src/pybind/mgr/dashboard/README.rst | 16 +- ceph/src/pybind/mgr/dashboard/base.html | 154 +- ceph/src/pybind/mgr/dashboard/clients.html | 5 +- ceph/src/pybind/mgr/dashboard/filesystem.html | 16 +- ceph/src/pybind/mgr/dashboard/health.html | 337 +- ceph/src/pybind/mgr/dashboard/module.py | 92 +- ceph/src/pybind/mgr/dashboard/rbd.html | 6 +- ceph/src/pybind/mgr/dashboard/rbd_ls.py | 45 +- .../pybind/mgr/dashboard/static/logo-mini.png | Bin 0 -> 1811 bytes ceph/src/pybind/mgr/dashboard/types.py | 7 + ceph/src/pybind/mgr/mgr_module.py | 44 +- ceph/src/pybind/mgr/restful/module.py | 10 +- .../mgr/{fsstatus => status}/__init__.py | 0 .../pybind/mgr/{fsstatus => status}/module.py | 34 +- ceph/src/pybind/mgr/zabbix/__init__.py | 1 + ceph/src/pybind/mgr/zabbix/module.py | 277 + .../src/pybind/mgr/zabbix/zabbix_template.xml | 1707 +++ ceph/src/pybind/rados/rados.pyx | 22 +- ceph/src/pybind/rbd/rbd.pyx | 15 +- ceph/src/rbd_replay/CMakeLists.txt | 5 +- ceph/src/rgw/CMakeLists.txt | 2 + ceph/src/rgw/librgw.cc | 13 + ceph/src/rgw/rgw_acl_swift.cc | 10 +- ceph/src/rgw/rgw_acl_swift.h | 4 +- ceph/src/rgw/rgw_admin.cc | 36 +- ceph/src/rgw/rgw_auth_s3.cc | 18 +- ceph/src/rgw/rgw_auth_s3.h | 3 +- ceph/src/rgw/rgw_bucket.cc | 55 +- ceph/src/rgw/rgw_common.cc | 12 +- ceph/src/rgw/rgw_common.h | 16 +- ceph/src/rgw/rgw_compression.cc | 58 +- ceph/src/rgw/rgw_compression.h | 1 - ceph/src/rgw/rgw_cr_rados.cc | 41 +- ceph/src/rgw/rgw_cr_rados.h | 27 +- ceph/src/rgw/rgw_data_sync.cc | 27 +- ceph/src/rgw/rgw_data_sync.h | 1 - ceph/src/rgw/rgw_es_query.cc | 2 +- ceph/src/rgw/rgw_es_query.h | 4 +- ceph/src/rgw/rgw_file.cc | 145 +- ceph/src/rgw/rgw_file.h | 50 +- ceph/src/rgw/rgw_frontend.h | 6 +- ceph/src/rgw/rgw_gc.cc | 4 + ceph/src/rgw/rgw_iam_policy.cc | 27 +- ceph/src/rgw/rgw_iam_policy.h | 14 +- ceph/src/rgw/rgw_lc.cc | 77 +- ceph/src/rgw/rgw_lc.h | 50 +- ceph/src/rgw/rgw_lc_s3.cc | 20 +- ceph/src/rgw/rgw_lc_s3.h | 25 +- ceph/src/rgw/rgw_lib.h | 2 +- ceph/src/rgw/rgw_main.cc | 23 +- ceph/src/rgw/rgw_metadata.cc | 8 +- ceph/src/rgw/rgw_multi.cc | 56 + ceph/src/rgw/rgw_multi.h | 7 + ceph/src/rgw/rgw_object_expirer_core.h | 7 +- ceph/src/rgw/rgw_op.cc | 175 +- ceph/src/rgw/rgw_op.h | 59 + ceph/src/rgw/rgw_period_puller.cc | 17 +- ceph/src/rgw/rgw_quota.cc | 52 +- ceph/src/rgw/rgw_quota.h | 2 +- ceph/src/rgw/rgw_rados.cc | 265 +- ceph/src/rgw/rgw_rados.h | 52 +- ceph/src/rgw/rgw_realm_reloader.cc | 13 +- ceph/src/rgw/rgw_realm_reloader.h | 4 +- ceph/src/rgw/rgw_reshard.cc | 2 +- ceph/src/rgw/rgw_reshard.h | 2 +- ceph/src/rgw/rgw_rest.cc | 12 +- ceph/src/rgw/rgw_rest.h | 12 + ceph/src/rgw/rgw_rest_log.cc | 38 +- ceph/src/rgw/rgw_rest_realm.cc | 30 +- ceph/src/rgw/rgw_rest_s3.cc | 340 +- ceph/src/rgw/rgw_rest_s3.h | 85 +- ceph/src/rgw/rgw_rest_s3website.h | 1 + ceph/src/rgw/rgw_rest_swift.cc | 21 +- ceph/src/rgw/rgw_rest_swift.h | 1 + ceph/src/rgw/rgw_rest_user.cc | 10 + ceph/src/rgw/rgw_swift_auth.cc | 2 +- ceph/src/rgw/rgw_sync.cc | 6 +- ceph/src/rgw/rgw_sync_module_es.cc | 17 +- ceph/src/rgw/rgw_tag.cc | 52 + ceph/src/rgw/rgw_tag.h | 40 + ceph/src/rgw/rgw_tag_s3.cc | 83 + ceph/src/rgw/rgw_tag_s3.h | 62 + ceph/src/rgw/rgw_torrent.h | 6 +- ceph/src/rgw/rgw_user.cc | 41 +- ceph/src/rgw/rgw_website.cc | 4 +- ceph/src/rgw/rgw_website.h | 2 +- ceph/src/script/ceph-release-notes | 16 +- ceph/src/test/ceph_objectstore_tool.py | 2 +- ceph/src/test/cli/ceph-conf/help.t | 2 +- ceph/src/test/cli/crushtool/help.t | 5 + ceph/src/test/cli/crushtool/rules.t | 159 + ceph/src/test/cli/crushtool/rules.txt | 54 + ceph/src/test/cli/osdmaptool/clobber.t | 10 +- ceph/src/test/cli/osdmaptool/create-print.t | 10 +- ceph/src/test/cli/osdmaptool/create-racks.t | 10 +- ceph/src/test/cli/osdmaptool/crush.t | 4 +- ceph/src/test/cli/osdmaptool/help.t | 2 + .../test/cli/osdmaptool/missing-argument.t | 2 + ceph/src/test/cli/osdmaptool/pool.t | 16 +- ceph/src/test/cli/osdmaptool/test-map-pgs.t | 6 +- ceph/src/test/cli/osdmaptool/tree.t | 18 +- ceph/src/test/cli/osdmaptool/upmap.t | 24 +- ceph/src/test/cli/radosgw-admin/help.t | 4 +- ceph/src/test/cls_rbd/test_cls_rbd.cc | 2 +- ceph/src/test/common/CMakeLists.txt | 7 + ceph/src/test/common/dns_resolve.cc | 56 +- .../test/common/test_mclock_priority_queue.cc | 318 + .../src/test/common/test_prioritized_queue.cc | 54 - .../common/test_weighted_priority_queue.cc | 80 - ceph/src/test/crush/CrushWrapper.cc | 14 +- ceph/src/test/crush/crush-choose-args.sh | 6 + ceph/src/test/crush/crush-classes.sh | 15 +- ceph/src/test/crush/crush.cc | 14 +- .../test/direct_messenger/DirectMessenger.h | 1 + ceph/src/test/encoding/types.h | 6 + .../test/erasure-code/ErasureCodeExample.h | 4 +- ceph/src/test/erasure-code/TestErasureCode.cc | 7 +- .../erasure-code/TestErasureCodeExample.cc | 4 +- .../test/erasure-code/TestErasureCodeIsa.cc | 14 +- .../erasure-code/TestErasureCodeJerasure.cc | 14 +- .../test/erasure-code/TestErasureCodeLrc.cc | 106 +- .../test/erasure-code/TestErasureCodeShec.cc | 202 +- .../erasure-code/TestErasureCodeShec_all.cc | 10 +- .../TestErasureCodeShec_arguments.cc | 6 +- .../TestErasureCodeShec_thread.cc | 6 +- .../erasure-code/test-erasure-code-plugins.sh | 4 +- .../test/erasure-code/test-erasure-code.sh | 14 +- .../src/test/erasure-code/test-erasure-eio.sh | 2 +- ceph/src/test/fio/ceph-bluestore.conf | 2 - ceph/src/test/fio/fio_ceph_objectstore.cc | 3 +- ceph/src/test/librados/CMakeLists.txt | 10 + ceph/src/test/librados/c_read_operations.cc | 4 +- ceph/src/test/librados/service.cc | 59 + ceph/src/test/librados/test.cc | 4 +- ceph/src/test/libradosstriper/striping.cc | 17 +- ceph/src/test/librbd/CMakeLists.txt | 6 +- .../test_mock_PreReleaseRequest.cc | 14 +- .../librbd/image/test_mock_RefreshRequest.cc | 73 +- .../librbd/io/test_mock_ImageRequestWQ.cc | 279 + ceph/src/test/librbd/mock/MockImageCtx.h | 9 +- .../librbd/mock/exclusive_lock/MockPolicy.h | 23 + .../test/librbd/mock/io/MockImageRequestWQ.h | 7 +- .../test_mock_DisableFeaturesRequest.cc | 16 +- .../test/librbd/test_mock_ExclusiveLock.cc | 25 +- ceph/src/test/librgw_file_aw.cc | 67 +- ceph/src/test/librgw_file_nfsns.cc | 10 +- ceph/src/test/mgr/mgr-dashboard-smoke.sh | 5 +- ceph/src/test/mon/CMakeLists.txt | 1 + ceph/src/test/mon/misc.sh | 46 +- ceph/src/test/mon/mon-bind.sh | 148 + ceph/src/test/mon/osd-crush-tree.rng | 6 + ceph/src/test/mon/osd-crush.sh | 70 - ceph/src/test/mon/osd-erasure-code-profile.sh | 8 +- ceph/src/test/msgr/perf_msgr_client.cc | 2 +- ceph/src/test/msgr/test_async_driver.cc | 12 +- ceph/src/test/multi_stress_watch.cc | 2 +- ceph/src/test/objectstore/store_test.cc | 9 +- ceph/src/test/osd/CMakeLists.txt | 22 + ceph/src/test/osd/TestMClockClientQueue.cc | 187 + ceph/src/test/osd/TestMClockOpClassQueue.cc | 187 + ceph/src/test/osd/TestOSDMap.cc | 55 +- ceph/src/test/osd/TestPGLog.cc | 4 +- ceph/src/test/osd/osd-fast-mark-down.sh | 21 +- ceph/src/test/osd/osd-scrub-repair.sh | 213 +- ceph/src/test/pybind/test_ceph_argparse.py | 3 - ceph/src/test/rgw/test_rgw_compression.cc | 151 + ceph/src/test/test_c_headers.c | 12 +- ceph/src/test/test_denc.cc | 1 + ceph/src/test/test_subprocess.cc | 25 + ceph/src/tools/ceph_conf.cc | 2 +- ceph/src/tools/ceph_objectstore_tool.cc | 31 +- ceph/src/tools/ceph_objectstore_tool.h | 4 +- ceph/src/tools/ceph_osdomap_tool.cc | 28 +- ceph/src/tools/crushtool.cc | 47 +- ceph/src/tools/osdmaptool.cc | 29 +- ceph/src/tools/rados/rados.cc | 12 +- ceph/src/tools/rbd_mirror/ClusterWatcher.cc | 12 +- ceph/src/tools/rbd_mirror/ImageReplayer.h | 2 +- ceph/src/tools/rbd_nbd/rbd-nbd.cc | 16 +- ceph/src/vstart.sh | 56 +- ceph/systemd/ceph-disk@.service | 2 +- ceph/systemd/ceph-fuse.target | 1 + ceph/systemd/ceph-mds.target | 1 + ceph/systemd/ceph-mgr.target | 1 + ceph/systemd/ceph-mgr@.service | 16 +- ceph/systemd/ceph-mon.target | 1 + ceph/systemd/ceph-mon@.service | 2 +- ceph/systemd/ceph-osd.target | 1 + ceph/systemd/ceph-radosgw.target | 1 + ceph/systemd/ceph-rbd-mirror.target | 1 + 893 files changed, 49645 insertions(+), 17274 deletions(-) create mode 100644 ceph/cmake/modules/Findzfs.cmake create mode 100644 ceph/doc/changelog/v10.2.8.txt create mode 100644 ceph/doc/changelog/v10.2.9.txt create mode 100644 ceph/doc/mgr/zabbix.rst delete mode 100644 ceph/qa/objectstore/filestore-btrfs.yaml create mode 100644 ceph/qa/suites/fs/basic_functional/overrides/whitelist_health.yaml create mode 100644 ceph/qa/suites/fs/thrash/overrides/whitelist_health.yaml delete mode 100644 ceph/qa/suites/krbd/rbd/tasks/rbd_workunit_suites_fsstress_btrfs.yaml create mode 100644 ceph/qa/suites/rados/singleton/all/mon-auth-caps.yaml create mode 100644 ceph/qa/suites/rados/singleton/all/random-eio.yaml create mode 100644 ceph/qa/suites/rados/singleton/all/thrash-eio.yaml create mode 100644 ceph/qa/suites/rados/singleton/all/thrash-rados/+ rename ceph/qa/suites/rados/singleton/all/{ => thrash-rados}/thrash-rados.yaml (92%) create mode 120000 ceph/qa/suites/rados/singleton/all/thrash-rados/thrashosds-health.yaml create mode 120000 ceph/qa/suites/rados/thrash-erasure-code-big/thrashosds-health.yaml create mode 120000 ceph/qa/suites/rados/thrash-erasure-code-isa/thrashosds-health.yaml create mode 120000 ceph/qa/suites/rados/thrash-erasure-code-overwrites/thrashosds-health.yaml create mode 120000 ceph/qa/suites/rados/thrash-erasure-code-shec/thrashosds-health.yaml create mode 120000 ceph/qa/suites/rados/thrash-erasure-code/thrashosds-health.yaml create mode 120000 ceph/qa/suites/rados/thrash-luminous/thrashosds-health.yaml create mode 120000 ceph/qa/suites/rados/thrash/thrashosds-health.yaml create mode 120000 ceph/qa/suites/rados/upgrade/jewel-x-singleton/thrashosds-health.yaml create mode 100644 ceph/qa/suites/rados/verify/d-thrash/default/+ rename ceph/qa/suites/rados/verify/d-thrash/{ => default}/default.yaml (100%) create mode 120000 ceph/qa/suites/rados/verify/d-thrash/default/thrashosds-health.yaml create mode 100644 ceph/qa/suites/rbd/maintenance/workloads/dynamic_features_no_cache.yaml create mode 120000 ceph/qa/suites/rbd/nbd/thrashosds-health.yaml create mode 120000 ceph/qa/suites/rbd/thrash/thrashosds-health.yaml create mode 100644 ceph/qa/suites/rgw/hadoop-s3a/s3a-hadoop-v28.yaml create mode 100644 ceph/qa/suites/rgw/hadoop-s3a/s3a-hadoop.yaml delete mode 120000 ceph/qa/suites/rgw/singleton/filestore-xfs.yaml create mode 120000 ceph/qa/suites/rgw/thrash/thrashosds-health.yaml delete mode 120000 ceph/qa/suites/upgrade/hammer-jewel-x/parallel/8-kraken.yaml create mode 120000 ceph/qa/suites/upgrade/hammer-jewel-x/parallel/8-luminous.yaml create mode 100644 ceph/qa/tasks/s3a_hadoop.py create mode 100644 ceph/qa/tasks/swift.py create mode 100644 ceph/qa/tasks/thrashosds-health.yaml create mode 100644 ceph/src/common/fork_function.h create mode 100644 ceph/src/common/mClockPriorityQueue.h create mode 100644 ceph/src/include/health.h create mode 100644 ceph/src/isa-l/CONTRIBUTING.md create mode 100644 ceph/src/isa-l/Doxyfile create mode 100644 ceph/src/isa-l/crc/crc64_base.c create mode 100644 ceph/src/isa-l/crc/crc64_ecma_norm_by8.asm create mode 100644 ceph/src/isa-l/crc/crc64_ecma_refl_by8.asm create mode 100644 ceph/src/isa-l/crc/crc64_example.c create mode 100644 ceph/src/isa-l/crc/crc64_funcs_perf.c create mode 100644 ceph/src/isa-l/crc/crc64_funcs_test.c create mode 100644 ceph/src/isa-l/crc/crc64_iso_norm_by8.asm create mode 100644 ceph/src/isa-l/crc/crc64_iso_refl_by8.asm create mode 100644 ceph/src/isa-l/crc/crc64_jones_norm_by8.asm create mode 100644 ceph/src/isa-l/crc/crc64_jones_refl_by8.asm create mode 100644 ceph/src/isa-l/crc/crc64_multibinary.asm create mode 100644 ceph/src/isa-l/crc/crc_base_aliases.c create mode 100644 ceph/src/isa-l/erasure_code/ec_base_aliases.c create mode 100644 ceph/src/isa-l/igzip/crc32_gzip_base.c delete mode 100644 ceph/src/isa-l/igzip/crc_data.asm delete mode 100644 ceph/src/isa-l/igzip/crc_utils_01.asm delete mode 100644 ceph/src/isa-l/igzip/crc_utils_04.asm create mode 100644 ceph/src/isa-l/igzip/encode_df.c create mode 100644 ceph/src/isa-l/igzip/encode_df.h create mode 100644 ceph/src/isa-l/igzip/encode_df_04.asm create mode 100644 ceph/src/isa-l/igzip/encode_df_asm.asm create mode 100644 ceph/src/isa-l/igzip/flatten_ll.c create mode 100644 ceph/src/isa-l/igzip/flatten_ll.h delete mode 100644 ceph/src/isa-l/igzip/generate_constant_block_header.c create mode 100644 ceph/src/isa-l/igzip/heap_macros.asm create mode 100644 ceph/src/isa-l/igzip/igzip_base_aliases.c create mode 100644 ceph/src/isa-l/igzip/igzip_body_02.asm delete mode 100644 ceph/src/isa-l/igzip/igzip_buffer_utils_01.asm delete mode 100644 ceph/src/isa-l/igzip/igzip_buffer_utils_04.asm delete mode 100644 ceph/src/isa-l/igzip/igzip_check.c create mode 100644 ceph/src/isa-l/igzip/igzip_decode_block_stateless.asm create mode 100644 ceph/src/isa-l/igzip/igzip_decode_block_stateless_01.asm create mode 100644 ceph/src/isa-l/igzip/igzip_decode_block_stateless_04.asm create mode 100644 ceph/src/isa-l/igzip/igzip_fuzz_inflate.c create mode 100644 ceph/src/isa-l/igzip/igzip_hist_perf.c create mode 100644 ceph/src/isa-l/igzip/igzip_icf_base.c create mode 100644 ceph/src/isa-l/igzip/igzip_icf_body.asm create mode 100644 ceph/src/isa-l/igzip/igzip_icf_body_01.asm create mode 100644 ceph/src/isa-l/igzip/igzip_icf_body_02.asm rename ceph/src/isa-l/igzip/{igzip_stateless_04.asm => igzip_icf_body_04.asm} (73%) create mode 100644 ceph/src/isa-l/igzip/igzip_icf_finish.asm create mode 100644 ceph/src/isa-l/igzip/igzip_inflate.c create mode 100644 ceph/src/isa-l/igzip/igzip_inflate_multibinary.asm delete mode 100644 ceph/src/isa-l/igzip/igzip_inflate_ref.c delete mode 100644 ceph/src/isa-l/igzip/igzip_inflate_ref.h create mode 100644 ceph/src/isa-l/igzip/igzip_level_buf_structs.h create mode 100644 ceph/src/isa-l/igzip/igzip_semi_dyn_file_perf.c delete mode 100644 ceph/src/isa-l/igzip/igzip_stateless.asm delete mode 100644 ceph/src/isa-l/igzip/igzip_stateless_01.asm delete mode 100644 ceph/src/isa-l/igzip/igzip_stateless_base.c create mode 100644 ceph/src/isa-l/igzip/igzip_update_histogram.asm create mode 100644 ceph/src/isa-l/igzip/igzip_update_histogram_01.asm create mode 100644 ceph/src/isa-l/igzip/igzip_update_histogram_04.asm create mode 100644 ceph/src/isa-l/igzip/inflate_data_structs.asm create mode 100644 ceph/src/isa-l/igzip/inflate_std_vects.h create mode 100644 ceph/src/isa-l/igzip/proc_heap.asm create mode 100644 ceph/src/isa-l/igzip/proc_heap_base.c create mode 100644 ceph/src/isa-l/igzip/rfc1951_lookup.asm create mode 100644 ceph/src/isa-l/include/crc64.h create mode 100644 ceph/src/isa-l/raid/pq_gen_avx512.asm create mode 100644 ceph/src/isa-l/raid/raid_base_aliases.c create mode 100644 ceph/src/isa-l/raid/raid_multibinary_i32.asm create mode 100644 ceph/src/isa-l/raid/xor_gen_avx512.asm create mode 100755 ceph/src/isa-l/tools/iindent delete mode 100644 ceph/src/jobs/alc.tp delete mode 100644 ceph/src/jobs/alcdat/makedirs delete mode 100644 ceph/src/jobs/alcdat/makedirs.big delete mode 100644 ceph/src/jobs/alcdat/makedirs.tput delete mode 100644 ceph/src/jobs/alcdat/makefiles.shared delete mode 100644 ceph/src/jobs/alcdat/openshared delete mode 100644 ceph/src/jobs/alcdat/ossh.include delete mode 100644 ceph/src/jobs/alcdat/ossh.include.big delete mode 100644 ceph/src/jobs/alcdat/ossh.lib delete mode 100644 ceph/src/jobs/alcdat/ossh.lib.big delete mode 100644 ceph/src/jobs/alcdat/striping delete mode 100644 ceph/src/jobs/example delete mode 100644 ceph/src/jobs/mds/log_striping delete mode 100644 ceph/src/jobs/mds/makedir_lat delete mode 100644 ceph/src/jobs/mds/makedirs delete mode 100644 ceph/src/jobs/mds/opensshlib delete mode 100644 ceph/src/jobs/meta1 delete mode 100755 ceph/src/jobs/meta1.proc.sh delete mode 100644 ceph/src/jobs/osd/ebofs delete mode 100644 ceph/src/jobs/osd/mds_log delete mode 100644 ceph/src/jobs/osd/osd_threads delete mode 100644 ceph/src/jobs/osd/striping delete mode 100644 ceph/src/jobs/osd/wr_lat2 delete mode 100644 ceph/src/jobs/osd/write_sizes delete mode 100644 ceph/src/jobs/rados/map_dist delete mode 100644 ceph/src/jobs/rados/rep_lat delete mode 100644 ceph/src/jobs/rados/wr_sizes delete mode 100644 ceph/src/jobs/runjobsample create mode 100644 ceph/src/messages/MMonHealthChecks.h create mode 100644 ceph/src/messages/MServiceMap.h create mode 100644 ceph/src/mgr/ServiceMap.cc create mode 100644 ceph/src/mgr/ServiceMap.h create mode 100644 ceph/src/mon/OldHealthMonitor.cc create mode 100644 ceph/src/mon/OldHealthMonitor.h create mode 100644 ceph/src/mon/health_check.h create mode 100644 ceph/src/osd/PGQueueable.cc create mode 100644 ceph/src/osd/PGQueueable.h create mode 100644 ceph/src/osd/mClockClientQueue.cc create mode 100644 ceph/src/osd/mClockClientQueue.h create mode 100644 ceph/src/osd/mClockOpClassQueue.cc create mode 100644 ceph/src/osd/mClockOpClassQueue.h create mode 100644 ceph/src/pybind/mgr/dashboard/static/logo-mini.png rename ceph/src/pybind/mgr/{fsstatus => status}/__init__.py (100%) rename ceph/src/pybind/mgr/{fsstatus => status}/module.py (90%) create mode 100644 ceph/src/pybind/mgr/zabbix/__init__.py create mode 100644 ceph/src/pybind/mgr/zabbix/module.py create mode 100644 ceph/src/pybind/mgr/zabbix/zabbix_template.xml create mode 100644 ceph/src/rgw/rgw_tag.cc create mode 100644 ceph/src/rgw/rgw_tag.h create mode 100644 ceph/src/rgw/rgw_tag_s3.cc create mode 100644 ceph/src/rgw/rgw_tag_s3.h create mode 100644 ceph/src/test/cli/crushtool/rules.t create mode 100644 ceph/src/test/cli/crushtool/rules.txt create mode 100644 ceph/src/test/common/test_mclock_priority_queue.cc create mode 100644 ceph/src/test/librados/service.cc create mode 100644 ceph/src/test/librbd/io/test_mock_ImageRequestWQ.cc create mode 100644 ceph/src/test/librbd/mock/exclusive_lock/MockPolicy.h create mode 100755 ceph/src/test/mon/mon-bind.sh create mode 100644 ceph/src/test/osd/TestMClockClientQueue.cc create mode 100644 ceph/src/test/osd/TestMClockOpClassQueue.cc diff --git a/Makefile b/Makefile index 67171c758..6d7902289 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ RELEASE=5.0 PACKAGE=ceph -VER=12.1.0 -DEBREL=pve2 +VER=12.1.1 +DEBREL=pve1 SRCDIR=ceph BUILDSRC=${SRCDIR}-${VER} diff --git a/ceph/.mailmap b/ceph/.mailmap index 802ba32bb..95c96cf8b 100644 --- a/ceph/.mailmap +++ b/ceph/.mailmap @@ -96,6 +96,7 @@ Eric Lee Eric Mourgaya Erwin, Brock A Esteban Molina-Estolano +Fan Yang Fangchen Sun Fang Yuxiang Fang Yuxiang @@ -269,6 +270,7 @@ Min Chen MingXin Liu Mingyue Zhao Mykola Golub +Myoungwon Oh Nathan Cutler Nathan Cutler Nathan Cutler @@ -372,6 +374,7 @@ Shun Song Shylesh Kumar Sirisha Guduru Song Baisen +Song Weibin Stephen F Taylor Subramanyam Varanasi Sushma Gurram @@ -400,6 +403,7 @@ Tommi Virtanen Tommi Virtanen Tone Zhang Travis Rhoden +Tushar Gohad Tyler Brekke Uday Mullangi Uday Mullangi diff --git a/ceph/.organizationmap b/ceph/.organizationmap index 17464131a..f6743643c 100644 --- a/ceph/.organizationmap +++ b/ceph/.organizationmap @@ -266,6 +266,7 @@ Intel Krzysztof Kosiński Intel Ma Jianpeng Intel Orlando Moreno Intel Shu, Xinxin +Intel Tushar Gohad Intel Wang, Yaguang Intel Xiaoxi Chen Intel Yan, Zheng @@ -331,6 +332,7 @@ MSys Technologies Rajesh Nambiar Anton Aksola Nebula Chris Holcombe Netease Dong Wu +Neunn Fan Yang Ocado Luis Periquito Odiso Alexandre Derumier Opower Derrick Schneider @@ -472,6 +474,7 @@ SAP Marc Koderer Science & Technology Facilities Council George Ryall SendFaster Christopher O'Connell SK Telecom Ilsoo Byun +SK Telecom Myoungwon Oh Sociomantic Labs Iain Buclaw Spectra Logic Alan Somers SUSE Abhishek Lekshmanan @@ -785,6 +788,7 @@ ZTE Luo Runbing ZTE Xie Xingguo ZTE Shun Song ZTE Song Baisen +ZTE Song Weibin ZTE Tang Wenjun ZTE Wei Qiaomiao ZTE Yan Jun diff --git a/ceph/CMakeLists.txt b/ceph/CMakeLists.txt index d6695b2a2..f0fe8e6a7 100644 --- a/ceph/CMakeLists.txt +++ b/ceph/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 2.8.11) project(ceph) -set(VERSION 12.1.0) +set(VERSION 12.1.1) if(POLICY CMP0046) # Tweak policies (this one disables "missing" dependency warning) @@ -214,10 +214,16 @@ set(HAVE_LIBFUSE ${FUSE_FOUND}) endif(${WITH_FUSE}) option(WITH_XFS "XFS is here" ON) -if(${WITH_XFS}) -find_package(xfs) -set(HAVE_LIBXFS ${XFS_FOUND}) -endif(${WITH_XFS}) +if(WITH_XFS) + find_package(xfs) + set(HAVE_LIBXFS ${XFS_FOUND}) +endif() + +option(WITH_ZFS "enable LibZFS if found" OFF) +if(WITH_ZFS) + find_package(zfs) + set(HAVE_LIBZFS ${ZFS_FOUND}) +endif() option(WITH_SPDK "Enable SPDK" OFF) if(WITH_SPDK) @@ -453,17 +459,16 @@ endif(${WITH_LTTNG}) option(WITH_OSD_INSTRUMENT_FUNCTIONS OFF) #option for Babeltrace -option(HAVE_BABELTRACE "Babeltrace libraries are enabled" ON) -if(${HAVE_BABELTRACE}) +option(WITH_BABELTRACE "Babeltrace libraries are enabled" ON) +if(WITH_BABELTRACE) + set(HAVE_BABELTRACE ON) find_package(babeltrace REQUIRED) - set(WITH_BABELTRACE ${BABELTRACE_FOUND}) set(HAVE_BABELTRACE_BABELTRACE_H ${BABELTRACE_FOUND}) set(HAVE_BABELTRACE_CTF_EVENTS_H ${BABELTRACE_FOUND}) set(HAVE_BABELTRACE_CTF_ITERATOR_H ${BABELTRACE_FOUND}) -endif(${HAVE_BABELTRACE}) +endif(WITH_BABELTRACE) option(DEBUG_GATHER "C_Gather debugging is enabled" ON) -option(HAVE_LIBZFS "LibZFS is enabled" OFF) option(ENABLE_COVERAGE "Coverage is enabled" OFF) option(PG_DEBUG_REFS "PG Ref debugging is enabled" OFF) diff --git a/ceph/PendingReleaseNotes b/ceph/PendingReleaseNotes index 7f57cc52a..0c02dd8ce 100644 --- a/ceph/PendingReleaseNotes +++ b/ceph/PendingReleaseNotes @@ -2,6 +2,9 @@ ------ * The "journaler allow split entries" config setting has been removed. * The 'apply' mode of cephfs-journal-tool has been removed +* Added new configuration "public bind addr" to support dynamic environments + like Kubernetes. When set the Ceph MON daemon could bind locally to an IP + address and advertise a different IP address "public addr" on the network. 12.0.0 ------ @@ -182,3 +185,28 @@ replicated rule in the CRUSH map for replicated pools. Erasure coded pools have rules that are automatically created for them if they are not specified at pool creation time. + +* The `status` ceph-mgr module is enabled by default, and initially provides two + commands: `ceph tell mgr osd status` and `ceph tell mgr fs status`. These + are high level colorized views to complement the existing CLI. + +12.1.1 +------ + +* choose_args encoding has been changed to make it architecture-independent. + If you deployed Luminous dev releases or 12.1.0 rc release and made use of + the CRUSH choose_args feature, you need to remove all choose_args mappings + from your CRUSH map before starting the upgrade. + +* The 'ceph health' structured output (JSON or XML) no longer contains + a 'timechecks' section describing the time sync status. This + information is now available via the 'ceph time-sync-status' + command. + +* Certain extra fields in the 'ceph health' structured output that + used to appear if the mons were low on disk space (which duplicated + the information in the normal health warning messages) are now gone. + +* The "ceph -w" output no longer contains audit log entries by default. + Add a "--watch-channel=audit" or "--watch-channel=*" to see them. + diff --git a/ceph/alpine/APKBUILD b/ceph/alpine/APKBUILD index 3fa716646..efd9df405 100644 --- a/ceph/alpine/APKBUILD +++ b/ceph/alpine/APKBUILD @@ -1,7 +1,7 @@ # Contributor: John Coyle # Maintainer: John Coyle pkgname=ceph -pkgver=12.1.0 +pkgver=12.1.1 pkgrel=0 pkgdesc="Ceph is a distributed object store and file system" pkgusers="ceph" @@ -63,7 +63,7 @@ makedepends=" xmlstarlet yasm " -source="ceph-12.1.0.tar.bz2" +source="ceph-12.1.1.tar.bz2" subpackages=" $pkgname-base $pkgname-common @@ -116,7 +116,7 @@ _sysconfdir=/etc _udevrulesdir=/etc/udev/rules.d _python_sitelib=/usr/lib/python2.7/site-packages -builddir=$srcdir/ceph-12.1.0 +builddir=$srcdir/ceph-12.1.1 build() { export CEPH_BUILD_VIRTUALENV=$builddir diff --git a/ceph/ceph.spec b/ceph/ceph.spec index e85a731a9..08882641e 100644 --- a/ceph/ceph.spec +++ b/ceph/ceph.spec @@ -62,10 +62,10 @@ # main package definition ################################################################################# Name: ceph -Version: 12.1.0 +Version: 12.1.1 Release: 0%{?dist} %if 0%{?fedora} || 0%{?rhel} -Epoch: 1 +Epoch: 2 %endif # define %_epoch_prefix macro which will expand to the empty string if %epoch is undefined @@ -77,7 +77,7 @@ License: LGPL-2.1 and CC-BY-SA-1.0 and GPL-2.0 and BSL-1.0 and BSD-3-Clause and Group: System/Filesystems %endif URL: http://ceph.com/ -Source0: http://ceph.com/download/ceph-12.1.0.tar.bz2 +Source0: http://ceph.com/download/ceph-12.1.1.tar.bz2 %if 0%{?suse_version} %if 0%{?is_opensuse} ExclusiveArch: x86_64 aarch64 ppc64 ppc64le @@ -131,6 +131,7 @@ BuildRequires: python-pecan BuildRequires: python-requests BuildRequires: python-virtualenv BuildRequires: python-werkzeug +BuildRequires: socat BuildRequires: snappy-devel BuildRequires: udev BuildRequires: util-linux @@ -611,6 +612,7 @@ Summary: Ceph distributed file system client library %if 0%{?suse_version} Group: System/Libraries %endif +Obsoletes: libcephfs1 %if 0%{?rhel} || 0%{?fedora} Obsoletes: ceph-libs < %{_epoch_prefix}%{version}-%{release} Obsoletes: ceph-libcephfs @@ -773,7 +775,7 @@ python-rbd, python-rgw or python-cephfs instead. # common ################################################################################# %prep -%autosetup -p1 -n ceph-12.1.0 +%autosetup -p1 -n ceph-12.1.1 %build %if 0%{with cephfs_java} @@ -836,10 +838,10 @@ cmake .. \ %endif %if %{with lttng} -DWITH_LTTNG=ON \ - -DHAVE_BABELTRACE=ON \ + -DWTIH_BABELTRACE=ON \ %else -DWITH_LTTNG=OFF \ - -DHAVE_BABELTRACE=OFF \ + -DWTIH_BABELTRACE=OFF \ %endif $CEPH_EXTRA_CMAKE_ARGS \ %if 0%{with ocf} @@ -1007,6 +1009,7 @@ fi %postun base /sbin/ldconfig +test -n "$FIRST_ARG" || FIRST_ARG=$1 %if 0%{?suse_version} DISABLE_RESTART_ON_UPDATE="yes" %service_del_postun ceph-disk@\*.service ceph.target @@ -1027,8 +1030,7 @@ if [ $FIRST_ARG -ge 1 ] ; then fi %files common -%docdir %{_docdir} -%docdir %{_docdir}/ceph +%dir %{_docdir}/ceph %doc %{_docdir}/ceph/sample.ceph.conf %doc %{_docdir}/ceph/COPYING %{_bindir}/ceph diff --git a/ceph/ceph.spec.in b/ceph/ceph.spec.in index 60d59c52c..07231917f 100644 --- a/ceph/ceph.spec.in +++ b/ceph/ceph.spec.in @@ -65,7 +65,7 @@ Name: ceph Version: @VERSION@ Release: @RPM_RELEASE@%{?dist} %if 0%{?fedora} || 0%{?rhel} -Epoch: 1 +Epoch: 2 %endif # define %_epoch_prefix macro which will expand to the empty string if %epoch is undefined @@ -131,6 +131,7 @@ BuildRequires: python-pecan BuildRequires: python-requests BuildRequires: python-virtualenv BuildRequires: python-werkzeug +BuildRequires: socat BuildRequires: snappy-devel BuildRequires: udev BuildRequires: util-linux @@ -611,6 +612,7 @@ Summary: Ceph distributed file system client library %if 0%{?suse_version} Group: System/Libraries %endif +Obsoletes: libcephfs1 %if 0%{?rhel} || 0%{?fedora} Obsoletes: ceph-libs < %{_epoch_prefix}%{version}-%{release} Obsoletes: ceph-libcephfs @@ -836,10 +838,10 @@ cmake .. \ %endif %if %{with lttng} -DWITH_LTTNG=ON \ - -DHAVE_BABELTRACE=ON \ + -DWTIH_BABELTRACE=ON \ %else -DWITH_LTTNG=OFF \ - -DHAVE_BABELTRACE=OFF \ + -DWTIH_BABELTRACE=OFF \ %endif $CEPH_EXTRA_CMAKE_ARGS \ %if 0%{with ocf} @@ -1007,6 +1009,7 @@ fi %postun base /sbin/ldconfig +test -n "$FIRST_ARG" || FIRST_ARG=$1 %if 0%{?suse_version} DISABLE_RESTART_ON_UPDATE="yes" %service_del_postun ceph-disk@\*.service ceph.target @@ -1027,8 +1030,7 @@ if [ $FIRST_ARG -ge 1 ] ; then fi %files common -%docdir %{_docdir} -%docdir %{_docdir}/ceph +%dir %{_docdir}/ceph %doc %{_docdir}/ceph/sample.ceph.conf %doc %{_docdir}/ceph/COPYING %{_bindir}/ceph diff --git a/ceph/cmake/modules/Finddpdk.cmake b/ceph/cmake/modules/Finddpdk.cmake index 6ce996645..343420a8e 100644 --- a/ceph/cmake/modules/Finddpdk.cmake +++ b/ceph/cmake/modules/Finddpdk.cmake @@ -71,5 +71,5 @@ if (EXISTS ${WITH_DPDK_MLX5}) list(APPEND check_LIBRARIES -libverbs) endif() set(DPDK_LIBRARIES - -Wl,--whole-archive ${check_LIBRARIES} -lpthread -Wl,--no-whole-archive) + -Wl,--whole-archive ${check_LIBRARIES} -Wl,--no-whole-archive) endif(DPDK_FOUND) diff --git a/ceph/cmake/modules/Findxfs.cmake b/ceph/cmake/modules/Findxfs.cmake index ecbf91c05..6171e3289 100644 --- a/ceph/cmake/modules/Findxfs.cmake +++ b/ceph/cmake/modules/Findxfs.cmake @@ -1,9 +1,9 @@ # Try to find xfs # Once done, this will define # -# XFS_FOUND - system has Profiler -# XFS_INCLUDE_DIR - the Profiler include directories -# XFS_LIBRARIES - link these to use Profiler +# XFS_FOUND - system has libxfs +# XFS_INCLUDE_DIR - the libxfs include directories +# XFS_LIBRARIES - link these to use libxfs if(XFS_INCLUDE_DIR AND XFS_LIBRARIES) set(XFS_FIND_QUIETLY TRUE) diff --git a/ceph/cmake/modules/Findzfs.cmake b/ceph/cmake/modules/Findzfs.cmake new file mode 100644 index 000000000..d92dd1fb0 --- /dev/null +++ b/ceph/cmake/modules/Findzfs.cmake @@ -0,0 +1,28 @@ +# find libzfs or libzfslinux +# Once done, this will define +# +# ZFS_FOUND - system has libzfs +# ZFS_INCLUDE_DIR - the libzfs include directories +# ZFS_LIBRARIES - link these to use libzfs + +find_package(PkgConfig) +if(PKG_CONFIG_FOUND) + pkg_check_modules(ZFS QUIET libzfs) +else() + find_path(ZFS_INCLUDE_DIR libzfs.h + HINTS + ENV ZFS_DIR + PATH_SUFFIXES libzfs) + + find_library(ZFS_LIBRARIES + NAMES zfs + HINTS + ENV ZFS_DIR) + set(XFS_LIBRARIES ${LIBXFS}) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(zfs DEFAULT_MSG + ZFS_INCLUDE_DIRS ZFS_LIBRARIES) + +mark_as_advanced(ZFS_INCLUDE_DIRS XFS_LIBRARIES) diff --git a/ceph/debian/ceph-base.dirs b/ceph/debian/ceph-base.dirs index 97d66adf0..a60a331ca 100644 --- a/ceph/debian/ceph-base.dirs +++ b/ceph/debian/ceph-base.dirs @@ -1,5 +1,5 @@ -var/lib/ceph/tmp -var/lib/ceph/bootstrap-osd var/lib/ceph/bootstrap-mds -var/lib/ceph/bootstrap-rgw var/lib/ceph/bootstrap-mgr +var/lib/ceph/bootstrap-osd +var/lib/ceph/bootstrap-rgw +var/lib/ceph/tmp diff --git a/ceph/debian/ceph-base.install b/ceph/debian/ceph-base.install index 2a56cabee..92af025a4 100644 --- a/ceph/debian/ceph-base.install +++ b/ceph/debian/ceph-base.install @@ -1,21 +1,21 @@ etc/init.d/ceph -usr/sbin/ceph-create-keys -usr/bin/ceph-detect-init usr/bin/ceph-debugpack +usr/bin/ceph-detect-init usr/bin/ceph-run usr/bin/crushtool usr/bin/monmaptool usr/bin/osdmaptool usr/lib/ceph/ceph_common.sh usr/lib/ceph/erasure-code/* +usr/lib/python*/dist-packages/ceph_detect_init* usr/lib/rados-classes/* +usr/sbin/ceph-create-keys usr/share/doc/ceph/sample.ceph.conf +usr/share/man/man8/ceph-create-keys.8 usr/share/man/man8/ceph-debugpack.8 usr/share/man/man8/ceph-deploy.8 +usr/share/man/man8/ceph-detect-init.8 usr/share/man/man8/ceph-run.8 usr/share/man/man8/crushtool.8 usr/share/man/man8/monmaptool.8 usr/share/man/man8/osdmaptool.8 -usr/lib/python*/dist-packages/ceph_detect_init* -usr/share/man/man8/ceph-detect-init.8 -usr/share/man/man8/ceph-create-keys.8 diff --git a/ceph/debian/ceph-base.maintscript b/ceph/debian/ceph-base.maintscript index 38e36d454..196dc0841 100644 --- a/ceph/debian/ceph-base.maintscript +++ b/ceph/debian/ceph-base.maintscript @@ -1,2 +1,2 @@ -rm_conffile /etc/logrotate.d/ceph.logrotate -- "$@" -rm_conffile /etc/logrotate.d/ceph -- "$@" +rm_conffile /etc/logrotate.d/ceph +rm_conffile /etc/logrotate.d/ceph.logrotate diff --git a/ceph/debian/ceph-common.dirs b/ceph/debian/ceph-common.dirs index a52e86d97..ff05698c2 100644 --- a/ceph/debian/ceph-common.dirs +++ b/ceph/debian/ceph-common.dirs @@ -1,3 +1,3 @@ etc/ceph -var/log/ceph var/lib/ceph +var/log/ceph diff --git a/ceph/debian/ceph-fuse.install b/ceph/debian/ceph-fuse.install index 364e86393..d6ad4dcb2 100644 --- a/ceph/debian/ceph-fuse.install +++ b/ceph/debian/ceph-fuse.install @@ -1,3 +1,3 @@ -usr/sbin/mount.fuse.ceph sbin usr/bin/ceph-fuse +usr/sbin/mount.fuse.ceph sbin usr/share/man/man8/ceph-fuse.8 diff --git a/ceph/debian/ceph-mon.install b/ceph/debian/ceph-mon.install index 9d08093f2..4fcee446e 100644 --- a/ceph/debian/ceph-mon.install +++ b/ceph/debian/ceph-mon.install @@ -1,5 +1,5 @@ usr/bin/ceph-mon usr/bin/ceph-rest-api +usr/lib/python*/dist-packages/ceph_rest_api.py* usr/share/man/man8/ceph-mon.8 usr/share/man/man8/ceph-rest-api.8 -usr/lib/python*/dist-packages/ceph_rest_api.py* diff --git a/ceph/debian/ceph-osd.install b/ceph/debian/ceph-osd.install index b1532d5e9..b87ec1715 100644 --- a/ceph/debian/ceph-osd.install +++ b/ceph/debian/ceph-osd.install @@ -1,15 +1,15 @@ -lib/udev/rules.d/95-ceph-osd.rules lib/udev/rules.d/60-ceph-by-parttypeuuid.rules -usr/sbin/ceph-disk +lib/udev/rules.d/95-ceph-osd.rules +usr/bin/ceph-bluestore-tool usr/bin/ceph-clsinfo usr/bin/ceph-objectstore-tool -usr/bin/ceph-bluestore-tool -usr/bin/ceph_objectstore_bench usr/bin/ceph-osd +usr/bin/ceph_objectstore_bench usr/lib/ceph/ceph-osd-prestart.sh +usr/lib/libos_tp.so* +usr/lib/libosd_tp.so* +usr/lib/python*/dist-packages/ceph_disk* +usr/sbin/ceph-disk usr/share/man/man8/ceph-clsinfo.8 usr/share/man/man8/ceph-disk.8 usr/share/man/man8/ceph-osd.8 -usr/lib/python*/dist-packages/ceph_disk* -usr/lib/libosd_tp.so* -usr/lib/libos_tp.so* diff --git a/ceph/debian/ceph-test.install b/ceph/debian/ceph-test.install index 15b04664e..edd4cef00 100644 --- a/ceph/debian/ceph-test.install +++ b/ceph/debian/ceph-test.install @@ -1,15 +1,18 @@ usr/bin/ceph-client-debug usr/bin/ceph-coverage +usr/bin/ceph-kvstore-tool +usr/bin/ceph-monstore-tool +usr/bin/ceph-osdomap-tool usr/bin/ceph_bench_log -usr/bin/ceph_kvstorebench -usr/bin/ceph_multi_stress_watch usr/bin/ceph_erasure_code usr/bin/ceph_erasure_code_benchmark +usr/bin/ceph_kvstorebench +usr/bin/ceph_multi_stress_watch usr/bin/ceph_omapbench -usr/bin/ceph_perf_objectstore usr/bin/ceph_perf_local usr/bin/ceph_perf_msgr_client usr/bin/ceph_perf_msgr_server +usr/bin/ceph_perf_objectstore usr/bin/ceph_psim usr/bin/ceph_radosacl usr/bin/ceph_rgw_jsonparser @@ -23,8 +26,5 @@ usr/bin/ceph_smalliobenchrbd usr/bin/ceph_test_* usr/bin/ceph_tpbench usr/bin/ceph_xattr_bench -usr/bin/ceph-monstore-tool -usr/bin/ceph-osdomap-tool -usr/bin/ceph-kvstore-tool -usr/share/java/libcephfs-test.jar usr/lib/ceph/ceph-monstore-update-crush.sh +usr/share/java/libcephfs-test.jar diff --git a/ceph/debian/changelog b/ceph/debian/changelog index 9a6469c30..0da87edd4 100644 --- a/ceph/debian/changelog +++ b/ceph/debian/changelog @@ -1,3 +1,9 @@ +ceph (12.1.1-1) stable; urgency=medium + + * New upstream release + + -- Ceph Release Team Mon, 17 Jul 2017 16:55:59 +0000 + ceph (12.1.0-1) stable; urgency=medium * New upstream release diff --git a/ceph/debian/control b/ceph/debian/control index a9ce89021..b9e4c6796 100644 --- a/ceph/debian/control +++ b/ceph/debian/control @@ -6,24 +6,24 @@ Vcs-Git: git://github.com/ceph/ceph.git Vcs-Browser: https://github.com/ceph/ceph Maintainer: Ceph Maintainers Uploaders: Ken Dreyer , - Alfredo Deza + Alfredo Deza , Build-Depends: bc, btrfs-tools, - gperf, - cmake, + cmake, cpio, - cryptsetup-bin | cryptsetup, + cryptsetup-bin | cryptsetup, cython, cython3, debhelper (>= 9), + default-jdk, dh-exec, dh-python, - dh-systemd, - default-jdk, + dh-systemd, + gdisk, git, - gdisk, + gperf, javahelper, - jq, + jq, junit4, libaio-dev, libbabeltrace-ctf-dev, @@ -33,47 +33,48 @@ Build-Depends: bc, libexpat1-dev, libfuse-dev, libgoogle-perftools-dev [i386 amd64 arm64], - libibverbs-dev, + libibverbs-dev, libkeyutils-dev, + libldap2-dev, libleveldb-dev, + liblttng-ust-dev, libnss3-dev, libsnappy-dev, - libldap2-dev, libssl-dev, - liblttng-ust-dev, libtool, libudev-dev, libxml2-dev, - lsb-release, + lsb-release, parted, pkg-config, python (>= 2.7), python-all-dev, python-cherrypy3, python-nose, - python-pecan, - python-prettytable, - python-setuptools, + python-pecan, + python-prettytable, + python-setuptools, python-sphinx, - python-werkzeug, + python-werkzeug, python3-all-dev, python3-setuptools, - virtualenv | python-virtualenv, + socat, uuid-runtime, valgrind, + virtualenv | python-virtualenv, xfslibs-dev, xfsprogs, xmlstarlet, yasm [amd64], - zlib1g-dev + zlib1g-dev, Standards-Version: 3.9.3 Package: ceph Architecture: linux-any -Depends: ceph-mon (= ${binary:Version}), - ceph-mgr (= ${binary:Version}), - ceph-osd (= ${binary:Version}) -Recommends: ceph-mds (= ${binary:Version}) +Depends: ceph-mgr (= ${binary:Version}), + ceph-mon (= ${binary:Version}), + ceph-osd (= ${binary:Version}), +Recommends: ceph-mds (= ${binary:Version}), Description: distributed storage and file system Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -90,20 +91,23 @@ Depends: binutils, grep, logrotate, psmisc, - ${python:Depends}, xfsprogs, ${misc:Depends}, - ${shlibs:Depends} + ${python:Depends}, + ${shlibs:Depends}, Recommends: btrfs-tools, ceph-mds (= ${binary:Version}), librados2 (= ${binary:Version}), libradosstriper1 (= ${binary:Version}), librbd1 (= ${binary:Version}), - ntp | time-daemon -Replaces: ceph-common (<< 0.78-500), python-ceph (<< 0.92-1223), - ceph-test (<< 0.94-1322), ceph (<< 10) -Breaks: python-ceph (<< 0.92-1223), ceph-test (<< 0.94-1322), - ceph (<< 10) + ntp | time-daemon, +Replaces: ceph (<< 10), + ceph-common (<< 0.78-500), + ceph-test (<< 0.94-1322), + python-ceph (<< 0.92-1223), +Breaks: ceph (<< 10), + ceph-test (<< 0.94-1322), + python-ceph (<< 0.92-1223), Description: common ceph daemon libraries and management tools Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -117,7 +121,8 @@ Package: ceph-base-dbg Architecture: linux-any Section: debug Priority: extra -Depends: ceph-base (= ${binary:Version}), ${misc:Depends} +Depends: ceph-base (= ${binary:Version}), + ${misc:Depends}, Description: debugging symbols for ceph-base Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -133,11 +138,11 @@ Package: ceph-mds Architecture: linux-any Depends: ceph-base (= ${binary:Version}), ${misc:Depends}, - ${shlibs:Depends} + ${shlibs:Depends}, Recommends: ceph-fuse (= ${binary:Version}), - libcephfs2 (= ${binary:Version}) -Replaces: ceph (<< 0.93-417) -Breaks: ceph (<< 0.93-417) + libcephfs2 (= ${binary:Version}), +Replaces: ceph (<< 0.93-417), +Breaks: ceph (<< 0.93-417), Description: metadata server for the ceph distributed file system Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -150,7 +155,8 @@ Package: ceph-mds-dbg Architecture: linux-any Section: debug Priority: extra -Depends: ceph-mds (= ${binary:Version}), ${misc:Depends} +Depends: ceph-mds (= ${binary:Version}), + ${misc:Depends}, Description: debugging symbols for ceph-mds Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -161,15 +167,15 @@ Description: debugging symbols for ceph-mds Package: ceph-mgr Architecture: linux-any Depends: ceph-base (= ${binary:Version}), + python-cherrypy3, python-openssl, python-pecan, python-werkzeug, ${misc:Depends}, ${python:Depends}, - python-cherrypy3, - ${shlibs:Depends} -Replaces: ceph (<< 0.93-417) -Breaks: ceph (<< 0.93-417) + ${shlibs:Depends}, +Replaces: ceph (<< 0.93-417), +Breaks: ceph (<< 0.93-417), Description: manager for the ceph distributed storage system Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -182,7 +188,8 @@ Package: ceph-mgr-dbg Architecture: linux-any Section: debug Priority: extra -Depends: ceph-mgr (= ${binary:Version}), ${misc:Depends} +Depends: ceph-mgr (= ${binary:Version}), + ${misc:Depends}, Description: debugging symbols for ceph-mgr Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -195,10 +202,10 @@ Architecture: linux-any Depends: ceph-base (= ${binary:Version}), python-flask, ${misc:Depends}, - ${shlibs:Depends} -Recommends: ceph-common -Replaces: ceph (<< 10) -Breaks: ceph (<< 10) + ${shlibs:Depends}, +Recommends: ceph-common, +Replaces: ceph (<< 10), +Breaks: ceph (<< 10), Description: monitor server for the ceph storage system Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -213,7 +220,8 @@ Package: ceph-mon-dbg Architecture: linux-any Section: debug Priority: extra -Depends: ceph-mon (= ${binary:Version}), ${misc:Depends} +Depends: ceph-mon (= ${binary:Version}), + ${misc:Depends}, Description: debugging symbols for ceph-mon Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -227,10 +235,10 @@ Depends: ceph-base (= ${binary:Version}), parted, ${misc:Depends}, ${python:Depends}, - ${shlibs:Depends} -Recommends: ceph-common (= ${binary:Version}) -Replaces: ceph (<< 10) -Breaks: ceph (<< 10) + ${shlibs:Depends}, +Recommends: ceph-common (= ${binary:Version}), +Replaces: ceph (<< 10), +Breaks: ceph (<< 10), Description: OSD server for the ceph storage system Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -244,7 +252,8 @@ Package: ceph-osd-dbg Architecture: linux-any Section: debug Priority: extra -Depends: ceph-osd (= ${binary:Version}), ${misc:Depends} +Depends: ceph-osd (= ${binary:Version}), + ${misc:Depends}, Description: debugging symbols for ceph-osd Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -254,8 +263,9 @@ Description: debugging symbols for ceph-osd Package: ceph-fuse Architecture: linux-any -Depends: ${misc:Depends}, ${shlibs:Depends} -Recommends: fuse +Depends: ${misc:Depends}, + ${shlibs:Depends}, +Recommends: fuse, Description: FUSE-based client for the Ceph distributed file system Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -273,7 +283,8 @@ Package: ceph-fuse-dbg Architecture: linux-any Section: debug Priority: extra -Depends: ceph-fuse (= ${binary:Version}), ${misc:Depends} +Depends: ceph-fuse (= ${binary:Version}), + ${misc:Depends}, Description: debugging symbols for ceph-fuse Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -285,8 +296,9 @@ Description: debugging symbols for ceph-fuse Package: rbd-fuse Architecture: linux-any -Depends: ${misc:Depends}, ${shlibs:Depends} -Recommends: fuse +Depends: ${misc:Depends}, + ${shlibs:Depends}, +Recommends: fuse, Description: FUSE-based rbd client for the Ceph distributed file system Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -299,7 +311,8 @@ Package: rbd-fuse-dbg Architecture: linux-any Section: debug Priority: extra -Depends: rbd-fuse (= ${binary:Version}), ${misc:Depends} +Depends: rbd-fuse (= ${binary:Version}), + ${misc:Depends}, Description: debugging symbols for rbd-fuse Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -313,7 +326,7 @@ Architecture: linux-any Depends: ceph-common (= ${binary:Version}), librados2 (= ${binary:Version}), ${misc:Depends}, - ${shlibs:Depends} + ${shlibs:Depends}, Description: Ceph daemon for mirroring RBD images Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -325,7 +338,8 @@ Package: rbd-mirror-dbg Architecture: linux-any Section: debug Priority: extra -Depends: rbd-mirror (= ${binary:Version}), ${misc:Depends} +Depends: rbd-mirror (= ${binary:Version}), + ${misc:Depends}, Description: debugging symbols for rbd-mirror Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -338,7 +352,7 @@ Description: debugging symbols for rbd-mirror Package: rbd-nbd Architecture: linux-any Depends: ${misc:Depends}, - ${shlibs:Depends} + ${shlibs:Depends}, Description: NBD-based rbd client for the Ceph distributed file system Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -353,7 +367,8 @@ Package: rbd-nbd-dbg Architecture: linux-any Section: debug Priority: extra -Depends: rbd-nbd (= ${binary:Version}), ${misc:Depends} +Depends: rbd-nbd (= ${binary:Version}), + ${misc:Depends}, Description: debugging symbols for rbd-nbd Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -365,27 +380,30 @@ Description: debugging symbols for rbd-nbd Package: ceph-common Architecture: linux-any -Depends: librbd1 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends}, - python-rados (= ${binary:Version}), +Depends: librbd1 (= ${binary:Version}), python-cephfs (= ${binary:Version}), + python-prettytable, + python-rados (= ${binary:Version}), python-rbd (= ${binary:Version}), + python-requests, python-rgw (= ${binary:Version}), + ${misc:Depends}, ${python:Depends}, - python-requests, - python-prettytable -Conflicts: ceph-client-tools -Replaces: ceph-client-tools, - ceph (<< 10), - ceph-test (<< 9.0.3-1646), - python-ceph (<< 0.92-1223), - librbd1 (<< 0.92-1238), - ceph-fs-common (<< 11.0) + ${shlibs:Depends}, +Conflicts: ceph-client-tools, +Replaces: ceph (<< 10), + ceph-client-tools, + ceph-fs-common (<< 11.0), + ceph-test (<< 9.0.3-1646), + librbd1 (<< 0.92-1238), + python-ceph (<< 0.92-1223), Breaks: ceph (<< 10), - ceph-test (<< 9.0.3-1646), - python-ceph (<< 0.92-1223), - librbd1 (<< 0.92-1238), - ceph-fs-common (<< 11.0) -Suggests: ceph-base (= ${binary:Version}), ceph-mds (= ${binary:Version}) + ceph-fs-common (<< 11.0), + ceph-test (<< 9.0.3-1646), + librbd1 (<< 0.92-1238), + python-ceph (<< 0.92-1223), +Suggests: ceph-base (= ${binary:Version}), + ceph-mds (= ${binary:Version}), Description: common utilities to mount and interact with a ceph storage cluster Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -394,11 +412,12 @@ Description: common utilities to mount and interact with a ceph storage cluster Package: ceph-common-dbg Architecture: linux-any -Depends: ceph-common (= ${binary:Version}), ${misc:Depends} -Conflicts: ceph-client-tools-dbg +Depends: ceph-common (= ${binary:Version}), + ${misc:Depends}, +Conflicts: ceph-client-tools-dbg, Replaces: ceph-client-tools-dbg, - ceph-test-dbg (<< 9.0.3-1646) -Breaks: ceph-test-dbg (<< 9.0.3-1646) + ceph-test-dbg (<< 9.0.3-1646), +Breaks: ceph-test-dbg (<< 9.0.3-1646), Section: debug Priority: extra Description: debugging symbols for ceph-common @@ -411,9 +430,11 @@ Description: debugging symbols for ceph-common Package: ceph-resource-agents Architecture: linux-any -Recommends: pacemaker +Recommends: pacemaker, Priority: extra -Depends: ceph (= ${binary:Version}), resource-agents, ${misc:Depends} +Depends: ceph (= ${binary:Version}), + resource-agents, + ${misc:Depends}, Description: OCF-compliant resource agents for Ceph Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -424,11 +445,14 @@ Description: OCF-compliant resource agents for Ceph such as Pacemaker. Package: librados2 -Conflicts: librados, librados1 -Replaces: librados, librados1 +Conflicts: librados, + librados1, +Replaces: librados, + librados1, Architecture: linux-any Section: libs -Depends: ${misc:Depends}, ${shlibs:Depends} +Depends: ${misc:Depends}, + ${shlibs:Depends}, Description: RADOS distributed object store client library RADOS is a reliable, autonomic distributed object storage cluster developed as part of the Ceph distributed storage system. This is a @@ -436,12 +460,13 @@ Description: RADOS distributed object store client library store using a simple file-like interface. Package: librados2-dbg -Conflicts: librados1-dbg -Replaces: librados1-dbg +Conflicts: librados1-dbg, +Replaces: librados1-dbg, Architecture: linux-any Section: debug Priority: extra -Depends: librados2 (= ${binary:Version}), ${misc:Depends} +Depends: librados2 (= ${binary:Version}), + ${misc:Depends}, Description: debugging symbols for librados RADOS is a reliable, autonomic distributed object storage cluster developed as part of the Ceph distributed storage system. This is a @@ -453,9 +478,13 @@ Description: debugging symbols for librados Package: librados-dev Architecture: linux-any Section: libdevel -Depends: librados2 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} -Conflicts: librados1-dev, librados2-dev -Replaces: librados1-dev, librados2-dev +Depends: librados2 (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends}, +Conflicts: librados1-dev, + librados2-dev, +Replaces: librados1-dev, + librados2-dev, Description: RADOS distributed object store client library (development files) RADOS is a reliable, autonomic distributed object storage cluster developed as part of the Ceph distributed storage system. This is a @@ -468,7 +497,9 @@ Description: RADOS distributed object store client library (development files) Package: libradosstriper1 Architecture: linux-any Section: libs -Depends: librados2 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Depends: librados2 (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends}, Description: RADOS striping interface Striping interface built on top of the rados library, allowing to stripe bigger objects onto several standard rados objects using @@ -478,7 +509,8 @@ Package: libradosstriper1-dbg Architecture: linux-any Section: debug Priority: extra -Depends: libradosstriper1 (= ${binary:Version}), ${misc:Depends} +Depends: libradosstriper1 (= ${binary:Version}), + ${misc:Depends}, Description: debugging symbols for libradosstriper libradosstriper is a striping interface built on top of the rados library, allowing to stripe bigger objects onto several standard @@ -489,7 +521,8 @@ Description: debugging symbols for libradosstriper Package: libradosstriper-dev Architecture: linux-any Section: libdevel -Depends: libradosstriper1 (= ${binary:Version}), ${misc:Depends} +Depends: libradosstriper1 (= ${binary:Version}), + ${misc:Depends}, Description: RADOS striping interface (development files) libradosstriper is a striping interface built on top of the rados library, allowing to stripe bigger objects onto several standard @@ -501,7 +534,9 @@ Description: RADOS striping interface (development files) Package: librbd1 Architecture: linux-any Section: libs -Depends: librados2 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Depends: librados2 (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends}, Description: RADOS block device client library RBD is a block device striped across multiple distributed objects in RADOS, a reliable, autonomic distributed object storage cluster @@ -512,7 +547,8 @@ Package: librbd1-dbg Architecture: linux-any Section: debug Priority: extra -Depends: librbd1 (= ${binary:Version}), ${misc:Depends} +Depends: librbd1 (= ${binary:Version}), + ${misc:Depends}, Description: debugging symbols for librbd1 RBD is a block device striped across multiple distributed objects in RADOS, a reliable, autonomic distributed object storage cluster @@ -525,9 +561,10 @@ Package: librbd-dev Architecture: linux-any Section: libdevel Depends: librados-dev (= ${binary:Version}), - librbd1 (= ${binary:Version}), ${misc:Depends} -Conflicts: librbd1-dev -Replaces: librbd1-dev + librbd1 (= ${binary:Version}), + ${misc:Depends}, +Conflicts: librbd1-dev, +Replaces: librbd1-dev, Description: RADOS block device client library (development files) RBD is a block device striped across multiple distributed objects in RADOS, a reliable, autonomic distributed object storage cluster @@ -538,11 +575,16 @@ Description: RADOS block device client library (development files) link against librbd1. Package: libcephfs2 -Conflicts: libceph, libceph1, libcephfs -Replaces: libceph, libceph1, libcephfs +Conflicts: libceph, + libceph1, + libcephfs, +Replaces: libceph, + libceph1, + libcephfs, Architecture: linux-any Section: libs -Depends: ${misc:Depends}, ${shlibs:Depends} +Depends: ${misc:Depends}, + ${shlibs:Depends}, Description: Ceph distributed file system client library Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -554,9 +596,10 @@ Package: libcephfs2-dbg Architecture: linux-any Section: debug Priority: extra -Depends: libcephfs2 (= ${binary:Version}), ${misc:Depends} -Conflicts: libceph1-dbg -Replaces: libceph1-dbg +Depends: libcephfs2 (= ${binary:Version}), + ${misc:Depends}, +Conflicts: libceph1-dbg, +Replaces: libceph1-dbg, Description: debugging symbols for libcephfs2 Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -569,9 +612,14 @@ Description: debugging symbols for libcephfs2 Package: libcephfs-dev Architecture: linux-any Section: libdevel -Depends: libcephfs2 (= ${binary:Version}), ${misc:Depends} -Conflicts: libceph-dev, libceph1-dev, libcephfs2-dev -Replaces: libceph-dev, libceph1-dev, libcephfs2-dev +Depends: libcephfs2 (= ${binary:Version}), + ${misc:Depends}, +Conflicts: libceph-dev, + libceph1-dev, + libcephfs2-dev, +Replaces: libceph-dev, + libceph1-dev, + libcephfs2-dev, Description: Ceph distributed file system client library (development files) Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -585,7 +633,9 @@ Description: Ceph distributed file system client library (development files) Package: librgw2 Architecture: linux-any Section: libs -Depends: librados2 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Depends: librados2 (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends}, Description: RADOS Gateway client library RADOS is a distributed object store used by the Ceph distributed storage system. This package provides a REST gateway to the @@ -598,7 +648,8 @@ Package: librgw2-dbg Architecture: linux-any Section: debug Priority: extra -Depends: librgw2 (= ${binary:Version}), ${misc:Depends} +Depends: librgw2 (= ${binary:Version}), + ${misc:Depends}, Description: debugging symbols for librbd1 RADOS is a distributed object store used by the Ceph distributed storage system. This package provides a REST gateway to the @@ -611,7 +662,8 @@ Package: librgw-dev Architecture: linux-any Section: libdevel Depends: librados-dev (= ${binary:Version}), - librgw2 (= ${binary:Version}), ${misc:Depends} + librgw2 (= ${binary:Version}), + ${misc:Depends}, Description: RADOS client library (development files) RADOS is a distributed object store used by the Ceph distributed storage system. This package provides a REST gateway to the @@ -624,11 +676,11 @@ Description: RADOS client library (development files) Package: radosgw Architecture: linux-any Depends: ceph-common (= ${binary:Version}), - mime-support, librgw2 (= ${binary:Version}), + mime-support, ${misc:Depends}, - ${shlibs:Depends} -Recommends: ntp | time-daemon + ${shlibs:Depends}, +Recommends: ntp | time-daemon, Description: REST gateway for RADOS distributed object store RADOS is a distributed object store used by the Ceph distributed storage system. This package provides a REST gateway to the @@ -641,7 +693,8 @@ Package: radosgw-dbg Architecture: linux-any Section: debug Priority: extra -Depends: radosgw (= ${binary:Version}), ${misc:Depends} +Depends: radosgw (= ${binary:Version}), + ${misc:Depends}, Description: debugging symbols for radosgw RADOS is a distributed object store used by the Ceph distributed storage system. This package provides a REST gateway to the @@ -652,7 +705,12 @@ Description: debugging symbols for radosgw Package: ceph-test Architecture: linux-any -Depends: ceph-common, curl, xmlstarlet, jq, ${misc:Depends}, ${shlibs:Depends} +Depends: ceph-common, + curl, + jq, + xmlstarlet, + ${misc:Depends}, + ${shlibs:Depends}, Description: Ceph test and benchmarking tools This package contains tools for testing and benchmarking Ceph. @@ -660,9 +718,10 @@ Package: ceph-test-dbg Architecture: linux-any Section: debug Priority: extra -Depends: ceph-test (= ${binary:Version}), ceph-common (= ${binary:Version}), +Depends: ceph-common (= ${binary:Version}), + ceph-test (= ${binary:Version}), curl, - ${misc:Depends} + ${misc:Depends}, Description: Ceph test and benchmarking tools . This package contains the debugging symbols for ceph-test. @@ -670,10 +729,10 @@ Description: Ceph test and benchmarking tools Package: python-ceph Architecture: linux-any Section: python -Depends: python-rados (= ${binary:Version}), +Depends: python-cephfs (= ${binary:Version}), + python-rados (= ${binary:Version}), python-rbd (= ${binary:Version}), python-rgw (= ${binary:Version}), - python-cephfs (= ${binary:Version}) Description: Meta-package for python libraries for the Ceph libraries Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -686,10 +745,10 @@ Architecture: linux-any Section: python Depends: librados2 (= ${binary:Version}), ${misc:Depends}, + ${python:Depends}, ${shlibs:Depends}, - ${python:Depends} -Replaces: python-ceph (<< 0.92-1223) -Breaks: python-ceph (<< 0.92-1223) +Replaces: python-ceph (<< 0.92-1223), +Breaks: python-ceph (<< 0.92-1223), Description: Python 2 libraries for the Ceph librados library Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -703,8 +762,8 @@ Architecture: linux-any Section: python Depends: librados2 (= ${binary:Version}), ${misc:Depends}, + ${python3:Depends}, ${shlibs:Depends}, - ${python3:Depends} Description: Python 3 libraries for the Ceph librados library Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -718,10 +777,10 @@ Architecture: linux-any Section: python Depends: librbd1 (>= ${binary:Version}), ${misc:Depends}, + ${python:Depends}, ${shlibs:Depends}, - ${python:Depends} -Replaces: python-ceph (<< 0.92-1223) -Breaks: python-ceph (<< 0.92-1223) +Replaces: python-ceph (<< 0.92-1223), +Breaks: python-ceph (<< 0.92-1223), Description: Python 2 libraries for the Ceph librbd library Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -735,8 +794,8 @@ Architecture: linux-any Section: python Depends: librbd1 (>= ${binary:Version}), ${misc:Depends}, + ${python3:Depends}, ${shlibs:Depends}, - ${python3:Depends} Description: Python 3 libraries for the Ceph librbd library Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -750,10 +809,10 @@ Architecture: linux-any Section: python Depends: librgw2 (>= ${binary:Version}), ${misc:Depends}, + ${python:Depends}, ${shlibs:Depends}, - ${python:Depends} -Replaces: python-ceph (<< 0.92-1223) -Breaks: python-ceph (<< 0.92-1223) +Replaces: python-ceph (<< 0.92-1223), +Breaks: python-ceph (<< 0.92-1223), Description: Python 2 libraries for the Ceph librgw library Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -767,8 +826,8 @@ Architecture: linux-any Section: python Depends: librgw2 (>= ${binary:Version}), ${misc:Depends}, + ${python3:Depends}, ${shlibs:Depends}, - ${python3:Depends} Description: Python 3 libraries for the Ceph librgw library Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -782,10 +841,10 @@ Architecture: linux-any Section: python Depends: libcephfs2 (= ${binary:Version}), ${misc:Depends}, + ${python:Depends}, ${shlibs:Depends}, - ${python:Depends} -Replaces: python-ceph (<< 0.92-1223) -Breaks: python-ceph (<< 0.92-1223) +Replaces: python-ceph (<< 0.92-1223), +Breaks: python-ceph (<< 0.92-1223), Description: Python 2 libraries for the Ceph libcephfs library Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -799,8 +858,8 @@ Architecture: linux-any Section: python Depends: libcephfs2 (= ${binary:Version}), ${misc:Depends}, + ${python3:Depends}, ${shlibs:Depends}, - ${python3:Depends} Description: Python 3 libraries for the Ceph libcephfs library Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -812,7 +871,8 @@ Description: Python 3 libraries for the Ceph libcephfs library Package: python3-ceph-argparse Architecture: linux-any Section: python -Depends: ${misc:Depends}, ${python3:Depends} +Depends: ${misc:Depends}, + ${python3:Depends}, Description: Python 3 utility libraries for Ceph CLI Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -824,20 +884,24 @@ Description: Python 3 utility libraries for Ceph CLI Package: libcephfs-java Section: java Architecture: all -Depends: libcephfs-jni (= ${binary:Version}), ${java:Depends}, ${misc:Depends} +Depends: libcephfs-jni (= ${binary:Version}), + ${java:Depends}, + ${misc:Depends}, Description: Java libraries for the Ceph File System Package: libcephfs-jni Architecture: linux-any Section: java -Depends: libcephfs2 (= ${binary:Version}), ${java:Depends}, - ${misc:Depends}, ${shlibs:Depends} +Depends: libcephfs2 (= ${binary:Version}), + ${java:Depends}, + ${misc:Depends}, + ${shlibs:Depends}, Description: Java Native Interface library for CephFS Java bindings Package: rados-objclass-dev Architecture: linux-any Section: libdevel -Depends: librados-dev (= ${binary:Version}) ${misc:Depends} +Depends: librados-dev (= ${binary:Version}) ${misc:Depends}, Description: RADOS object class development kit. . This package contains development files needed for building RADOS object class plugins. diff --git a/ceph/debian/copyright b/ceph/debian/copyright index 362ae78f2..994d67607 100644 --- a/ceph/debian/copyright +++ b/ceph/debian/copyright @@ -38,25 +38,25 @@ Copyright: Copyright 2012-2013 Intel Corporation All Rights Reserved. License: BSD 3-clause -Files: src/common/sctp_crc32.c: +Files: src/common/sctp_crc32.c: Copyright: Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. Copyright (c) 2004-2006 Intel Corporation - All Rights Reserved License: Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - + a) Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - + b) 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. - + c) Neither the name of Cisco Systems, Inc. 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 @@ -110,19 +110,19 @@ License: 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 diff --git a/ceph/debian/libcephfs-dev.install b/ceph/debian/libcephfs-dev.install index d2d648719..e2cf6e9f3 100644 --- a/ceph/debian/libcephfs-dev.install +++ b/ceph/debian/libcephfs-dev.install @@ -1,3 +1,3 @@ -usr/include/cephfs/libcephfs.h usr/include/cephfs/ceph_statx.h +usr/include/cephfs/libcephfs.h usr/lib/libcephfs.so diff --git a/ceph/debian/libcephfs2.install b/ceph/debian/libcephfs2.install index f1b4adf05..b7c0eb058 100644 --- a/ceph/debian/libcephfs2.install +++ b/ceph/debian/libcephfs2.install @@ -1,2 +1 @@ - usr/lib/libcephfs.so.* diff --git a/ceph/debian/librados-dev.install b/ceph/debian/librados-dev.install index ec6b4332a..19ce3914f 100644 --- a/ceph/debian/librados-dev.install +++ b/ceph/debian/librados-dev.install @@ -2,13 +2,13 @@ usr/bin/librados-config usr/include/rados/buffer.h usr/include/rados/buffer_fwd.h usr/include/rados/crc32c.h +usr/include/rados/inline_memory.h usr/include/rados/librados.h usr/include/rados/librados.hpp -usr/include/rados/inline_memory.h +usr/include/rados/memory.h usr/include/rados/page.h usr/include/rados/rados_types.h usr/include/rados/rados_types.hpp -usr/include/rados/memory.h usr/lib/librados.so usr/lib/librados_tp.so usr/share/man/man8/librados-config.8 diff --git a/ceph/debian/librados2.install b/ceph/debian/librados2.install index 722bf5804..3bdeedfd1 100644 --- a/ceph/debian/librados2.install +++ b/ceph/debian/librados2.install @@ -1,3 +1,3 @@ +usr/lib/ceph/libceph-common.so* usr/lib/librados.so.* usr/lib/librados_tp.so.* -usr/lib/ceph/libceph-common.so* diff --git a/ceph/debian/libradosstriper1.install b/ceph/debian/libradosstriper1.install index 0adecb525..46235acff 100644 --- a/ceph/debian/libradosstriper1.install +++ b/ceph/debian/libradosstriper1.install @@ -1,2 +1 @@ - usr/lib/libradosstriper.so.* diff --git a/ceph/debian/python-cephfs.install b/ceph/debian/python-cephfs.install index ed18d2e7e..d8a283424 100644 --- a/ceph/debian/python-cephfs.install +++ b/ceph/debian/python-cephfs.install @@ -1,3 +1,3 @@ usr/lib/python2*/dist-packages/ceph_volume_client.py* -usr/lib/python2*/dist-packages/cephfs.so usr/lib/python2*/dist-packages/cephfs-*.egg-info +usr/lib/python2*/dist-packages/cephfs.so diff --git a/ceph/debian/python-rados.install b/ceph/debian/python-rados.install index 64379a78a..0519518e4 100644 --- a/ceph/debian/python-rados.install +++ b/ceph/debian/python-rados.install @@ -1,2 +1,2 @@ -usr/lib/python2*/dist-packages/rados.so usr/lib/python2*/dist-packages/rados-*.egg-info +usr/lib/python2*/dist-packages/rados.so diff --git a/ceph/debian/python-rbd.install b/ceph/debian/python-rbd.install index 57051ff12..4a170ce56 100644 --- a/ceph/debian/python-rbd.install +++ b/ceph/debian/python-rbd.install @@ -1,2 +1,2 @@ -usr/lib/python2*/dist-packages/rbd.so usr/lib/python2*/dist-packages/rbd-*.egg-info +usr/lib/python2*/dist-packages/rbd.so diff --git a/ceph/debian/python-rgw.install b/ceph/debian/python-rgw.install index 15e1f4921..05e6936c0 100644 --- a/ceph/debian/python-rgw.install +++ b/ceph/debian/python-rgw.install @@ -1,2 +1,2 @@ -usr/lib/python2*/dist-packages/rgw.so usr/lib/python2*/dist-packages/rgw-*.egg-info +usr/lib/python2*/dist-packages/rgw.so diff --git a/ceph/debian/python3-cephfs.install b/ceph/debian/python3-cephfs.install index 8d07200da..6eb883670 100644 --- a/ceph/debian/python3-cephfs.install +++ b/ceph/debian/python3-cephfs.install @@ -1,3 +1,3 @@ usr/lib/python3*/dist-packages/ceph_volume_client.py -usr/lib/python3*/dist-packages/cephfs.cpython*.so usr/lib/python3*/dist-packages/cephfs-*.egg-info +usr/lib/python3*/dist-packages/cephfs.cpython*.so diff --git a/ceph/debian/python3-rados.install b/ceph/debian/python3-rados.install index 5622ac0e4..98b5d76cb 100644 --- a/ceph/debian/python3-rados.install +++ b/ceph/debian/python3-rados.install @@ -1,2 +1,2 @@ -usr/lib/python3*/dist-packages/rados.cpython*.so usr/lib/python3*/dist-packages/rados-*.egg-info +usr/lib/python3*/dist-packages/rados.cpython*.so diff --git a/ceph/debian/python3-rbd.install b/ceph/debian/python3-rbd.install index c721ca25a..5f4e6e143 100644 --- a/ceph/debian/python3-rbd.install +++ b/ceph/debian/python3-rbd.install @@ -1,2 +1,2 @@ -usr/lib/python3*/dist-packages/rbd.cpython*.so usr/lib/python3*/dist-packages/rbd-*.egg-info +usr/lib/python3*/dist-packages/rbd.cpython*.so diff --git a/ceph/debian/python3-rgw.install b/ceph/debian/python3-rgw.install index 4131a2ce5..57f455907 100644 --- a/ceph/debian/python3-rgw.install +++ b/ceph/debian/python3-rgw.install @@ -1,2 +1,2 @@ -usr/lib/python3*/dist-packages/rgw.cpython*.so usr/lib/python3*/dist-packages/rgw-*.egg-info +usr/lib/python3*/dist-packages/rgw.cpython*.so diff --git a/ceph/debian/radosgw.install b/ceph/debian/radosgw.install index 9f2c8debb..d58379929 100644 --- a/ceph/debian/radosgw.install +++ b/ceph/debian/radosgw.install @@ -1,5 +1,5 @@ usr/bin/radosgw -usr/bin/radosgw-token usr/bin/radosgw-es usr/bin/radosgw-object-expirer +usr/bin/radosgw-token usr/share/man/man8/radosgw.8 diff --git a/ceph/debian/rules b/ceph/debian/rules index d4b3c97f7..2e4ec9d22 100755 --- a/ceph/debian/rules +++ b/ceph/debian/rules @@ -131,9 +131,16 @@ override_dh_installinit: dh_installinit -p ceph-base --name ceph --no-start dh_installinit -p radosgw --no-start -override_dh_systemd_start: + # NOTE: execute systemd helpers so they pickup dh_install'ed units and targets + dh_systemd_enable dh_systemd_start --no-restart-on-upgrade +override_dh_systemd_enable: + # systemd enable done as part of dh_installinit + +override_dh_systemd_start: + # systemd start done as part of dh_installinit + override_dh_strip: dh_strip -pceph-mds --dbg-package=ceph-mds-dbg dh_strip -pceph-fuse --dbg-package=ceph-fuse-dbg diff --git a/ceph/doc/cephfs/administration.rst b/ceph/doc/cephfs/administration.rst index 23bd5fc6a..f4976cfa2 100644 --- a/ceph/doc/cephfs/administration.rst +++ b/ceph/doc/cephfs/administration.rst @@ -81,17 +81,29 @@ These commands act on specific mds daemons or ranks. :: - mds fail -This command deactivates an MDS causing it to flush its entire journal to -backing RADOS objects and close all open client sessions. Deactivating an MDS -is primarily intended for bringing down a rank after reducing the number of -active MDS (max_mds). +Mark an MDS daemon as failed. This is equivalent to what the cluster +would do if an MDS daemon had failed to send a message to the mon +for ``mds_beacon_grace`` second. If the daemon was active and a suitable +standby is available, using ``mds fail`` will force a failover to the standby. + +If the MDS daemon was in reality still running, then using ``mds fail`` +will cause the daemon to restart. If it was active and a standby was +available, then the "failed" daemon will return as a standby. :: mds deactivate +Deactivate an MDS, causing it to flush its entire journal to +backing RADOS objects and close all open client sessions. Deactivating an MDS +is primarily intended for bringing down a rank after reducing the number of +active MDS (max_mds). + +Use ``mds deactivate`` in conjunction with adjustments to ``max_mds`` to +shrink an MDS cluster. See :doc:`/cephfs/multimds` + :: tell mds. diff --git a/ceph/doc/cephfs/experimental-features.rst b/ceph/doc/cephfs/experimental-features.rst index bdfa998a9..5e5b414ec 100644 --- a/ceph/doc/cephfs/experimental-features.rst +++ b/ceph/doc/cephfs/experimental-features.rst @@ -23,22 +23,7 @@ failures within it are unlikely to make non-inlined data inaccessible Inline data has always been off by default and requires setting the "inline_data" flag. -Multi-MDS filesystem clusters ------------------------------ -CephFS has been designed from the ground up to support fragmenting the metadata -hierarchy across multiple active metadata servers, to allow horizontal scaling -to arbitrary throughput requirements. Unfortunately, doing so requires a lot -more working code than having a single MDS which is authoritative over the -entire filesystem namespace. - -Multiple active MDSes are generally stable under trivial workloads, but often -break in the presence of any failure, and do not have enough testing to offer -any stability guarantees. If a filesystem with multiple active MDSes does -experience failure, it will require (generally extensive) manual intervention. -There are serious known bugs. - -Multi-MDS filesystems have always required explicitly increasing the "max_mds" -value and have been further protected with the "allow_multimds" flag for Jewel. + Mantle: Programmable Metadata Load Balancer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -102,3 +87,21 @@ the ``allow_dirfrags`` flag on the filesystem: ceph fs set allow_dirfrags +Multiple active metadata servers +-------------------------------- + +Prior to the *Luminous* (12.2.x) release, running multiple active metadata +servers within a single filesystem was considered experimental. Creating +multiple active metadata servers is now permitted by default on new +filesystems. + +Filesystems created with older versions of Ceph still require explicitly +enabling multiple active metadata servers as follows: + +:: + + ceph fs set allow_multimds + +Note that the default size of the active mds cluster (``max_mds``) is +still set to 1 initially. + diff --git a/ceph/doc/cephfs/mantle.rst b/ceph/doc/cephfs/mantle.rst index 8a7d729ac..6ad973e2d 100644 --- a/ceph/doc/cephfs/mantle.rst +++ b/ceph/doc/cephfs/mantle.rst @@ -76,7 +76,6 @@ Mantle with `vstart.sh` :: - bin/ceph fs set cephfs allow_multimds true --yes-i-really-mean-it bin/ceph fs set cephfs max_mds 5 bin/ceph fs set cephfs_a balancer greedyspill.lua diff --git a/ceph/doc/changelog/v10.2.8.txt b/ceph/doc/changelog/v10.2.8.txt new file mode 100644 index 000000000..575a7b062 --- /dev/null +++ b/ceph/doc/changelog/v10.2.8.txt @@ -0,0 +1,5435 @@ +commit f5b1f1fd7c0be0506ba73502a675de9d048b744e +Author: Jenkins Build Slave User +Date: Thu Jul 6 14:56:18 2017 +0000 + + 10.2.8 + +commit 66dbf9beef04988dbd3653591e51afa6d84e3990 +Merge: 2f491b2e5e f46ccf2cb4 +Author: Nathan Cutler +Date: Tue Jul 4 17:43:57 2017 +0200 + + Merge pull request #14710 from smithfarm/wip-start-race + + tests: rados: sleep before ceph tell osd.0 flush_pg_stats after restart + + Reviewed-by: Sage Weil + Reviewed-by: Kefu Chai + Reviewed-by: David Zafman + +commit 2f491b2e5e8b1f340b28415c3bd3d9628603c377 +Merge: 552a573f84 a372b4eca1 +Author: Yuri Weinstein +Date: Tue Jul 4 07:31:50 2017 -0700 + + Merge pull request #16089 from ceph/wip_fix_point_jewel + + qa/Fixed upgrade sequence to 10.2.0 -> 10.2.7 -> latest -x (10.2.8) + + Reviewed-by: Nathan Cutler + +commit 552a573f8426ecfec1a0df21a6c3941afd4e460c +Merge: 53a3be7261 55eeaadfc4 +Author: Yuri Weinstein +Date: Mon Jul 3 17:23:43 2017 -0700 + + Merge pull request #16088 from smithfarm/wip-fix-client-upgrade-centos + + tests: run upgrade/client-upgrade on latest CentOS 7.3 + + Reviewed-by: Yuri Weinstein + +commit a372b4eca1f25647541943918ae737f20783db11 +Author: Yuri Weinstein +Date: Mon Jul 3 14:18:14 2017 -0700 + + Fixed upgrade sequence to 10.2.0 -> 10.2.7 -> latest -x (10.2.8) + + Signed-off-by: Yuri Weinstein + +commit 55eeaadfc4025c83cb63c951265710868df0325f +Author: Nathan Cutler +Date: Mon Jul 3 22:55:21 2017 +0200 + + tests: run upgrade/client-upgrade on latest CentOS 7.3 + + Before this patch, all centos jobs were failing because there are no longer any + CentOS 7.2 machines in Sepia. + + Signed-off-by: Nathan Cutler + +commit 53a3be7261cfeb12445fbdba8238eefa40ed09f5 +Merge: 84bd162978 d33b30cdb0 +Author: Nathan Cutler +Date: Fri Jun 30 16:43:38 2017 +0200 + + Merge pull request #15504 from Vicente-Cheng/wip-20151-jewel + + jewel: ceph-disk: do not setup_statedir on trigger + + Reviewed-by: Josh Durgin + +commit 84bd162978e48eead40335bcbd92e4ab18e9c590 +Merge: c710689109 8e0e4a0ce7 +Author: Nathan Cutler +Date: Wed Jun 28 10:20:23 2017 +0200 + + Merge pull request #15904 from smithfarm/wip-20413-jewel + + jewel: tests: upgrade:hammer-x/stress-split-erasure-code-x86_64 fails in 10.2.8 integration testing + + Reviewed-by: Brad Hubbard + +commit c7106891096c895f0cc5c2cef438078ea48de95d +Merge: 5c6cb14806 9d3110c276 +Author: Nathan Cutler +Date: Wed Jun 28 08:16:33 2017 +0200 + + Merge pull request #14930 from smithfarm/wip-19829-jewel + + jewel: tests: New upgrade test for #14930 + + Reviewed-by: Josh Durgin + +commit 5c6cb1480699f5ce464e25b9cacdda770ce3660d +Merge: bdc085d02a d43e19d886 +Author: Nathan Cutler +Date: Wed Jun 28 08:16:04 2017 +0200 + + Merge pull request #14392 from asheplyakov/19508-jewel + + jewel: osd: pg_pool_t::encode(): be compatible with Hammer <= 0.94.6 + + Reviewed-by: Josh Durgin + +commit 9d3110c276917055b078cd14c181b2bda2625821 +Author: Nathan Cutler +Date: Sun Jun 25 10:32:16 2017 +0200 + + tests: upgrade/hammer-x/v0-94-6-mon-overload: tweak packages list + + Include some hammer dependencies that aren't in the jewel default packages + list, and exclude some java packages that may not be in the hammer repo and are + not needed for the upgrade test in any case. + + N.B.: This cannot be cherry-picked from master because upgrade/hammer-x was + dropped in master. + + Signed-off-by: Nathan Cutler + +commit 6a64f8901bb3b218a8dc58b11d6c13033d45f067 +Author: Nathan Cutler +Date: Wed May 3 11:39:27 2017 +0200 + + tests: upgrade/hammer-x: new v0-94-6-mon-overload subsuite + + This is not a cherry-pick from master because direct upgrades + from hammer to kraken+ are not supported. + + Fixes: http://tracker.ceph.com/issues/19829 + References: http://tracker.ceph.com/issues/19508 + Signed-off-by: Nathan Cutler + +commit bdc085d02ab9723f6b90b6a3047bc51cf224b930 +Merge: e41ae4a7b1 d2d4b7202d +Author: Nathan Cutler +Date: Tue Jun 27 12:41:59 2017 +0200 + + Merge pull request #15936 from batrick/i20412 + + qa: enable quotas for pre-luminous quota tests + + Reviewed-by: John Spray + Reviewed-by: Nathan Cutler + +commit d2d4b7202d77e5696eb18c4da4f7d614116ced36 +Author: Patrick Donnelly +Date: Mon Jun 26 19:04:48 2017 -0700 + + qa: enable quotas for pre-luminous quota tests + + This cannot be cherry-picked from master because the config option is removed + since 0f250a889dba2100d3afcea0a18e4f6a8d086b86. + + Fixes: http://tracker.ceph.com/issues/20412 + + Signed-off-by: Patrick Donnelly + +commit e41ae4a7b1b9cc4394473e21f6e6d6ef9cab1d59 +Merge: a21af3b7a1 682b4d717c +Author: Sage Weil +Date: Mon Jun 26 21:24:11 2017 -0500 + + Merge pull request #15933 from smithfarm/wip-hammer-jewel-x + + jewel: tests: drop upgrade/hammer-jewel-x + +commit 682b4d717c96b516c315a01b1174af3503dedba6 +Author: Nathan Cutler +Date: Tue Jun 27 02:27:22 2017 +0200 + + tests: drop upgrade/hammer-jewel-x + + This suite doesn't have any test logic in it. Its existence in the jewel branch + appears to be an oversight. + + This cannot be cherry-picked from master because the upgrade/hammer-jewel-x + suite is present (and justified) in master and is not currently being dropped + there. + + Signed-off-by: Nathan Cutler + +commit a21af3b7a1ea5abfa4f344800e413d6249824204 +Merge: 615a6ab9b7 a744340790 +Author: John Spray +Date: Mon Jun 26 16:25:12 2017 -0400 + + Merge pull request #15438 from Vicente-Cheng/wip-20027-jewel + + jewel: mds: issue new caps when sending reply to client + + Reviewed-by: John Spray + +commit 615a6ab9b723d204c6de567750fe9450742fcedb +Merge: 9b13b48b3e 8ac0e5c363 +Author: John Spray +Date: Mon Jun 26 16:23:48 2017 -0400 + + Merge pull request #15000 from jan--f/wip-19846-jewel + + jewel: cephfs: normalize file open flags internally used by cephfs + + Reviewed-by: John Spray + +commit 9b13b48b3ed919340789a41d065eb4a9a27110de +Merge: d217da1742 b429fa1807 +Author: Nathan Cutler +Date: Mon Jun 26 18:25:03 2017 +0200 + + Merge pull request #15383 from asheplyakov/20014-bp-jewel + + jewel: cls/rgw: list_plain_entries() stops before bi_log entries + + Reviewed-by: Orit Wasserman + +commit d217da174252f9126d530868aa472230ecba31ca +Merge: e520040ece 4028774122 +Author: Zack Cerza +Date: Mon Jun 26 10:17:03 2017 -0600 + + Merge pull request #15870 from smithfarm/wip-swift-task-move-jewel + + tests: move swift.py task from teuthology to ceph, phase one (jewel) + +commit e520040ecec756ce181f716dad1c0bad41c77a7d +Merge: dde8656e6b 1c0c9093ab +Author: Nathan Cutler +Date: Mon Jun 26 09:24:04 2017 +0200 + + Merge pull request #15842 from smithfarm/wip-sortbitwise-jewel + + qa/suites/upgrade/hammer-x: set "sortbitwise" for jewel clusters + + Reviewed-by: Kefu Chai + +commit dde8656e6b5e7ffe66a6fd695cbc17dfb18fb43e +Merge: 498c96e66a 06cf9f3650 +Author: John Spray +Date: Sun Jun 25 19:59:40 2017 -0400 + + Merge pull request #15468 from smithfarm/wip-20140-jewel + + jewel: cephfs: Journaler may execute on_safe contexts prematurely + + Reviewed-by: John Spray + +commit 4028774122954023265d7825fbf9e91dc526fdee +Author: Nathan Cutler +Date: Sun Jun 25 12:42:36 2017 +0200 + + tests: swift.py: tweak imports + + The ".." form only works within the teuthology repo. With swift.py now in the + Ceph repo, we have to be explicit. + + Error message was: "ValueError: Attempted relative import beyond toplevel + package + + Signed-off-by: Nathan Cutler + +commit 8e0e4a0ce7489542f47522e0a5161a5bf123c744 +Author: Nathan Cutler +Date: Sun Jun 25 10:27:58 2017 +0200 + + tests: upgrade/hammer-x/stress-split: tweak packages list + + Include some hammer dependencies that aren't in the jewel default packages + list, and exclude some java packages that may not be in the hammer repo and are + not needed for the upgrade test in any case. + + N.B.: This cannot be cherry-picked from master because upgrade/hammer-x was + dropped in master. + + Signed-off-by: Nathan Cutler + +commit a86ce728954a765797ce634025d43650d990e480 +Author: Nathan Cutler +Date: Sun Jun 25 09:27:47 2017 +0200 + + tests: swift.py: clone the ceph-jewel branch + + The master branch of ceph/swift.git contains tests that are incompatible with + Jewel and Hammer. The ceph-jewel branch omits these tests. + + Signed-off-by: Nathan Cutler + +commit 498c96e66a91edc8bd614cfc8fc5a14b3d210a76 +Merge: 38af498f9f cda721bbbf +Author: John Spray +Date: Fri Jun 23 08:02:48 2017 -0400 + + Merge pull request #15472 from smithfarm/wip-20148-jewel + + jewel: mds: Too many stat ops when trying to probe a large file + + Reviewed-by: John Spray + +commit 3d5b489369bb2cecccb1f36347654c0a37069d1c +Merge: 38af498f9f 7b58ac97e9 +Author: Nathan Cutler +Date: Fri Jun 23 08:35:27 2017 +0200 + + Merge branch 'master' of /home/smithfarm/src/ceph/upstream/teuthology into wip-swift-task-move-jewel + +commit 7b58ac97e9dd195f4170e9e0ea00bae76d1f3ccd +Author: Nathan Cutler +Date: Fri Jun 23 08:27:42 2017 +0200 + + tests: move swift.py task to qa/tasks + + In preparation for moving this task from ceph/teuthology.git into ceph/ceph.git + + The move is necessary because jewel-specific changes are needed, yet teuthology + does not maintain a separate branch for jewel. Also, swift.py is a + Ceph-specific task so it makes more sense to have it in Ceph. + + Signed-off-by: Nathan Cutler + +commit 38af498f9f7b62f9f851364ae7f2691832423198 +Merge: d0ae1de51f aa0cd461df +Author: Nathan Cutler +Date: Thu Jun 22 22:07:23 2017 +0200 + + Merge pull request #15529 from badone/wip-async-sleep-timer-fix-jewel + + jewel: osd: Implement asynchronous scrub sleep + + Reviewed-by: Josh Durgin + +commit 1c0c9093ab913a82c1dc5656a54b4009bdc35c9c +Author: Nathan Cutler +Date: Thu Jun 22 11:32:42 2017 +0200 + + qa/suites/upgrade/hammer-x: set "sortbitwise" for jewel clusters + + Inspired by 3734280522a913ca8340ebc98b80978f63bade6f + + This cannot be cherry-picked from master because master does not have + qa/suites/upgrade/hammer-x + + Signed-off-by: Nathan Cutler + +commit d0ae1de51f5faf26a2f4b0d5b7f494a4923f870d +Merge: 64c011a8c4 de76fdbb9f +Author: Kefu Chai +Date: Thu Jun 22 11:59:51 2017 +0800 + + Merge pull request #15824 from tchaikov/jewel + + qa/workunits/rados/test-upgrade-*: whitelist tests the right way + + Reviewed-by: Sage Weil + +commit de76fdbb9f435652e2c15326d00b01d26ab007a7 +Author: Kefu Chai +Date: Thu Jun 22 08:06:43 2017 +0800 + + qa/workunits/rados/test-upgrade-*: whitelist tests the right way + + --gtest_filter=POSTIVE_PATTERNS[-NEGATIVE_PATTERNS], so we cannot add + multiple exclusive patterns using -pattern:-pattern, instead, we should + use: -pattern:pattern + + Signed-off-by: Kefu Chai + Conflicts: + qa/workunits/rados/test-upgrade-v11.0.0.sh: this change is not + cherry-picked from master, because the clone-range op was removed + from master. and only supported in pre-luminous releases. + +commit 64c011a8c4af27dc095b1a9190ccf1ca76d2cc8f +Merge: e8da5e376f ab78cd040f +Author: Nathan Cutler +Date: Tue Jun 20 22:54:00 2017 +0200 + + Merge pull request #14661 from smithfarm/wip-19575-jewel + + jewel: rgw: unsafe access in RGWListBucket_ObjStore_SWIFT::send_response() + + Reviewed-by: Casey Bodley + +commit e8da5e376fc426f85fcab84a5ae71b3c17ed0068 +Merge: 5a1e849ecf 1af6781d3c +Author: Kefu Chai +Date: Tue Jun 20 22:42:47 2017 +0800 + + Merge pull request #15778 from tchaikov/wip-upgrade-without-clone-range-jewel + + qa/workunits/rados/test-upgrade-*: whitelist tests for master + + Reviewed-by: Sage Weil + +commit d43e19d88692bd318f0569559867df919c26d8db +Author: Alexey Sheplyakov +Date: Fri Apr 7 12:34:20 2017 +0400 + + jewel: osd: pg_pool_t::encode(): be compatible with Hammer <= 0.94.6 + + This patch is necessary for Jewel only since direct upgrades from Hammer + to Kraken and newer are not supported. + + Fixes: http://tracker.ceph.com/issues/19508 + + Signed-off-by: Alexey Sheplyakov + +commit 1af6781d3c60421930087d31124e62cae530ca24 +Author: Kefu Chai +Date: Tue Jun 20 19:49:14 2017 +0800 + + qa/workunits/rados/test-upgrade-*: whitelist tests for master + + The jewel-x upgrade test now runs this script against a mixed cluster on + a machine with code from master installed. That means we have to + skip any new tests that will fail on a mixed cluster. CloneRange was + removed in 0d7b0b7. + + Signed-off-by: Kefu Chai + Conflicts: + qa/workunits/rados/test-upgrade-v11.0.0.sh: this change is not + cherry-picked from master, because the clone-range op was removed from + master. and only supported in pre-luminous releases. + +commit a74434079088129244b7aae6ccc6df7094282eba +Author: Yan, Zheng +Date: Sat Apr 22 12:27:12 2017 +0800 + + mds: issue new caps when sending reply to client + + After Locker::issue_new_caps() adds new Capability data struct, + do not issue caps immediately. Let CInode::encode_inodestate() + do the job instead. This can avoid various races that early reply + is not allowed, caps that haven't been sent to client gets revoked. + + Fixes: http://tracker.ceph.com/issues/19635 + Signed-off-by: "Yan, Zheng" + (cherry picked from commit 799703a4acb49db0b6cc99a23e4326767e694c3a) + +commit d33b30cdb019937ff88f9724599f52f4e00d37cf +Author: Loic Dachary +Date: Thu Jun 1 11:37:20 2017 +0200 + + ceph-disk: do not setup_statedir on trigger + + trigger may run when statedir is unavailable and does not use it. + + Fixes: http://tracker.ceph.com/issues/19941 + + Signed-off-by: Loic Dachary + (cherry picked from commit 16bfbdd3d9988523bba31aace516c303057daa58) + +commit f46ccf2cb4701cd93cd9b15a4e57b5b97798b947 +Author: Nathan Cutler +Date: Fri Apr 21 11:05:05 2017 +0200 + + tests: rados: sleep before ceph tell osd.0 flush_pg_stats after restart + + Even though we wait for HEALTH_OK after restarting the daemons, they are not + ready to respond to flush_pg_stats. + + The reason why the osd is not ready for "tell" command after "ceph health" + shows that the cluster is "HEALTH_OK" is that the monitor fails to be notified + that the osd in question is not up in "heatbeat_interval". Because infernalis + does not have the osd_fast_fail_on_connection_refused support, the monitor + needs longer to detect that an osd is down, and osd_heartbeat_grace is used to + determine if an osd is down. + + References: http://tracker.ceph.com/issues/16239 + Signed-off-by: Nathan Cutler + Signed-off-by: Kefu Chai + +commit ab78cd040f6d3946ed40b6638ebcf52969a7cbb6 +Author: Yehuda Sadeh +Date: Wed Mar 8 14:52:34 2017 -0800 + + rgw: fix crash when listing objects via swift + + Fixes: http://tracker.ceph.com/issues/19249 + + Signed-off-by: Yehuda Sadeh + (cherry picked from commit a9ec5e8ce184e19c009863db4d3519f9d8af91bd) + + Conflicts: + src/rgw/rgw_rest_swift.cc ("key" element of RGWObjEnt struct + is not a reference; fix) + + (cherry picked from commit 92b35155ff7b7492f3c50bf4f2ff0ffef2ca1c55) + +commit 5a1e849ecf215d82e31b9bdd0970cb04200de2c9 +Merge: 2469085d57 66c3db7aee +Author: Nathan Cutler +Date: Mon Jun 19 22:46:47 2017 +0200 + + Merge pull request #14752 from cbodley/wip-19474 + + jewel: rgw: allow system users to read SLO parts + + Reviewed-by: Casey Bodley + +commit cda721bbbfae00ec4244718ae20cbd9ae914c630 +Author: Yan, Zheng +Date: Fri May 19 09:37:15 2017 +0800 + + client: update the 'approaching max_size' code + + The old 'approaching max_size' code expects MDS set max_size to + '2 x reported_size'. This is no longer true. The new code reports + file size when half of previous max_size increment has been used. + + Signed-off-by: "Yan, Zheng" + (cherry picked from commit 9316b0442c6f828dcf8da952e4c7a63c4db1398d) + + Conflicts: + src/client/Client.cc - in jewel, second argument to check_caps() is + a bool (see 0df562a8e13 which is not in jewel) + +commit 439f39128ec278ce78139d4b96ed098c68efa3f5 +Author: Yan, Zheng +Date: Wed May 17 19:08:37 2017 +0800 + + mds: limit client writable range increment + + For very large file, setting the writable range to '2 * file_size' + causes file recovery to run a long time. To recover a 1T file, Filer + needs to probe 2T~1T range. + + Fixes: http://tracker.ceph.com/issues/19955 + Signed-off-by: "Yan, Zheng" + (cherry picked from commit 538f35bef944b18e9bca2b15ed7f4e8807ef0554) + + Conflicts: + src/mds/Locker.h - in jewel, file_update_finish() has different + arguments than it does in master + +commit 06cf9f365033f7913051bdf4060f0bc6fc0444d7 +Author: Yan, Zheng +Date: Tue May 23 21:46:54 2017 +0800 + + osdc/Journaler: avoid executing on_safe contexts prematurely + + Journaler::_do_flush() can skip flushing some data when prezered + journal space isn't enough. Before updating Journaler::next_safe_pos, + we need to check if Journaler::_do_flush() has flushed enough data. + + Fixes: http://tracker.ceph.com/issues/20055 + Signed-off-by: "Yan, Zheng" + (cherry picked from commit 6511e7a9e35a14216c03cd6921ca4d232274f953) + +commit 2e299b50de4a297fee2aec21290632336d239857 +Author: Yan, Zheng +Date: Wed Apr 12 16:00:18 2017 +0800 + + osdc/Journaler: make header write_pos align to boundary of flushed entry + + This can speed up the process that detects and drops partial written + entry in the log tail. + + Signed-off-by: "Yan, Zheng" + (cherry picked from commit 8ae2962b79903e217fda83cea4140af64b5d6883) + + Conflicts: + src/osdc/Journaler.cc - 8d4f6b92cba is not being backported to jewel + src/osdc/Journaler.h - Journaler::Journaler initializer list is different in jewel, compared to master + +commit 2469085d57a05933589165f6f99a67b2e28c7022 +Merge: 42c3fbc129 d57437e338 +Author: John Spray +Date: Wed Jun 14 10:01:27 2017 -0400 + + Merge pull request #14672 from smithfarm/wip-19334-jewel + + jewel: MDS heartbeat timeout during rejoin, when working with large amount of caps/inodes + + Reviewed-by: John Spray + +commit 8ac0e5c363bd6439071d26874b6714cf2376736f +Author: Yan, Zheng +Date: Fri May 12 10:38:51 2017 +0800 + + pybind: fix cephfs.OSError initialization + + Traceback (most recent call last): + File "", line 1, in + File "cephfs.pyx", line 672, in cephfs.LibCephFS.open (/home/zhyan/Ceph/ceph-2/build/src/pybind/cephfs/pyrex/cephfs.c:10160) + File "cephfs.pyx", line 155, in cephfs.OSError.__init__ (/home/zhyan/Ceph/ceph-2/build/src/pybind/cephfs/pyrex/cephfs.c:1889) + TypeError: __init__() takes exactly 3 positional arguments (2 given) + + Signed-off-by: "Yan, Zheng" + (cherry picked from commit e6493f64ba4592b8dca54ece4464efa6c7f331a7) + +commit 09b9410c2e69a466b001d92fc14eb44d768009f1 +Author: Yan, Zheng +Date: Wed May 10 08:13:52 2017 +0800 + + pybind: fix open flags calculation + + (O_WRONLY | O_RDWR) is invaild open flags + + Fixes: http://tracker.ceph.com/issues/19890 + Signed-off-by: "Yan, Zheng" + (cherry picked from commit 2c25c99cb4572ffae97555a56b24a4c4097dcdec) + +commit 42c3fbc129cbb60d447c1a6b0402a9def1656446 +Merge: 71d45e1905 7347f11939 +Author: John Spray +Date: Wed Jun 14 09:43:05 2017 -0400 + + Merge pull request #14677 from smithfarm/wip-19665-jewel + + jewel: mds: C_MDSInternalNoop::complete doesn't free itself + + Reviewed-by: John Spray + +commit 71d45e190528124a8ff7e4674f7bfb7c340f80ee +Merge: 27c915f5d2 e6daee8a9f +Author: John Spray +Date: Wed Jun 14 09:35:08 2017 -0400 + + Merge pull request #15466 from smithfarm/wip-19762-jewel + + jewel: cephfs: non-local quota changes not visible until some IO is done + + Reviewed-by: John Spray + +commit 27c915f5d21bd84502e35eb269d955fafc47de0b +Merge: a76357622a db053da618 +Author: John Spray +Date: Wed Jun 14 09:32:47 2017 -0400 + + Merge pull request #14700 from smithfarm/wip-19709-jewel + + jewel: mds: enable start when session ino info is corrupt + + Reviewed-by: John Spray + +commit a76357622a2773850153aa1f6ea02b1737942c4b +Merge: 85aab833f7 db86a24e79 +Author: John Spray +Date: Wed Jun 14 09:31:22 2017 -0400 + + Merge pull request #14685 from smithfarm/wip-19675-jewel + + jewel: cephfs: Test failure: test_data_isolated (tasks.cephfs.test_volume_client.TestVolumeClient) + + Reviewed-by: John Spray + +commit 85aab833f7f66ac81d8b12f4203fa215787f8d2a +Merge: f6b395115e 7b9283beec +Author: John Spray +Date: Wed Jun 14 09:30:53 2017 -0400 + + Merge pull request #14684 from smithfarm/wip-19673-jewel + + jewel: cephfs: mds is crushed, after I set about 400 64KB xattr kv pairs to a file + + Reviewed-by: John Spray + +commit f6b395115e4de15d73269ff6b96f2ee0fd0ea9c3 +Merge: ff60fceb5f b52c508861 +Author: John Spray +Date: Wed Jun 14 09:30:13 2017 -0400 + + Merge pull request #14683 from smithfarm/wip-19671-jewel + + jewel: cephfs: MDS assert failed when shutting down + + Reviewed-by: John Spray + +commit ff60fceb5f5f7f9df4a48da4ad8bd863b9a04e2d +Merge: 6a6d57d2de 96e801fb53 +Author: John Spray +Date: Wed Jun 14 09:29:50 2017 -0400 + + Merge pull request #14682 from smithfarm/wip-19668-jewel + + jewel: cephfs: MDS goes readonly writing backtrace for a file whose data pool has been removed + + Reviewed-by: John Spray + +commit 6a6d57d2de674c5a971e999cb2731b2d8ae1b523 +Merge: 8260669efa f34489dd52 +Author: John Spray +Date: Wed Jun 14 09:27:13 2017 -0400 + + Merge pull request #14679 from smithfarm/wip-19666-jewel + + jewel: cephfs: The mount point break off when mds switch hanppened. + + Reviewed-by: John Spray + +commit 8260669efa74f41d3b1b1039fb7b34e070951c34 +Merge: 013529b61f 824b19a9a6 +Author: John Spray +Date: Wed Jun 14 09:26:40 2017 -0400 + + Merge pull request #14676 from smithfarm/wip-19619-jewel + + jewel: cephfs: MDS server crashes due to inconsistent metadata. + + Reviewed-by: John Spray + +commit 013529b61fc4fbf02656f7c6cb0baa1bc6004758 +Merge: b518522f64 eab56dae67 +Author: John Spray +Date: Wed Jun 14 09:24:38 2017 -0400 + + Merge pull request #14674 from smithfarm/wip-19482-jewel + + jewel: cephfs: No output for ceph mds rmfailed 0 --yes-i-really-mean-it command + + Reviewed-by: John Spray + +commit b518522f64b66f4a14618a9345b6314ca0f2c54c +Merge: 388e0d1bc3 63f41d543f +Author: John Spray +Date: Wed Jun 14 09:23:27 2017 -0400 + + Merge pull request #14671 from smithfarm/wip-19044-jewel + + jewel: tests: buffer overflow in test LibCephFS.DirLs + + Reviewed-by: John Spray + +commit 388e0d1bc35985a6916d3eb1ca5184a0907b6e8b +Merge: d7c7ce7ebb 7146816065 +Author: John Spray +Date: Wed Jun 14 09:23:13 2017 -0400 + + Merge pull request #14670 from smithfarm/wip-18949-jewel + + jewel: mds: avoid reusing deleted inode in StrayManager::_purge_stray_logged + + Reviewed-by: John Spray + +commit d7c7ce7ebbb663dab0dfa8058c845d494d7615cc +Merge: d717ef73bc d8b139b584 +Author: John Spray +Date: Wed Jun 14 09:22:28 2017 -0400 + + Merge pull request #14669 from smithfarm/wip-18900-jewel + + jewel: cephfs: Test failure: test_open_inode + + Reviewed-by: John Spray + +commit d717ef73bc0d5ef24551ec9157385c8b0521380b +Merge: c2a3b7567f 36c86f71ef +Author: John Spray +Date: Wed Jun 14 09:21:43 2017 -0400 + + Merge pull request #14668 from smithfarm/wip-18705-jewel + + jewel: mds: fragment space check can cause replayed request fail + + Reviewed-by: John Spray + +commit c2a3b7567fbe0b2f62bcd38cd9bb9a5a2a238743 +Merge: fd9256b770 5b56214519 +Author: John Spray +Date: Tue Jun 13 19:05:55 2017 +0100 + + Merge pull request #14698 from smithfarm/wip-19677-jewel + + jewel: cephfs: ceph-fuse does not recover after lost connection to MDS + + Reviewed-by: John Spray + +commit fd9256b77010066c934fd0016eb6d3f9c1fb54e1 +Merge: 26ada59c81 c49b114e8d +Author: Abhishek L +Date: Fri Jun 9 19:39:17 2017 +0200 + + Merge pull request #14766 from smithfarm/wip-19757-jewel + + jewel: rgw: fix failed to create bucket if a non-master zonegroup has a single zone + + Reviewed-by: Abhishek Lekshmanan + Reviewed-by: Casey Bodley + +commit 26ada59c810bfda5c16f2d935a2b98711e7b2c76 +Merge: fdd25c2bdb e552d91f73 +Author: Abhishek L +Date: Fri Jun 9 19:38:46 2017 +0200 + + Merge pull request #14787 from linuxbox2/jewel-rgw-shard-limit-ck + + jewel: rgw: add bucket size limit check to radosgw-admin + + + Reviewed-by: Abhishek Lekshmanan + Reviewed-by: Casey Bodley + +commit fdd25c2bdb9ec6bb8e3061088b8782bfb2331bc4 +Merge: cfd6750416 fb3ee2efcc +Author: Abhishek L +Date: Fri Jun 9 19:38:23 2017 +0200 + + Merge pull request #14789 from mdw-at-linuxbox/wip-jewel-rgw-rvk + + jewel: rgw: swift: disable revocation thread if sleep == 0 || cache_size == 0 + + + Reviewed-by: Abhishek Lekshmanan + Reviewed-by: Casey Bodley + +commit cfd6750416baeb2bbd3836bc7dc55d83fc214c20 +Merge: ce1fc3492e 86980a045b +Author: Abhishek L +Date: Fri Jun 9 19:36:02 2017 +0200 + + Merge pull request #14815 from smithfarm/wip-19786-jewel + + jewel: rgw: failure to create s3 type subuser from admin rest api + + Reviewed-by: Abhishek Lekshmanan + Reviewed-by: Casey Bodley + +commit ce1fc3492e87c669f7059c2047a3bed077418a89 +Merge: 7ca0252560 aa99558934 +Author: Nathan Cutler +Date: Wed Jun 7 20:13:15 2017 +0200 + + Merge pull request #15312 from theanalyst/wip-20078 + + jewel: rgw: only append zonegroups to rest params if not empty + + Reviewed-by: Casey Bodley + +commit 7ca0252560d1ff23384afb50a9c2ae2aad2ce85c +Merge: 62c500f522 59bd6711a4 +Author: Nathan Cutler +Date: Wed Jun 7 13:48:06 2017 +0200 + + Merge pull request #15382 from theanalyst/wip-mem-leak2 + + jewel: rgw:fix memory leaks in data/md sync + + Reviewed-by: Casey Bodley + +commit aa0cd461df5fee6d143bc07440ec6de829761cef +Author: Brad Hubbard +Date: Mon May 22 13:21:25 2017 +1000 + + osd: Move scrub sleep timer to osdservice + + PR 14886 erroneously creates a scrub sleep timer for every pg resulting + in a proliferation of threads. Move the timer to the osd service so + there can be only one. + + Fixes: http://tracker.ceph.com/issues/19986 + + Signed-off-by: Brad Hubbard + (cherry picked from commit f110a82437df79dc20207d296e8229fc0e9ce18b) + + Conflicts: + src/osd/PG.cc - ceph_clock_now requires a CephContext argmunent + in Jewel + +commit c47bd0562b1187ffb0b1b2c1ef5f105aa7951d10 +Author: Brad Hubbard +Date: Mon Apr 24 14:10:47 2017 +1000 + + osd: Implement asynchronous scrub sleep + + Rather than blocking the main op queue just do an async sleep. + + Fixes: http://tracker.ceph.com/issues/19497 + + Signed-off-by: Brad Hubbard + (cherry picked from commit 7af3e86c2e4992db35637864b83832535c94d0e6) + +commit e6daee8a9fbc576da2a03550a81056d093a516c9 +Author: Nathan Cutler +Date: Sun Jun 4 20:39:58 2017 +0200 + + Client.cc: adjust Client::_getattr calls + + Signed-off-by: Nathan Cutler + +commit a2c7a2262ac8ecbea78f09e6e8e6a37498568d57 +Author: John Spray +Date: Wed Mar 15 19:36:08 2017 +0000 + + qa/cephfs: use getfattr/setfattr helpers + + Signed-off-by: John Spray + (cherry picked from commit dd43d3bc646aeab88486b0963fc83de0b18800c4) + + Conflicts: + qa/tasks/cephfs/test_data_scan.py: difference in the + self._mount.run_shell() call in NonDefaultLayout::write (which is + being dropped by this commit) - in jewel it has "sudo", and in + master it doesn't + +commit 12aa35a6d50f612df77199ac4f35c7baeed0583e +Author: John Spray +Date: Wed Jun 22 13:00:44 2016 +0100 + + tasks/cephfs: fix race while mounting + + This could fail if the mount hadn't finished + coming up. + + Signed-off-by: John Spray + (cherry picked from commit adfb757c898a80f18c15dafd02e29840c5931c87) + +commit a7b699269b65c76361fcb1d10593812be40c7612 +Author: John Spray +Date: Wed Mar 15 19:26:30 2017 +0000 + + qa: add test for reading quotas from different clients + + Fixes: http://tracker.ceph.com/issues/17939 + Signed-off-by: John Spray + (cherry picked from commit 61617f8f10a6322603a9add77980865cd972ef97) + +commit 8b8ee392b8093b9b140dbbe895691f69ae40440f +Author: John Spray +Date: Wed Mar 15 17:51:44 2017 +0000 + + client: _getattr on quota_root before using in statfs + + ...so that after someone adjusts the quota settings + on an inode that another client is using as its mount root, + the change is visible immediately on the other client. + + Signed-off-by: John Spray + (cherry picked from commit 3d25941aadd223669448d0f5d3c0bd1fefa72308) + +commit dd7d59a08141d6a24b172c22f5e27c8962e25fb9 +Author: John Spray +Date: Wed Mar 15 15:32:47 2017 +0000 + + client: getattr before read on ceph.* xattrs + + Previously we were returning values for quota, layout + xattrs without any kind of update -- the user just got + whatever happened to be in our cache. + + Clearly this extra round trip has a cost, but reads of + these xattrs are fairly rare, happening on admin + intervention rather than in normal operation. + + Fixes: http://tracker.ceph.com/issues/17939 + Signed-off-by: John Spray + (cherry picked from commit 532dc4b68e538c189ef828f67cecd0d647a62250) + +commit 62c500f52240eaa5faadd3795bd9ec84bdcbc6c7 +Merge: 2badc2416c 8dd93cabd5 +Author: David Zafman +Date: Fri Jun 2 09:54:22 2017 -0700 + + Merge pull request #15416 from dzafman/wip-20126 + + Reviewed-by: Josh Durgin + +commit 8dd93cabd52cbafc29a47862f343431eb6f1cfe3 +Author: David Zafman +Date: Wed May 31 15:39:19 2017 -0700 + + osd: Object level shard errors are tracked and used if no auth available + + Shards with object mismatch are tracked to mark them inconsistent + Fix test because storing omap_digest in object_info not behaving as before + + Fixes: http://tracker.ceph.com/issues/20089 + + Signed-off-by: David Zafman + + (cherry picked from commit 1cacbea763c7aabfeaaf4bd5e878301044184117) + + Conflicts: + src/test/osd/osd-scrub-repair.sh (no alloc_hint in object_info) + +commit 59bd6711a47c354117a612dd4ef033d70d449383 +Author: weiqiaomiao +Date: Wed Jun 1 17:20:49 2016 +0800 + + rgw:fix memory leaks + + Signed-off-by: weiqiaomiao + (cherry picked from commit 73e5be2b6133cf4caa0e5e5c8c9eae748b785dbf) + +commit b429fa1807062716c9705ddcf316ed9b2741cc43 +Author: Casey Bodley +Date: Fri May 5 14:56:40 2017 -0400 + + cls/rgw: list_plain_entries() stops before bi_log entries + + list_plain_entries() was using encode_obj_versioned_data_key() to set + its end_key, which gives a prefix of BI_BUCKET_OBJ_INSTANCE_INDEX[=2] + + that range between start_key and end_key would not only span the + BI_BUCKET_OBJS_INDEX[=0] prefixes, but BI_BUCKET_LOG_INDEX[=1] prefixes + as well. this can result in list_plain_entries() trying and failing to + decode a rgw_bi_log_entry as a rgw_bucket_dir_entry + + Fixes: http://tracker.ceph.com/issues/19876 + + Signed-off-by: Casey Bodley + (cherry picked from commit b29a1633a57abf443d5790c13d680d2917f86037) + +commit 2badc2416c9e16babbc91364502dcb03877e88bf +Merge: 5d2a68eb90 1f895c2403 +Author: Sage Weil +Date: Tue May 30 09:39:47 2017 -0500 + + Merge pull request #15360 from liewegas/wip-jewel-master-mixed + + qa/workunits/rados/test-upgrade-*: whitelist tests for master + + Reviewed-by: Kefu Chai + +commit 1f895c24030b79ae9f2eae16b09582fc72928b6a +Author: Sage Weil +Date: Tue May 30 09:58:09 2017 -0400 + + qa/workunits/rados/test-upgrade-*: whitelist tests for master + + The jewel-x upgrade test now runs this script against a mixed cluster on + a machine with code from master installed. That means we have to skip + any new tests that will fail on a mixed cluster. + + Signed-off-by: Sage Weil + +commit 5d2a68eb903f533689d1a1cbc410ca940baeaff3 +Merge: 998d1ee4f5 81e35b9416 +Author: Nathan Cutler +Date: Sat May 27 09:21:44 2017 +0200 + + Merge pull request #15208 from liewegas/wip-sortbitwise-jewel + + mon: fix 'sortbitwise' warning on jewel + + Reviewed-by: Josh Durgin + +commit 998d1ee4f503cb4875283fe8d2140f3b10a26643 +Merge: 54bc1e13ea 99c65bbc18 +Author: Nathan Cutler +Date: Sat May 27 02:46:55 2017 +0200 + + Merge pull request #14851 from yehudasa/wip-rgw-support-ragweed-jewel + + jewel: rgw: add apis to support ragweed suite + + Reviewed-by: Nathan Cutler + +commit aa99558934c6143cb35e722148b87f35ccecc397 +Author: Yehuda Sadeh +Date: Tue Aug 23 10:22:42 2016 -0700 + + rgw: rest conn functions cleanup, only append zonegroup if not empty + + Signed-off-by: Yehuda Sadeh + (cherry picked from commit 4e41af19846db75081cb0ddb7b33dc2bb9321ace) + +commit 5d90798432a6446636699fc03b2f548010b1212f +Author: Karol Mroz +Date: Thu Mar 17 10:32:14 2016 +0100 + + rgw: rest and http client code to use param vectors + + Replaces param/header lists with vectors. In these cases, we're only ever + adding to the back of the list, so a vector should be more efficient. + Also moves param_pair_t/param_vec_t higher up the include chain for + cleaner function signatures. + + Signed-off-by: Karol Mroz + (cherry picked from commit d4a2527872e0f5c3ae2874bb7d0ff459ae83cfd4) + + Conflicts: + src/rgw/rgw_http_client.cc + trivial ws conflict on rebase + +commit 54bc1e13ea19642c8d5893f29e96ee5c053f9c59 +Merge: 966f222917 43327f83ef +Author: Alfredo Deza +Date: Thu May 25 12:45:30 2017 -0400 + + Merge pull request #14765 from smithfarm/wip-18972-jewel + + jewel: ceph-disk does not support cluster names different than 'ceph' + + Reviewed-by: Alfredo Deza + +commit 81e35b941659a0f6dff8a935c27c7dd6d5cc4213 +Author: Sage Weil +Date: Wed May 24 09:48:11 2017 -0400 + + qa/suites/rados/singleton-nomsgr/*: set sortbitwise after upgrade + + Signed-off-by: Sage Weil + +commit f2814e4dbb2821a415310559fce405c2eab23947 +Author: huanwen ren +Date: Tue Dec 27 10:54:45 2016 +0000 + + mon/OSDMonitor: fixup sortbitwise flag warning + + "ceph -s" does not report warning when using + command "ceph osd unset sortbitwise" to drop + sortbitwise flag. + we should use "osdmap.get_up_osd_features() & + CEPH_FEATURE_OSD_BITWISE_HOBJ_SORT" + instead of "(osdmap.get_features(CEPH_ENTITY_TYPE_OSD, NULL) & + CEPH_FEATURE_OSD_BITWISE_HOBJ_SORT)", + because osdmap.get_features only get local "features" + + Signed-off-by: huanwen ren + (cherry picked from commit c25ee187e28724846d0011cd8145e16956d3636e) + +commit 02617188688eebde759c375a2257e076e4538491 +Author: Sage Weil +Date: Tue Nov 1 12:09:57 2016 -0400 + + mon: remove config option to disable no sortbitwise warning + + We'll require this soon. + + Signed-off-by: Sage Weil + (cherry picked from commit 04e3319e8aecde9ca58ccb7c89016f9079c7d657) + +commit 966f2229178c5d72722982d0f6a40f4d01210d9a +Merge: 6537fc741c 4ceaa7cce9 +Author: Nathan Cutler +Date: Wed May 17 09:29:21 2017 +0200 + + Merge pull request #13450 from dreamhost/wip-18887-jewel + + jewel: msg: IPv6 Heartbeat packets are not marked with DSCP QoS - simple messenger + + Reviewed-by: Josh Durgin + +commit bb79663490468b4ac2832aa9e3cbac019c1f712d +Author: Jan Fajerski +Date: Thu Apr 20 18:38:43 2017 +0200 + + fs: normalize file open flags internally used by cephfs + + The file open flags (O_foo) are platform specific. Normalize these flags + before they are send to the MDS. For processing of client messages the + MDS should only compare to these normalized flags. + Otherwise this can lead to bogus flags getting transmitted on ppc64. + + Signed-off-by: Jan Fajerski + (cherry picked from commit 88d2da5e93198e69435e288ce00d216d5fe27f80) + + Conflicts: + src/client/Client.cc + Conflicts can be resolved by choosing changes from HEAD and + adding a call to ceph_flags_sys2wire where flags are logged. + src/mds/Server.cc + Conflicts can be resolved by choosing changes from HEAD and + while making sure that the MDS compares request O_ flags the + the CEPH_O_ flags, since all wire O_ flags are normalized. + +commit 4ceaa7cce9c9132d47564d79204b48b1d02e531c +Author: Robin H. Johnson +Date: Wed May 3 22:31:40 2017 -0700 + + msg/simple/Pipe: manual backport of fix in PR#14795 + + Manual backport of errno fixup from PR#14795 + (6f1037e22c2a304795895498cdc955e0ef80f8e3), as noted by + https://github.com/ceph/ceph/pull/13450#discussion_r114696885. + + Signed-off-by: Robin H. Johnson + +commit 6537fc741c3267472e607e581c002854d8eafd46 +Merge: af31b453f4 82ea0971b3 +Author: Nathan Cutler +Date: Wed May 3 13:04:27 2017 +0200 + + Merge pull request #14667 from smithfarm/wip-18699-jewel + + jewel: client: fix the cross-quota rename boundary check conditions + + Reviewed-by: Gregory Farnum + +commit af31b453f404cb73ee7bdb8b6b02d71ad8aab7e7 +Merge: 472034cbe0 335258f975 +Author: Nathan Cutler +Date: Wed May 3 10:33:24 2017 +0200 + + Merge pull request #14332 from shinobu-x/wip-19396-jewel + + jewel: Objecter::epoch_barrier isn't respected in _op_submit() + + Reviewed-by: Josh Durgin + +commit 472034cbe0735131f3419205e9f7e6530377bfba +Merge: afe98ba074 acf608a903 +Author: Nathan Cutler +Date: Wed May 3 10:32:37 2017 +0200 + + Merge pull request #14204 from dzafman/wip-18533-jewel + + jewel: core: two instances of omap_digest mismatch + + Reviewed-by: Josh Durgin + +commit afe98ba07436ea105f4c9c42a52795ce3757419e +Merge: 0353a91bfd 043d70461c +Author: Nathan Cutler +Date: Wed May 3 10:31:38 2017 +0200 + + Merge pull request #13884 from shinobu-x/wip-19119-jewel + + jewel: pre-jewel "osd rm" incrementals are misinterpreted + + Reviewed-by: Josh Durgin + +commit 0353a91bfd799077ddd87de901e8a07f5da6a13d +Merge: 460b12c259 608785a007 +Author: Nathan Cutler +Date: Wed May 3 10:30:32 2017 +0200 + + Merge pull request #13647 from mslovy/wip-19083-jewel + + jewel: osd: preserve allocation hint attribute during recovery + + Reviewed-by: Gregory Farnum + +commit 460b12c259f5563d9d1b2477149fe79486ba5bcd +Merge: 630cfca36c 905c4acb99 +Author: Nathan Cutler +Date: Fri Apr 28 10:24:35 2017 +0200 + + Merge pull request #14791 from smithfarm/wip-19774-jewel + + jewel: osd: promote throttle parameters are reversed + + Reviewed-by: Sage Weil + +commit 630cfca36c5a42a58882966c5598752aac9ff54e +Merge: 013e781b45 3ec1a9bf16 +Author: Nathan Cutler +Date: Fri Apr 28 10:23:45 2017 +0200 + + Merge pull request #14763 from smithfarm/wip-19562-jewel + + jewel: api_misc: [ FAILED ] LibRadosMiscConnectFailure.ConnectFailure + + Reviewed-by: Sage Weil + +commit 99c65bbc1899663d0b23e2cec3d6e516d0e95ad7 +Author: Yehuda Sadeh +Date: Mon Jan 9 13:04:43 2017 -0800 + + rgw: new rest api to retrieve object layout + + Signed-off-by: Yehuda Sadeh + (cherry picked from commit 2768583dc486109e49d209243675b99fdd39e92c) + +commit 33745a342433716ad8a07ef846dbea9b57de5017 +Author: Yehuda Sadeh +Date: Thu Jan 5 13:47:24 2017 -0800 + + rgw: rest api to read zone config params + + Signed-off-by: Yehuda Sadeh + (cherry picked from commit a220a2efbfd675e6abf14ae33c21005bcbf6dadf) + +commit 013e781b45e28af15da4ddc32025aad713f128e8 +Merge: d144d99f00 b698d1fa4c +Author: Nathan Cutler +Date: Thu Apr 27 21:46:41 2017 +0200 + + Merge pull request #14481 from dillaman/wip-19468-jewel + + jewel: librbd: is_exclusive_lock_owner API should ping OSD + + Reviewed-by: Jason Dillaman + +commit d144d99f008776dc02c5838feb5a9eb9b84a400b +Merge: 0f0cd82eda dbe90c79b8 +Author: Nathan Cutler +Date: Thu Apr 27 21:05:11 2017 +0200 + + Merge pull request #14666 from smithfarm/wip-19612-jewel + + jewel: librbd: Issues with C API image metadata retrieval functions + + Reviewed-by: Jason Dillaman + +commit 0f0cd82edabcb2feb0b29793e5b45eb424f1c42d +Merge: eba821ce9c 216156b5d4 +Author: Nathan Cutler +Date: Thu Apr 27 21:04:27 2017 +0200 + + Merge pull request #14664 from smithfarm/wip-19325-jewel + + jewel: rbd: [api] temporarily restrict (rbd_)mirror_peer_add from adding multiple peers + + Reviewed-by: Jason Dillaman + +commit eba821ce9c61bcb197895e6949ce30a5c07097fa +Merge: 25e29c9215 b8fd297eb6 +Author: Nathan Cutler +Date: Thu Apr 27 20:46:08 2017 +0200 + + Merge pull request #14694 from ceph/wip-bp-systemd + + [backport] qa/tasks: systemd test backport to jewel + + Reviewed-by: Nathan Cutler + +commit 25e29c921557883da4bf48ff2496bcec6448e6ec +Merge: d7b63e21ca 7c6c3c753c +Author: Nathan Cutler +Date: Thu Apr 27 08:44:26 2017 +0200 + + Merge pull request #13544 from shinobu-x/wip-18932-jewel + + jewel: tests: 'ceph auth import -i' overwrites caps, should alert user before overwrite + + Reviewed-by: Kefu Chai + +commit acf608a9034e915e38ccea6002ee808c46620433 +Author: David Zafman +Date: Mon Mar 20 17:28:45 2017 -0700 + + filestore, tools: Fix logging of DBObjectMap check() repairs + + Signed-off-by: David Zafman + (cherry picked from commit 1704f62c0831e6b07138f7dd14a89fef3c9ed2c1) + +commit fecc52338b2a58bf1730f7b7a3e4a293e45160d2 +Author: David Zafman +Date: Fri Mar 3 15:04:02 2017 -0800 + + osd: Simplify DBObjectMap by no longer creating complete tables + + Bump the version for new maps to 3 + Make clone less efficient but simpler + Add rename operation (use instead of clone/unlink) + For now keep code that understands version 2 maps + + Signed-off-by: David Zafman + (cherry picked from commit 738156a99ed1caf61e5a8230eb8048360056c08e) + + No ghobject_t::operator>() so use Kraken cmp_bitwise() instead + Need to use MIN_GHOBJ/MAX_GHOBJ instead of std::min/std::max + +commit 6902c3141eeaefaacd92f33877cf319872f626c7 +Author: David Zafman +Date: Wed Feb 15 16:17:32 2017 -0800 + + ceph-osdomap-tool: Fix seg fault with large amount of check error output + + Signed-off-by: David Zafman + (cherry picked from commit 1dda0411f4fbb14ce1e0062da9f14ec3af505d39) + +commit 4a3e4bcf40cd004fc53e7be467a29084dedc3e1c +Author: David Zafman +Date: Wed Feb 15 15:02:33 2017 -0800 + + osd: Add automatic repair for DBObjectMap bug + + Add repair command to ceph-osdomap-tool too + + Under some situations the previous rm_keys() code would + generated a corrupt complete table. There is no way to + figure out what the table should look like now. By removing + the entries we fix the corruption and aren't much worse off + because the corruption caused some deleted keys to re-appear. + + This doesn't breaking the parent/child relationship during + repair because some of the keys may still be contained + in the parent. + + Signed-off-by: David Zafman + (cherry picked from commit 4cd3c74c928a32e065ed9543d6c91d8718a6ae3d) + + Conflicts: + src/os/filestore/DBObjectMap.h (trivial) + +commit d4f0ac0a405266f638b25ec475c0110741e3c431 +Author: David Zafman +Date: Wed Feb 15 14:59:40 2017 -0800 + + ceph-osdomap-tool: Fix tool exit status + + Signed-off-by: David Zafman + (cherry picked from commit 666f14ed90655a2d1bedde8561949625db7a9e6c) + +commit 5f36c319cd7fa4be15efd27b8aabbebc99d8999c +Author: Samuel Just +Date: Fri Feb 10 15:51:42 2017 -0800 + + DBObjectMap: rewrite rm_keys and merge_new_complete + + Leverage the updated in_complete_region and needs_parent to simplify + these methods. + + Signed-off-by: Samuel Just + (cherry picked from commit c4dffb68eaafe724f7fdae93a4285a7f8003ea29) + +commit 1fe4b856a37b29c85a9317e514c7f15f8e4905d5 +Author: Samuel Just +Date: Fri Feb 10 15:50:57 2017 -0800 + + DBObjectMap: strengthen in_complete_region post condition + + Previously, in_complete_region didn't guarantee anything about + where it left complete_iter pointing. It will be handy for + complete_iter to be pointing at the lowest interval which ends + after to_test. Make it so. + + Signed-off-by: Samuel Just + (cherry picked from commit 97b35f4d7d4862da4b6f50ecaef0d292a671fd04) + +commit 85f2151fec991e5db13d8e6f44b27e092605fb35 +Author: Samuel Just +Date: Fri Feb 10 15:48:57 2017 -0800 + + DBObjectMap: fix next_parent() + + The previous implementation assumed that + lower_bound(parent_iter->key()) always leaves the iterator + on_parent(). There isn't any guarantee, however, that that + key isn't present on the child as well. + + Signed-off-by: Samuel Just + (cherry picked from commit 74a7631d0938d7b44894f022224eab10a90d5cec) + +commit 484ccda5c53a8ee151b9f97687edd160ad7ebbd7 +Author: Samuel Just +Date: Thu Feb 9 10:47:59 2017 -0800 + + test_object_map: add tests to trigger some bugs related to 18533 + + Signed-off-by: Samuel Just + (cherry picked from commit f131dbcf5bb17107c029f942a57e9bf4432a26ee) + +commit cdeb690869bf6dd52226476c21514cf03ff37d6e +Author: David Zafman +Date: Tue Feb 14 12:40:33 2017 -0800 + + test: Add ceph_test_object_map to make check tests + + Signed-off-by: David Zafman + (cherry picked from commit 0e97a01bd7291458881ee53cece2d887f6333669) + +commit cf5d588d39498c8d65bc64bd2935aecac8546e40 +Author: David Zafman +Date: Wed Feb 8 18:56:27 2017 -0800 + + ceph-osdomap-tool: Add --debug and only show internal logging if enabled + + Signed-off-by: David Zafman + (cherry picked from commit 5fb2b2d13953979e5da9f571ab8c4b0b510b8368) + +commit 4c4a06ff525d9fa2271099db73701c7994054d36 +Author: David Zafman +Date: Wed Feb 8 18:55:48 2017 -0800 + + osd: DBOjectMap::check: Dump complete mapping when inconsistency found + + Signed-off-by: David Zafman + (cherry picked from commit fcf1e17c645e8fad5216c3e59627c817e5c858c7) + +commit 6c128ff8c6944e57059008959f49bd03635c5417 +Author: David Zafman +Date: Wed Feb 8 15:38:51 2017 -0800 + + test_object_map: Use ASSERT_EQ() for check() so failure doesn't stop testing + + Signed-off-by: David Zafman + (cherry picked from commit 053a273cbc02d6902a4bb1f11db1ea946498df3a) + +commit aa769a9d08ac7490f5063bb44c3a44c77a5d7232 +Author: David Zafman +Date: Wed Feb 8 10:02:40 2017 -0800 + + tools: Check for overlaps in internal "complete" table for DBObjectMap + + Changed check to return an error count and fix tool error message + + Signed-off-by: David Zafman + (cherry picked from commit e5e8eb962db6187ea19b96ba29ac83469c90b4ea) + + Conflicts: + src/os/filestore/DBObjectMap.h (trivial) + +commit 761ee7c6af8802ab6b668a0b7ccaa819b2764456 +Author: David Zafman +Date: Wed Feb 8 09:40:49 2017 -0800 + + tools: Add dump-headers command to ceph-osdomap-tool + + Signed-off-by: David Zafman + (cherry picked from commit f4101591ad701a62fe027c4744ca8ea505f44bdc) + + Conflicts: + src/os/filestore/DBObjectMap.h (trivial) + +commit 117db1c6d6952d181614f4fe22f0b1866eed6f10 +Author: David Zafman +Date: Mon Feb 6 21:09:42 2017 -0800 + + tools: Add --oid option to ceph-osdomap-tool + + Signed-off-by: David Zafman + (cherry picked from commit 2d94889e9ee3359017b1efd560f3557ce03ccee6) + +commit 4d8120d3b3975ce101f6272240e5e43bcfe0e742 +Author: David Zafman +Date: Mon Feb 6 21:31:18 2017 -0800 + + osd: Remove unnecessary assert and assignment in DBObjectMap + + Fix and add comment(s) + + Signed-off-by: David Zafman + (cherry picked from commit 937e6a03ea4692cc44d53faa0615f8e808c9eb03) + +commit 86980a045b7176428062a19758d145e38e515b40 +Author: snakeAngel2015 +Date: Mon Jul 18 14:51:37 2016 +0800 + + rgw: add suport for creating S3 type subuser of admin rest api + + Fixes: http://tracker.ceph.com/issues/16682 + + The original code cannot support create s3 type subuser of admin rest api as when i execute the following command: + + ./s3curl.pl --id=personal --put -- http://radosgw.h3c.com:8000/admin/user?subuser\&uid=yrf2\&subuser=yrf2:yrf1\&key-type=s3 -v + + it would return msg as follows : + + < HTTP/1.1 403 Forbidden + < Date: Thu, 14 Jul 2016 07:04:40 GMT + * Server Apache/2.4.7 (Ubuntu) is not blacklisted + < Server: Apache/2.4.7 (Ubuntu) + < x-amz-request-id: tx00000000000000006608f-0057873988-8551-slave + < Accept-Ranges: bytes + < Content-Length: 114 + < Content-Type: application/json + < + * Connection #0 to host slave.com left intact + {"Code":"InvalidAccessKeyId","RequestId":"tx00000000000000006608f-0057873988-8551-slave","HostId":"8551-slave-us"} + + But i have modified the codes for support it ,and it will return actual msg as follows : + + "subusers": [ + { + "id": "yrf2:yrf1", + "permissions": "" + } + ], + "keys": [ + { + "user": "yrf2", + "access_key": "B46PXYFEWUX0IMHGKP8C", + "secret_key": "2JYxywXizqwiiMd74UXrJdSJMPNlBtYwF5z8rNvh" + }, + { + "user": "yrf2:yrf1", + "access_key": "INO55WXJ7JQ1ZZGSAB6B", + "secret_key": "GgCKEfF9hArV2hglunbO7KtvKZnbhmsDpqjSj5DL" + } + ], + + Please check it ,thanks . + + Signed-off-by: snakeAngel2015 + (cherry picked from commit 6535f6ad2137ee55bf5531e865c05aa10bd39bd0) + +commit d7b63e21ca9818e21afeb2945b882e24b7a9b10b +Merge: a3fae531cd f32b5c613a +Author: Nathan Cutler +Date: Wed Apr 26 21:32:31 2017 +0200 + + Merge pull request #14809 from tchaikov/wip-18193-jewel + + jewel: tests: test/librados/tmap_migrate: g_ceph_context->put() upon return + + Reviewed-by: Nathan Cutler + +commit a3fae531cdb8c2c64c66d38c947ca139f4ede83d +Merge: 89d6ddb1f5 6c4826606d +Author: Nathan Cutler +Date: Wed Apr 26 21:32:09 2017 +0200 + + Merge pull request #14701 from smithfarm/wip-18193-jewel + + jewel: core: transient jerasure unit test failures + + Reviewed-by: Kefu Chai + +commit 89d6ddb1f5ee08b0f019dfaadc5857a788c92a09 +Merge: c5f1fce21d be9e83281b +Author: Matt Benjamin +Date: Wed Apr 26 14:28:29 2017 -0400 + + Merge pull request #14776 from linuxbox2/jewel-pullup-civet-chunked + + [DNM] jewel: pullup civet chunked + +commit c5f1fce21d0996cce751b6bcca5e57da2cafc135 +Merge: 4d97e0ba8e 97cd21afc5 +Author: Nathan Cutler +Date: Wed Apr 26 19:32:07 2017 +0200 + + Merge pull request #14416 from smithfarm/wip-19557-jewel + + jewel: tests: upgrade/hammer-x failing with OSD has the store locked when Thrasher runs ceph-objectstore-tool on down PG + + Reviewed-by: Kefu Chai + +commit be9e83281b8c765cd111d5687a516fcd3ca521a5 +Author: Matt Benjamin +Date: Tue Apr 25 09:44:39 2017 -0400 + + civetweb: pullup chunked encoding by Marcus + + Fixes: http://tracker.ceph.com/issues/19736 + + Signed-off-by: Matt Benjamin + +commit 608785a0079f807ff860c56d96b1b67bf6a2ed74 +Author: yaoning +Date: Fri Jun 24 09:51:07 2016 +0800 + + os: make zero values noops for set_alloc_hint() in FileStore + + Signed-off-by: yaoning + (cherry picked from commit e2ec24f61b55457caccefecd56f9f08b98264802) + +commit f32b5c613a8acd50e32747c3581131d28d209efa +Author: Kefu Chai +Date: Wed Apr 26 22:58:30 2017 +0800 + + test/librados/tmap_migrate: g_ceph_context->put() upon return + + Signed-off-by: Kefu Chai + Conflict: test/librados/tmap_migrate.cc + this change is not cherry-picked from master, because tmap_migrate was + removed in master. so we are applying the same change in + cb1cda96713b2ec0f6418c4cbe3d964c2020729c to this test. + +commit 905c4acb99f9ea78ff615034dae969ab089bda06 +Author: Mark Nelson +Date: Tue May 3 09:56:47 2016 -0500 + + Fix reveresed promote throttle default parameters. + + Signed-off-by: Mark Nelson + (cherry picked from commit 793ceac2f3d5a2c404ac50569c44a21de6001b62) + +commit fb3ee2efcc13c37db90faa1bc8bad584bab22efa +Author: Marcus Watts +Date: Thu Apr 13 05:33:55 2017 -0400 + + rgw: swift: disable revocation thread if sleep == 0 || cache_size == 0 + + Keystone tokens can be revoked. This causes them to fail + validation. However, in ceph, we cache them. As long as + they're in the cache we trust them. To find revoked tokens + there's a call OSI-PKI/revoked but that's only useful for + pki tokens. Installations using fernet/uuid may not even + have the proper credentials to support the call, in which + case the call blows up in various ways filling up logs + with complaints. + + This code makes the revocation thread optional; by disabling it, + the complaints go away. A further fix is in the works + to use other more modern calls available in modern keystone + installations to properly deal with non-PKI/PKIZ tokens. + + (NB: jewel has this logic in src/rgw/rgw_swift.cc not in src/rgw/rgw_keystone.h) + + To disable the revocation thread, use at least one of these: + rgw_keystone_token_cache_size = 0 + using this will cause tokens to be validated on every call. + You may instead want to set + rgw_keystone_revocation_interval = 0 + using just this will disable the revocation thread, + but leaves the cache in use. That avoids the extra + validation overhead, but means token revocation won't + work very well. + + Fixes: http://tracker.ceph.com/issues/9493 + Fixes: http://tracker.ceph.com/issues/19499 + + Signed-off-by: Marcus Watts + (cherry picked from commit 003291a8cbca455c0e8731f66759395a0bb1f555) + +commit 4d97e0ba8ebc89b7797b0936a9e046ef59cc3899 +Merge: cc820a0d4c c2efeb4b62 +Author: Nathan Cutler +Date: Tue Apr 25 21:06:26 2017 +0200 + + Merge pull request #14686 from smithfarm/wip-19686-jewel + + jewel: osd: Give requested scrubs a higher priority + + Reviewed-by: David Zafman + +commit e552d91f73d996c44821f5fbfb28cfc3e5cddc9a +Author: Matt Benjamin +Date: Sat Nov 5 13:13:47 2016 -0400 + + rgw: add bucket size limit check to radosgw-admin + + The change adds a new list of all buckets x all users, with + fields for bucket name, tenant name, current num_objects, + current num_shards, current objects per shard, and the + corresponding fill_status--the latter consisting of 'OK', + 'WARN %', or 'OVER %.' + + The warning check is relative to two new tunables. The threshold + max objects per shard is set as rgw_bucket_safe_max_objects_per_shard, + which defaults to 100K. The value rgw_bucket_warning_threshold is + a percent of the current safe max at which to warn (defaults to + 90% of full). + + From review: + + * fix indentation (rgw_admin) + * if user a user_id is provided, check only buckets for that user + * update shard warn pct to be pct-of-fill (not 100 - pct-of-fill) + * print only buckets near or over per-shard limit, if --warnings-only + * s/bucket limitcheck/bucket limit check */ + * sanity shard limit should be 90, not 10 (because that changed) + * fixes for memleaks and other points found by cbodley + + Fixes: http://tracker.ceph.com/issues/17925 + + Signed-off-by: Matt Benjamin + (cherry picked from commit 7bc144ce36fedc16a3dedc54598b0d75fb8c68bc) + +commit cc820a0d4c2676799383aeaf49a9269e104853ce +Merge: 5ee54cfe8f d079b91479 +Author: Nathan Cutler +Date: Tue Apr 25 17:38:21 2017 +0200 + + Merge pull request #14605 from asheplyakov/19476-jewel + + jewel: rgw: don't return skew time in pre-signed url + + Reviewed-by: Casey Bodley + +commit 5ee54cfe8f0a955b11edb4819a652ee420f43e5d +Merge: 37254aee6c c05bd1cb1f +Author: Nathan Cutler +Date: Tue Apr 25 17:37:16 2017 +0200 + + Merge pull request #14660 from smithfarm/wip-19478-jewel + + jewel: rgw: zonegroupmap set does not work + + Reviewed-by: Casey Bodley + +commit 37254aee6c3f725cf60deb5c7a3fc28405c51216 +Merge: 09919f938f faeb8088ac +Author: Nathan Cutler +Date: Tue Apr 25 17:36:23 2017 +0200 + + Merge pull request #14607 from asheplyakov/19607-jewel + + jewel: rgw: multisite: fetch_remote_obj() gets wrong version when copying from remote + + Reviewed-by: Casey Bodley + +commit 09919f938f3c1e9e81963f676a9dd13114d54e73 +Merge: d5e1345a2a 527911fab7 +Author: Nathan Cutler +Date: Tue Apr 25 15:50:26 2017 +0200 + + Merge pull request #14587 from asheplyakov/19617-jewel + + jewel: mon/MonClient: make get_mon_log_message() atomic + + Reviewed-by: Sage Weil + +commit 6c4826606dc81fdd847959a49454c69a958bb1d8 +Author: Kefu Chai +Date: Mon Dec 5 20:23:21 2016 +0800 + + test/ceph_crypto: do not read ceph.conf in global_init() + + ForkDeathTest.MD5 expect an empty output while global_init() complains + if ceph.conf is missing if 0 is passed in as the `flags`. this test + passes if ceph.conf is in current working directory, but jenkins does + not prepare this file for this test. + + Fixes: http://tracker.ceph.com/issues/18128 + Signed-off-by: Kefu Chai + (cherry picked from commit c72a2271a8012a66d7bbccf5766a73da5bb878d6) + + Conflicts: + src/test/ceph_crypto.cc - jewel does not have + 5af29540675b674c1985ff98b28a783ed124acf6 + +commit aca2659952528aa1b40b02828293342128657194 +Author: Loic Dachary +Date: Thu Dec 8 12:40:42 2016 +0100 + + tests: fix erasure-code premature deallocation of cct + + The setup function returns before the run function, the cct variable + must be a data member, not a local variable that gets de-allocated + before run() starts. + + Signed-off-by: Loic Dachary + (cherry picked from commit efa1e54362423d4cfd1541fb8c68237b7b9ebbe3) + +commit 8bddd427d9a4bca75a352ca333847dbd6d2c369c +Author: Pan Liu +Date: Thu Feb 16 22:17:52 2017 +0800 + + rbd-nbd: no need create asok file for unmap and list-mapped commands. + + Fixes: http://tracker.ceph.com/issues/17951 + Signed-off-by: Pan Liu + (cherry picked from commit 72352653d585ef89043a4ece371b5c0cb3f6f32a) + +commit 328bfbd25c63b1b0e253865abedada7a9e5858e4 +Author: Jason Dillaman +Date: Tue Nov 29 12:36:00 2016 -0500 + + rbd-nbd: restart parent process logger after forking + + Fixes: http://tracker.ceph.com/issues/18070 + Signed-off-by: Jason Dillaman + (cherry picked from commit 29baf254d72cc593572b5a6215360ba51e3be198) + +commit 192e7bcdcd1bc02b40b29eff86a335cc8919f663 +Author: Kefu Chai +Date: Wed Nov 23 19:45:57 2016 +0800 + + crushtool: do not release g_ceph_context at exit + + it is but a work around of occasionally timeout. + + Signed-off-by: Kefu Chai + (cherry picked from commit d305cc51b18cbf4b2757bbacb5d43324461306a9) + +commit 8a2f27cc632c26d7c2b8e8528b4d459b1d78705b +Author: Kefu Chai +Date: Tue Nov 15 14:21:03 2016 +0800 + + common,test: g_ceph_context->put() upon return + + prior to this change, global_init() could create a new CephContext + and assign it to g_ceph_context. it's our responsibilty to release + the CephContext explicitly using cct->put() before the application + quits. but sometimes, we fail to do so. + + in this change, global_init() will return an intrusive_ptr, + which calls `g_ceph_context->put()` in its dtor. this ensures that + the CephContext is always destroyed before main() returns. so the + log is flushed before _log_exp_length is destroyed. + + there are two cases where global_pre_init() is called directly. + - ceph_conf.cc: g_ceph_context->put() will be called by an intrusive_ptr<> + deleter. + - rgw_main.cc: global_init() is called later on on the success code + path, so it will be taken care of. + + Fixes: http://tracker.ceph.com/issues/17762 + Signed-off-by: Kefu Chai + (cherry picked from commit cb1cda96713b2ec0f6418c4cbe3d964c2020729c) + + Conflicts: + src/ceph_fuse.cc + src/ceph_mgr.cc + src/global/global_init.cc + src/rgw/rgw_main.cc + src/test/compressor/test_compression.cc + src/test/compressor/test_compression_plugin.cc + src/test/compressor/test_compression_plugin_snappy.cc + src/test/compressor/test_compression_plugin_zlib.cc + src/test/compressor/test_compression_snappy.cc + src/test/compressor/test_compression_zlib.cc + src/test/erasure-code/TestErasureCode.cc + src/test/erasure-code/TestErasureCodeExample.cc + src/test/erasure-code/TestErasureCodeIsa.cc + src/test/erasure-code/TestErasureCodeJerasure.cc + src/test/erasure-code/TestErasureCodeLrc.cc + src/test/erasure-code/TestErasureCodePlugin.cc + src/test/erasure-code/TestErasureCodePluginIsa.cc + src/test/erasure-code/TestErasureCodePluginJerasure.cc + src/test/erasure-code/TestErasureCodePluginLrc.cc + src/test/erasure-code/TestErasureCodePluginShec.cc + src/test/erasure-code/TestErasureCodeShec.cc + src/test/erasure-code/TestErasureCodeShec_thread.cc + src/test/fio/fio_ceph_objectstore.cc + src/test/librados/misc.cc + src/test/mon/PGMap.cc + src/test/msgr/test_async_networkstack.cc + src/test/msgr/test_userspace_event.cc + src/test/objectstore/Allocator_test.cc + src/test/objectstore/BitAllocator_test.cc + src/test/objectstore/test_bluefs.cc + src/test/objectstore/test_bluestore_types.cc + src/test/objectstore/test_memstore_clone.cc + src/test/osd/TestPGLog.cc + src/test/rgw/test_http_manager.cc + src/test/rgw/test_rgw_compression.cc + src/test/test_mempool.cc + src/tools/rados/rados.cc + +commit d5e1345a2a6bd8456417db6bb60d61871165e6bd +Merge: 256f48f463 5096fc9c7c +Author: Nathan Cutler +Date: Tue Apr 25 15:42:43 2017 +0200 + + Merge pull request #14665 from smithfarm/wip-19610-jewel + + jewel: [librados_test_stub] cls_cxx_map_get_XYZ methods don't return correct value + + Reviewed-by: Jason Dillaman + +commit 256f48f46354f11a2f238f24fa9d890b55f4f4fc +Merge: 4f67da1b9d 21a83e1276 +Author: Nathan Cutler +Date: Tue Apr 25 09:20:19 2017 +0200 + + Merge pull request #14653 from smithfarm/wip-19662-jewel + + jewel: rgw_file: fix event expire check, don't expire directories being read + + Reviewed-by: Matt Benjamin + +commit 4f67da1b9d554a1a5371665573b1f56d3f903de3 +Merge: c2452c5364 33af18e592 +Author: Loic Dachary +Date: Tue Apr 25 09:17:33 2017 +0200 + + Merge pull request #14635 from smithfarm/wip-19690-jewel + + jewel: doc: Improvements to crushtool manpage + + Reviewed-by: Loic Dachary + +commit 040ff013d5c8aded8beedc59bbc4f5afccc64e46 +Author: Kefu Chai +Date: Wed Nov 16 11:56:09 2016 +0800 + + crushtool: s/exit(EXIT_FAILURE)/return EXIT_FAILURE/ + + so the destructor(s) can be called. + + Signed-off-by: Kefu Chai + (cherry picked from commit e01b89ed6be6b99fec5c725f4bc5769b42468cac) + + Conflicts: + src/tools/crushtool.cc - jewel does not have 17feefbcb3105553b763cb7ce123b20b77b95857 + +commit 8e993e6e43ecd6e2b444961d1e6c945081b64207 +Author: Kefu Chai +Date: Wed Nov 16 11:19:04 2016 +0800 + + global/signal_handler: reset injected segv after test + + ~CephContext() => ~TypedSingletonWrapper() => ~MempoolObs => + unregister_command() => ldout() << "unregister_command" => + Log::submit_entry() => *(volatile int *)(0) = 0xdead; + + Signed-off-by: Kefu Chai + (cherry picked from commit d932c8f2f23263924103a900714db82ee87f6eef) + + Conflicts: + src/log/Log.cc - jewel has "namespace log" instead of "namespace + logging" (trivial resolution) + +commit f1c0042b831826e5bd72ada79a4918a9c26bda24 +Author: Kefu Chai +Date: Tue Nov 15 14:42:35 2016 +0800 + + test_cors.cc: fix the mem leak + + Signed-off-by: Kefu Chai + (cherry picked from commit c8a3777203482cabf6739a8ba69b127df8697628) + +commit c49b114e8dde6c3f3c5a5b663bd8299b4f2feafb +Author: weiqiaomiao +Date: Tue Sep 6 16:34:52 2016 +0800 + + rgw: fix failed to create bucket if a non-master zonegroup has a single zone + + If a non-master zonegroup has a single zone, the metadata sync thread not running and + the non-master zonegroup can't sync user from master zonegroup, + so we can't create bucket(or other metadata update) in it + because the authenticated user not found in the zone of non-master zonegroup. + + Signed-off-by: weiqiaomiao + (cherry picked from commit 949af79b21098e6410bc29274cf36eae2d89faea) + + Conflicts: + src/rgw/rgw_rados.cc - retain d32654b7cd60ccc4e23d3f05b9e4385a697bacd6 + which was merged after this commit + +commit 43327f83efcbc5ce54be866a30da8dd1e58d6707 +Author: Loic Dachary +Date: Wed Feb 22 01:49:12 2017 +0100 + + ceph-disk: dmcrypt activate must use the same cluster as prepare + + When dmcrypt is used, the fsid cannot be retrieved from the data + partition because it is encrypted. Store the fsid in the lockbox to + enable dmcrypt activation using the same logic as regular activation. + + The fsid is used to retrive the cluster name that was used during + prepare, reason why activation does not and must not have a --cluster + argument. + + Fixes: http://tracker.ceph.com/issues/17821 + + Signed-off-by: Loic Dachary + (cherry picked from commit 7f66672b675abbc0262769d32a38112c781fefac) + + Conflicts: + src/ceph-disk/ceph_disk/main.py - in master, self.create_key() takes an + argument (self.args.cluster) but in jewel it takes no argument + +commit c2452c53641fca416268c2e31c774b8b7e609c88 +Merge: 82b8c89e47 01d04e28db +Author: Nathan Cutler +Date: Tue Apr 25 07:20:41 2017 +0200 + + Merge pull request #13608 from smithfarm/wip-19063-jewel + + jewel: tests: eliminate race condition in Thrasher constructor + + Reviewed-by: Kefu Chai + Reviewed-by: David Zafman + +commit 3ec1a9bf16e2c305096e11223aaa8db94dc4084d +Author: Sage Weil +Date: Fri Mar 31 10:06:42 2017 -0400 + + ceph_test_librados_api_misc: fix stupid LibRadosMiscConnectFailure.ConnectFailure test + + Sometimes the cond doesn't time out and it wakes up instead. Just repeat + the test many times to ensure that at least once it times out (usually + it doesn't; it's pretty infrequent that it doesn't). + + Fixes: http://tracker.ceph.com/issues/15368 + Signed-off-by: Sage Weil + (cherry picked from commit 8bc197400d94ee2716d3f2fa454247379a676cf9) + +commit 82b8c89e477610641a6e21123b7c929e9c560729 +Merge: 28c7ce595a 30c9527353 +Author: Nathan Cutler +Date: Mon Apr 24 22:27:33 2017 +0200 + + Merge pull request #14195 from cbodley/wip-19353 + + jewel: rgw: use separate http_manager for read_sync_status + + Reviewed-by: Yehuda Sadeh + +commit 28c7ce595ab8fef7c0076f091f249f6b3548ad54 +Merge: c05ecff3f0 2e50fe1684 +Author: Nathan Cutler +Date: Mon Apr 24 22:26:50 2017 +0200 + + Merge pull request #14066 from asheplyakov/19321-bp-jewel + + jewel: rgw: fix break inside of yield in RGWFetchAllMetaCR + + Reviewed-by: Yehuda Sadeh + +commit c05ecff3f0cb5af2f3aa52b68188742796335ddb +Merge: 3240cbf4ef dc4e7a1a86 +Author: Nathan Cutler +Date: Mon Apr 24 22:26:14 2017 +0200 + + Merge pull request #14064 from asheplyakov/19211-bp-jewel + + jewel: rgw: "cluster [WRN] bad locator @X on object @X...." in cluster log + + Reviewed-by: Yehuda Sadeh + +commit 3240cbf4ef60733f55800039051e85f2a7ace61d +Merge: d4672acbb8 85fbb00f6e +Author: Nathan Cutler +Date: Mon Apr 24 22:25:21 2017 +0200 + + Merge pull request #13842 from smithfarm/wip-19145-jewel + + jewel: rgw: a few cases where rgw_obj is incorrectly initialized + + Reviewed-by: Yehuda Sadeh + +commit d4672acbb82daf81eaf259e659dd627ec9f3bc79 +Merge: 61ed719d75 ec0668c201 +Author: Nathan Cutler +Date: Mon Apr 24 22:24:29 2017 +0200 + + Merge pull request #13837 from smithfarm/wip-19048-jewel + + jewel: rgw: multisite: some yields in RGWMetaSyncShardCR::full_sync() resume in incremental_sync() + + Reviewed-by: Yehuda Sadeh + +commit 61ed719d75bf3606fa9e3ae8c8ed776aa2ee4313 +Merge: f5e51db564 ced799f9c6 +Author: Nathan Cutler +Date: Mon Apr 24 22:23:24 2017 +0200 + + Merge pull request #13724 from asheplyakov/18626-bp-jewel + + jewel: rgw: Use decoded URI when verifying TempURL + + Reviewed-by: Yehuda Sadeh + +commit 66c3db7aee5b53f83e87ee8c8f081ab9b0336177 +Author: Casey Bodley +Date: Wed Mar 8 16:31:34 2017 -0500 + + rgw: data sync skips slo data when syncing the manifest object + + Fixes: http://tracker.ceph.com/issues/19027 + + Signed-off-by: Casey Bodley + (cherry picked from commit 8b69847d7b3e92c70090d1dddf7cea5c44fb6b20) + + Conflicts: bucket cleanup, overrides + +commit 303a62f7f15c69413165ed604869909587714a94 +Author: Casey Bodley +Date: Mon Mar 13 11:33:02 2017 -0400 + + rgw: RGWGetObj applies skip_manifest flag to SLO + + Signed-off-by: Casey Bodley + (cherry picked from commit 987377ae34382e107e1d54f0bfc1121fcedb4513) + +commit f3d99ae8aafaa65e91cd233b5ce8054678d8fa11 +Author: Casey Bodley +Date: Tue Feb 21 10:27:13 2017 -0500 + + rgw: allow system users to read SLO parts + + multisite data sync relies on fetching the object as the system user + + Fixes: http://tracker.ceph.com/issues/19027 + + Signed-off-by: Casey Bodley + (cherry picked from commit d50d18c500fd5dd89e7cada1162cf453b36df370) + + Conflicts: auth rework + +commit f5e51db5644d4eafdbe3b2d541582a17febed139 +Merge: c90cfb7a32 eac0e27193 +Author: Nathan Cutler +Date: Fri Apr 21 22:51:59 2017 +0200 + + Merge pull request #14643 from smithfarm/wip-revert-14427 + + Wip revert 14427 + + Reviewed-by: Josh Durgin + +commit db053da61807e26876d97786550a769295c7955a +Author: John Spray +Date: Mon Mar 27 12:56:31 2017 +0100 + + mds: validate prealloc_inos on sessions after load + + Mitigates http://tracker.ceph.com/issues/16842 + + Signed-off-by: John Spray + (cherry picked from commit c39aaf90ed1b23343eba2b341bb8ee6a50a4ea74) + + Conflicts: + src/mds/InoTable.cc - no 5259683e7819c22c14b21b1dd678a33e14574f21 in jewel + src/mds/InoTable.h - no 5259683e7819c22c14b21b1dd678a33e14574f21 in jewel + +commit 2b5eb8fa141fa8bd9173dee206ec3530d702fc3a +Author: John Spray +Date: Mon Mar 27 12:33:59 2017 +0100 + + mds: operator<< for Session + + Use this to get a nice human readable name + when available (also including the session id in + parentheses) + + Signed-off-by: John Spray + (cherry picked from commit 0f89787d8312f132ebb621f16c44e950b17a395a) + +commit 5b562145197833c6a6f48f006dfb13b6e38f9084 +Author: Henrik Korkuc +Date: Sun Feb 19 11:44:20 2017 +0200 + + client/Client.cc: add feature to reconnect client after MDS reset + + Client.cc marks session as stale instead of reconecting after received + reset from MDS. On MDS side session is closed so MDS is ignoring cap + renew. This adds option to reconnect stale client sessions instead of + just marking sessions stale. + + Fixes: http://tracker.ceph.com/issues/18757 + + Signed-off-by: Henrik Korkuc + (cherry picked from commit e0bbc704676ef4aed510daff075ef63c9e73b7b3) + +commit 8f21038d30097622e319ab986631b03f87f5d907 +Author: Kefu Chai +Date: Tue Mar 21 12:49:45 2017 +0800 + + doc: cephfs: fix the unexpected indent warning + + Signed-off-by: Kefu Chai + (cherry picked from commit e423f0b59711422b40c4b3de0bdc73b0947c04d3) + +commit f9a1954e113e807b5f9ee6fd56351adc2841730a +Author: Barbora Ančincová +Date: Thu Feb 16 10:45:36 2017 +0100 + + doc: additional edits in FUSE client config + + Signed-off-by: Bara Ancincova (bara@redhat.com) + (cherry picked from commit b6cad3364c020abd3acf906643fa0b6cbb862a0a) + +commit 018649f8a4628881c706a6df9b3eef48403fe91e +Author: Barbora Ančincová +Date: Thu Jan 26 12:23:34 2017 +0100 + + doc: Dirty data are not the same as corrupted data + + Signed-off-by: Bara Ancincova (bara@redhat.com) + (cherry picked from commit 80db40f8559128baadad42b925ae813e51a31409) + +commit 1d8a5b6d64a26a36fb3a227c52908631d95bef79 +Author: Barbora Ančincová +Date: Mon Jan 23 16:34:55 2017 +0100 + + doc: minor changes in fuse client config reference + + Signed-off-by: Bara Ancincova (bara@redhat.com) + (cherry picked from commit e57605681f10436f4b2c85e95179a2904b8c80da) + +commit 1ae46b2b94280b8b4a1db89b2cbed8f12bcbcc53 +Author: Patrick Donnelly +Date: Sun Jul 24 23:21:29 2016 -0400 + + doc: add client config ref + + Fixes: http://tracker.ceph.com/issues/16743 + + Signed-off-by: Patrick Donnelly + (cherry picked from commit 9ad2ccf29830d5309336fc7de877b6926e5dbacd) + +commit b8fd297eb64cd29c58596d0a5b0be8fbe9d94a72 +Author: Vasu Kulkarni +Date: Tue Apr 11 13:51:47 2017 -0700 + + use sudo to check check health + + Signed-off-by: Vasu Kulkarni + (cherry picked from commit 7af157ad4ce7f7e2b8de97ee10eeaf64b9099bc0) + +commit 1b91ffc0fbe76c5475f17d4e15ea295ee3680688 +Author: Vasu Kulkarni +Date: Wed Mar 29 09:27:20 2017 -0700 + + Add reboot case for systemd test + + test systemd units restart after reboot + + Signed-off-by: Vasu Kulkarni + (cherry picked from commit 7b587304a54d9b21041ffdfbc85fad8d87859c49) + +commit 3d8d1dad8a698a9fb45be7b31c92f8b71ee67720 +Author: Vasu Kulkarni +Date: Wed Mar 29 09:56:11 2017 -0700 + + Fix distro's, point to latest version + + Signed-off-by: Vasu Kulkarni + (cherry picked from commit 1947648669971c1bd1ca189870ed9b25bbd48d3a) + +commit c90cfb7a327fcbb9508e617c2353becb7e5cb45f +Merge: 327276cf3d 9b77b16b88 +Author: Nathan Cutler +Date: Thu Apr 20 22:05:57 2017 +0200 + + Merge pull request #14602 from asheplyakov/19646-jewel + + jewel: ceph-disk: enable directory backed OSD at boot time + + Reviewed-by: Loic Dachary + +commit 327276cf3d4fb7a2558620a8a7d9cc90e5d6e5c5 +Merge: 7008c64c51 25e43ac256 +Author: Nathan Cutler +Date: Thu Apr 20 22:04:41 2017 +0200 + + Merge pull request #14449 from smithfarm/wip-test-doc-oversight + + tests: fix oversight in yaml comment + + Reviewed-by: Loic Dachary + +commit f34489dd52f07aeb88e1dbf361ead63f09bb9c65 +Author: YunfeiGuan +Date: Mon Apr 10 05:48:47 2017 +0000 + + cephfs: fix mount point break off problem after mds switch occured + + The hot-standby become active as we expected but the mount piont broken strangely + when the active mds is down. The root reason is the new mds use last_cap_renews + decoded from ESesson::replay in find_idle_sessions and wrongly killed the session. + Maybe we should reset session->last_cap_renew to the current time when server send + OPEN to client in reconnect stage. + + Fixes: http://tracker.ceph.com/issues/19437 + Signed-off-by: Guan yunfei + (cherry picked from commit 4ef830c5d6f22bf0d4f82a8624c772ecbbda44a6) + + Conflicts: + src/mds/Server.cc (leave '\n' in because jewel does not have + 693132eb00b1803d5e97a79908521d5a6903e9f8; jewel ceph_clock_now takes a + CephContext object) + +commit 7008c64c5143a3ea19d6679a3e521897f74ff69a +Merge: d62644abcd f8aa6be06c +Author: Nathan Cutler +Date: Thu Apr 20 19:26:52 2017 +0200 + + Merge pull request #13606 from smithfarm/wip-19062-jewel + + jewel: build/ops: enable build of ceph-resource-agents package on rpm-based os + + Reviewed-by: Ken Dreyer + +commit d62644abcde0fd99da24922ce7638d173952ceb4 +Merge: 8df8960553 482bd1adab +Author: Nathan Cutler +Date: Thu Apr 20 18:18:05 2017 +0200 + + Merge pull request #14654 from smithfarm/wip-19461-jewel + + jewel: admin ops: fix the quota section + + Reviewed-by: Casey Bodley + +commit c2efeb4b62e6dc4e6975561eb8b20cfca66f7237 +Author: David Zafman +Date: Mon Apr 17 14:58:02 2017 -0700 + + osd: Give requested scrub work a higher priority + + Once started we now queue scrub work at higher priority than + scheduled scrubs. + + Fixes: http://tracker.ceph.com/issues/15789 + + Signed-off-by: David Zafman + (cherry picked from commit ebab8b1f4f67fbdec1e147c580329c1e2b5cf7cd) + + Conflicts: + src/osd/OSD.h - in jewel, the PGScrub() call is enclosed within + op_wq.queue(make_pair(...)) instead of enqueue_back() + +commit db86a24e7906ca7c70c60b1752f1230d56361bcd +Author: Yan, Zheng +Date: Wed Feb 22 17:33:05 2017 +0800 + + client: wait for lastest osdmap when handling set file/dir layout + + Fixes: http://tracker.ceph.com/issues/18914 + Signed-off-by: "Yan, Zheng" + (cherry picked from commit 76f5eb86cdd61dde4e6c7cfeb5cf34f0c0334f21) + + Conflicts: + src/client/Client.cc (jewel does not have 201c56039) + src/client/Client.h (jewel does not have 201c56039) + +commit 7b9283beec0c4bf8e2067558fc4e03e336849b77 +Author: Yang Honggang +Date: Thu Apr 13 20:09:07 2017 +0800 + + cephfs: fix write_buf's _len overflow problem + + After I have set about 400 64KB xattr kv pair to a file, + mds is crashed. Every time I try to start mds, it will crash again. + The root reason is write_buf._len overflowed when doing + Journaler::append_entry(). + + This patch try to fix this problem through the following changes: + + 1. limit file/dir's xattr size + 2. throttle journal entry append operations + + Fixes: http://tracker.ceph.com/issues/19033 + Signed-off-by: Yang Honggang joseph.yang@xtaotech.com + (cherry picked from commit eb915d0eeccbe523f8f70f6571880003ff459459) + +commit b52c5088618011a569f157616c5c667c2fc1e9fe +Author: John Spray +Date: Wed Mar 8 12:13:46 2017 +0000 + + mds: shut down finisher before objecter + + Some of the finisher contexts would try to call into Objecter. + We mostly are protected from this by mds_lock+the stopping + flag, but at the Filer level there's no mds_lock, so in the + case of file size probing we have a problem. + + Fixes: http://tracker.ceph.com/issues/19204 + Signed-off-by: John Spray + (cherry picked from commit 177a97d5c55ee6a2d5dcd3cf0893546190b10f7a) + + Conflicts: + src/mds/MDSRank.cc (no purge_queue.shutdown() in jewel because jewel + does not have 8ebf7d95a9071de24bb1e56a6423c505169cb4de) + +commit 96e801fb53941214c669ac01c1804a4d1f27086c +Author: John Spray +Date: Tue Mar 28 14:13:33 2017 -0400 + + mds: ignore ENOENT on writing backtrace + + We get ENOENT when a pool doesn't exist. This can + happen because we don't prevent people deleting + former cephfs data pools whose files may not have + had their metadata flushed yet. + + http://tracker.ceph.com/issues/19401 + Signed-off-by: John Spray + (cherry picked from commit 3fccc2372f2715d075b05e459140360cf6e7ca96) + +commit 8df896055366d777ca309dd4a7840f2a2a5a72cc +Merge: da888fa871 7468689314 +Author: Nathan Cutler +Date: Thu Apr 20 14:53:30 2017 +0200 + + Merge pull request #14680 from smithfarm/wip-19711-jewel + + jewel: [test] test_notify.py: rbd.InvalidArgument: error updating features for image test_notify_clone2 + + Reviewed-by: Jason Dillaman + +commit 74686893147f2d7e1fd1287de37587554fea96c6 +Author: Jason Dillaman +Date: Wed Apr 19 09:26:31 2017 -0400 + + test: rbd master/slave notify test should test active features + + Fixes: http://tracker.ceph.com/issues/19692 + Signed-off-by: Jason Dillaman + (cherry picked from commit 0dcba41cba96566d0b8da54cf0316d523b88ded2) + +commit 7347f1193963666ce07ff9163064aeb0cf343d38 +Author: Yan, Zheng +Date: Wed Apr 5 21:29:10 2017 +0800 + + mds: make C_MDSInternalNoop::complete() delete 'this' + + Fixes: http://tracker.ceph.com/issues/19501 + Signed-off-by: "Yan, Zheng" + (cherry picked from commit 424e0c6744e7f63459ca0ff7deab751726aa30cd) + + Conflicts: + src/mds/MDSContext.h (omit "override" because jewel does not have + 1a91aeab987870b3ccbcf2f1e476fac8b534d449) + +commit 824b19a9a66261a90c4e4de64e877a42438febd2 +Author: John Spray +Date: Wed Mar 29 19:38:37 2017 +0100 + + tools/cephfs: set dir_layout when injecting inodes + + When we left this as zero, the MDS would interpret it was HASH_LINUX + rather than the default HASH_RJENKINS. Potentially that + could cause problems if there perhaps were already dirfrags in + the metadata pool that were set up using rjenkins. Mainly + it just seems more appropriate to explicitly set this field + rather than hit the fallback behaviour. + + Related: http://tracker.ceph.com/issues/19406 + Signed-off-by: John Spray + (cherry picked from commit 7d6d542885bd29b71214f9ca52bd26e9183c5d01) + +commit eab56dae6714706cf9650dff172b20a764f5481c +Author: John Spray +Date: Thu Mar 9 13:15:46 2017 +0000 + + mon: fix hiding mdsmonitor informative strings + + Local `stringstream ss` declarations were hiding + the real variable used to feed back to the user. + + Fixes: http://tracker.ceph.com/issues/16709 + Signed-off-by: John Spray + (cherry picked from commit 00404ae9bd4cce0518a44d36d2d6a5612f4f9d04) + +commit da888fa8713178cc23c1069ce2651e02c98aad05 +Merge: 8068b546af 2271cd8128 +Author: Kefu Chai +Date: Thu Apr 20 19:10:33 2017 +0800 + + Merge pull request #14402 from shinobu-x/wip-17331-jewel + + jewel: ceph-disk: ceph-disk list reports mount error for OSD having mount options with SELinux context + + Reviewed-by: Loic Dachary + Reviewed-by: Brad Hubbard + Reviewed-by: Kefu Chai + +commit 8068b546afbe8e774c9d699205a32215e38c5d4f +Merge: 118ccad0ba 754b4a482c +Author: Nathan Cutler +Date: Thu Apr 20 13:06:33 2017 +0200 + + Merge pull request #13865 from smithfarm/wip-19158-jewel + + jewel: rgw: health check errors out incorrectly + + Reviewed-by: Radoslaw Zarzynski + +commit d57437e338984c5db84f9d16387e082ada5a0a33 +Author: John Spray +Date: Mon Mar 6 11:51:31 2017 +0000 + + mds: reset heartbeat in export_remaining_imported_caps + + This loop can be very long. + + Fixes: http://tracker.ceph.com/issues/19118 + Signed-off-by: John Spray + (cherry picked from commit 85071f1509beba4a390730e6a3a4332484646d63) + +commit 6adf1904ed7209b70328b20f248a701fbdd3127c +Author: John Spray +Date: Mon Mar 6 11:24:50 2017 +0000 + + mds: heartbeat_reset in dispatch + + Previously we only heartbeated in tick. However, our locking is + not guaranteed to be fair, so on a super-busy dispatch queue it may be + possible for the heartbeat to time out while the tick() function + is waiting for mds_lock. + + Fixes: http://tracker.ceph.com/issues/19118 + Signed-off-by: John Spray + (cherry picked from commit 819394549af10532419d88742fae3a69d2ea487d) + +commit 63f41d543f8a5f1f55a12612d39c6a2a1cf9c114 +Author: Yan, Zheng +Date: Wed Feb 15 11:45:26 2017 +0800 + + test/libcephfs: avoid buffer overflow when testing ceph_getdents() + + The buffer size should be at least "2 * sizeof(struct dirent)". + Otherwise, the code that checks dentry '..' overflow. + + Fixes: http://tracker.ceph.com/issues/18941 + Signed-off-by: "Yan, Zheng" + (cherry picked from commit fa6671345b8f3a82dcd232f99e55a982b0a641f1) + +commit 7146816065bea55b4e3fec59048a459bcff50f55 +Author: Zhi Zhang +Date: Fri Feb 10 10:56:46 2017 +0800 + + mds/StrayManager: aviod reusing deleted inode in StrayManager::_purge_stray_logged + + Signed-off-by: Zhi Zhang + (cherry picked from commit 4978e57419482384279d7e784a625f5e5c10961a) + +commit d8b139b5847cb46aa13486ee85e26f26421f36d6 +Author: John Spray +Date: Wed Feb 1 00:38:08 2017 +0000 + + tasks/cephfs: switch open vs. write in test_open_inode + + Do the write after opening the file, so that we get good + behaviour wrt the change in Mount.open_background that uses + file existence to confirm that the open happened. + + Signed-off-by: John Spray + (cherry picked from commit a027dba78fc8bc84ae39d7998b386ce21c01e1bf) + +commit e8ae80fc8721e500782c7e87a7cb89128c2a9687 +Author: John Spray +Date: Thu Jan 26 16:48:58 2017 +0000 + + qa: fix race in Mount.open_background + + Previously a later remote call could end up executing + before the remote python program in open_background + had actually got as far as opening the file. + + Fixes: http://tracker.ceph.com/issues/18661 + Signed-off-by: John Spray + (cherry picked from commit c6d91dd91252e703d08b8ac62ac6a47ee82c0bed) + +commit 36c86f71efc10f9a651aedf01dc6fb9d1bfed703 +Author: Yan, Zheng +Date: Wed Jan 25 15:28:23 2017 +0800 + + mds: don't purge strays when mds is in clientreplay state + + MDS does not trim log when it's in clientreplay state. If mds hang + at clientreplay state (due to bug), purging strays can submit lots + of log events and create very large mds log. + + Signed-off-by: "Yan, Zheng" + (cherry picked from commit 86bbc7fff02668077f27d0924ba3efe6544b77f6) + +commit 8b01cf33575783661a1e1151c8214d327a08b6f9 +Author: Yan, Zheng +Date: Wed Jan 25 11:03:45 2017 +0800 + + mds: skip fragment space check for replayed request + + when handling replayed request, stray directory can be different + from the stray directory used by the original request. The fragment + space check for stray directory can fail. + + Fixes: http://tracker.ceph.com/issues/18660 + Signed-off-by: "Yan, Zheng" + (cherry picked from commit afe889cbc5baab196567c2aad01f49fe90901fda) + +commit 82ea0971b3cb07c32ec837cb85de63d4068a70d7 +Author: Greg Farnum +Date: Wed Dec 14 12:09:44 2016 -0800 + + client: fix the cross-quota rename boundary check conditions + + We were previously rejecting a rename if either of the involved directories + was a quota root, even if the other directory was part of the same quota + "tree". What we really want to do is identify the correct quota root + (whether local or ancestral) for each directory and compare them. So + now we do. + + Signed-off-by: Greg Farnum + (cherry picked from commit 8e8892aa46accb519faa4bb9fecf66618f1b11b2) + + Conflicts: + src/client/Client.cc (do not pass perm to get_quota_root() because + jewel does not have 3caa4d233633fb7a67747f2c79c4a0ab89112294) + +commit dbe90c79b86743c7d143d33eb5389fcee0ac76ef +Author: Mykola Golub +Date: Tue Apr 11 22:31:43 2017 +0200 + + librbd: fix rbd_metadata_list and rbd_metadata_get + + - properly check for val_len in rbd_metadata_list + - don't expect output buffers are zero pre-filled + + Fixes: http://tracker.ceph.com/issues/19588 + Signed-off-by: Mykola Golub + (cherry picked from commit 75afc74ea681402e22b6dec8b83276d145fc786b) + +commit 5096fc9c7c62e3043a9a0638eb2516792526fdd7 +Author: Jason Dillaman +Date: Wed Apr 12 10:47:28 2017 -0400 + + test/librados_test_stub: fixed cls_cxx_map_get_keys/vals return value + + Fixes: http://tracker.ceph.com/issues/19597 + Signed-off-by: Jason Dillaman + (cherry picked from commit 9ffd464dac102f684d6dfa78e58d2cb45e165ed6) + +commit 216156b5d4e2666ca592eaab2211940028422bc0 +Author: Jason Dillaman +Date: Fri Mar 10 10:56:38 2017 -0500 + + rbd: prevent adding multiple mirror peers to a single pool + + The rbd-mirror daemon does not currently support replication + from multiple peers. Until that is supported, add a temporary + restriction to prevent confusion. + + Fixes: http://tracker.ceph.com/issues/19256 + Signed-off-by: Jason Dillaman + (cherry picked from commit c0c9d1014d57b3d5b95e7513fcc38d04b9ea5165) + +commit c05bd1cb1f570c42b1999fbc70c86b0a72a7fcb3 +Author: Orit Wasserman +Date: Wed Apr 5 13:31:08 2017 +0300 + + radosgw-admin: use zone id when creating a zone + + Fixes: http://tracker.ceph.com/issues/19498 + Signed-off-by: Orit Wasserman + (cherry picked from commit 3fea36d635fcba8ca584a1c0ec9f07840009402c) + +commit ba81cbbdee1ccf95ceff56eef0a1b2b06be4024a +Author: Casey Bodley +Date: Tue Mar 14 15:43:13 2017 -0400 + + qa: rgw task uses period instead of region-map + + Signed-off-by: Casey Bodley + (cherry picked from commit e3e3a71d1f1fb43bb4172ce2dfac9a28ca89df0f) + +commit a755c95262e10fac774716e460e2ba2eaee9df70 +Author: Casey Bodley +Date: Tue Mar 14 14:18:15 2017 -0400 + + rgw-admin: remove deprecated regionmap commands + + Fixes: http://tracker.ceph.com/issues/18725 + + Signed-off-by: Casey Bodley + (cherry picked from commit 5830c1849a0c0110d17c37784808e456e6dcb7b3) + + Conflicts: + src/rgw/rgw_admin.cc (trivial resolution) + +commit 482bd1adabf6f54c8f2bd73090d2e4c02d07f8a3 +Author: hrchu +Date: Wed Mar 29 02:17:04 2017 +0000 + + doc: rgw: correct the quota section + + Add the missing option and fix typo. + + Fixes: http://tracker.ceph.com/issues/19397 + + Signed-off-by: Chu, Hua-Rong + (cherry picked from commit 51a88267f0d7f51aeb62092949b66b9f6c062e15) + +commit 21a83e1276e415e98a3780d0374bb9d4feb191d9 +Author: Matt Benjamin +Date: Wed Mar 15 16:35:16 2017 -0400 + + rgw_file: remove unused rgw_key variable + + Signed-off-by: Matt Benjamin + (cherry picked from commit 1100a1c26e76485569cfebcf863b18cf908f6161) + +commit ebad040b3ab62e702afc52edd9d99d984b24cdc1 +Author: Matt Benjamin +Date: Fri Apr 14 15:56:37 2017 -0400 + + rgw_file: fix readdir after dirent-change + + Also, fixes link count computation off-by-one, update of state.nlink + after computation, link computation reset at start, and a time print + in debug log. + + Fixes: http://tracker.ceph.com/issues/19634 + + Signed-off-by: Matt Benjamin + + link count + + Signed-off-by: Matt Benjamin + (cherry picked from commit e0f80266ecd424bf9466579b3edc03911a7c5719) + +commit dd9833cacaec20e5bd1a70ec46a427a7352eb5d6 +Author: Matt Benjamin +Date: Tue Apr 11 06:42:07 2017 -0400 + + rgw_file: don't expire directories being read + + If a readdir expire event turns out to be older than last_readdir, + just reschedule it (but actually, we should just discard it, as + another expire event must be in queue. + + Fixes: http://tracker.ceph.com/issues/19625 + + Signed-off-by: Matt Benjamin + (cherry picked from commit 007b7451c26716c51207c161dc347e9a00da53f1) + +commit 30a5e857aade2474c5bd621c57938dfe333c3ae5 +Author: Matt Benjamin +Date: Wed Mar 15 16:40:35 2017 -0400 + + rgw_file: rgw_readdir: return dot-dirs only when *offset is 0 + + Signed-off-by: Matt Benjamin + (cherry picked from commit 61482c2b85a07519f2256b1a3f2b6d8aa99d5f06) + +commit fe836bfb7a286c87c57576d29d6862be2514ada5 +Author: Matt Benjamin +Date: Tue Apr 11 05:56:13 2017 -0400 + + rgw_file: chunked readdir + + Adjust readdir callback path for new nfs-ganesha chunked readdir, + including changes to respect the result of callback to not + continue. + + Pending introduction of offset name hint, our caller will just be + completely enumerating, so it is possible to remove the offset map + and just keep a last offset. + + Fixes: http://tracker.ceph.com/issues/19624 + + Signed-off-by: Matt Benjamin + (cherry picked from commit e0191d74e3aef06bf300df045a53a3952a71f651) + +commit 16eeb8c2acc8a1f843fa87967c2ee4c0ed2cd8bd +Author: Gui Hecheng +Date: Fri Mar 31 10:42:40 2017 +0800 + + rgw_file: fix missing unlock in unlink + + Fixes: http://tracker.ceph.com/issues/19435 + + Signed-off-by: Gui Hecheng + (cherry picked from commit cb6808a6366a70f54d0cc16437d16aa1b7819c84) + +commit 8c7cb8227c39b09060cdca4e11dec75cf7f2336c +Author: Matt Benjamin +Date: Mon Mar 13 21:52:08 2017 -0400 + + rgw_file: implement reliable has-children check (unlink dir) + + Bug report and discussion provided by + Gui Hecheng in nfs-ganesha upstream + github. Briefly, while a reliable check is potentially costly, + it is necessary. + + Fixes: http://tracker.ceph.com/issues/19270 + + Signed-off-by: Matt Benjamin + (cherry picked from commit b05f1c6d61aa4501a971e87de6dcaf3e58c3d9b4) + +commit 18f14dd86400b50f46930a9ef56666d82035507e +Author: Matt Benjamin +Date: Tue Apr 4 20:16:13 2017 -0400 + + rgw_file: introduce rgw_lookup type hints + + The new type hints optimize object type deduction, when the + rgw_lookup is called from an rgw_readdir callback. + + Fixes: http://tracker.ceph.com/issues/19623 + + Signed-off-by: Matt Benjamin + (cherry picked from commit 2e66c7a7cc763c5c0d6f5db04855f60f2b2ceed3) + +commit 118ccad0ba763b98c9ee3de225a947be5372dc0d +Merge: bf30ecd7cb 65465356b5 +Author: Nathan Cutler +Date: Thu Apr 20 11:08:45 2017 +0200 + + Merge pull request #14383 from smithfarm/wip-19547-jewel + + jewel: build/ops: rbdmap.service not included in debian packaging (jewel-only) + + Reviewed-by: Ken Dreyer + +commit bf30ecd7cb8dea43a9d55cb1b02c72bfda6bad09 +Merge: 376c5e4753 9e123e6d6c +Author: Nathan Cutler +Date: Thu Apr 20 11:02:39 2017 +0200 + + Merge pull request #14143 from smithfarm/wip-19355-jewel + + jewel: rgw: when converting region_map we need to use rgw_zone_root_pool + + Reviewed-by: Casey Bodley + +commit 376c5e47531a2803ac9b7ea236b989c528268a9f +Merge: da306df4de e2ee70a8ad +Author: Nathan Cutler +Date: Thu Apr 20 11:01:49 2017 +0200 + + Merge pull request #14136 from smithfarm/wip-19330-jewel + + jewel: rgw: upgrade to multisite v2 fails if there is a zone without zone info + + Reviewed-by: Casey Bodley + +commit da306df4deaaa782c0bad72539affd3ee1ec7efc +Merge: 57b210da41 5ee8feaba4 +Author: Nathan Cutler +Date: Thu Apr 20 11:00:35 2017 +0200 + + Merge pull request #13872 from smithfarm/wip-19163-jewel + + jewel: doc: radosgw-admin: add the 'object stat' command to usage + + Reviewed-by: Casey Bodley + +commit 57b210da4185d624524d05bcd9ad01c2df16ca76 +Merge: db92019e9a 9cd7dd8490 +Author: Nathan Cutler +Date: Thu Apr 20 10:59:33 2017 +0200 + + Merge pull request #13863 from smithfarm/wip-19155-jewel + + jewel: rgw: typo in rgw_admin.cc + + Reviewed-by: Casey Bodley + +commit db92019e9af43c2367fdf7865c0fab8cb38453e6 +Merge: 6dcd5fa847 6add2a457e +Author: Nathan Cutler +Date: Thu Apr 20 10:56:35 2017 +0200 + + Merge pull request #13779 from smithfarm/wip-18866-jewel + + jewel: rgw: 'radosgw-admin sync status' on master zone of non-master zonegroup + + Reviewed-by: Casey Bodley + +commit eac0e27193c67ffca60b5e7c61e7769ad8ace6aa +Author: Nathan Cutler +Date: Wed Apr 19 16:53:57 2017 +0200 + + Revert "osdc/Objecter: If osd full, it should pause read op which w/ rwordered flag." + + This reverts commit 2d68822c784eb4d62d3b0198ed4ec04404dbffb3. + + Signed-off-by: Nathan Cutler + +commit 0efe16d2566f0d6040f61fafd38c6661f08da1cd +Author: Nathan Cutler +Date: Wed Apr 19 16:53:49 2017 +0200 + + Revert "osdc/Objecter: resend RWORDERED ops on full" + + This reverts commit f2474042ecd6560323673170c13f2cb964406e70. + + Signed-off-by: Nathan Cutler + +commit 33af18e59298926d9636023faf871a191d582c1a +Author: Nathan Cutler +Date: Tue Apr 18 08:06:01 2017 +0200 + + doc: mention --show-mappings in crushtool manpage + + Fixes: http://tracker.ceph.com/issues/19649 + Signed-off-by: Loic Dachary + Signed-off-by: Nathan Cutler + (cherry picked from commit b48b6f4ed8b5f5b5852cbbfd5b3d5b650efb7f1b) + +commit 6dcd5fa8474c3a43ffca2394557b11f4906ee1ff +Merge: 7c006fc164 68fcb01211 +Author: Gregory Farnum +Date: Wed Apr 19 02:47:27 2017 -0400 + + Merge pull request #14596 from gregsfortytwo/wip-17916-divergent + + Wip 17916 divergent + + Reviewed-by: Josh Durgin + +commit 97cd21afc54efe3afb482b041f9c34ab6cdc682e +Author: Nathan Cutler +Date: Sun Apr 9 20:11:27 2017 +0200 + + tests: Thrasher: handle "OSD has the store locked" gracefully + + On slower machines (VPS, OVH) it takes time for the OSD to go down. + + Fixes: http://tracker.ceph.com/issues/19556 + Signed-off-by: Nathan Cutler + (cherry picked from commit a5b19d2d73540b730392f8001c8601f2cecc1b51) + +commit faeb8088ac3bd16bc04a1e5a55fec50285a7253f +Author: Casey Bodley +Date: Wed Apr 5 16:19:57 2017 -0400 + + rgw: fix for null version_id in fetch_remote_obj() + + commit 8b43c9781206c22d9aedb4beb8d669bf1e23169f fixed the wrong use of + the dest_obj's version, but removed the check for "null" version + + Signed-off-by: Casey Bodley + (cherry picked from commit 915370776df5b964c2ee8d9f9329562919eef8d5) + +commit 6180fcb4ec33bdade37f5693193712f8016b2560 +Author: Zhang Shaowen +Date: Fri Mar 17 16:26:56 2017 +0800 + + rgw: version id doesn't work in fetch_remote_obj + + Signed-off-by: Zhang Shaowen + (cherry picked from commit 8b43c9781206c22d9aedb4beb8d669bf1e23169f) + + Conflicts: + src/rgw/rgw_rados.cc: trivial: dest_obj.key.instance in master + versus dest_obj.get_instance() in Jewel + +commit d079b91479abfb474fad4fafe54c119f009ea572 +Author: liuchang0812 +Date: Fri Feb 10 18:02:03 2017 +0800 + + rgw: don't return skew time in pre-signed url + + Fixes: http://tracker.ceph.com/issues/18828 + + Signed-off-by: liuchang0812 + (cherry picked from commit dd8b348f4aad0124e8a4457117bf3f5f76af7bdb) + +commit 9b77b16b888b8efbf7d50d333e1880a6ec70d87a +Author: Loic Dachary +Date: Thu Apr 13 23:49:50 2017 +0200 + + ceph-disk: enable directory backed OSD at boot time + + https://github.com/ceph/ceph/commit/539385b143feee3905dceaf7a8faaced42f2d3c6 + introduced a regression preventing directory backed OSD from starting at + boot time. + + For device backed OSD the boot sequence starts with ceph-disk@.service + and proceeds to + + systemctl enable --runtime ceph-osd@.service + + where the --runtime ensure ceph-osd@12 is removed when the machine + reboots so that it does not compete with the ceph-disk@/dev/sdb1 unit at + boot time. + + However directory backed OSD solely rely on the ceph-osd@.service unit + to start at boot time and will therefore fail to boot. + + The --runtime flag is selectively set for device backed OSD only. + + Fixes: http://tracker.ceph.com/issues/19628 + + Signed-off-by: Loic Dachary + (cherry picked from commit f425a127b7487d2093c8c943f0bcdec3d673d601) + + Conflicts: + src/ceph-disk/ceph_disk/main.py: trivial: Jewel does not support + OpenRC and other inits, hence no corresponding 'elif' + +commit 68fcb01211e064f0d200cc9c9576254e9a6b949c +Author: Greg Farnum +Date: Mon Apr 17 18:09:55 2017 -0700 + + pglog: require users set a config option before ignoring divergent_priors + + Signed-off-by: Greg Farnum + +commit b9477303b010b3653934f77fa533df01aeff1c3c +Author: Greg Farnum +Date: Fri Apr 7 14:33:20 2017 -0700 + + osd: pglog: clean up divergent_priors off disk when running; don't assert on startup + + Fixes: http://tracker.ceph.com/issues/17916 + + Signed-off-by: Greg Farnum + +commit 7c006fc1640d2f6b9dc9002bfd994ecdf25510ee +Merge: e31a540dce 721b2083cd +Author: Gregory Farnum +Date: Mon Apr 17 17:41:19 2017 -0400 + + Merge pull request #14492 from gregsfortytwo/wip-jewel-snaptrim + + Backport snap trimming improvements to Jewel + + Reviewed-by: Josh Durgin + +commit 721b2083cd2ed8567d41aba6b17caf30b678e6b3 +Merge: a84dc8fe74 e31a540dce +Author: Gregory Farnum +Date: Mon Apr 17 17:39:59 2017 -0400 + + Merge branch 'jewel' into wip-jewel-snaptrim + +commit a84dc8fe747d1e17c7910c9857f7f5d3d56e2dff +Author: Greg Farnum +Date: Mon Apr 17 14:32:38 2017 -0700 + + PendingReleaseNotes: discuss snap trim improvements + + Signed-off-by: Greg Farnum + +commit 360a9d9af003c650cdf00534909d6488c702c413 +Author: Greg Farnum +Date: Wed Apr 12 16:30:55 2017 -0700 + + PrimaryLogPG: reimplement osd_snap_trim_sleep within the state machine + + Rather than blocking the main op queue, just pause for that amount of + time between state machine cycles. + + Also, add osd_snap_trim_sleep to a few of the thrasher yamls. + + Signed-off-by: Samuel Just + (cherry picked from commit 2ed7759cfeb03e71f0fbd98fe7c2db2bb741861c) + + Conflicts: + src/osd/PrimaryLogPG.cc + + Signed-off-by: Greg Farnum + (cherry picked from commit 67336454a4cee66522bc0ca01b2c58b8960f75ec) + + Conflicts: + qa/suites/rados/thrash/thrashers/default.yaml + qa/suites/rados/thrash/thrashers/pggrow.yaml + src/osd/OSD.h + src/osd/ReplicatedPG.cc + src/osd/ReplicatedPG.h + + Signed-off-by: Greg Farnum + +commit 18dbf6a0245e35dbbdb5ddb760182795b37983c0 +Author: Samuel Just +Date: Thu Jan 26 15:41:21 2017 -0800 + + rados: check that pool is done trimming before removing it + + Signed-off-by: Samuel Just + (cherry picked from commit 4aebf59d906fa3e03d21bdac182f89fe3cd4c802) + (cherry picked from commit 34398c29b3c57f00d932cf96570f882dce64a82b) + +commit 7f78450bd184335ba0098f3ded0fefa2c79a5dd5 +Author: Greg Farnum +Date: Tue Apr 11 14:04:19 2017 -0700 + + osd/ReplicatedPG: limit the number of concurrently trimming pgs + + This patch introduces an AsyncReserver for snap trimming to limit the + number of pgs on any single OSD which can be trimming, as with backfill. + Unlike backfill, we don't take remote reservations on the assumption + that the set of pgs with trimming work to do is already well + distributed, so it doesn't seem worth the implementation overhead to get + reservations from the peers as well. + + Signed-off-by: Samuel Just + (cherry picked from commit 21cc515adfb225ba70f1d80b1b76f0345c214c22) + + Conflicts: + src/osd/PrimaryLogPG.cc + src/osd/PrimaryLogPG.h + + Signed-off-by: Greg Farnum + + (cherry picked from commit 68ea24396ca6450d4d8042a7c5f51306b7d199fa) + (cherry picked from commit c7176b869898c870b56b1762958652d801af4c4c) + + Conflicts: Many. As evidenced by involving two distinct patches + in this one commit, it wasn't a clean backport. + + Signed-off-by: Greg Farnum + +commit 527911fab78b4752313a4a2a5d3ab0ae736bc50f +Author: Kefu Chai +Date: Mon Apr 10 14:53:46 2017 +0800 + + mon/MonClient: make get_mon_log_message() atomic + + * LogClient: move reset_session() into get_mon_log_message() and add a + "flush" param to the latter. so it can get_mon_log_message() + atomically. otherwise another call changing the log queue could sneak + in between reset_session() and get_mon_log_message(). + * MonClient: add a "flush" param to do_send() so we can reset the + LogClient session once we are connected to a monitor. + + Fixes: http://tracker.ceph.com/issues/19427 + Signed-off-by: Kefu Chai + (cherry picked from commit 5215e291da2b527d85e129eda86043490843178e) + + Conflicts: + src/mon/MonClient.cc: handle_auth: replaced 'log_client->reset_session(); + send_log();' sequence with newly introduced 'send_log(true);' like + the original patch does + +commit e31a540dcea96b3d5b4f7ecd20e2d54e81a68e2b +Merge: 7c36d1650f 06916a8798 +Author: Nathan Cutler +Date: Fri Apr 14 22:28:51 2017 +0200 + + Merge pull request #13834 from smithfarm/wip-18969-jewel + + jewel: rgw: Change loglevel to 20 for 'System already converted' message + + Reviewed-by: Casey Bodley + Reviewed-by: Nathan Cutler + +commit 7c36d1650fdb7a357ff724b37cf59b4da413f76b +Merge: 0e3aa2cb01 4c1f302f7d +Author: Nathan Cutler +Date: Fri Apr 14 22:26:51 2017 +0200 + + Merge pull request #13833 from smithfarm/wip-18908-jewel + + jewel: rgw: the swift container acl does not support field .ref + + Reviewed-by: Radoslaw Zarzynski + +commit b698d1fa4ce4aca5e392eeec600e3357c3cf71a9 +Author: Jason Dillaman +Date: Thu Mar 16 12:28:41 2017 -0400 + + librbd: is_exclusive_lock_owner API should ping OSD + + This is required to detect if a peer has been silently blacklisted + and is therefore no longer the lock owner. + + Fixes: http://tracker.ceph.com/issues/19287 + Signed-off-by: Jason Dillaman + (cherry picked from commit e15db05960a284bdf3701256722299d553cfd5aa) + + Conflicts: + src/librbd/ManagedLock.[h|cc]: logic moved to ExclusiveLock + + (cherry picked from commit 7e30b630e2806c73ea503871599f958b58df7934) + +commit 0e3aa2cb011be8a2af69040b94ee240ea6c1e663 +Merge: 8d5a5ddfec 419c9926d9 +Author: Nathan Cutler +Date: Thu Apr 13 11:09:27 2017 +0200 + + Merge pull request #13214 from ovh/bp-osd-updateable-throttles-jewel + + jewel: osd: allow client throttler to be adjusted on-fly, without restart + + Reviewed-by: Josh Durgin + +commit 8d5a5ddfecc7c020eeb8aeb927e007bc04885534 +Merge: 091aaa2ab7 bcd3c906e5 +Author: Nathan Cutler +Date: Thu Apr 13 10:44:23 2017 +0200 + + Merge pull request #14326 from shinobu-x/wip-15025-jewel + + jewel: osd: new added OSD always down when full flag is set + + Reviewed-by: Josh Durgin + +commit d311eea6bc5b2c88984cfc16340970ea1459b74a +Author: Robin H. Johnson +Date: Sat Feb 11 10:32:53 2017 -0800 + + msg/simple/Pipe: support IPv6 QoS. + + Extend DSCP marking for heartbeat packets to IPv6, as commit + 9b9a682fe035c985e416ee1c112fa58f9045a27c only implemented + support for IPv4. + + Conflicts: Cherry-picked 91a29bc490fdfbbef0875fa620c7ba1a1a6492ae from master to avoid conflict. + Backport: jewel, luminious + Fixes: http://tracker.ceph.com/issues/18887 + Signed-off-by: Robin H. Johnson + (cherry picked from commit 2d6021fbf7a728f73c2998be17e9224f14b83a30) + +commit 332b5174c769f395074255e075de8d2cc1ee4021 +Author: Jason Dillaman +Date: Thu Mar 16 12:27:08 2017 -0400 + + pybind: fix incorrect exception format strings + + Signed-off-by: Jason Dillaman + (cherry picked from commit 68617455f534a612ade1331f43b032ab524704ae) + +commit 091aaa2ab768858e840e2d05e0896c229ce69984 +Merge: 3f2e4cd2d5 d30c4d55ad +Author: Nathan Cutler +Date: Wed Apr 12 11:38:48 2017 +0200 + + Merge pull request #13874 from smithfarm/wip-19171-jewel + + jewel: doc: rgw S3 create bucket should not do response in json + + Reviewed-by: Abhishek Lekshmanan + +commit 3f2e4cd2d53f1cbdbdb1fc8687c5ffe0d46b346b +Merge: ea0bc6c553 0e11a938c5 +Author: Nathan Cutler +Date: Wed Apr 12 11:06:40 2017 +0200 + + Merge pull request #13492 from shinobu-x/wip-18516-jewel + + jewel: build/ops: "osd marked itself down" will not recognised if host runs mon + osd on shutdown/reboot + + Reviewed-by: Nathan Cutler + +commit ea0bc6c553454f7641a2594013412aee142fbd11 +Merge: 845972f4de d012c381e8 +Author: Nathan Cutler +Date: Wed Apr 12 11:01:23 2017 +0200 + + Merge pull request #13254 from shinobu-x/wip-14609-jewel + + jewel: common: radosstriper: protect aio_write API from calls with 0 bytes + + Reviewed-by: Kefu Chai + +commit 845972f4de1d803aa4dab0e1afaed693bbba088f +Merge: a3deef997f cfa37d6a16 +Author: Nathan Cutler +Date: Wed Apr 12 10:52:10 2017 +0200 + + Merge pull request #13489 from shinobu-x/wip-18955-jewel + + jewel: ceph-disk: bluestore --setgroup incorrectly set with user + + Reviewed-by: Loic Dachary + Reviewed-by: Nathan Cutler + +commit a3deef997ff0800b9e3e2d141cfc6fdc73cac837 +Merge: 702edb5519 39aab763a4 +Author: Nathan Cutler +Date: Wed Apr 12 10:51:42 2017 +0200 + + Merge pull request #14070 from smithfarm/wip-19339-jewel + + jewel: tests: dummy suite fails in OpenStack + + Reviewed-by: Loic Dachary + +commit 702edb5519e67bc5f8c5b65c6f63c9635cd758cf +Merge: f509ccc4b7 a20d2b89ee +Author: Nathan Cutler +Date: Wed Apr 12 10:51:12 2017 +0200 + + Merge pull request #14329 from smithfarm/wip-19493-jewel + + jewel: ceph-disk: Racing between partition creation & device node creation + + Reviewed-by: Loic Dachary + Reviewed-by: Sébastien Han + +commit f509ccc4b734697267cec35ff57dd7f1c5aaaddb +Merge: c8c4bff2af f2474042ec +Author: Nathan Cutler +Date: Wed Apr 12 10:48:29 2017 +0200 + + Merge pull request #14427 from smithfarm/wip-19140-jewel + + jewel: osdc/Objecter: If osd full, it should pause read op which w/ rwordered flag + + Reviewed-by: Kefu Chai + +commit c8c4bff2afa7fe0339a97f32e69bb9d0546f1318 +Merge: 349baea1a4 b5b441abaa +Author: Nathan Cutler +Date: Wed Apr 12 10:48:08 2017 +0200 + + Merge pull request #14324 from shinobu-x/wip-19371-jewel + + jewel: common: monitor creation with IPv6 public network segfaults + + Reviewed-by: Kefu Chai + +commit 349baea1a4486e475e0381a6b316d64a6ce0139c +Merge: dd466b7d9a 72e2476a13 +Author: Nathan Cutler +Date: Wed Apr 12 10:45:35 2017 +0200 + + Merge pull request #14112 from shinobu-x/wip-19192-jewel + + jewel: tools: brag fails to count "in" mds + + Reviewed-by: Kefu Chai + +commit dd466b7d9acb03c8830bdd83b3b73602c68083c2 +Merge: b8f8bd0a94 ee06517547 +Author: Nathan Cutler +Date: Wed Apr 12 10:45:11 2017 +0200 + + Merge pull request #14150 from smithfarm/wip-18823-jewel + + jewel: tests: run-rbd-unit-tests.sh assert in lockdep_will_lock, TestLibRBD.ObjectMapConsistentSnap + + Reviewed-by: Jason Dillaman + +commit b8f8bd0a949c917b119eca91aec95c6a971a1fb4 +Merge: 222916a375 1cc8d0d085 +Author: Nathan Cutler +Date: Wed Apr 12 10:44:47 2017 +0200 + + Merge pull request #14152 from smithfarm/wip-18893-jewel + + jewel: librbd: Incomplete declaration for ContextWQ in librbd/Journal.h + + Reviewed-by: Jason Dillaman + +commit 222916a3758b0253bcb851b5e955f6970f171306 +Merge: 49f84b1a14 b85677397e +Author: Nathan Cutler +Date: Wed Apr 12 10:44:25 2017 +0200 + + Merge pull request #14154 from smithfarm/wip-18948-jewel + + jewel: tests: additional rbd-mirror test stability improvements + + Reviewed-by: Jason Dillaman + +commit 49f84b1a14295e80ef35204ed691b3131c5f744c +Merge: 2a232d43a1 f6489d01ca +Author: Nathan Cutler +Date: Wed Apr 12 10:44:04 2017 +0200 + + Merge pull request #14148 from smithfarm/wip-18778-jewel + + jewel: rbd: rbd --pool=x rename y z does not work + + Reviewed-by: Jason Dillaman + +commit 2a232d43a18b47399f96abeac3ac800f204a9eaf +Merge: 413ac584d6 8bed107b84 +Author: Nathan Cutler +Date: Wed Apr 12 10:43:41 2017 +0200 + + Merge pull request #14083 from smithfarm/wip-19357-jewel + + jewel: rbd: systemctl stop rbdmap unmaps all rbds and not just the ones in /etc/ceph/rbdmap + + Reviewed-by: Jason Dillaman + +commit 413ac584d63fd469ea28defa68c39538444d01b1 +Merge: 23d595b1b0 547e867628 +Author: Nathan Cutler +Date: Wed Apr 12 10:43:21 2017 +0200 + + Merge pull request #13154 from smithfarm/wip-18496-jewel + + jewel: librbd: Possible deadlock performing a synchronous API action while refresh in-progress + + Reviewed-by: Jason Dillaman + +commit 23d595b1b0fb874adfd1507d86db261cf6a193a9 +Merge: 4add6f5580 915dbace5d +Author: Nathan Cutler +Date: Wed Apr 12 10:42:54 2017 +0200 + + Merge pull request #13244 from smithfarm/wip-18775-jewel + + jewel: rbd: qemu crash triggered by network issues + + Reviewed-by: Jason Dillaman + +commit 4add6f5580b7d65571bc426e95fac35be7150ff4 +Merge: 37ab19cc29 1a4e1e09b1 +Author: Nathan Cutler +Date: Wed Apr 12 10:42:23 2017 +0200 + + Merge pull request #13809 from asheplyakov/18321-bp-jewel + + jewel: librbd: remove image header lock assertions + + Reviewed-by: Jason Dillaman + +commit 37ab19cc29d61970e08af1b4627137cfcaa99474 +Merge: f7c04e3ca6 8d0140a9ed +Author: Nathan Cutler +Date: Wed Apr 12 10:41:56 2017 +0200 + + Merge pull request #13107 from smithfarm/wip-18669-jewel + + jewel: tests: [ FAILED ] TestLibRBD.ImagePollIO in upgrade:client-upgrade-kraken-distro-basic-smithi + + Reviewed-by: Jason Dillaman + +commit f7c04e3ca69c7fc134b267e825277eccea228c9b +Merge: d2909bdb4c a18a2dd108 +Author: Nathan Cutler +Date: Wed Apr 12 10:39:26 2017 +0200 + + Merge pull request #13585 from asheplyakov/jewel-bp-16585 + + jewel: msg: set close on exec flag + + Reviewed-by: Kefu Chai + +commit d2909bdb4cf135de850cc865f735cc61eb3d4ea6 +Merge: cd748603da 6d47615c11 +Author: Nathan Cutler +Date: Wed Apr 12 03:56:22 2017 +0200 + + Merge pull request #14371 from tchaikov/wip-19429-jewel + + jewel: tests: clone workunit using the branch specified by task + + Nathan Cutler + +commit cd748603da43c0b7377b5ef07aff618711b4879c +Merge: 1a20c12355 dd25a8f36b +Author: Nathan Cutler +Date: Wed Apr 12 03:54:11 2017 +0200 + + Merge pull request #14325 from shinobu-x/wip-18619-jewel + + jewel: osd: degraded and misplaced status output inaccurate + + Reviewed-by: Josh Durgin + +commit 1a20c123556e2f566af7e87ab3da6fc2ca328bb9 +Merge: 4838c4db4c 7fdf4d41c5 +Author: Nathan Cutler +Date: Wed Apr 12 03:53:25 2017 +0200 + + Merge pull request #14236 from smithfarm/wip-19392-jewel + + jewel: mon: remove bad rocksdb option + + Reviewed-by: Josh Durgin + +commit 4838c4db4c610926edc599677cb7e74f3bdc3077 +Merge: e26b7033eb 3860ccf16d +Author: Nathan Cutler +Date: Wed Apr 12 03:52:41 2017 +0200 + + Merge pull request #14181 from mslovy/wip-19394-jewel + + jewel: osd: bypass readonly ops when osd full + + Reviewed-by: Josh Durgin + +commit e26b7033ebd4a09210d482a54677806fe2c03505 +Merge: 389150bcc3 819af9e413 +Author: Nathan Cutler +Date: Wed Apr 12 03:49:49 2017 +0200 + + Merge pull request #14113 from shinobu-x/wip-19319-jewel + + jewel: cli: RadosImport::import should return an error if Rados::connect fails + + Reviewed-by: Brad Hubbard + Reviewed-by: David Zafman + +commit 389150bcc376702022cf15c0c79dbe856a97dffa +Merge: a8b10082f5 90de64bd81 +Author: Nathan Cutler +Date: Wed Apr 12 03:45:33 2017 +0200 + + Merge pull request #14047 from asheplyakov/reindex-on-pg-split + + jewel: osd: reindex properly on pg log split + + Reviewed-by: Sage Weil + Reviewed-by: Josh Durgin + +commit a8b10082f5761ea1132b85bd916a84f87e0276e2 +Merge: 32ed9b7897 ae498e84ff +Author: Nathan Cutler +Date: Wed Apr 12 03:45:15 2017 +0200 + + Merge pull request #14044 from mslovy/wip-19311-jewel + + jewel: core: os/filestore: fix clang static check warn use-after-free + + Reviewed-by: Sage Weil + Reviewed-by: Josh Durgin + +commit 32ed9b789733e21a2d597c7016eabf95763e50ae +Merge: 6705e911a2 335b5fa4a9 +Author: Nathan Cutler +Date: Wed Apr 12 03:44:25 2017 +0200 + + Merge pull request #13932 from asheplyakov/18911-bp-jewel + + jewel: rbd-nbd: check /sys/block/nbdX/size to ensure kernel mapped correctly + + Reviewed-by: Mykola Golub + Reviewed-by: Jason Dillaman + +commit 6705e911a229cee50d5ac992c7dd9af834f2400d +Merge: 3d21a0080d 714eb863c3 +Author: Nathan Cutler +Date: Wed Apr 12 03:42:13 2017 +0200 + + Merge pull request #13831 from jan--f/wip-19206-jewel + + jewel: fs: Invalid error code returned by MDS is causing a kernel client WARNING + + Reviewed-by: John Spray + +commit 3d21a0080dfd00c0b89ed23fd8049e46c3041af4 +Merge: 8a6d64331b 6b5322c5f6 +Author: Nathan Cutler +Date: Wed Apr 12 03:41:36 2017 +0200 + + Merge pull request #13827 from tchaikov/wip-19185-jewel + + jewel: osd: ReplicatedPG: try with pool's use-gmt setting if hitset archive not found + + Reviewed-by: Sage Weil + Reviewed-by: Josh Durgin + +commit 8a6d64331b73a4a24a59f4dcdb6771f1dc638879 +Merge: f96392a589 cebba011e5 +Author: Nathan Cutler +Date: Wed Apr 12 03:40:09 2017 +0200 + + Merge pull request #13788 from shinobu-x/wip-18235-jewel + + jewel: core: os/filestore/HashIndex: be loud about splits + + Reviewed-by: Josh Durgin + +commit f96392a58970ab1e81653d5657d3d680120a02b6 +Merge: 8fe6ffcfef 1d054c3856 +Author: Nathan Cutler +Date: Wed Apr 12 03:39:27 2017 +0200 + + Merge pull request #13786 from shinobu-x/wip-19129-jewel + + jewel: build/ops: ceph-base package missing dependency for psmisc + + Reviewed-by: Nathan Cutler + +commit 8fe6ffcfef8918fd8634e87255ad3fe7a544aa16 +Merge: 6f589a159e b249fd5bd8 +Author: Nathan Cutler +Date: Wed Apr 12 03:38:34 2017 +0200 + + Merge pull request #13732 from liewegas/wip-19119-jewel + + jewel: doc: PendingReleaseNotes: note about 19119 + + Reviewed-by: Nathan Cutler + +commit 6f589a159e4eb5f6c96634a742acaf6cd6e174c2 +Merge: b8f2d35884 8c7a1df251 +Author: Nathan Cutler +Date: Wed Apr 12 03:36:21 2017 +0200 + + Merge pull request #13541 from shinobu-x/wip-18929-jewel + + jewel: osd: restrict want_acting to up+acting on recovery completion + + Reviewed-by: Josh Durgin + Reviewed-by: Nathan Cutler + +commit b8f2d35884a52586a28f1ff4eaf99c8c3ba1c43f +Merge: 40d1443d68 2d17092fab +Author: Nathan Cutler +Date: Wed Apr 12 03:34:54 2017 +0200 + + Merge pull request #13477 from asheplyakov/jewel-bp-18951 + + jewel: osd: --flush-journal: sporadic segfaults on exit + + Reviewed-by: Sage Weil + Reviewed-by: Josh Durgin + +commit 40d1443d68b788737f83c10db3811bc37dbe8dda +Merge: 50e863e0f4 07501dec6f +Author: Nathan Cutler +Date: Wed Apr 12 03:33:25 2017 +0200 + + Merge pull request #13261 from shinobu-x/wip-18587-jewel + + jewel: mon: OSDMonitor: make 'osd crush move ...' work on osds + + Reviewed-by: Josh Durgin + Reviewed-by: Nathan Cutler + +commit 25e43ac25619d883d5a04e2df1cf6f57fea73fd0 +Author: Nathan Cutler +Date: Tue Apr 11 08:23:23 2017 +0200 + + tests: fix oversight in yaml comment + + When the file was copied from the hammer version, the word "hammer" + was not changed to "infernalis". + + Signed-off-by: Nathan Cutler + + This cannot be cherry-picked from master because the test has been dropped. + +commit f2474042ecd6560323673170c13f2cb964406e70 +Author: Sage Weil +Date: Thu Mar 2 21:20:08 2017 -0600 + + osdc/Objecter: resend RWORDERED ops on full + + Our condition for respecting the FULL flag is complex, and involves + the WRITE | RWORDERED flags vs the FULL_FORCE | FULL_TRY flags. Previously, + we could block a read bc of RWORDRED but not resend it later. + + Fix by capturing the complex condition in a respects_full() bool and using + it both for the blocking-on-send and resending-on-possibly-notfull-later + checks. + + Fixes: http://tracker.ceph.com/issues/19133 + Signed-off-by: Sage Weil + (cherry picked from commit c4b73f19a7be13ff412eef804efcd8c18ed4dae6) + +commit 2d68822c784eb4d62d3b0198ed4ec04404dbffb3 +Author: Jianpeng Ma +Date: Thu May 5 23:44:57 2016 +0800 + + osdc/Objecter: If osd full, it should pause read op which w/ rwordered flag. + + Signed-off-by: Jianpeng Ma + (cherry picked from commit 07b2a22210e26eac1b2825c30629788da05e5e12) + +commit 2271cd81282f3f026316134cbab630f3e4f47782 +Author: Brad Hubbard +Date: Mon Apr 3 13:37:17 2017 +1000 + + ceph-disk: Populate mount options when running "list" + + Also tidy up by moving duplicated code into a function + + Fixes: http://tracker.ceph.com/issues/17331 + Signed-off-by: Brad Hubbard + (cherry picked from commit 7943ab2e01e24f2dfc5b6f1d3ffdc8a49e01af45) + +commit 65465356b5e7cb6cba67f8cbb81259d21e888dfb +Author: Ken Dreyer +Date: Tue Feb 16 12:56:34 2016 -0700 + + debian: replace SysV rbdmap with systemd service + + Stop shipping /etc/init.d/rbdmap in the Debian packages. Ship the + rbdmap.service systemd unit file instead. + + The corresponding change has already been made for RPMs, in + 9224ac2ad25f7d017916f58b642c0ea25305c3e5. + + For Upstart-based systems (eg Ubuntu Trusty), the Debian packages + already contain rbdmap.conf. + + (This gets us a tiny bit closer to being able to remove the rbdmap SysV + script from our tree entirely.) + + Signed-off-by: Ken Dreyer + (cherry picked from commit 839807118dda2fb4d57ed9d50ec46e3ee0e2820a) + + Conflicts: + debian/ceph-common.install (retain /etc/init.d/rbdmap so jewel users can choose sysvinit or systemd) + debian/rules (retain /etc/init.d/rbdmap so jewel users can choose sysvinit or systemd) + +commit 6d47615c11a216733ba368f0dbd9a0a1b9c8fd35 +Author: Kefu Chai +Date: Sat Apr 1 23:04:22 2017 +0800 + + qa/tasks/workunit.py: use "overrides" as the default settings of workunit + + otherwise the settings in "workunit" tasks are always overridden by the + settings in template config. so we'd better follow the way of how + "install" task updates itself with the "overrides" settings: it uses the + "overrides" as the *defaults*. + + Fixes: http://tracker.ceph.com/issues/19429 + Signed-off-by: Kefu Chai + (cherry picked from commit 47080150a17d238f38d9da824d227393ad767aad) + +commit fdc71e75cd6361be49c4c20e77d3bdff017b38bf +Author: Kefu Chai +Date: Thu Mar 30 12:37:01 2017 +0800 + + tasks/workunit.py: specify the branch name when cloning a branch + + c1309fb failed to specify a branch when cloning using --depth=1, which + by default clones the HEAD. and we can not "git checkout" a specific + sha1 if it is not HEAD, after cloning using '--depth=1', so in this + change, we dispatch "tag", "branch", "HEAD" using three Refspec classes. + + Signed-off-by: Kefu Chai + Signed-off-by: Dan Mick + (cherry picked from commit 9ca7ccf5f1739f731da8bf31260594aea3a2932d) + + Conflicts: + qa/tasks/workunit.py (trivial resolution) + +commit 6c14a803894d71bae858705855551a44bdf9bf67 +Author: Dan Mick +Date: Tue Mar 28 20:08:13 2017 -0700 + + tasks/workunit.py: when cloning, use --depth=1 + + Help avoid killing git.ceph.com. A depth 1 clone takes about + 7 seconds, whereas a full one takes about 3:40 (much of it + waiting for the server to create a huge compressed pack) + + Signed-off-by: Dan Mick + (cherry picked from commit c1309fbef300a062138ac40eb5d3e5081b833072) + +commit f8aa6be06cc628b1cf64c9196c30045d020d657e +Author: Nathan Cutler +Date: Fri Apr 7 06:59:13 2017 +0200 + + build/ops: rpm: move $CEPH_EXTRA_CONFIGURE_ARGS to right place + + Signed-off-by: Nathan Cutler + +commit bb3eb4284fe74cbf78e4a406c7b5f67a8e3c84b3 +Author: Nathan Cutler +Date: Fri Apr 7 06:48:51 2017 +0200 + + build/ops: rpm: explicitly provide --with-ocf to configure + + Fixes: http://tracker.ceph.com/issues/19546 + Signed-off-by: Nathan Cutler + + (Note: This cannot be cherry-picked because master uses cmake, but + the fix does bring the jewel spec file into better alignment its master + counterpart, at least as far as this one little bit is concerned.) + +commit 30c952735327d05b6049e9364c1a053ebf651751 +Author: lu.shasha +Date: Mon Feb 27 15:52:43 2017 +0800 + + rgw: use separate http_manager for read_sync_status + + concurrent users of read_sync_status() use different cr managers, when get_resource must + use http_manager related to the cr manager. + + Fixes: http://tracker.ceph.com/issues/19236 + + Signed-off-by: Shasha Lu + (cherry picked from commit c412024889f8995d98096ac863bafee71624bd70) + +commit 87cb8474f523be1b281882c46a8a3597977a51c9 +Author: Casey Bodley +Date: Thu Jul 28 20:20:29 2016 -0400 + + rgw: pass cr registry to managers + + Signed-off-by: Casey Bodley + (cherry picked from commit ef4d7eab11fb5d2a41c9c28b9eb8b075aaff0d05) + + Conflicts: + src/rgw/rgw_rados.cc: removed ref to RGWSyncLogTrimThread (not backported) + +commit 1a6d7c0506d4bcda775dda05bb357d4d5695dabb +Author: Casey Bodley +Date: Fri Jul 22 11:00:16 2016 -0400 + + rgw: use separate cr manager for read_sync_status + + RGWCoroutinesManager::run() is not reentrant, so concurrent users of + read_sync_status() must use different managers + + Signed-off-by: Casey Bodley + (cherry picked from commit 6b1e40d7a21c549b55e6576ec56973c8d3c092d1) + +commit c466adee9c8f7a97ff7e99bee56da8ce51bf0f00 +Author: Casey Bodley +Date: Thu Jul 21 23:46:20 2016 -0400 + + rgw: change read_sync_status interface + + RGWDataSyncStatusManager::read_sync_status() now operates on the given + parameter, rather than its internal member variable. this allows + multiple concurrent readers, which is needed for the rest interface + + Signed-off-by: Casey Bodley + (cherry picked from commit b7cd4e0e8b879b5e528de75bea3307585b96cbf2) + +commit 36921a3f3d01547508dc6270f6b19f2576e067d9 +Author: Casey Bodley +Date: Wed Jun 8 11:24:11 2016 -0400 + + rgw: don't ignore ENOENT in RGWRemoteDataLog::read_sync_status() + + rest handlers for sync status need to return ENOENT errors. the only + other callers are in radosgw-admin, so the ENOENT errors are ignored at + those call sites instead + + Signed-off-by: Casey Bodley + (cherry picked from commit 2cc533b30c0f23c0750ea8d02c51b3b3d3b4821a) + +commit b249fd5bd816a63b445db12c8f846cfda199c8b8 +Author: Sage Weil +Date: Wed Mar 1 13:18:44 2017 -0600 + + PendingReleaseNotes: warning about 'osd rm ...' and #19119 + + See http://tracker.ceph.com/issues/19119 + + Signed-off-by: Sage Weil + (cherry picked from commit be96003c464481d8e84825178d600234a0d64d22) + +commit 335258f975a8e8539774e8cb22690d746ec90d9f +Author: Ilya Dryomov +Date: Tue Mar 28 11:49:08 2017 +0200 + + osdc/Objecter: respect epoch barrier in _op_submit() + + Epoch barrier instructs us to avoid sending (i.e. pause) any OSD ops + until we see a barrier epoch. The only thing epoch_barrier check in + target_should_be_paused() does is keep already paused ops paused. We + need to actually pause incoming OSD ops in _op_submit(). + + Fixes: http://tracker.ceph.com/issues/19396 + Signed-off-by: Ilya Dryomov + (cherry picked from commit f8e8efc0a53d7bd807cc0c2178aef7c4bed62ab7) + +commit a20d2b89ee13e311cf1038c54ecadae79b68abd5 +Author: Erwan Velu +Date: Fri Mar 31 14:54:33 2017 +0200 + + ceph-disk: Adding retry loop in get_partition_dev() + + There is very rare cases where get_partition_dev() is called before the actual partition is available in /sys/block/. + + It appear that waiting a very short is usually enough to get the partition beein populated. + + Analysis: + update_partition() is supposed to be enough to avoid any racing between events sent by parted/sgdisk/partprobe and + the actual creation on the /sys/block//* entrypoint. + On our CI that race occurs pretty often but trying to reproduce it locally never been possible. + + This patch is almost a workaround rather than a fix to the real problem. + It offer retrying after a very short to be make a chance the device to appear. + This approach have been succesful on the CI. + + Note his patch is not changing the timing when the device is perfectly created on time and just differ by a 1/5th up to 2 seconds when the bug occurs. + + A typical output from the build running on a CI with that code. + command_check_call: Running command: /usr/bin/udevadm settle --timeout=600 + get_dm_uuid: get_dm_uuid /dev/sda uuid path is /sys/dev/block/8:0/dm/uuid + get_partition_dev: Try 1/10 : partition 2 for /dev/sda does not in /sys/block/sda + get_partition_dev: Found partition 2 for /dev/sda after 1 tries + get_dm_uuid: get_dm_uuid /dev/sda uuid path is /sys/dev/block/8:0/dm/uuid + get_dm_uuid: get_dm_uuid /dev/sda2 uuid path is /sys/dev/block/8:2/dm/uuid + + fixes: #19428 + + Signed-off-by: Erwan Velu + (cherry picked from commit 93e7b95ed8b4c78daebf7866bb1f0826d7199075) + +commit 2d5d0aec60ec9689d44a53233268e9b9dd25df95 +Author: Erwan Velu +Date: Wed Mar 22 10:11:44 2017 +0100 + + ceph-disk: Reporting /sys directory in get_partition_dev() + + When get_partition_dev() fails, it reports the following message : + ceph_disk.main.Error: Error: partition 2 for /dev/sdb does not appear to exist + The code search for a directory inside the /sys/block/get_dev_name(os.path.realpath(dev)). + + The issue here is the error message doesn't report that path when failing while it might be involved in. + + This patch is about reporting where the code was looking at when trying to estimate if the partition was available. + + Signed-off-by: Erwan Velu + (cherry picked from commit 413c9fcfbe8e6ab33d73b8428090ccacc33c5d15) + +commit bcd3c906e5b57e7f44df1963c6e11b78ff89482c +Author: Mingxin Liu +Date: Mon Mar 13 23:41:58 2017 +0800 + + osd: don't share osdmap with objecter when preboot + + Signed-off-by: Mingxin Liu + (cherry picked from commit a5a3644eecc49b4eea890c6999fe87536495dcbe) + +commit dd25a8f36bef1901f3ce6193cfcbdaf7ab2424a1 +Author: David Zafman +Date: Wed Jan 18 08:33:40 2017 -0800 + + osd: Calculate degraded and misplaced more accurately + + Calculate num_object_copies based on the larger of pool size, + up set size and acting set size. + + Calculate num_objects_degraded as the difference between num_object_copies + and all copies found on acting set and backfilling up set OSDs. + + Calculate num_objects_misplaced as all copies on acting set OSDs not in up set + less copies that have been backfilled to up set OSDs. + + Fixes: http://tracker.ceph.com/issues/18619 + + Signed-off-by: David Zafman + (cherry picked from commit 8423bc40759cca137f61e7b755411719a84369d4) + +commit b5b441abaa852e85ddefd8b22835c9b85898cc06 +Author: Fabian Grünbichler +Date: Wed Mar 22 16:13:50 2017 +0100 + + common: fix segfault in public IPv6 addr picking + + sockaddr is only 16 bytes big, so declaring net as sockaddr + and then casting to sockaddr_in6 in case of IPv6 cannot + work. + + using sockaddr_storage works for both IPv4 and IPv6, and is + used in other code parts as well. + + note that the tests did not find this issue as they declared + the bigger structs and casted the references to (sockaddr *) + + Fixes: http://tracker.ceph.com/issues/19371 + Signed-off-by: Fabian Grünbichler + (cherry picked from commit ae2ee3d3835fe25b35eeb1a841ee5234cd69eb65) + +commit 7fdf4d41c5bef14269cb302301a08d5a3a57a768 +Author: Sage Weil +Date: Mon May 2 15:29:12 2016 -0400 + + mon: remove bad rocksdb option + + Signed-off-by: Sage Weil + (cherry picked from commit 0ac671ece258e509f71a05253e62a9878e279840) + +commit 3860ccf16d7dfb137face9886c3d7f29cd527835 +Author: Jianpeng Ma +Date: Thu May 5 23:07:06 2016 +0800 + + osd: bypass readonly ops when osd full. + + Signed-off-by: Jianpeng Ma + (cherry picked from commit e2a0ae8e88e6b7354b14adb503fd8ba8525bee39) + See: http://tracker.ceph.com/issues/19394 + + Signed-off-by: yaoning + +commit b85677397ef9a3fe16c087e67d3f752851bbe070 +Author: Jason Dillaman +Date: Mon Nov 21 15:31:43 2016 -0500 + + qa/workunits/rbd: resolve potential rbd-mirror race conditions + + Fixes: http://tracker.ceph.com/issues/18935 + Signed-off-by: Jason Dillaman + (cherry picked from commit 63eae97afc1a92412525468263fb8696a243ebac) + +commit 1cc8d0d08560af4e8785d7c4c6a925b1fc9f988e +Author: Boris Ranto +Date: Wed Feb 8 23:47:57 2017 +0100 + + librbd: Include WorkQueue.h since we use it + + We use m_work_queue of type ContextWQ in handle_update function but we + do not include common/WorkQueue.h that defines ContextWQ. This results + in dereference of an incomplete type and causes build error in latest + Fedora rawhide (future 26). + + Fixes: http://tracker.ceph.com/issues/18862 + + Signed-off-by: Boris Ranto + (cherry picked from commit 480f82847ad1fc7959f1fe5a90761a5a24550993) + +commit ee06517547ae174472d739f966c0a27d3a97d742 +Author: Jason Dillaman +Date: Wed Jan 18 20:54:22 2017 -0500 + + librbd: avoid possible recursive lock when racing acquire lock + + Fixes: http://tracker.ceph.com/issues/17447 + Signed-off-by: Jason Dillaman + (cherry picked from commit 5e46e8eb664f573bd70ae7c96a6d9a98b0deb09e) + +commit f6489d01ca41d6979b5de28e3cde6b43fcaa8edb +Author: Gaurav Kumar Garg +Date: Mon Jan 30 13:03:20 2017 +0100 + + rbd: destination pool should be source pool if it is not specified + + Currently if user perform image rename operation and user give pool + name as a optional parameter (--pool=) then currently + its taking this optional pool name for source pool and making + destination pool name default pool name. + With this fix if user provide pool name as a optional pool name + parameter then it will consider both soruce and destination pool + name as optional parameter pool name. + + Fixes: http://tracker.ceph.com/issues/18326 + + Reported-by: МАРК КОРЕНБЕРГ + Signed-off-by: Gaurav Kumar Garg + (cherry picked from commit 01f23aa99fb694da326ab408e75b33c640ce660b) + +commit 9e123e6d6c8bbd54514b498df5a22d961f0cefbb +Author: Orit Wasserman +Date: Sun Mar 12 12:11:28 2017 +0200 + + rgw: use rgw_zone_root_pool for region_map like is done in hammer + + Fixes: http://tracker.ceph.com/issues/19195 + Signed-off-by: Orit Wasserman + (cherry picked from commit c91dd6d9efd148e0fe0f027dde537e977de9aa26) + +commit e2ee70a8ad51992bbd763d2465f6d8a01dad6a31 +Author: Orit Wasserman +Date: Thu Mar 9 13:03:24 2017 +0200 + + rgw: skip conversion of zones without any zoneparams + + Fixes: http://tracker.ceph.com/issues/19231 + Signed-off-by: Orit Wasserman + (cherry picked from commit 36cf5a5c8179c6313346b2e29286c537c6fefce8) + +commit c7d292bf6714d7aaf10412e5109badb90f5dc208 +Author: Orit Wasserman +Date: Thu Mar 9 11:16:26 2017 +0200 + + rgw: better debug information for upgrade + + Signed-off-by: Orit Wasserman + (cherry picked from commit e9f3bf8eab1dd46a92f54b0f7afe1f4c0e4204db) + +commit 11f5c841c7698e6239017478fa05f742b7c0ab1c +Author: Danny Al-Gaaf +Date: Tue Jan 31 18:01:32 2017 +0100 + + rgw/rgw_rados.cc: prefer ++operator for non-primitive iterators + + Signed-off-by: Danny Al-Gaaf + (cherry picked from commit 7086cf9a73f2ec1eb96c0e752beb1b74fca18570) + +commit 819af9e4139997cd845dc24a137d43218d8a40a8 +Author: Brad Hubbard +Date: Tue Mar 21 12:22:20 2017 +1000 + + tools/rados: Check return value of connect + + Fail gracefully if Rados::connect returns an error. + + Fixes: http://tracker.ceph.com/issues/19319 + Signed-off-by: Brad Hubbard + (cherry picked from commit c119091ef0844e4a1ddd790a8bfef8f06bb57d58) + +commit 72e2476a130e14abcd541ff61328454cb69ad9c3 +Author: Kefu Chai +Date: Mon Mar 6 11:33:27 2017 +0800 + + brag: count the number of mds in fsmap not in mdsmap + + this change was introduced in 4e9b953 + + Fixes: http://tracker.ceph.com/issues/19192 + Signed-off-by: Peng Zhang + (cherry picked from commit 2d25a9c0c760664d3de33ecca0e0272c1031cd46) + +commit 3cb192779a1c3662d27bba7715eb31c5f7b6a5b7 +Author: Oleh Prypin +Date: Thu Jun 30 00:51:50 2016 +0300 + + brag: Assume there are 0 MDS instead of crashing when data is missing + + Signed-off-by: Oleh Prypin + +commit 8bed107b84efdc8c735245cdfb51bfd8d07da13b +Author: David Disseldorp +Date: Fri Feb 10 19:19:46 2017 +0100 + + doc: update description of rbdmap unmap[-all] behaviour + + Fixes: http://tracker.ceph.com/issues/18884 + + Signed-off-by: David Disseldorp + (cherry picked from commit f987396e126d5e61240a6645ffed439f79b072b4) + +commit da4e0b56c60f4bc2c67daa5dfe4d5255ab8bfc03 +Author: Nathan Cutler +Date: Thu Dec 15 18:23:41 2016 +0100 + + doc: add verbiage to rbdmap manpage + + Fixes: http://tracker.ceph.com/issues/18262 + Signed-off-by: Nathan Cutler + (cherry picked from commit fbac4a081547d83bb2436cd60b0b7ee7250f8a6c) + +commit 167d4fd7ccf0cdac536f95250bbfa3e9879ab769 +Author: David Disseldorp +Date: Fri Feb 10 17:50:12 2017 +0100 + + rbdmap: unmap RBDMAPFILE images unless called with unmap-all + + When called with a "map" parameter, the rbdmap script iterates the list + of images present in RBDMAPFILE (/etc/ceph/rbdmap), and maps each entry. + When called with "unmap", rbdmap currently iterates *all* mapped RBD + images and unmaps each one, regardless of whether it's listed in the + RBDMAPFILE or not. + + This commit adds functionality such that only RBD images listed in the + configuration file are unmapped. This behaviour is the new default for + "rbdmap unmap". A new "unmap-all" parameter is added to offer the old + unmap-all-rbd-images behaviour, which is used by the systemd service. + + Fixes: http://tracker.ceph.com/issues/18884 + + Signed-off-by: David Disseldorp + (cherry picked from commit e58413abf408cbe254232e563f3e30d2dc0d707c) + +commit 39aab763a44e45e025c311cdfff95116df11a4c4 +Author: Nathan Cutler +Date: Thu Dec 15 13:01:02 2016 +0100 + + Revert "dummy: reduce run time, run user.yaml playbook" + + This reverts commit d4e3cec1851ae35889127b90912e133178085bc6. + + Fixes: http://tracker.ceph.com/issues/18259 + Signed-off-by: Nathan Cutler + (cherry picked from commit a8a2a8c3e68b910dbaeb3186576898bf9f89f9fd) + +commit 2e50fe1684f73ebe96969c341242b6f20c8470a0 +Author: Casey Bodley +Date: Thu Oct 20 15:01:01 2016 -0400 + + rgw: fix break inside of yield in RGWFetchAllMetaCR + + the yield macro is implemented with for/switch, so the breaks in + RGWFetchAllMetaCR weren't being applied to the for loop as expected - + so any of these breaks send RGWFetchAllMetaCR into an infinite loop + + removed the yield {} block, so that breaks will apply to the for loop as + intended, then added a single yield; statement to allow the + entries_index consumer to run one per iteration + + Fixes: http://tracker.ceph.com/issues/17655 + + Signed-off-by: Casey Bodley + (cherry picked from commit 190bd385a7be52867d65740c410884f5c8cbc21f) + +commit dc4e7a1a865ea0ae7362c1b6a7a542aa5f72107d +Author: Casey Bodley +Date: Fri Mar 3 12:10:40 2017 -0500 + + rgw: delete_system_obj() fails on empty object name + + Signed-off-by: Casey Bodley + (cherry picked from commit 67401193f871db95a6045915fa59dce8c5dd1012) + +commit e9a577c8c535702d1eb285429978bdbb395e2d5c +Author: Casey Bodley +Date: Fri Mar 3 11:42:45 2017 -0500 + + rgw: if user.email is empty, dont try to delete + + Fixes: http://tracker.ceph.com/issues/18980 + + Signed-off-by: Casey Bodley + (cherry picked from commit 022ecf0fcc8e44912c8758ee1d9a452dc23cbbce) + +commit 90de64bd81fedcb9540e40d50420e169a4a81248 +Author: Alexey Sheplyakov +Date: Mon Mar 20 14:05:17 2017 +0400 + + jewel: osd/PGLog: reindex properly on pg log split + + When PGLog::IndexedLog::split_into runs it builds the list, which means + the old indices are wrong (point to bad memory), but index() will not + rebuild them because ever since b858e86 we won't rebuild them if they + are already built. Fix that by calling unindex() before the split. + + Based on 643ae42cf27f16dd6ed4e1402acc0483bb9fca74. Notice that both + the child and the parent log are re-indexed in Jewel, so the only + problem is missing unindex(). + + Signed-off-by: Alexey Sheplyakov + +commit ae498e84ffcff7424721f0d2704ec739d1cc092d +Author: liuchang0812 +Date: Tue Dec 20 13:21:40 2016 +0800 + + os/filestore: fix clang static check warn use-after-free + + Signed-off-by: liuchang0812 + (cherry picked from commit 1d359455b3dd6abb383542ba596a03f14ac54dbd) + See: http://tracker.ceph.com/issues/19311 + + Signed-off-by: yaoning + +commit 335b5fa4a9694620546422f9a02bdcc16549d7cc +Author: Mykola Golub +Date: Thu Feb 2 11:11:35 2017 +0100 + + rbd-nbd: check /sys/block/nbdX/size to ensure kernel mapped correctly + + Fixes: http://tracker.ceph.com/issues/18335 + Signed-off-by: Mykola Golub + (cherry picked from commit 596e5ea8a5df72002672eef0a6d20572ca6f60f0) + + Conflicts: + qa/workunits/rbd/rbd-nbd.sh: the original commit removes + TOO_LARGE_IMAGE test, do the same thing + src/tools/rbd_nbd/rbd-nbd.cc: help git to add + "include/stringify.h" + + Other changes: + src/tools/rbd_nbd/rbd-nbd.cc: #include so + the code compiles + + Signed-off-by: Alexey Sheplyakov + +commit ced799f9c6558482d538f8dec854c62162685ad0 +Author: Michal Koutný +Date: Thu Jan 26 16:08:09 2017 -0500 + + rgw: Use decoded URI when verifying TempURL + + Instead of calliing url_decode directly, we reuse s->decoded_uri that is + initialized in RGWREST::preprocess(). + + Fixes: http://tracker.ceph.com/issues/18590 + + Adapted from 4e1318f4dcbfd64c3ec94f4addf6e38ddd6c013a. Cherry-picking + that patch requires a quite a number of unrelated changes, hence this + patch does s/s->info.request_uri/s->decoded_uri/ to keep the fix as + minimal as possible. + + Signed-off-by: Alexey Sheplyakov + +commit 043d70461c1eb874d9185f9bd671930fad05ff65 +Author: Ilya Dryomov +Date: Wed Mar 1 17:19:04 2017 +0100 + + osd/OSDMap: don't set weight to IN when OSD is destroyed + + Since commit 4e28f9e63644 ("osd/OSDMap: clear osd_info, osd_xinfo on + osd deletion"), weight is set to IN when OSD is deleted. This changes + the result of applying an incremental for clients, not just OSDs. + Because CRUSH computations are obviously affected, pre-4e28f9e63644 + servers disagree with post-4e28f9e63644 clients on object placement, + resulting in misdirected requests. + + Fixes: http://tracker.ceph.com/issues/19119 + Signed-off-by: Ilya Dryomov + (cherry picked from commit a6009d1039a55e2c77f431662b3d6cc5a8e8e63f) + +commit 6b5322c5f62f4b90c4206c6ddcc70d090fa7eeb9 +Author: Kefu Chai +Date: Tue Mar 7 18:49:46 2017 +0800 + + osd/ReplicatedPG: try with pool's use-gmt setting if hitset archive not found + + due to http://tracker.ceph.com/issues/19185, a hammer OSD could store + pg_hit_set_info_t with "use-gmt = true" even the pool setting is false. + so we use the pool setting as a fallback if the hitset archive is not + found locally and the pool.use_gmt does not match with hitset.use_gmt. + + Fixes: http://tracker.ceph.com/issues/19185 + Signed-off-by: Kefu Chai + + Conflicts: + osd/ReplicatedPG.cc: This cannot be cherry-picked from master + because: hammer should upgrade to jewel first before moving to a + higher version. so there is no necessary to include this workaround + in releases later than jewel. + +commit d30c4d55ad52e2b63fdbd06ce256d92fc3fd36c9 +Author: Abhishek Lekshmanan +Date: Thu Feb 16 17:40:50 2017 +0100 + + doc: rgw: make a note abt system users vs normal users + + Mention that system users don't behave like normal users in context of + normal rest operations + + Fixes: http://tracker.ceph.com/issues/18889 + Signed-off-by: Abhishek Lekshmanan + (cherry picked from commit a47bcf70c9f51a6601b809cba219f5615b204d34) + + Conflicts: + doc/radosgw/multisite.rst (trivial whitespace difference) + +commit 5ee8feaba469886f9e3bd3909475ffef62ba261d +Author: root +Date: Tue Feb 7 14:37:36 2017 +0530 + + rgw: Let the object stat command be shown in the usage + + Fixes: http://tracker.ceph.com/issues/19013 + Signed-off-by: Pavan Rallabhandi + (cherry picked from commit 0fe76f83d19be098ef54fb0492a376fef3aa9e23) + +commit 754b4a482cb0369215beed58103a1e241231cf77 +Author: root +Date: Tue Feb 21 16:33:29 2017 +0530 + + rgw: Correct the return codes for the health check feature + Fixes: http://tracker.ceph.com/issues/19025 + Signed-off-by: Pavan Rallabhandi + + (cherry picked from commit 4da2bf310f6d43423554c32e43ebf90ad2c3f3a9) + +commit 9cd7dd84909abdb9e603ff3aeb9958cdab8c70ad +Author: Ronak Jain +Date: Wed Feb 22 12:03:46 2017 +0530 + + rgw: Fixes typo in rgw_admin.cc + + Issue: http://tracker.ceph.com/issues/19026 + Signed-off-by: Ronak Jain + (cherry picked from commit 58837ef6ce8cbcfc2cac29d5f833b2cf62d8737a) + +commit 85fbb00f6ef5f11bc5d615ccd8e2202ce3896fd1 +Author: Yehuda Sadeh +Date: Mon Feb 27 10:35:01 2017 -0800 + + rgw: don't init rgw_obj from rgw_obj_key when it's incorrect to do so + + Fixes: http://tracker.ceph.com/issues/19096 + + rgw_obj_key currently deals with the bucket index key, and not + representing a (name, instance, ns) tupple. Need to initialize + it in two steps. + + Signed-off-by: Yehuda Sadeh + (cherry picked from commit 392c5d9dae6ba699014ffe6e1e67818fa62d7e41) + +commit ec0668c201a71b4a17ef0ab3c5908f57229aa6ef +Author: Casey Bodley +Date: Tue Nov 29 11:29:41 2016 -0500 + + rgw: fix for broken yields in RGWMetaSyncShardCR + + Fixes: http://tracker.ceph.com/issues/18076 + + Signed-off-by: Casey Bodley + (cherry picked from commit e62d48a9bf2e309eab1a863f167af5267ebcc371) + +commit 6afe3efa4b636ede1cd77086cb2e70ed09fa2e95 +Author: Abhishek Lekshmanan +Date: Mon Jul 25 11:21:11 2016 +0200 + + rgw: kill a compile warning for rgw_sync + + killing the compile warning for + + ``` + /ceph/src/rgw/rgw_sync.cc:1462:12: + warning: suggest explicit braces to avoid ambiguous ‘else’ [-Wparentheses] + if (can_adjust_marker) yield { + ^ + ``` + + Signed-off-by: Abhishek Lekshmanan + Signed-off-by: Casey Bodley + (cherry picked from commit 831640bb46621a6f003ad562cef7928ffa9a7ad3) + +commit 06916a8798439ec033294d791749ce7381d92f51 +Author: Vikhyat Umrao +Date: Mon Feb 13 23:07:25 2017 +0530 + + rgw: change log level to 20 for 'System already converted' message + + Fixes: http://tracker.ceph.com/issues/18919 + + Signed-off-by: Vikhyat Umrao + (cherry picked from commit 55b567c767830170d04de4cdc8f10aba30a3f379) + +commit 4c1f302f7d71bedb0dead220f17eeb84e7e3f737 +Author: Jing Wenjun +Date: Wed Jan 11 05:28:43 2017 +0800 + + rgw: the swift container acl should support field .ref + + On the openstack-swift. The container acl supports .ref, which is ignored on ceph swift. + + Fixes: http://tracker.ceph.com/issues/18484 + Signed-off-by: Jing Wenjun + (cherry picked from commit b06f9cd9f0900db7b0d0fbcaea69cdd0d4b10132) + + Conflicts: + src/rgw/rgw_acl_swift.cc - no extract_referer_urlspec() in jewel + see https://github.com/ceph/ceph/pull/8657 + +commit 714eb863c30df4e653068e6ea16630504e58b704 +Author: xie xingguo +Date: Tue Jun 14 19:32:01 2016 +0800 + + server: negative error code when responding to client + + As the comment suggests. Also a zero or positive return code + shall indicates a success, which does not match our intention here. + + Signed-off-by: xie xingguo + (cherry picked from commit 26931f888ce4661765cca106b3a3dc66702266df) + Signed-off-by: Jan Fajerski + +commit 1a4e1e09b1e562bf97cfe96f5cb9f937b6987165 +Author: Jason Dillaman +Date: Tue Dec 13 14:10:58 2016 -0500 + + librbd: remove image header lock assertions + + This assertions can sporadically fail if the watch is lost and + recovered in the background. Upon a true loss of the lock, the + client would either be blacklisted or it would have completed + all in-flight ops before releasing. + + Fixes: http://tracker.ceph.com/issues/18244 + Signed-off-by: Jason Dillaman + (cherry picked from commit ce4f2a52ec0a794d89e7576b59c9b9aefe3db288) + + Conflicts: + src/librbd/operation/SnapshotCreateRequest.cc: rbd class + does not support the snapshot namespaces in Jewel, skip + the corresponding argument + +commit cebba011e502f7009208bbddc295eb17f88f1bb9 +Author: Dan van der Ster +Date: Fri Dec 9 22:06:26 2016 +0100 + + os/filestore/HashIndex: be loud about splits + + Filestore splits are a rare yet important enough event that an + OSD should visibly report when they happen. + + Without this reporting an operator could spend hours trying to + understand the cause of any split-induced slow requests. + + Fixes: http://tracker.ceph.com/issues/18235 + Signed-off-by: Dan van der Ster + (cherry picked from commit 61c47acd3a1f3e01f0106d4a541bb7f28a1301d8) + +commit 1d054c3856a63ceebe44f66ff83fda691c374f71 +Author: Nathan Cutler +Date: Thu Mar 2 12:41:07 2017 +0100 + + build/ops: add psmisc dependency to ceph-base (deb and rpm) + + Fixes: http://tracker.ceph.com/issues/19129 + Signed-off-by: Nathan Cutler + (cherry picked from commit 769b695465162bc8424abf8e2f259e6765b5bbff) + + Conflicts: + debian/control (jewel does not have f11acf2b 7e71cd2c) + +commit 6add2a457e2826b71c0e9e82c6f6686cecbc4584 +Author: Jing Wenjun +Date: Fri Nov 25 21:31:22 2016 +0800 + + rgw: metadata sync info should be shown at master zone of slave zonegroup + + When executing 'radosgw-admin sync status', the metadata sync info should be shown on the srceen at master zone of slave zonegroup. + + Using the function store->is_meta_master() instead of 'zonegroup.is_master && zone.id == zonegroup.master_zone' + + Fixes: http://tracker.ceph.com/issues/18091 + Signed-off-by: Jing Wenjun + (cherry picked from commit c12d0af2f98b246a73cc3ee027449a22192795b3) + +commit 0e11a938c5c9acd8a50efa9a154ea3bf21bcafc5 +Author: Boris Ranto +Date: Wed Jan 25 12:39:40 2017 +0100 + + systemd: Start OSDs after MONs + + Currently, we start/stop OSDs and MONs simultaneously. This may cause + problems especially when we are shutting down the system. Once the mon + goes down it causes a re-election and the MONs can miss the message + from the OSD that is going down. + + Resolves: http://tracker.ceph.com/issues/18516 + + Signed-off-by: Boris Ranto + (cherry picked from commit 7f4acf45dd0d86e7d9992a8c30e5876fb57b1914) + + Conflicts: + systemd/ceph-osd@.service (jewel does not have 4179aa8d) + +commit 3bdd4398f1dcad0b7e22f1750ca524b97feca15a +Author: yaoning +Date: Mon Jun 6 13:31:52 2016 +0800 + + osd: preserve allocation hint attribute during recovery + + Signed-off-by: yaoning + (cherry picked from commit e15be792960da6bac2bd469acf7d30007be61781) + + Conflicts: + src/osd/ReplicatedBackend.cc (in master, it contains alloc_hint_flags for set_alloc_hint) + src/osd/ReplicatedPG.cc (in master, it contains alloc_hint_flags in object_info_t struct) + src/osd/osd_types.cc (in master, it contains alloc_hint_flags in message serialization) + alloc_hint_flags is used in master bluestore, filestore does not use alloc_hint_flags. + therefore, remove alloc_hint_flags here in jewel + + Signed-off-by: yaoning + +commit 8d0140a9eda814beadf1f59c9b4205f30a1d2e35 +Author: Jason Dillaman +Date: Tue Jan 24 09:24:52 2017 -0500 + + librbd: improve debug logging for lock / watch state machines + + Signed-off-by: Jason Dillaman + (cherry picked from commit cc046597983bd491cc66081cc33d9046264fe24b) + + Conflicts: + NOTE: cherry-picked from kraken commit to avoid conflicts + +commit 62ce3461c3b205eaa9062113526cf572184d0a27 +Author: Jason Dillaman +Date: Mon Jan 23 21:24:41 2017 -0500 + + test: use librados API to retrieve config params + + The CephContext object is not ABI-stable, so it is necessary to + use the "conf_get" librados methods to safely retrieve a setting. + + Fixes: http://tracker.ceph.com/issues/18617 + Signed-off-by: Jason Dillaman + (cherry picked from commit 2ed02f3cd56bf89984c3538ac3f21ec2321cd3b7) + + Conflicts: + src/test/librbd/test_librbd.cc (jewel does not have + 006138e2d80b779d8c15b141002bb4b3852f6c4a or + cb3712e08cdc2c37a983b479f4692bbdfe83b220) + +commit 01d04e28db7c2969b86df5b38a20b9eb156cf393 +Author: Nathan Cutler +Date: Thu Feb 2 23:23:54 2017 +0100 + + tests: Thrasher: eliminate a race between kill_osd and __init__ + + If Thrasher.__init__() spawns the do_thrash thread before initializing the + ceph_objectstore_tool property, do_thrash races with the rest + of Thrasher.__init__() and in some cases do_thrash can call kill_osd() before + Trasher.__init__() progresses much further. This can lead to an exception + ("AttributeError: Thrasher instance has no attribute 'ceph_objectstore_tool'") + being thrown in kill_osd(). + + This commit eliminates the race by making sure the ceph_objectstore_tool + attribute is initialized before the do_thrash thread is spawned. + + Fixes: http://tracker.ceph.com/issues/18799 + Signed-off-by: Nathan Cutler + (cherry picked from commit b519d38fb1967628ad8a1c46fcfb3f984de58790) + + Conflicts: + qa/tasks/ceph_manager.py (jewel has only one if statement after + "self.thread = gevent.spawn(self.do_thrash)" while master has four; + jewel lacks 66836c957ffd974dec136997e23261ec7de2f0aa which disables + ceph-objectstore-tool testing in master) + +commit 08a667883b68ccc72e3a4bc3013856deef1df93d +Author: Nathan Cutler +Date: Sat Feb 18 14:33:25 2017 +0100 + + rpm: build ceph-resource-agents by default + + To align with debian build + + Fixes: http://tracker.ceph.com/issues/17613 + Signed-off-by: Nathan Cutler + (cherry picked from commit 3e157bf16c3020ac11cb26df5df3ed331faf3c25) + +commit d22becab0f2c541584ce891d392760a5c4f1d153 +Author: Yan Jun +Date: Thu Jul 14 19:10:29 2016 +0800 + + msg/simple: cleanups + + should save the `errno` which may be changed by `ldout` and/or `<<` operator + + Signed-off-by: Yan Jun + (cherry picked from commit 91a29bc490fdfbbef0875fa620c7ba1a1a6492ae) + Signed-off-by: Robin H. Johnson + +commit a18a2dd108678d2e4b57e08b559c1f9a262d6923 +Author: Kefu Chai +Date: Fri Jun 17 13:58:55 2016 +0800 + + msg/simple: set close on exec on server sockets + + mds execv() when handling the "respawn" command, to avoid fd leakage, + and enormous CLOSE_WAIT connections after respawning, we need to set + FD_CLOEXEC flag for the socket fds. + + Fixes: http://tracker.ceph.com/issues/16390 + Signed-off-by: Kefu Chai + (cherry picked from commit f019ad563ce90f5aea0d8dd8b7b98688441596e0) + +commit 91a968b8fc7b363cae351b8648259211a1e71d18 +Author: Kefu Chai +Date: Fri Jun 17 01:17:05 2016 +0800 + + msg/async: set close on exec on server sockets + + mds execv() when handling the "respawn" command, to avoid fd leakage, + and enormous CLOSE_WAIT connections after respawning, we need to set + FD_CLOEXEC flag for the socket fds. + + Fixes: http://tracker.ceph.com/issues/16390 + Signed-off-by: Kefu Chai + (cherry picked from commit eaf68c724144d07f9506037a14d9192cb9f16d70) + + Conflicts: + src/msg/async/AsyncMessenger.cc: Processor::accept(): applied + the hunk manually (invoke set_close_on_exec on a socket + returned by accept) + +commit 547e867628975c7144590e9332aa62b0ef82a433 +Author: Jason Dillaman +Date: Thu Jan 5 12:12:57 2017 -0500 + + librbd: possible deadlock with flush if refresh in-progress + + Fixes: http://tracker.ceph.com/issues/18419 + Signed-off-by: Jason Dillaman + (cherry picked from commit b95f92a5572d3035c20eba07e76d2c825a9853f7) + + Conflicts: + src/librbd/ImageState.h (master commit just adds a function + declaration, so just add it to jewel as well) + +commit 07501dec6f1c70afd4e4c2a50d7f874c39f2220b +Author: Sage Weil +Date: Wed Jan 18 17:02:54 2017 -0600 + + mon/OSDMonitor: make 'osd crush move ...' work on osds + + Currently it only allows you to move buckets, which is annoying and much + less useful. To move an OSD you need to use create-or-move, which is + harder to use. + + Fixes: http://tracker.ceph.com/issues/18587 + Signed-off-by: Sage Weil + (cherry picked from commit 47956475dea8bb8e07331dd76344a60b776b5158) + + Conflicts: + qa/workunits/mon/crush_ops.sh: adapted "ceph osd find" to jewel syntax + +commit 7c6c3c753ccdd3baea834338e1a761f05b4e0a12 +Author: Vikhyat Umrao +Date: Thu Feb 16 23:51:11 2017 +0530 + + auth: 'ceph auth import -i' overwrites caps, if caps are not specified + in given keyring file, should alert user and should not allow this import. + Because in 'ceph auth list' we keep all the keyrings with caps and importing + 'client.admin' user keyring without caps locks the cluster with error[1] + because admin keyring caps are missing in 'ceph auth'. + + [1] Error connecting to cluster: PermissionDeniedError + + Fixes: http://tracker.ceph.com/issues/18932 + + Signed-off-by: Vikhyat Umrao + (cherry picked from commit 90144aa64c11a685b6a7cb3aafea75d427f569be) + +commit 8c7a1df251e8289e7cf2df5b3096b91d8640695d +Author: Sage Weil +Date: Tue Feb 14 15:00:09 2017 -0500 + + osd/PG: restrict want_acting to up+acting on recovery completion + + On recovery completion we recalculate want_acting to see if we + should add recently backfilled osds into acting. However, at + this point we may have gotten infos from others OSDs outside + of up/acting that could be used for want_acting. We currently + assert that only up/acting osds are used in + PG::RecoveryState::Active::react(const AdvMap&), so we must + restrict want_acting to up/acting here. + + We could remove this restriction, but it would mean + + 1) checking on every map change that want_acting hasn't been + invalidated, and if so, recalculating want_acting and requesting + a new pg_temp. Also, presumably + + 2) on each new info, checking whether we can construct a better + want_acting, and if so, doing it. + + That would be a good thing, but is a more complicated change. In + reality this case comes up very rarely, so simply make our + post-recovery want_acting calculation limit itself to up+acting. + + See 1db67c443d84dc5d1ff53cc820fdfd4a2128b680 for the assertion. + + Signed-off-by: Sage Weil + (cherry picked from commit 0f2dee9aa48a00a7f2f809cd4d20e98df771da81) + +commit cfa37d6a1674e3f6f8eef4d8519823a7af70df01 +Author: craigchi +Date: Thu Feb 16 19:21:48 2017 +0800 + + ceph-disk: Fix getting wrong group name when --setgroup in bluestore + + ceph-disk prepare --setgroup will be wrong when using with + bluestore + + Signed-off-by: craigchi + (cherry picked from commit a8c0870e7370a0948e8e7fd53d3376b85bf9c649) + +commit 2d17092fab8080f819369d74d4c76d8ae58d899b +Author: Alexey Sheplyakov +Date: Tue Feb 7 16:47:45 2017 +0400 + + ceph-osd: --flush-journal: sporadic segfaults on exit + + FileStore holds a number of recources like op thread pool and work + queue, key/value DB threads, etc. These should be properly stopped + (released) before exiting to avoid segfaults on exit. + + Note: more code paths (mkfs, dump_journal, etc) need similar fixes, + these will be submitted as separate patches. + + Fixes: http://tracker.ceph.com/issues/18820 + Signed-off-by: Alexey Sheplyakov + (cherry picked from commit 00184814c156f6194a6ba4b696073ca1c18a3f8f) + + Adjustments: + - release g_ceph_context in the same way as the main code path does + +commit d012c381e8c59994ea9a40dc006d23f1bdd6a026 +Author: Sebastien Ponce +Date: Tue May 10 11:27:59 2016 +0200 + + radosstriper : protect aio_write API from calls with 0 bytes + + an assertion was failing so far, while we only have to return without doing anything + + Signed-off-by: Sebastien Ponce + (cherry picked from commit 7cce1e8c51640f466d8bb37a21c0d5f1b00db8ab) + +commit 915dbace5ddea69fff29f7965f213229b6fbc0ac +Author: Jason Dillaman +Date: Tue Jan 17 11:55:00 2017 -0500 + + osdc: cache should ignore error bhs during trim + + A read error (such as injecting a timeout into an OSD op) might result + in a bh in an error state. These should be trimable by the cache. + + Fixes: http://tracker.ceph.com/issues/18436 + Signed-off-by: Jason Dillaman + (cherry picked from commit 5910ed9de9856b5821488a1836487bbbd3d6460e) + +commit 419c9926d9ed57cb60228bc95956a9a1471b92cb +Author: Piotr Dałek +Date: Tue Jan 31 16:07:18 2017 +0100 + + OSD: allow client throttler to be adjusted on-fly, without restart + + This patch allows the osd_client_message_cap and + osd_client_message_size_cap to be adjusted on-fly, using admin socket + functionality. + + Fixes: http://tracker.ceph.com/issues/18791 + Signed-off-by: Piotr Dałek + (cherry picked from commit 64c309d7e18a975931b526e6f5d6f610c3a0d632) + + Conflicts: + src/osd/OSD.cc (suppressed post-jewel option) + +commit 957c19b844fb44cde78ad59f872815f82bbf23b8 +Author: Ali Maredia +Date: Thu Nov 10 13:58:35 2016 -0500 + + swift: added "--cluster" to rgw-admin command for multisite support + + Signed-off-by: Ali Maredia + +commit 8423bc1eefa45366bdd215a17c61701c9b05dfdd +Merge: 6dc30c4140 c078534376 +Author: Andrew Schoen +Date: Thu Apr 23 14:49:30 2015 -0500 + + Merge pull request #470 from ceph/wip-remote + + Add timeouts to Remote connection functions + +commit 6dc30c4140a833fd6cd126f8b5c1eceebad90510 +Merge: d55484f9e5 c078534376 +Author: Andrew Schoen +Date: Mon Apr 20 12:38:29 2015 -0500 + + Merge pull request #466 from ceph/wip-11426 + + Log stderr in get_latest_image_version_deb() + +commit d55484f9e562779e7d47a8f63ff029337dc01eef +Merge: c078534376 cd72cf2b31 +Author: Dan Mick +Date: Wed Apr 15 10:30:46 2015 -0700 + + Merge pull request #462 from ceph/wip-ssh-keys + + When modifying authorized_keys, store a backup + +commit c078534376d594aa3bf70d1d2e5dfc09ca8ae248 +Merge: cd72cf2b31 fce2ed683f +Author: Zack Cerza +Date: Tue Apr 14 11:38:15 2015 -0600 + + Merge pull request #460 from zhouyuan/mkdir_p + + Make parent directories as needed + +commit cd72cf2b3132e7c6371aa4dbfe7564ad3ad0509e +Author: Yehuda Sadeh +Date: Mon Nov 24 09:59:30 2014 -0800 + + swift: set full access to subusers creation + + Default subuser permissions are 'none'. + + Signed-off-by: Yehuda Sadeh + +commit fce2ed683fcd3798db968a40200f8e8f215595fa +Author: Zack Cerza +Date: Wed Aug 6 10:06:34 2014 -0600 + + Remove most ceph-specific tasks. They are in ceph-qa-suite now. + + Signed-off-by: Zack Cerza + +commit fac452ae55594aea482db5c13a0bd0207b6ecff6 +Author: Zack Cerza +Date: Thu Mar 27 11:35:28 2014 -0500 + + Revert "Lines formerly of the form '(remote,) = ctx.cluster.only(role).remotes.keys()'" + + This reverts commit d693b3f8950ffd1f2492a4db0f8234fee31f00f0. + +commit e98b107302e06fa5c3c628a7ab0e7455de9ab568 +Author: Warren Usui +Date: Fri Feb 28 19:13:40 2014 -0800 + + Lines formerly of the form '(remote,) = ctx.cluster.only(role).remotes.keys()' + and '(remote,) = ctx.cluster.only(role).remotes.iterkeys()' would fail with + ValueError and no message if there were less than 0 or more than 1 key. + Now a new function, get_single_remote_value() is called which prints out + more understandable messages. + + Fixes: 7510 + Reviewed-by: Josh Durgin + Signed-off-by: Warren Usui + +commit e5fe884edfec66cc7e520938bd520aa8f1344f85 +Merge: 8e2cdbf5ed f8bf53c4fe +Author: Alfredo Deza +Date: Wed Feb 19 16:40:17 2014 -0500 + + Merge pull request #186 from ceph/wip-7369 + + Fix #7369: "sed expression must be raw string" + +commit 8e2cdbf5ede871ebde260e6bdaec13daae03cfc5 +Merge: 132f3e8ae6 f8bf53c4fe +Author: Zack Cerza +Date: Fri Feb 14 14:59:04 2014 -0600 + + Merge pull request #188 from ceph/wip-calamari-onefile + + Add Calamari test tasks, test script + +commit 132f3e8ae664a35cad89896b7300be13b5c604ec +Merge: 24363351c3 7b63876676 +Author: Zack Cerza +Date: Fri Feb 14 11:50:55 2014 -0600 + + Merge pull request #192 from ceph/wip-6537-wusui + + Readjust the indentation of mon_clock_skew_check.py and mon_thrash.py. + +commit 24363351c3b1d23a8d6ef4e3f952855415f97ba8 +Merge: 4eb147291f 7b63876676 +Author: Zack Cerza +Date: Fri Feb 14 11:45:51 2014 -0600 + + Merge pull request #194 from ceph/wip-6534-wusui + + Add docstrings to internal.py + +commit 4eb147291fccdb2164a46e977ee43dbf50894e5a +Merge: ad9aaf8fa3 f4284b520a +Author: Zack Cerza +Date: Fri Feb 14 11:45:19 2014 -0600 + + Merge pull request #193 from ceph/wip-6538-wusui + + Add doc strings to Swift tests + +commit ad9aaf8fa35d49c33373fa69df7b38d3aca6abc5 +Merge: 7b63876676 f8bf53c4fe +Author: Zack Cerza +Date: Fri Feb 14 11:43:15 2014 -0600 + + Merge pull request #187 from ceph/wip-better-debug + + Debug output improvements + +commit f4284b520a554b1cbe130731741e53a7fcf4e35f +Author: Warren Usui +Date: Thu Feb 13 21:11:34 2014 -0800 + + Add doc strings to Swift tests + + Fixes: 6538 + Signed-off-by: Warren Usui + +commit 7b63876676f1a6845ba3b9147cf7bb2348ef2468 +Author: Warren Usui +Date: Tue Feb 11 20:21:06 2014 -0800 + + Add docstrings to s3 related tasks. + + Fixes: 6536 + Signed-off-by: Warren Usui + +commit f8bf53c4fe52009abdf730b05e2cb2ddbb412dea +Author: Zack Cerza +Date: Tue Sep 24 14:19:24 2013 -0500 + + Fix namespace collision + +commit db6efe3e0ba7446ca42baf2a50eef18a10cf4a10 +Merge: 611733c8b5 66555a4039 +Author: Alfredo Deza +Date: Tue Sep 24 08:17:22 2013 -0700 + + Merge pull request #106 from ceph/wip-mirror + + Remove lots of ceph.com hardcoding; default to upstream sources + +commit 66555a4039c61db9b96d6eecf8d2f298c98b6bad +Author: Zack Cerza +Date: Fri Sep 20 15:53:58 2013 -0500 + + Don't hardcode the git://ceph.com/git/ mirror + + Default to https://github.com/ceph/ but add a ~/teuthology.yaml option + +commit 611733c8b5ea55206df50c122efac612cb146c2f +Merge: 2346f1d735 6e8a3807c7 +Author: Sage Weil +Date: Fri Sep 6 13:24:34 2013 -0700 + + Merge pull request #78 from ceph/wip-6247 + + Move helper scripts to /usr/local/bin to clean up logs. + +commit 6e8a3807c766f728027c3099eebfa24cdc645bd1 +Author: Zack Cerza +Date: Fri Sep 6 15:08:01 2013 -0500 + + Helper scripts live in /usr/local/bin now! + +commit 2346f1d735ccb40d00b8ff61d4acb446f684b3b2 +Author: Joe Buck +Date: Fri Aug 23 19:54:53 2013 -0700 + + s3tests: extend for multi-region tests + + Added code to the s3tests task to extract + multi-region info so that that data + can be added to the S3TEST_CONF file + used to run S3 tests. + + Signed-off-by: Joe Buck + Reviewed-by: Josh Durgin + +commit d3b6d633e161bc422f4781c7be5011f8a7ed8a32 +Merge: 442a36c57c 09b01b27a3 +Author: Alfredo Deza +Date: Mon Aug 19 14:10:18 2013 -0700 + + Merge pull request #41 from ceph/wip-3791 + + Various usability and documentation fixes + +commit 442a36c57c3173b36ce17e5f85a49abf7e80ea93 +Merge: 09b01b27a3 9b2c4fa4ad +Author: wusui +Date: Fri Aug 16 14:47:59 2013 -0700 + + Merge pull request #40 from ceph/wip-teutharm-wusui + + Wip teutharm wusui + +commit 09b01b27a3a1310d4257133def60896ad37fb575 +Author: Zack Cerza +Date: Thu Aug 15 08:49:35 2013 -0500 + + Fix some instances where print is being used instead of log + +commit 9b2c4fa4ad4c4258b26526afb0c16c71ce47f593 +Author: Josh Durgin +Date: Wed Jul 31 13:32:58 2013 -0700 + + s3/swift tests: call radosgw-admin as the right client + + This allows the right region and zone info to be read from ceph.conf + + Signed-off-by: Josh Durgin + +commit 3b3816df58a3ba1f2f850faf8969ad070aa0046e +Author: Yehuda Sadeh +Date: Thu Jul 25 16:47:34 2013 -0700 + + s3tests: clone correct branch + + Signed-off-by: Yehuda Sadeh + +commit f5170fb460a2183aed33122b4e6d0117a4220fec +Merge: 7207a31e58 bd56af707a +Author: Sandon Van Ness +Date: Thu Jul 25 19:50:39 2013 -0700 + + Merge branch 'master' of github.com:ceph/teuthology + +commit 7207a31e5812dd0b29f2d6378360015622ddf4aa +Merge: bd56af707a 3da945512e +Author: Sandon Van Ness +Date: Thu Jul 25 19:50:02 2013 -0700 + + Merge remote-tracking branch 'origin/wip-sandon-vm' + + Conflicts: + teuthology/lock.py + teuthology/misc.py + teuthology/task/install.py + +commit bd56af707ae50c98ec46344cf57eb333061847b1 +Merge: 3da945512e 343a42c0d8 +Author: Josh Durgin +Date: Fri Jul 19 14:44:51 2013 -0700 + + Merge branch 'wip-centos-rgw' + +commit 343a42c0d86af5b8630a30716c03fc84ba22f944 +Author: Josh Durgin +Date: Tue Jul 9 18:50:52 2013 -0700 + + s3tests: fix client configurations that aren't dictionaries + + They're always used as dictionaries later on. + + Signed-off-by: Josh Durgin + +commit 3da945512ed78081be5dbe9ba59c836a311e1973 +Merge: 2c34d1971f 253cc98d98 +Author: Sage Weil +Date: Mon Jun 24 16:18:36 2013 -0700 + + Merge pull request #15 from ceph/wip-ulimits + + Reviewed-by: Warren Usui + +commit 253cc98d98855d65be7ebcdd46a39aa1004f8e67 +Author: Sage Weil +Date: Sun Jun 23 09:15:28 2013 -0700 + + enable-coredump -> adjust-ulimits + + and set max_files to be big, too! + +commit 2c34d1971f1e82311b364bf8efe60b223158d676 +Merge: 61dba20d1f b366ad334a +Author: Warren Usui +Date: Tue May 7 19:27:51 2013 -0700 + + Merge branch 'wip-teuth4768a-wusui' + + Conflicts: + teuthology/task/install.py + +commit 61dba20d1fce774eac5b56f0d61d4229460875c0 +Merge: a9f3eb6310 5a7267f85c +Author: Sage Weil +Date: Mon May 6 21:31:36 2013 -0700 + + Merge branch 'next' + +commit a9f3eb631064931cbdde7ef218c16e154bdb9991 +Author: Sage Weil +Date: Thu May 2 13:47:46 2013 -0700 + + s3tests: add force-branch with higher precdence than 'branch' + + This way we can force a branch despite something in overrides. + + Signed-off-by: Sage Weil + +commit b366ad334af55867ba781e22c8f87b6ac7775bf2 +Merge: 2a51e32891 5a7267f85c +Author: Josh Durgin +Date: Wed May 1 09:52:02 2013 -0700 + + Merge remote branch 'origin/next' + +commit 5a7267f85c80f88aca1b0081b07de1de3909f2e7 +Author: Josh Durgin +Date: Tue Apr 30 17:07:53 2013 -0700 + + fix some errors found by pyflakes + + Signed-off-by: Josh Durgin + +commit f866037f045887ccc5da15404935ce3361a74a08 +Author: Josh Durgin +Date: Tue Apr 30 13:23:22 2013 -0700 + + s3tests: revert useless portion of 1c50db6a4630d07e72144dafd985c397f8a42dc5 + + Perhaps it was attempting to debug something, but it shouldn't have been committed. + + Signed-off-by: Josh Durgin + +commit 2dcce57c00264b85cfb906223dfb89db9cc61ba5 +Author: Josh Durgin +Date: Tue Apr 30 16:49:04 2013 -0700 + + rgw tests: remove users after each test + + These should all be cleanup up at some point. They're + almost all the same code. + + Signed-off-by: Josh Durgin + +commit 3c604251d9014dba45f3adbb2008bac16ff6346d +Author: Josh Durgin +Date: Tue Apr 30 16:47:34 2013 -0700 + + rgw tests: clean up immediately after the test + + There's no need for an explicit cleanup function, so move it back + to where it came from (except in s3roundtrip, which did not have it). + + Instead, since these use a nested contextmanager, pass through + and yield to the top-level run_tasks after the nested + contextmanager has finished (and thus run all the cleanup steps + in the subtasks for this test). + + Signed-off-by: Josh Durgin + +commit 022bd4aa42312b80917169282cbfba655bbad6f1 +Author: Yehuda Sadeh +Date: Tue Apr 30 07:06:03 2013 -0700 + + swift, s3readwrite: add missing yield + + Signed-off-by: Yehuda Sadeh + +commit 820c72b8d0177b01f69887ec64d98702db37077c +Author: Yehuda Sadeh +Date: Mon Apr 29 11:24:04 2013 -0700 + + s3tests, s3readwrite, swift: cleanup explicitly + + Cleaning up test dir explicitly after run, so that + consecutive runs don't fail. + + Signed-off-by: Yehuda Sadeh + +commit 2a51e328913f16917a881129b475a4aeeab24ed0 +Merge: cccadb9b03 617534e769 +Author: Yehuda Sadeh +Date: Wed Feb 20 14:10:50 2013 -0800 + + Merge remote-tracking branch 'origin/wip-3634' + +commit cccadb9b03ca4421a5fd841a61bf252c329e3649 +Merge: 3eb19c8107 fa1f89478a +Author: Sage Weil +Date: Tue Feb 19 21:04:24 2013 -0800 + + Merge branch 'unstable' + + Conflicts: + teuthology/task/workunit.py + +commit fa1f89478a76373cb33cf2524e2ebf68b3cd622c +Author: Sander Pool +Date: Wed Feb 6 19:16:52 2013 +0000 + + Install ceph debs and use installed debs + + The ceph task installs ceph using the debian + packages now, and all invocations of binaries installed + in {tmpdir}/binary/usr/local/bin/ are replace with + the use of the binaries installed in standard locations + by the debs. + + Author: Sander Pool + Signed-off-by: Sam Lang + +commit 3eb19c810725b011baacdb8a6f5b172f4720a39a +Author: Sam Lang +Date: Wed Jan 23 14:37:39 2013 -0600 + + Replace /tmp/cephtest/ with configurable path + + Teuthology uses /tmp/cephtest/ as the scratch test directory for + a run. This patch replaces /tmp/cephtest/ everywhere with a + per-run directory: {basedir}/{rundir} where {basedir} is a directory + configured in .teuthology.yaml (/tmp/cephtest if not specified), + and {rundir} is the name of the run, as given in --name. If no name + is specified, {user}-{timestamp} is used. + + To get the old behavior (/tmp/cephtest), set test_path: /tmp/cephtest + in .teuthology.yaml. + + This change was modivated by #3782, which requires a test dir that + survives across reboots, but also resolves #3767. + + Signed-off-by: Sam Lang + Reviewed-by: Josh Durgin + +commit 2f829870e140c87b30e5b7aa3ad237a90dcb2179 +Author: Yehuda Sadeh +Date: Fri Dec 21 10:20:02 2012 -0800 + + task/swift: change upstream repository url + + Signed-off-by: Yehuda Sadeh + +commit 334d6386753510c312898552c6f92313942786ef +Merge: b8e6ce4db9 26df886d82 +Author: Joao Eduardo Luis +Date: Thu Nov 29 00:53:59 2012 +0000 + + Merge branch 'wip-mon-thrasher' + +commit b8e6ce4db9a603ce3523b1759c65eeadee55daa7 +Author: Sage Weil +Date: Thu Nov 22 13:59:58 2012 -0800 + + s3tests: fix typo + +commit 26df886d825e28c25b630887b8dcc1c8c6d687d8 +Author: Yehuda Sadeh +Date: Mon Nov 19 16:19:06 2012 -0800 + + rgw-logsocket: a task to verify opslog socket works + + Signed-off-by: Yehuda Sadeh + +commit 617534e76978acb09a9f925f18bba475a65a7dd2 +Author: Sage Weil +Date: Mon Sep 10 11:08:57 2012 -0700 + + s3tests: run against arbitrary branch/sha1 of s3-tests.git + +commit 7d5c7ee8c6f2bfedd193a8d3b7102b4cfe0bf74f +Author: Sage Weil +Date: Wed Jun 6 16:00:55 2012 -0700 + + pull s3-tests.git using git, not http + +commit ce951cf4caffd5d6883cc8dcd24372bcdf03690a +Author: Sage Weil +Date: Sat May 5 09:30:41 2012 -0700 + + ceph.newdream.net -> ceph.com + +commit 2b879905fcfd660e242ed1a804d1c8301d17ab84 +Merge: 1ac4bb10fc 1970713a2f +Author: Mark Nelson +Date: Wed Mar 14 15:32:23 2012 -0500 + + Merge branch 'master' of github.com:ceph/teuthology + +commit 1970713a2fc43e3afae376712356ca93a65d9e1f +Author: Sage Weil +Date: Fri Mar 2 10:55:19 2012 -0800 + + github.com/NewDreamNetwork -> github.com/ceph + +commit 1ac4bb10fc4b7d8d07c44b0e92b1627c721ab925 +Author: Josh Durgin +Date: Tue Feb 21 14:54:33 2012 -0800 + + Add necessary imports for s3 tasks, and keep them alphabetical. + +commit 92110e5a4460281139233dcea3f629d01182d398 +Author: Yehuda Sadeh +Date: Tue Feb 21 12:12:03 2012 -0800 + + rgw: access key uses url safe chars + + Signed-off-by: Yehuda Sadeh + +commit 709d9441127fec93da74c7702cafa54a47e10e8f +Author: Sage Weil +Date: Sun Jan 15 22:48:33 2012 -0800 + + use local mirrors for (most) github urls + + A cronjob on ceph.newdream.net updates these every 15 minutes. Sigh. + +commit 9598e47949ba65030c722947dc433e38875b1bd6 +Author: Tommi Virtanen +Date: Mon Dec 5 10:07:25 2011 -0800 + + Rename "testrados" and "testswift" tasks to not begin with "test". + + Anything "test*" looks like a unit test, and shouldn't be used for + actual code. + +commit 6236e7db22edac7b51fc6329188b6afa74f3fc78 +Author: Yehuda Sadeh +Date: Thu Nov 17 16:53:21 2011 -0800 + + testswift: fix config + +commit 1dd607cabb07126769b4beb1ba6677e21c448719 +Author: Yehuda Sadeh +Date: Wed Nov 16 16:00:01 2011 -0800 + + rgw: add swift task + + still not completely working (for some reason it skips all the tests) + +commit cb425c158085568cd92c239a071e282c74eddf1a +Author: Greg Farnum +Date: Fri Sep 30 09:26:42 2011 -0700 + + s3-tests: use radosgw-admin instead of radosgw_admin + + Signed-off-by: Greg Farnum + +commit 37d7d515345ab04c333d6fada722e432e5816eb3 +Author: Tommi Virtanen +Date: Fri Sep 16 11:09:45 2011 -0700 + + s3tests: Clone repository from github. + + Signed-off-by: Tommi Virtanen + +commit 29a242d97dd4a5a9110710027cdddb244b8b0e29 +Author: Tommi Virtanen +Date: Tue Sep 13 14:53:02 2011 -0700 + + Move orchestra to teuthology.orchestra so there's just one top-level package. + +commit ec49a5f263f71aa473257e3fd49d86e475fe9456 +Author: Tommi Virtanen +Date: Fri Sep 9 13:22:03 2011 -0700 + + Callers of task s3tests.create_users don't need to provide dummy "fixtures" dict. + +commit d7d995e82b45e6077040b467c8ef9a82a573faf7 +Author: Stephon Striplin +Date: Tue Aug 9 13:43:46 2011 -0700 + + allow s3tests.create_users defaults be overridden + +commit 0086109767d5bfbbc370ca13d3fe91895b207821 +Author: Josh Durgin +Date: Thu Jul 14 16:47:29 2011 -0700 + + Make targets a dictionary mapping hosts to ssh host keys. + +commit 1b2c96416f554c0890b2690291b9a2dc8a6dc17a +Author: Tommi Virtanen +Date: Wed Jul 6 14:17:24 2011 -0700 + + Skip s3-tests marked fails_on_rgw, they will fail anyway. + +commit 06fb9b95e39985630d89e1635dcd12510686d9cd +Author: Tommi Virtanen +Date: Tue Jul 5 09:27:28 2011 -0700 + + The shell exits after the command, hence there is no need for pushd/popd. + +commit cd524a6904bf8254edc73a9148308f642638e33d +Author: Josh Durgin +Date: Fri Jun 24 17:09:47 2011 -0700 + + Add s3tests task. diff --git a/ceph/doc/changelog/v10.2.9.txt b/ceph/doc/changelog/v10.2.9.txt new file mode 100644 index 000000000..551f268ee --- /dev/null +++ b/ceph/doc/changelog/v10.2.9.txt @@ -0,0 +1,63 @@ +commit 2ee413f77150c0f375ff6f10edd6c8f9c7d060d0 +Author: Jenkins Build Slave User +Date: Thu Jul 13 13:04:57 2017 +0000 + + 10.2.9 + +commit 9295f588535c45431d19b9601b4063c8de88752d +Merge: 7b10d629ae fef1c8718f +Author: Nathan Cutler +Date: Thu Jul 13 10:31:31 2017 +0200 + + Merge pull request #16282 from smithfarm/wip-20599-jewel + + jewel: cephfs: Damaged MDS with 10.2.8 + + Reviewed-by: Yan, Zheng + +commit fef1c8718f77c190a0908d353f38b16b7c3832ab +Author: Nathan Cutler +Date: Wed Jul 12 08:40:20 2017 +0200 + + Revert "osdc/Journaler: make header write_pos align to boundary of flushed entry" + + This reverts commit 2e299b50de4a297fee2aec21290632336d239857. + + Signed-off-by: Nathan Cutler + +commit 3f89971e9edb88e313e1c190f7d05a83b52e6d91 +Author: Nathan Cutler +Date: Wed Jul 12 08:40:13 2017 +0200 + + Revert "osdc/Journaler: avoid executing on_safe contexts prematurely" + + This reverts commit 06cf9f365033f7913051bdf4060f0bc6fc0444d7. + + Signed-off-by: Nathan Cutler + +commit 7b10d629ae32122b267486fe9e176f5cd0e330cf +Merge: f5b1f1fd7c 6b479c275a +Author: Sage Weil +Date: Tue Jul 11 15:58:04 2017 -0500 + + Merge pull request #16273 from smithfarm/wip-jewel-pending-release-notes + + jewel: doc: clarify status of jewel PendingReleaseNotes + +commit 6b479c275a24451c278074d81758a385eca12869 +Author: Nathan Cutler +Date: Tue Jul 11 22:53:56 2017 +0200 + + doc: zero PendingReleaseNotes in preparation for v10.2.9 + + Signed-off-by: Nathan Cutler + +commit 55de93f9d711e13980168cc884dcb04d8849708e +Author: Nathan Cutler +Date: Tue Jul 11 22:27:33 2017 +0200 + + doc: clarify status of jewel PendingReleaseNotes + + Status as of 10.2.8 release + + Signed-off-by: Nathan Cutler diff --git a/ceph/doc/dev/erasure-coded-pool.rst b/ceph/doc/dev/erasure-coded-pool.rst index 0043e171b..4694a7a82 100644 --- a/ceph/doc/dev/erasure-coded-pool.rst +++ b/ceph/doc/dev/erasure-coded-pool.rst @@ -60,13 +60,13 @@ Set up an erasure-coded pool and the associated crush ruleset:: Set the ruleset failure domain to osd (instead of the host which is the default):: $ ceph osd erasure-code-profile set myprofile \ - ruleset-failure-domain=osd + crush-failure-domain=osd $ ceph osd erasure-code-profile get myprofile k=2 m=1 plugin=jerasure technique=reed_sol_van - ruleset-failure-domain=osd + crush-failure-domain=osd $ ceph osd pool create ecpool 12 12 erasure myprofile Control the parameters of the erasure code plugin:: @@ -127,11 +127,11 @@ Remove a profile that is no longer in use (otherwise it will fail with EBUSY):: Set the ruleset to take ssd (instead of default):: $ ceph osd erasure-code-profile set myprofile \ - ruleset-root=ssd + crush-root=ssd $ ceph osd erasure-code-profile get myprofile k=2 m=1 plugin=jerasure technique=reed_sol_van - ruleset-root=ssd + crush-root=ssd diff --git a/ceph/doc/dev/index.rst b/ceph/doc/dev/index.rst index abefa34a2..8a91a094e 100644 --- a/ceph/doc/dev/index.rst +++ b/ceph/doc/dev/index.rst @@ -589,9 +589,9 @@ When your PR hits GitHub, the Ceph project's `Continuous Integration (CI) infrastructure will test it automatically. At the time of this writing (March 2016), the automated CI testing included a test to check that the commits in the PR are properly signed (see `Submitting patches`_) and a -``make check`` test. +`make check`_ test. -The latter, ``make check``, builds the PR and runs it through a battery of +The latter, `make check`_, builds the PR and runs it through a battery of tests. These tests run on machines operated by the Ceph Continuous Integration (CI) team. When the tests complete, the result will be shown on GitHub in the pull request itself. @@ -599,6 +599,29 @@ on GitHub in the pull request itself. You can (and should) also test your modifications before you open a PR. Refer to the `Testing`_ chapter for details. +Notes on PR make check test +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The GitHub `make check`_ test is driven by a Jenkins instance. + +Jenkins merges the PR branch into the latest version of the base branch before +starting the build, so you don't have to rebase the PR to pick up any fixes. + +You can trigger the PR tests at any time by adding a comment to the PR - the +comment should contain the string "test this please". Since a human subscribed +to the PR might interpret that as a request for him or her to test the PR, it's +good to write the request as "Jenkins, test this please". + +The `make check`_ log is the place to go if there is a failure and you're not +sure what caused it. To reach it, first click on "details" (next to the `make +check`_ test in the PR) to get into the Jenkins web GUI, and then click on +"Console Output" (on the left). + +Jenkins is set up to grep the log for strings known to have been associated +with `make check`_ failures in the past. However, there is no guarantee that +the strings are associated with any given `make check`_ failure. You have to +dig into the log to be sure. + Integration tests AKA ceph-qa-suite ----------------------------------- @@ -669,26 +692,28 @@ flagged for backporting, in which case the status should be changed to Testing ======= -Ceph has two types of tests: "make check" tests and integration tests. +Ceph has two types of tests: `make check`_ tests and integration tests. The former are run via `GNU Make `, and the latter are run via the `teuthology framework`_. The following two -chapters examine the "make check" and integration tests in detail. +chapters examine the `make check`_ and integration tests in detail. + +.. _`make check`: Testing - make check ==================== -After compiling Ceph, the ``make check`` command can be used to run the +After compiling Ceph, the `make check`_ command can be used to run the code through a battery of tests covering various aspects of Ceph. For -inclusion in "make check", a test must: +inclusion in `make check`_, a test must: * bind ports that do not conflict with other tests * not require root access * not require more than one machine to run * complete within a few minutes -While it is possible to run ``make check`` directly, it can be tricky to +While it is possible to run `make check`_ directly, it can be tricky to correctly set up your environment. Fortunately, a script is provided to -make it easier run "make check" on your code. It can be run from the +make it easier run `make check`_ on your code. It can be run from the top-level directory of the Ceph source tree by doing:: $ ./run-make-check.sh @@ -698,15 +723,13 @@ command to complete successfully on x86_64 (other architectures may have different constraints). Depending on your hardware, it can take from 20 minutes to three hours to complete, but it's worth the wait. -Future sections ---------------- +Caveats +------- -* Principles of make check tests -* Where to find test results -* How to interpret test results -* Find the corresponding source code -* Writing make check tests -* Make check caveats +1. Unlike the various Ceph daemons and ``ceph-fuse``, the `make check`_ tests + are linked against the default memory allocator (glibc) unless explicitly + linked against something else. This enables tools like valgrind to be used + in the tests. Testing - integration tests =========================== @@ -1149,7 +1172,7 @@ reduce the number of tests that are triggered. For instance:: teuthology-suite --suite rados --subset 0/4000 will run as few tests as possible. The tradeoff in this case is that -some tests will only run on ``xfs`` and not on ``ext4`` or ``btrfs``, +not all combinations of test variations will together, but no matter how small a ratio is provided in the ``--subset``, teuthology will still ensure that all files in the suite are in at least one test. Understanding the actual logic that drives this @@ -1203,7 +1226,7 @@ Since testing in the cloud is done using the `ceph-workbench ceph-qa-suite`_ tool, you will need to install that first. It is designed to be installed via Docker, so if you don't have Docker running on your development machine, take care of that first. You can follow `the official -tutorial`_ to install if +tutorial `_ to install if you have not installed yet. Once Docker is up and running, install ``ceph-workbench`` by following the @@ -1433,7 +1456,7 @@ The following instructions should work on jewel and above. Step 1 - build Ceph ------------------- -Refer to :doc:`install/build-ceph`. +Refer to :doc:`/install/build-ceph`. You can do step 2 separately while it is building. diff --git a/ceph/doc/dev/object-store.rst b/ceph/doc/dev/object-store.rst index 8e00d1970..355f51548 100644 --- a/ceph/doc/dev/object-store.rst +++ b/ceph/doc/dev/object-store.rst @@ -57,6 +57,9 @@ "PrimaryLogPG" -> "OSDMap" "ObjectStore" -> "FileStore" + "ObjectStore" -> "BlueStore" + + "BlueStore" -> "rocksdb" "FileStore" -> "xfs" "FileStore" -> "btrfs" diff --git a/ceph/doc/dev/osd_internals/erasure_coding/developer_notes.rst b/ceph/doc/dev/osd_internals/erasure_coding/developer_notes.rst index a9ef9b55c..770ff4a74 100644 --- a/ceph/doc/dev/osd_internals/erasure_coding/developer_notes.rst +++ b/ceph/doc/dev/osd_internals/erasure_coding/developer_notes.rst @@ -166,14 +166,14 @@ key=value pairs stored in an `erasure code profile`_. :: $ ceph osd erasure-code-profile set myprofile \ - ruleset-failure-domain=osd + crush-failure-domain=osd $ ceph osd erasure-code-profile get myprofile directory=/usr/lib/ceph/erasure-code k=2 m=1 plugin=jerasure technique=reed_sol_van - ruleset-failure-domain=osd + crush-failure-domain=osd $ ceph osd pool create ecpool 12 12 erasure myprofile The *plugin* is dynamically loaded from *directory* and expected to diff --git a/ceph/doc/dev/osd_internals/osd_throttles.rst b/ceph/doc/dev/osd_internals/osd_throttles.rst index e1142b3f7..6739bd9ea 100644 --- a/ceph/doc/dev/osd_internals/osd_throttles.rst +++ b/ceph/doc/dev/osd_internals/osd_throttles.rst @@ -17,7 +17,7 @@ flushing and block in FileStore::_do_op if we have exceeded any hard limits until the background flusher catches up. The relevant config options are filestore_wbthrottle*. There are -different defaults for btrfs and xfs. Each set has hard and soft +different defaults for xfs and btrfs. Each set has hard and soft limits on bytes (total dirty bytes), ios (total dirty ios), and inodes (total dirty fds). The WBThrottle will begin flushing when any of these hits the soft limit and will block in throttle() diff --git a/ceph/doc/dev/perf_histograms.rst b/ceph/doc/dev/perf_histograms.rst index a1f49644e..c277ac209 100644 --- a/ceph/doc/dev/perf_histograms.rst +++ b/ceph/doc/dev/perf_histograms.rst @@ -47,35 +47,35 @@ In other words, histogram of type "18" is a histogram of unsigned 64-bit integer Here is an example of the schema output:: -{ - "AsyncMessenger::Worker-0": {}, - "AsyncMessenger::Worker-1": {}, - "AsyncMessenger::Worker-2": {}, - "mutex-WBThrottle::lock": {}, - "objecter": {}, - "osd": { - "op_r_latency_out_bytes_histogram": { - "type": 18, - "description": "Histogram of operation latency (including queue time) + data read", - "nick": "" - }, - "op_w_latency_in_bytes_histogram": { - "type": 18, - "description": "Histogram of operation latency (including queue time) + data written", - "nick": "" - }, - "op_rw_latency_in_bytes_histogram": { - "type": 18, - "description": "Histogram of rw operation latency (including queue time) + data written", - "nick": "" - }, - "op_rw_latency_out_bytes_histogram": { - "type": 18, - "description": "Histogram of rw operation latency (including queue time) + data read", - "nick": "" + { + "AsyncMessenger::Worker-0": {}, + "AsyncMessenger::Worker-1": {}, + "AsyncMessenger::Worker-2": {}, + "mutex-WBThrottle::lock": {}, + "objecter": {}, + "osd": { + "op_r_latency_out_bytes_histogram": { + "type": 18, + "description": "Histogram of operation latency (including queue time) + da ta read", + "nick": "" + }, + "op_w_latency_in_bytes_histogram": { + "type": 18, + "description": "Histogram of operation latency (including queue time) + da ta written", + "nick": "" + }, + "op_rw_latency_in_bytes_histogram": { + "type": 18, + "description": "Histogram of rw operation latency (including queue time) + data written", + "nick": "" + }, + "op_rw_latency_out_bytes_histogram": { + "type": 18, + "description": "Histogram of rw operation latency (including queue time) + data read", + "nick": "" + } } } -} Dump diff --git a/ceph/doc/index.rst b/ceph/doc/index.rst index 4fe3eada8..d070c4726 100644 --- a/ceph/doc/index.rst +++ b/ceph/doc/index.rst @@ -19,7 +19,7 @@ system**. - Striped objects - Cloud solution integration - Multi-site deployment -- Disaster recovery +- Multi-site replication .. raw:: html @@ -36,7 +36,7 @@ system**. - KVM/libvirt support - Back-end for cloud solutions - Incremental backup -- Disaster recovery +- Disaster recovery (multisite asynchronous replication) .. raw:: html @@ -46,7 +46,7 @@ system**. - Separates metadata from data - Dynamic rebalancing - Subdirectory snapshots -- Configurable striping +- Configurable striping - Kernel driver support - FUSE support - NFS/CIFS deployable diff --git a/ceph/doc/install/manual-deployment.rst b/ceph/doc/install/manual-deployment.rst index e60c6beab..a7f628caa 100644 --- a/ceph/doc/install/manual-deployment.rst +++ b/ceph/doc/install/manual-deployment.rst @@ -295,7 +295,7 @@ Manager daemon configuration On each node where you run a ceph-mon daemon, you should also set up a ceph-mgr daemon. -See `../mgr/administrator`_ +See :doc:`../mgr/administrator` Adding OSDs =========== @@ -323,7 +323,7 @@ on ``node2`` and ``node3``: #. Prepare the OSD. :: ssh {node-name} - sudo ceph-disk prepare --cluster {cluster-name} --cluster-uuid {uuid} --fs-type {ext4|xfs|btrfs} {data-path} [{journal-path}] + sudo ceph-disk prepare --cluster {cluster-name} --cluster-uuid {uuid} {data-path} [{journal-path}] For example:: diff --git a/ceph/doc/install/manual-freebsd-deployment.rst b/ceph/doc/install/manual-freebsd-deployment.rst index 5be1651e3..007c558fc 100644 --- a/ceph/doc/install/manual-freebsd-deployment.rst +++ b/ceph/doc/install/manual-freebsd-deployment.rst @@ -380,11 +380,10 @@ create the first two OSDs with the short form procedure, execute the following on ``node2`` and ``node3``: -#. Prepare the OSD. :: +#. Prepare the OSD. On FreeBSD only existing directories can be use to create OSDs in:: - ssh {node-name} sudo ceph-disk prepare --cluster {cluster-name} --cluster-uuid {uuid} {path-to-ceph-osd-directory} @@ -526,9 +525,9 @@ OSDs with the long form procedure, execute the following on ``node2`` and Once you start your OSD, it is ``up`` and ``in``. - For FreeBSD using rc.d init:: + For FreeBSD using rc.d init. - After adding the OSD to ``ceph.conf`` + After adding the OSD to ``ceph.conf``:: sudo service ceph start osd.{osd-num} diff --git a/ceph/doc/man/8/ceph-create-keys.rst b/ceph/doc/man/8/ceph-create-keys.rst index 8d1dc915a..0827a0a62 100644 --- a/ceph/doc/man/8/ceph-create-keys.rst +++ b/ceph/doc/man/8/ceph-create-keys.rst @@ -9,7 +9,7 @@ ceph-create-keys -- ceph keyring generate tool Synopsis ======== -| **ceph-create-keys** [-h] [-v] [--cluster *name*] --id *id* +| **ceph-create-keys** [-h] [-v] [-t seconds] [--cluster *name*] --id *id* Description @@ -40,6 +40,10 @@ Options name of the cluster (default 'ceph'). +.. option:: -t + + time out after **seconds** (default: 600) waiting for a response from the monitor + .. option:: -i, --id id of a ceph-mon that is coming up. **ceph-create-keys** will wait until it joins quorum. diff --git a/ceph/doc/man/8/ceph-deploy.rst b/ceph/doc/man/8/ceph-deploy.rst index 3f197504e..ff96574df 100644 --- a/ceph/doc/man/8/ceph-deploy.rst +++ b/ceph/doc/man/8/ceph-deploy.rst @@ -522,7 +522,7 @@ Options .. option:: --fs-type - Filesystem to use to format disk ``(xfs, btrfs or ext4)``. + Filesystem to use to format disk ``(xfs, btrfs or ext4)``. Note that support for btrfs and ext4 is no longer tested or recommended; please use xfs. .. option:: --fsid diff --git a/ceph/doc/man/8/ceph-osd.rst b/ceph/doc/man/8/ceph-osd.rst index 3b89740fc..388e339d9 100644 --- a/ceph/doc/man/8/ceph-osd.rst +++ b/ceph/doc/man/8/ceph-osd.rst @@ -20,7 +20,7 @@ Description system. It is responsible for storing objects on a local file system and providing access to them over the network. -The datapath argument should be a directory on a btrfs file system +The datapath argument should be a directory on a xfs file system where the object data resides. The journal is optional, and is only useful performance-wise when it resides on a different disk than datapath with low latency (ideally, an NVRAM device). diff --git a/ceph/doc/man/8/rados.rst b/ceph/doc/man/8/rados.rst index 90668706c..bc0322bb6 100644 --- a/ceph/doc/man/8/rados.rst +++ b/ceph/doc/man/8/rados.rst @@ -94,8 +94,8 @@ Pool specific commands :command:`get` *name* *outfile* Read object name from the cluster and write it to outfile. -:command:`put` *name* *infile* - Write object name to the cluster with contents from infile. +:command:`put` *name* *infile* [--offset offset] + Write object name with start offset (default:0) to the cluster with contents from infile. :command:`append` *name* *infile* Append object name to the cluster with contents from infile. diff --git a/ceph/doc/mgr/administrator.rst b/ceph/doc/mgr/administrator.rst index e636c80ed..d78a30a4d 100644 --- a/ceph/doc/mgr/administrator.rst +++ b/ceph/doc/mgr/administrator.rst @@ -27,11 +27,12 @@ of ``ceph status``, which should now include a mgr status line:: Client authentication --------------------- + The manager is a new daemon which requires new CephX capabilities. If you upgrade a cluster from an old version of Ceph, or use the default install/deploy tools, your admin client should get this capability automatically. If you use tooling from elsewhere, you may get EACCES errors when invoking certain ceph cluster commands. -To fix that, add a "mgr allow *" stanza to your client's cephx capabilities by +To fix that, add a "mgr allow \*" stanza to your client's cephx capabilities by `Modifying User Capabilities`_. High availability @@ -76,12 +77,6 @@ OPTION(mgr_module_path, OPT_STR, CEPH_PKGLIBDIR "/mgr") // where to load python :Type: String :Default: ``"/mgr"`` -``mgr modules`` - -:Description: List of python modules to load -:Type: String -:Default: ``"rest"`` (Load the REST API module only) - ``mgr data`` :Description: Path to load daemon data (such as keyring) @@ -101,4 +96,4 @@ OPTION(mgr_module_path, OPT_STR, CEPH_PKGLIBDIR "/mgr") // where to load python :Type: Integer :Default: ``30`` -.. _Modifying User Capabilities: ../rados/operations/user-management#modify-user-capabilities +.. _Modifying User Capabilities: ../../rados/operations/user-management/#modify-user-capabilities diff --git a/ceph/doc/mgr/dashboard.rst b/ceph/doc/mgr/dashboard.rst index 7f837f26d..ac1b961f7 100644 --- a/ceph/doc/mgr/dashboard.rst +++ b/ceph/doc/mgr/dashboard.rst @@ -2,14 +2,50 @@ dashboard plugin ================ Dashboard plugin visualizes the statistics of the cluster using a web server -hosted by ``ceph-mgr``. Like most web applications, dashboard binds to a host -name and port. Since each ``ceph-mgr`` hosts its own instance of dashboard, we -need to configure them separately. The hostname and port are stored using the -configuration key facility. So we can configure them like:: +hosted by ``ceph-mgr``. + +Enabling +-------- + +The *dashboard* module is enabled with:: + + ceph mgr module enable dashboard + +Configuration +------------- + +Like most web applications, dashboard binds to a host name and port. +By default, the ``ceph-mgr`` daemon hosting the dashboard (i.e., the +currently active manager) will bind to port 7000 and any available +IPv4 or IPv6 address on the host. + +Since each ``ceph-mgr`` hosts its own instance of dashboard, it may +also be necessary to configure them separately. The hostname and port +can be changed via the configuration key facility:: ceph config-key put mgr/dashboard/$name/server_addr $IP ceph config-key put mgr/dashboard/$name/server_port $PORT -where ``$name`` is the ID of the ceph-mgr who is hosting this dashboard web app. -If they are not configured, the web app will be bound to ``127.0.0.1:7000``. +where ``$name`` is the ID of the ceph-mgr who is hosting this +dashboard web app. + +These settings can also be configured cluster-wide and not manager +specific. For example,:: + + ceph config-key put mgr/dashboard/server_addr $IP + ceph config-key put mgr/dashboard/server_port $PORT + +If the port is not configured, the web app will bind to port ``7000``. +If the address it not configured, the web app will bind to ``::``, +which corresponds to all available IPv4 and IPv6 addresses. + +Load balancer +------------- +Please note that the dashboard will *only* start on the manager which +is active at that moment. Query the Ceph cluster status to see which +manager is active (e.g., ``ceph mgr dump``). In order to make the +dashboard available via a consistent URL regardless of which manager +daemon is currently active, you may want to set up a load balancer +front-end to direct traffic to whichever manager endpoint is +available. diff --git a/ceph/doc/mgr/index.rst b/ceph/doc/mgr/index.rst index 38bdec153..28280d062 100644 --- a/ceph/doc/mgr/index.rst +++ b/ceph/doc/mgr/index.rst @@ -28,5 +28,6 @@ sensible. Installation and Configuration Dashboard RESTful + Zabbix Writing plugins diff --git a/ceph/doc/mgr/plugins.rst b/ceph/doc/mgr/plugins.rst index 89f74469b..b5a13cc3e 100644 --- a/ceph/doc/mgr/plugins.rst +++ b/ceph/doc/mgr/plugins.rst @@ -21,13 +21,10 @@ Installing a plugin ------------------- Once your module is present in the location set by the -``mgr module path`` configuration setting, add its name -to the ``mgr modules`` configuration setting and restart the ceph-mgr -daemon to load it. +``mgr module path`` configuration setting, you can enable it +via the ``ceph mgr module enable`` command:: -If you're working within a Ceph vstart cluster then your module -should be found in the default pybind/mgr location, and you only -have to add it to ``mgr modules`` to get it loaded. + ceph mgr module enable mymodule Note that the MgrModule interface is not stable, so any modules maintained outside of the Ceph tree are liable to break when run against any newer diff --git a/ceph/doc/mgr/restful.rst b/ceph/doc/mgr/restful.rst index 846c98840..4dc33d723 100644 --- a/ceph/doc/mgr/restful.rst +++ b/ceph/doc/mgr/restful.rst @@ -1,25 +1,89 @@ restful plugin ============== -RESTful plugin offers the REST API access to the status of the cluster. RESTful -plugin enables you to secure the API endpoints via SSL. If you don't have a -security certificate and key already, you need to create them first:: +RESTful plugin offers the REST API access to the status of the cluster +over an SSL-secured connection. + +Enabling +-------- + +The *restful* module is enabled with:: + + ceph mgr module enable restful + +You will also need to configure an SSL certificate below before the +API endpoint is available. By default the module will accept HTTPS +requests on port ``8003`` on all IPv4 and IPv6 addresses on the host. + +Securing +-------- + +All connections to *restful* are secured with SSL. You can generate a +self-signed certificate with the command:: + + ceph restful create-self-signed-cert + +Note that with a self-signed certificate most clients will need a flag +to allow a connection and/or suppress warning messages. For example, +if the ``ceph-mgr`` daemon is on the same host,:: + + curl -k https://localhost:8003/ + +To properly secure a deployment, a certificate that is signed by the +organization's certificate authority should be used. For example, a key pair +can be generated with a command similar to:: openssl req -new -nodes -x509 \ -subj "/O=IT/CN=ceph-mgr-restful" \ - -days 3650 -keyout $PKEY -out $CERT -extensions v3_ca + -days 3650 -keyout restful.key -out restful.crt -extensions v3_ca -where ``$PKEY`` and ``$CERT`` are the paths to the private key and the -certificate. And then you need to import the keystore to the cluster using the -configuration key facility, so RESTful plugin can read them at startup:: +The ``restful.crt`` should then be signed by your organization's CA +(certificate authority). Once that is done, you can set it with:: - ceph config-key put mgr/restful/$name/crt -i $CERT - ceph config-key put mgr/restful/$name/key -i $PKEY + ceph config-key put mgr/restful/$name/crt -i restful.crt + ceph config-key put mgr/restful/$name/key -i restful.key -Also, like other web applications, RESTful plugin is bound to the a hostname and -a port:: +where ``$name`` is the name of the ``ceph-mgr`` instance (usually the +hostname). If all manager instances are to share the same certificate, +you can leave off the ``$name`` portion:: + + ceph config-key put mgr/restful/crt -i restful.crt + ceph config-key put mgr/restful/key -i restful.key + + +Configuring IP and port +----------------------- + +Like any other RESTful API endpoint, *restful* binds to an IP and +port. By default, the currently active ``ceph-mgr`` daemon will bind +to port 8003 and any available IPv4 or IPv6 address on the host. + +Since each ``ceph-mgr`` hosts its own instance of *restful*, it may +also be necessary to configure them separately. The IP and port +can be changed via the configuration key facility:: ceph config-key put mgr/restful/$name/server_addr $IP ceph config-key put mgr/restful/$name/server_port $PORT -If not specified, the plugin uses ``127.0.0.1:8003`` by default. +where ``$name`` is the ID of the ceph-mgr daemon (usually the hostname). + +These settings can also be configured cluster-wide and not manager +specific. For example,:: + + ceph config-key put mgr/restful/server_addr $IP + ceph config-key put mgr/restful/server_port $PORT + +If the port is not configured, *restful* will bind to port ``8003``. +If the address it not configured, the *restful* will bind to ``::``, +which corresponds to all available IPv4 and IPv6 addresses. + +Load balancer +------------- + +Please note that *restful* will *only* start on the manager which +is active at that moment. Query the Ceph cluster status to see which +manager is active (e.g., ``ceph mgr dump``). In order to make the +API available via a consistent URL regardless of which manager +daemon is currently active, you may want to set up a load balancer +front-end to direct traffic to whichever manager endpoint is +available. diff --git a/ceph/doc/mgr/zabbix.rst b/ceph/doc/mgr/zabbix.rst new file mode 100644 index 000000000..03abdd6ef --- /dev/null +++ b/ceph/doc/mgr/zabbix.rst @@ -0,0 +1,104 @@ +Zabbix plugin +============= + +The Zabbix plugin actively sends information to a Zabbix server like: + +- Ceph status +- I/O operations +- I/O bandwidth +- OSD status +- Storage utilization + +Requirements +============ + +The plugin requires that the *zabbix_sender* executable is present on *all* +machines running ceph-mgr. It can be installed on most distributions using +the package manager. + +Dependencies +------------ +Installing zabbix_sender can be done under Ubuntu or CentOS using either apt +or dnf. + +On Ubuntu Xenial: + +:: + + apt install zabbix-agent + +On Fedora: + +:: + + dnf install zabbix-sender + + +Enabling +======== + +Add this to your ceph.conf on nodes where you run ceph-mgr: + +:: + + [mgr] + mgr modules = zabbix + +If you use any other ceph-mgr modules, make sure they're in the list too. + +Restart the ceph-mgr daemon after modifying the setting to load the module. + + +Configuration +============= + +Two configuration keys are mandatory for the module to work: + +- mgr/zabbix/zabbix_host +- mgr/zabbix/identifier + +The parameter *zabbix_host* controls the hostname of the Zabbix server to which +*zabbix_sender* will send the items. This can be a IP-Address if required by +your installation. + +The *identifier* parameter controls the identifier/hostname to use as source +when sending items to Zabbix. This should match the name of the *Host* in +your Zabbix server. + +Additional configuration keys which can be configured and their default values: + +- mgr/zabbix/zabbix_port: 10051 +- mgr/zabbix/zabbix_sender: /usr/bin/zabbix_sender +- mgr/zabbix/interval: 60 + +Configurations keys +------------------- + +Configuration keys can be set on any machine with the proper cephx credentials, +these are usually Monitors where the *client.admin* key is present. + +:: + + ceph config-key put + +For example: + +:: + + ceph config-key put mgr/zabbix/zabbix_host zabbix.localdomain + ceph config-key put mgr/zabbix/identifier ceph.eu-ams02.local + +Debugging +========= + +Should you want to debug the Zabbix module increase the logging level for +ceph-mgr and check the logs. + +:: + + [mgr] + debug mgr = 20 + +With logging set to debug for the manager the plugin will print various logging +lines prefixed with *mgr[zabbix]* for easy filtering. + diff --git a/ceph/doc/rados/configuration/ceph-conf.rst b/ceph/doc/rados/configuration/ceph-conf.rst index a56eee880..c5cf27cb7 100644 --- a/ceph/doc/rados/configuration/ceph-conf.rst +++ b/ceph/doc/rados/configuration/ceph-conf.rst @@ -383,8 +383,9 @@ use with Ceph, and mount it to the directory you just created:: sudo mkfs -t {fstype} /dev/{disk} sudo mount -o user_xattr /dev/{hdd} /var/lib/ceph/osd/ceph-{osd-number} -We recommend using the ``xfs`` file system or the ``btrfs`` file system when -running :command:`mkfs`. +We recommend using the ``xfs`` file system when running +:command:`mkfs`. (``btrfs`` and ``ext4`` are not recommended and no +longer tested.) See the `OSD Config Reference`_ for additional configuration details. diff --git a/ceph/doc/rados/configuration/filestore-config-ref.rst b/ceph/doc/rados/configuration/filestore-config-ref.rst index 6b351f0bf..4dff60c1e 100644 --- a/ceph/doc/rados/configuration/filestore-config-ref.rst +++ b/ceph/doc/rados/configuration/filestore-config-ref.rst @@ -302,7 +302,7 @@ Misc ``filestore split multiple`` -:Description: ``filestore_split_multiple * abs(filestore_merge_threshold) * 16`` +:Description: ``(filestore_split_multiple * abs(filestore_merge_threshold) + (rand() % filestore_split_rand_factor)) * 16`` is the maximum number of files in a subdirectory before splitting into child directories. @@ -311,6 +311,19 @@ Misc :Default: ``2`` +``filestore split rand factor`` + +:Description: A random factor added to the split threshold to avoid + too many filestore splits occurring at once. See + ``filestore split multiple`` for details. + This can only be changed for an existing osd offline, + via ceph-objectstore-tool's apply-layout-settings command. + +:Type: Unsigned 32-bit Integer +:Required: No +:Default: ``20`` + + ``filestore update to`` :Description: Limits filestore auto upgrade to specified version. diff --git a/ceph/doc/rados/configuration/filesystem-recommendations.rst b/ceph/doc/rados/configuration/filesystem-recommendations.rst index 6225dd379..c967d60ce 100644 --- a/ceph/doc/rados/configuration/filesystem-recommendations.rst +++ b/ceph/doc/rados/configuration/filesystem-recommendations.rst @@ -34,16 +34,12 @@ Recommended We currently recommend ``XFS`` for production deployments. -We used to recommend ``btrfs`` for testing, development, and any non-critical -deployments becuase it has the most promising set of features. However, we -now plan to avoid using a kernel file system entirely with the new BlueStore -backend. ``btrfs`` is still supported and has a comparatively compelling -set of features, but be mindful of its stability and support status in your -Linux distribution. - Not recommended --------------- +We recommand *against* using ``btrfs`` due to the lack of a stable +version to test against and frequent bugs in the ENOSPC handling. + We recommend *against* using ``ext4`` due to limitations in the size of xattrs it can store, and the problems this causes with the way Ceph handles long RADOS object names. Although these issues will generally @@ -64,36 +60,3 @@ following configuration option:: to use RGW or other librados clients that do not properly handle or politely surface any resulting ENAMETOOLONG errors. - - -Filesystem Background Info -========================== - -The ``XFS``, ``btrfs`` and ``ext4`` file systems provide numerous -advantages in highly scaled data storage environments when `compared`_ -to ``ext3``. - -``XFS``, ``btrfs`` and ``ext4`` are `journaling file systems`_, which means that -they are more robust when recovering from crashes, power outages, etc. These -filesystems journal all of the changes they will make before performing writes. - -``XFS`` was developed for Silicon Graphics, and is a mature and stable -filesystem. By contrast, ``btrfs`` is a relatively new file system that aims -to address the long-standing wishes of system administrators working with -large scale data storage environments. ``btrfs`` has some unique features -and advantages compared to other Linux filesystems. - -``btrfs`` is a `copy-on-write`_ filesystem. It supports file creation -timestamps and checksums that verify metadata integrity, so it can detect -bad copies of data and fix them with the good copies. The copy-on-write -capability means that ``btrfs`` can support snapshots that are writable. -``btrfs`` supports transparent compression and other features. - -``btrfs`` also incorporates multi-device management into the file system, -which enables you to support heterogeneous disk storage infrastructure, -data allocation policies. The community also aims to provide ``fsck``, -deduplication, and data encryption support in the future. - -.. _copy-on-write: http://en.wikipedia.org/wiki/Copy-on-write -.. _compared: http://en.wikipedia.org/wiki/Comparison_of_file_systems -.. _journaling file systems: http://en.wikipedia.org/wiki/Journaling_file_system diff --git a/ceph/doc/rados/configuration/mon-lookup-dns.rst b/ceph/doc/rados/configuration/mon-lookup-dns.rst index 9aa1d3739..e32b3206a 100644 --- a/ceph/doc/rados/configuration/mon-lookup-dns.rst +++ b/ceph/doc/rados/configuration/mon-lookup-dns.rst @@ -46,8 +46,6 @@ With those records now existing we can create the SRV TCP records with the name _ceph-mon._tcp.example.com. 60 IN SRV 10 60 6789 mon2.example.com. _ceph-mon._tcp.example.com. 60 IN SRV 10 60 6789 mon3.example.com. -In this case the Monitors are running on port *6789*. +In this case the Monitors are running on port *6789*, and their priority and weight are all *10* and *60* respectively. -The current implementation in clients and daemons does *not* honor nor respect the weight or priority set in SRV records. - -All records returned will be treated equally in a Round Robin fashion. +The current implementation in clients and daemons will *only* respect the priority set in SRV records, and they will only connect to the monitors with lowest-numbered priority. The targets with the same priority will be selected at random. diff --git a/ceph/doc/rados/configuration/mon-osd-interaction.rst b/ceph/doc/rados/configuration/mon-osd-interaction.rst index ab57cb069..e335ff070 100644 --- a/ceph/doc/rados/configuration/mon-osd-interaction.rst +++ b/ceph/doc/rados/configuration/mon-osd-interaction.rst @@ -246,6 +246,7 @@ Monitor Settings ``mon osd laggy max interval`` + :Description: Maximum value of ``laggy_interval`` in laggy estimations (in seconds). Monitor uses an adaptive approach to evaluate the ``laggy_interval`` of a certain OSD. This value will be used to calculate the grace time for diff --git a/ceph/doc/rados/configuration/network-config-ref.rst b/ceph/doc/rados/configuration/network-config-ref.rst index 910637afe..693520625 100644 --- a/ceph/doc/rados/configuration/network-config-ref.rst +++ b/ceph/doc/rados/configuration/network-config-ref.rst @@ -375,6 +375,20 @@ addresses. :Default: ``false`` :Required: No +``public bind addr`` + +:Description: In some dynamic deployments the Ceph MON daemon might bind + to an IP address locally that is different from the ``public addr`` + advertised to other peers in the network. The environment must ensure + that routing rules are set correclty. If ``public bind addr`` is set + the Ceph MON daemon will bind to it locally and use ``public addr`` + in the monmaps to advertise its address to peers. This behavior is limited + to the MON daemon. + +:Type: IP Address +:Required: No +:Default: N/A + Hosts @@ -383,7 +397,9 @@ Hosts Ceph expects at least one monitor declared in the Ceph configuration file, with a ``mon addr`` setting under each declared monitor. Ceph expects a ``host`` setting under each declared monitor, metadata server and OSD in the Ceph -configuration file. +configuration file. Optionally, a monitor can be assigned with a priority, and +the clients will always connect to the monitor with lower value of priority if +specified. ``mon addr`` @@ -396,6 +412,15 @@ configuration file. :Required: No :Default: N/A +``mon priority`` + +:Description: The priority of the declared monitor, the lower value the more + prefered when a client selects a monitor when trying to connect + to the cluster. + +:Type: Unsigned 16-bit Integer +:Required: No +:Default: 0 ``host`` diff --git a/ceph/doc/rados/configuration/osd-config-ref.rst b/ceph/doc/rados/configuration/osd-config-ref.rst index 801363930..c1e8b047d 100644 --- a/ceph/doc/rados/configuration/osd-config-ref.rst +++ b/ceph/doc/rados/configuration/osd-config-ref.rst @@ -785,13 +785,6 @@ Miscellaneous :Default: ``false`` -``osd preserve trimmed log`` - -:Description: Preserves trimmed log files, but uses more disk space. -:Type: Boolean -:Default: ``false`` - - ``osd fast fail on connection refused`` :Description: If this option is enabled, crashed OSDs are marked down diff --git a/ceph/doc/rados/operations/erasure-code-isa.rst b/ceph/doc/rados/operations/erasure-code-isa.rst index 9d4ff7f52..b52933ae8 100644 --- a/ceph/doc/rados/operations/erasure-code-isa.rst +++ b/ceph/doc/rados/operations/erasure-code-isa.rst @@ -16,8 +16,9 @@ To create a new *isa* erasure code profile:: technique={reed_sol_van|cauchy} \ [k={data-chunks}] \ [m={coding-chunks}] \ - [ruleset-root={root}] \ - [ruleset-failure-domain={bucket-type}] \ + [crush-root={root}] \ + [crush-failure-domain={bucket-type}] \ + [crush-device-class={device-class}] \ [directory={directory}] \ [--force] @@ -55,7 +56,7 @@ Where: :Required: No. :Default: reed_sol_van -``ruleset-root={root}`` +``crush-root={root}`` :Description: The name of the crush bucket used for the first step of the ruleset. For intance **step take default**. @@ -64,7 +65,7 @@ Where: :Required: No. :Default: default -``ruleset-failure-domain={bucket-type}`` +``crush-failure-domain={bucket-type}`` :Description: Ensure that no two chunks are in a bucket with the same failure domain. For instance, if the failure domain is @@ -76,6 +77,16 @@ Where: :Required: No. :Default: host +``crush-device-class={device-class}`` + +:Description: Restrict placement to devices of a specific class (e.g., + ``ssd`` or ``hdd``), using the crush device class names + in the CRUSH map. + +:Type: String +:Required: No. +:Default: + ``directory={directory}`` :Description: Set the **directory** name from which the erasure code diff --git a/ceph/doc/rados/operations/erasure-code-jerasure.rst b/ceph/doc/rados/operations/erasure-code-jerasure.rst index b0e6020cd..e8da097c2 100644 --- a/ceph/doc/rados/operations/erasure-code-jerasure.rst +++ b/ceph/doc/rados/operations/erasure-code-jerasure.rst @@ -20,8 +20,9 @@ To create a new *jerasure* erasure code profile:: k={data-chunks} \ m={coding-chunks} \ technique={reed_sol_van|reed_sol_r6_op|cauchy_orig|cauchy_good|liberation|blaum_roth|liber8tion} \ - [ruleset-root={root}] \ - [ruleset-failure-domain={bucket-type}] \ + [crush-root={root}] \ + [crush-failure-domain={bucket-type}] \ + [crush-device-class={device-class}] \ [directory={directory}] \ [--force] @@ -70,7 +71,7 @@ Where: :Required: No. :Default: 2048 -``ruleset-root={root}`` +``crush-root={root}`` :Description: The name of the crush bucket used for the first step of the ruleset. For intance **step take default**. @@ -79,7 +80,7 @@ Where: :Required: No. :Default: default -``ruleset-failure-domain={bucket-type}`` +``crush-failure-domain={bucket-type}`` :Description: Ensure that no two chunks are in a bucket with the same failure domain. For instance, if the failure domain is @@ -91,7 +92,17 @@ Where: :Required: No. :Default: host -``directory={directory}`` +``crush-device-class={device-class}`` + +:Description: Restrict placement to devices of a specific class (e.g., + ``ssd`` or ``hdd``), using the crush device class names + in the CRUSH map. + +:Type: String +:Required: No. +:Default: + + ``directory={directory}`` :Description: Set the **directory** name from which the erasure code plugin is loaded. diff --git a/ceph/doc/rados/operations/erasure-code-lrc.rst b/ceph/doc/rados/operations/erasure-code-lrc.rst index 3c9b26918..447ce23ab 100644 --- a/ceph/doc/rados/operations/erasure-code-lrc.rst +++ b/ceph/doc/rados/operations/erasure-code-lrc.rst @@ -27,7 +27,7 @@ observed.:: $ ceph osd erasure-code-profile set LRCprofile \ plugin=lrc \ k=4 m=2 l=3 \ - ruleset-failure-domain=host + crush-failure-domain=host $ ceph osd pool create lrcpool 12 12 erasure LRCprofile @@ -40,8 +40,8 @@ OSD is in the same rack as the lost chunk.:: $ ceph osd erasure-code-profile set LRCprofile \ plugin=lrc \ k=4 m=2 l=3 \ - ruleset-locality=rack \ - ruleset-failure-domain=host + crush-locality=rack \ + crush-failure-domain=host $ ceph osd pool create lrcpool 12 12 erasure LRCprofile @@ -55,9 +55,10 @@ To create a new lrc erasure code profile:: k={data-chunks} \ m={coding-chunks} \ l={locality} \ - [ruleset-root={root}] \ - [ruleset-locality={bucket-type}] \ - [ruleset-failure-domain={bucket-type}] \ + [crush-root={root}] \ + [crush-locality={bucket-type}] \ + [crush-failure-domain={bucket-type}] \ + [crush-device-class={device-class}] \ [directory={directory}] \ [--force] @@ -94,7 +95,7 @@ Where: :Required: Yes. :Example: 3 -``ruleset-root={root}`` +``crush-root={root}`` :Description: The name of the crush bucket used for the first step of the ruleset. For intance **step take default**. @@ -103,7 +104,7 @@ Where: :Required: No. :Default: default -``ruleset-locality={bucket-type}`` +``crush-locality={bucket-type}`` :Description: The type of the crush bucket in which each set of chunks defined by **l** will be stored. For instance, if it is @@ -115,7 +116,7 @@ Where: :Type: String :Required: No. -``ruleset-failure-domain={bucket-type}`` +``crush-failure-domain={bucket-type}`` :Description: Ensure that no two chunks are in a bucket with the same failure domain. For instance, if the failure domain is @@ -127,6 +128,16 @@ Where: :Required: No. :Default: host +``crush-device-class={device-class}`` + +:Description: Restrict placement to devices of a specific class (e.g., + ``ssd`` or ``hdd``), using the crush device class names + in the CRUSH map. + +:Type: String +:Required: No. +:Default: + ``directory={directory}`` :Description: Set the **directory** name from which the erasure code @@ -220,7 +231,7 @@ OSD is in the same rack as the lost chunk.:: [ "cDDD____", "" ], [ "____cDDD", "" ], ]' \ - ruleset-steps='[ + crush-steps='[ [ "choose", "rack", 2 ], [ "chooseleaf", "host", 4 ], ]' @@ -351,7 +362,7 @@ racks. For instance:: - ruleset-steps='[ [ "choose", "rack", 2 ], [ "chooseleaf", "host", 4 ] ]' + crush-steps='[ [ "choose", "rack", 2 ], [ "chooseleaf", "host", 4 ] ]' will create a ruleset that will select two crush buckets of type *rack* and for each of them choose four OSDs, each of them located in diff --git a/ceph/doc/rados/operations/erasure-code-shec.rst b/ceph/doc/rados/operations/erasure-code-shec.rst index 6c3b84863..e3bab3765 100644 --- a/ceph/doc/rados/operations/erasure-code-shec.rst +++ b/ceph/doc/rados/operations/erasure-code-shec.rst @@ -16,8 +16,9 @@ To create a new *shec* erasure code profile:: [k={data-chunks}] \ [m={coding-chunks}] \ [c={durability-estimator}] \ - [ruleset-root={root}] \ - [ruleset-failure-domain={bucket-type}] \ + [crush-root={root}] \ + [crush-failure-domain={bucket-type}] \ + [crush-device-class={device-class}] \ [directory={directory}] \ [--force] @@ -52,7 +53,7 @@ Where: :Required: No. :Default: 2 -``ruleset-root={root}`` +``crush-root={root}`` :Description: The name of the crush bucket used for the first step of the ruleset. For intance **step take default**. @@ -61,7 +62,7 @@ Where: :Required: No. :Default: default -``ruleset-failure-domain={bucket-type}`` +``crush-failure-domain={bucket-type}`` :Description: Ensure that no two chunks are in a bucket with the same failure domain. For instance, if the failure domain is @@ -73,6 +74,16 @@ Where: :Required: No. :Default: host +``crush-device-class={device-class}`` + +:Description: Restrict placement to devices of a specific class (e.g., + ``ssd`` or ``hdd``), using the crush device class names + in the CRUSH map. + +:Type: String +:Required: No. +:Default: + ``directory={directory}`` :Description: Set the **directory** name from which the erasure code @@ -129,5 +140,5 @@ Erasure code profile examples $ ceph osd erasure-code-profile set SHECprofile \ plugin=shec \ k=8 m=4 c=3 \ - ruleset-failure-domain=host + crush-failure-domain=host $ ceph osd pool create shecpool 256 256 erasure SHECprofile diff --git a/ceph/doc/rados/operations/erasure-code.rst b/ceph/doc/rados/operations/erasure-code.rst index 568f26aec..6ec5a097d 100644 --- a/ceph/doc/rados/operations/erasure-code.rst +++ b/ceph/doc/rados/operations/erasure-code.rst @@ -37,7 +37,7 @@ displayed with:: k=2 m=1 plugin=jerasure - ruleset-failure-domain=host + crush-failure-domain=host technique=reed_sol_van Choosing the right profile is important because it cannot be modified @@ -45,7 +45,7 @@ after the pool is created: a new pool with a different profile needs to be created and all objects from the previous pool moved to the new. The most important parameters of the profile are *K*, *M* and -*ruleset-failure-domain* because they define the storage overhead and +*crush-failure-domain* because they define the storage overhead and the data durability. For instance, if the desired architecture must sustain the loss of two racks with a storage overhead of 40% overhead, the following profile can be defined:: @@ -53,7 +53,7 @@ the following profile can be defined:: $ ceph osd erasure-code-profile set myprofile \ k=3 \ m=2 \ - ruleset-failure-domain=rack + crush-failure-domain=rack $ ceph osd pool create ecpool 12 12 erasure myprofile $ echo ABCDEFGHI | rados --pool ecpool put NYAN - $ rados --pool ecpool get NYAN - @@ -62,7 +62,7 @@ the following profile can be defined:: The *NYAN* object will be divided in three (*K=3*) and two additional *chunks* will be created (*M=2*). The value of *M* defines how many OSD can be lost simultaneously without losing any data. The -*ruleset-failure-domain=rack* will create a CRUSH ruleset that ensures +*crush-failure-domain=rack* will create a CRUSH ruleset that ensures no two *chunks* are stored in the same rack. .. ditaa:: diff --git a/ceph/doc/rados/operations/operating.rst b/ceph/doc/rados/operations/operating.rst index 972c3d7f0..791941a94 100644 --- a/ceph/doc/rados/operations/operating.rst +++ b/ceph/doc/rados/operations/operating.rst @@ -8,9 +8,9 @@ Running Ceph with systemd ========================== -For all distributions that support systemd (CentOS 7, Fedora, Debian Jessie -8.x, SUSE), ceph daemons are now managed using native systemd files instead of -the legacy sysvinit scripts. For example:: +For all distributions that support systemd (CentOS 7, Fedora, Debian +Jessie 8 and later, SUSE), ceph daemons are now managed using native +systemd files instead of the legacy sysvinit scripts. For example:: sudo systemctl start ceph.target # start all daemons sudo systemctl status ceph-osd@12 # check status of osd.12 diff --git a/ceph/doc/rados/operations/placement-groups.rst b/ceph/doc/rados/operations/placement-groups.rst index 98e13f860..d822373dd 100644 --- a/ceph/doc/rados/operations/placement-groups.rst +++ b/ceph/doc/rados/operations/placement-groups.rst @@ -296,6 +296,9 @@ resources. However, if 1,000 pools were created with 512 placement groups each, the OSDs will handle ~50,000 placement groups each and it would require significantly more resources and time for peering. +You may find the `PGCalc`_ tool helpful. + + .. _setting the number of placement groups: Set the Number of Placement Groups diff --git a/ceph/doc/rados/operations/pools.rst b/ceph/doc/rados/operations/pools.rst index 7db41d636..b93631d8c 100644 --- a/ceph/doc/rados/operations/pools.rst +++ b/ceph/doc/rados/operations/pools.rst @@ -57,9 +57,9 @@ For example:: To create a pool, execute:: ceph osd pool create {pool-name} {pg-num} [{pgp-num}] [replicated] \ - [crush-ruleset-name] [expected-num-objects] + [crush-rule-name] [expected-num-objects] ceph osd pool create {pool-name} {pg-num} {pgp-num} erasure \ - [erasure-code-profile] [crush-ruleset-name] [expected_num_objects] + [erasure-code-profile] [crush-rule-name] [expected_num_objects] Where: @@ -104,10 +104,10 @@ Where: :Required: No. :Default: replicated -``[crush-ruleset-name]`` +``[crush-rule-name]`` -:Description: The name of a CRUSH ruleset to use for this pool. The specified - ruleset must exist. +:Description: The name of a CRUSH rule to use for this pool. The specified + rule must exist. :Type: String :Required: No. diff --git a/ceph/doc/rados/operations/user-management.rst b/ceph/doc/rados/operations/user-management.rst index 2e47f37ff..efd92f730 100644 --- a/ceph/doc/rados/operations/user-management.rst +++ b/ceph/doc/rados/operations/user-management.rst @@ -361,6 +361,7 @@ are often restricted to accessing a particular pool. :: .. _modify-user-capabilities: + Modify User Capabilities ------------------------ diff --git a/ceph/doc/rados/troubleshooting/log-and-debug.rst b/ceph/doc/rados/troubleshooting/log-and-debug.rst index 757dfb178..c91f27218 100644 --- a/ceph/doc/rados/troubleshooting/log-and-debug.rst +++ b/ceph/doc/rados/troubleshooting/log-and-debug.rst @@ -394,13 +394,6 @@ OSD :Required: No :Default: 1 -``osd preserve trimmed log`` - -:Description: Preserves trimmed logs after trimming. -:Type: Boolean -:Required: No -:Default: ``false`` - ``osd tmapput sets uses tmap`` diff --git a/ceph/doc/rados/troubleshooting/troubleshooting-osd.rst b/ceph/doc/rados/troubleshooting/troubleshooting-osd.rst index f72c6a4ad..81e76eccd 100644 --- a/ceph/doc/rados/troubleshooting/troubleshooting-osd.rst +++ b/ceph/doc/rados/troubleshooting/troubleshooting-osd.rst @@ -286,10 +286,11 @@ A storage drive should only support one OSD. Sequential read and sequential write throughput can bottleneck if other processes share the drive, including journals, operating systems, monitors, other OSDs and non-Ceph processes. -Ceph acknowledges writes *after* journaling, so fast SSDs are an attractive -option to accelerate the response time--particularly when using the ``XFS`` or -``ext4`` filesystems. By contrast, the ``btrfs`` filesystem can write and journal -simultaneously. +Ceph acknowledges writes *after* journaling, so fast SSDs are an +attractive option to accelerate the response time--particularly when +using the ``XFS`` or ``ext4`` filesystems. By contrast, the ``btrfs`` +filesystem can write and journal simultaneously. (Note, however, that +we recommend against using ``btrfs`` for production deployments.) .. note:: Partitioning a drive does not change its total throughput or sequential read/write limits. Running a journal in a separate partition @@ -364,10 +365,13 @@ might not have a recent enough version of ``glibc`` to support ``syncfs(2)``. Filesystem Issues ----------------- -Currently, we recommend deploying clusters with XFS. The btrfs -filesystem has many attractive features, but bugs in the filesystem may -lead to performance issues. We do not recommend ext4 because xattr size -limitations break our support for long object names (needed for RGW). +Currently, we recommend deploying clusters with XFS. + +We recommend against using btrfs or ext4. The btrfs filesystem has +many attractive features, but bugs in the filesystem may lead to +performance issues and suprious ENOSPC errors. We do not recommend +ext4 because xattr size limitations break our support for long object +names (needed for RGW). For more information, see `Filesystem Recommendations`_. @@ -438,7 +442,7 @@ Events from the OSD as it prepares operations - queued_for_pg: the op has been put into the queue for processing by its PG - reached_pg: the PG has started doing the op -- waiting for *: the op is waiting for some other work to complete before it +- waiting for \*: the op is waiting for some other work to complete before it can proceed (a new OSDMap; for its object target to scrub; for the PG to finish peering; all as specified in the message) - started: the op has been accepted as something the OSD should actually do diff --git a/ceph/doc/rados/troubleshooting/troubleshooting-pg.rst b/ceph/doc/rados/troubleshooting/troubleshooting-pg.rst index 4fddb389d..e221344d1 100644 --- a/ceph/doc/rados/troubleshooting/troubleshooting-pg.rst +++ b/ceph/doc/rados/troubleshooting/troubleshooting-pg.rst @@ -516,7 +516,7 @@ ruleset:: You can resolve the problem by creating a new pool in which PGs are allowed to have OSDs residing on the same host with:: - ceph osd erasure-code-profile set myprofile ruleset-failure-domain=osd + ceph osd erasure-code-profile set myprofile crush-failure-domain=osd ceph osd pool create erasurepool 16 16 erasure myprofile CRUSH gives up too soon diff --git a/ceph/doc/radosgw/index.rst b/ceph/doc/radosgw/index.rst index d64e6dd6b..657a6f9b9 100644 --- a/ceph/doc/radosgw/index.rst +++ b/ceph/doc/radosgw/index.rst @@ -45,10 +45,12 @@ you may write data with one API and retrieve it with the other. Swift API Admin Ops API Python binding + Export over NFS OpenStack Keystone Integration OpenStack Barbican Integration Multi-tenancy Compression + LDAP Authentication Server-Side Encryption Bucket Policy Data Layout in RADOS diff --git a/ceph/doc/release-notes.rst b/ceph/doc/release-notes.rst index e466614f0..9b40925f6 100644 --- a/ceph/doc/release-notes.rst +++ b/ceph/doc/release-notes.rst @@ -3,13 +3,423 @@ =============== v12.1.0 Luminous (RC) -==================== +===================== + +This is the first release candidate for Luminous, the next long term +stable release. -This is the first release candidate for Luminous, the next long term stable release. +Ceph Luminous (v12.2.0) will be the foundation for the next long-term +stable release series. There have been major changes since Kraken +(v11.2.z) and Jewel (v10.2.z), and the upgrade process is non-trivial. +Please read these release notes carefully. Major Changes from Kraken ------------------------- +- *General*: + + * Ceph now has a simple, built-in web-based dashboard for monitoring + cluster status. FIXME DOCS. + +- *RADOS*: + + * *BlueStore*: + + - The new *BlueStore* backend for *ceph-osd* is now stable and the new + default for newly created OSDs. BlueStore manages data stored by each OSD + by directly managing the physical HDDs or SSDs without the use of an + intervening file system like XFS. This provides greater performance + and features. FIXME DOCS + - BlueStore supports *full data and metadata checksums* of all + data stored by Ceph. + - BlueStore supports inline compression using zlib, snappy, or LZ4. (Ceph + also supports zstd for RGW compression but zstd is not recommended for + BlueStore for performance reasons.) FIXME DOCS + + * *Erasure coded* pools now have full support for *overwrites*, + allowing them to be used with RBD and CephFS. `Read more about EC overwrites`_. + + * *ceph-mgr*: + + - There is a new daemon, *ceph-mgr*, which is a required part of any + Ceph deployment. Although IO can continue when *ceph-mgr* is + down, metrics will not refresh and some metrics-related calls + (e.g., ``ceph df``) may block. We recommend deploying several instances of + *ceph-mgr* for reliability. See the notes on `Upgrading`_ below. + - The *ceph-mgr* daemon includes a REST-based management API. The + API is still experimental and somewhat limited but will form the basis + for API-based management of Ceph going forward. FIXME DOCS + + * The overall *scalability* of the cluster has improved. We have + successfully tested clusters with up to 10,000 OSDs. + * Each OSD can now have a *device class* associated with it (e.g., `hdd` or + `ssd`), allowing CRUSH rules to trivially map data to a subset of devices + in the system. Manually writing CRUSH rules or manual editing of the CRUSH + is normally not required. FIXME DOCS + * You can now *optimize CRUSH weights* can now be optimized to + maintain a *near-perfect distribution of data* across OSDs. FIXME DOCS + * There is also a new `upmap` exception mechanism that allows + individual PGs to be moved around to achieve a *perfect + distribution* (this requires luminous clients). FIXME DOCS + * Each OSD now adjusts its default configuration based on whether the + backing device is an HDD or SSD. Manual tuning generally not required. + * The prototype *mclock QoS queueing algorithm* is now available. FIXME DOCS + * There is now a *backoff* mechanism that prevents OSDs from being + overloaded by requests to objects or PGs that are not currently able to + process IO. + * There is a *simplified OSD replacement process* that is more robust. FIXME DOCS + * You can query the supported features and (apparent) releases of + all connected daemons and clients with ``ceph features``. FIXME DOCS + * You can configure the oldest Ceph client version you wish to allow to + connect to the cluster via ``ceph osd set-require-min-compat-client`` and + Ceph will prevent you from enabling features that will break compatibility + with those clients. FIXME DOCS + * Several `sleep` settings, include ``osd_recovery_sleep``, + ``osd_snap_trim_sleep``, and ``osd_scrub_sleep`` have been + reimplemented to work efficiently. (These are used in some cases + to work around issues throttling background work.) + +- *RGW*: + + * RGW *metadata search* backed by ElasticSearch now supports end + user requests service via RGW itself, and also supports custom + metadata fields. A query language a set of RESTful APIs were + created for users to be able to search objects by their + metadata. New APIs that allow control of custom metadata fields + were also added. + * RGW now supports *dynamic bucket index sharding*. As the number + of objects in a bucket grows, RGW will automatically reshard the + bucket index in response. No user intervention or bucket size + capacity planning is required. + * RGW introduces *server side encryption* of uploaded objects with + three options for the management of encryption keys: automatic + encryption (only recommended for test setups), customer provided + keys similar to Amazon SSE-C specification, and through the use of + an external key management service (Openstack Barbican) similar + to Amazon SSE-KMS specification. + * RGW now has preliminary AWS-like bucket policy API support. For + now, policy is a means to express a range of new authorization + concepts. In the future it will be the foundation for additional + auth capabilities such as STS and group policy. + * RGW has consolidated the several metadata index pools via the use of rados + namespaces. + +- *RBD*: + + * RBD now has full, stable support for *erasure coded pools* via the new + ``--data-pool`` option to ``rbd create``. + * RBD mirroring's rbd-mirror daemon is now highly available. We + recommend deploying several instances of rbd-mirror for + reliability. + * The default 'rbd' pool is no longer created automatically during + cluster creation. Additionally, the name of the default pool used + by the rbd CLI when no pool is specified can be overridden via a + new ``rbd default pool = `` configuration option. + * Initial support for deferred image deletion via new ``rbd + trash`` CLI commands. Images, even ones actively in-use by + clones, can be moved to the trash and deleted at a later time. + * New pool-level ``rbd mirror pool promote`` and ``rbd mirror pool + demote`` commands to batch promote/demote all mirrored images + within a pool. + * Mirroring now optionally supports a configurable replication delay + via the ``rbd mirroring replay delay = `` configuration + option. + * Improved discard handling when the object map feature is enabled. + * rbd CLI ``import`` and ``copy`` commands now detect sparse and + preserve sparse regions. + * Images and Snapshots will now include a creation timestamp + +- *CephFS*: + + * *Multiple active MDS daemons* is now considered stable. The number + of active MDS servers may be adjusted up or down on an active CephFS file + system. + * CephFS *directory fragmentation* is now stable and enabled by + default on new filesystems. To enable it on existing filesystems + use "ceph fs set allow_dirfrags". Large or very busy + directories are sharded and (potentially) distributed across + multiple MDS daemons automatically. + * Directory subtrees can be explicitly pinned to specific MDS daemons in + cases where the automatic load balancing is not desired or effective. + +- *Miscellaneous*: + + * Release packages are now being built for *Debian Stretch*. The + distributions we build for now includes: + + - CentOS 7 (x86_64 and aarch64) + - Debian 8 Jessie (x86_64) + - Debian 9 Stretch (x86_64) + - Ubuntu 16.04 Xenial (x86_64 and aarch64) + - Ubuntu 14.04 Trusty (x86_64) + + Note that QA is limited to CentOS and Ubuntu (xenial and trusty). + + * *CLI changes*: + + - The ``ceph -s`` or ``ceph status`` command has a fresh look. + - ``ceph {osd,mds,mon} versions`` summarizes versions of running daemons. + - ``ceph {osd,mds,mon} count-metadata `` similarly + tabulates any other daemon metadata visible via the ``ceph + {osd,mds,mon} metadata`` commands. + - ``ceph features`` summarizes features and releases of connected + clients and daemons. + - ``ceph osd require-osd-release `` replaces the old + ``require_RELEASE_osds`` flags. + - ``ceph osd pg-upmap``, ``ceph osd rm-pg-upmap``, ``ceph osd + pg-upmap-items``, ``ceph osd rm-pg-upmap-items`` can explicitly + manage `upmap` items (FIXME DOCS). + - ``ceph osd getcrushmap`` returns a crush map version number on + stderr, and ``ceph osd setcrushmap [version]`` will only inject + an updated crush map if the version matches. This allows crush + maps to be updated offline and then reinjected into the cluster + without fear of clobbering racing changes (e.g., by newly added + osds or changes by other administrators). + - ``ceph osd create`` has been replaced by ``ceph osd new``. This + should be hidden from most users by user-facing tools like + `ceph-disk`. + - ``ceph osd destroy`` will mark an OSD destroyed and remove its + cephx and lockbox keys. However, the OSD id and CRUSH map entry + will remain in place, allowing the id to be reused by a + replacement device with minimal data rebalancing. + - ``ceph osd purge`` will remove all traces of an OSD from the + cluster, including its cephx encryption keys, dm-crypt lockbox + keys, OSD id, and crush map entry. + - ``ceph osd ls-tree `` will output a list of OSD ids under + the given CRUSH name (like a host or rack name). This is useful + for applying changes to entire subtrees. For example, ``ceph + osd down `ceph osd ls-tree rack1```. + - ``ceph osd {add,rm}-{noout,noin,nodown,noup}`` allow the + `noout`, `nodown`, `noin`, and `noup` flags to be applied to + specific OSDs. + - ``ceph log last [n]`` will output the last *n* lines of the cluster + log. + - ``ceph mgr dump`` will dump the MgrMap, including the currently active + ceph-mgr daemon and any standbys. + - ``ceph mgr module ls`` will list active ceph-mgr modules. + - ``ceph mgr module {enable,disable} `` will enable or + disable the named mgr module. The module must be present in the + configured `mgr_module_path` on the host(s) where `ceph-mgr` is + running. + - ``ceph osd crush swap-bucket `` will swap the + contents of two CRUSH buckets in the hierarchy while preserving + the buckets' ids. This allows an entire subtree of devices to + be replaced (e.g., to replace an entire host of FileStore OSDs + with newly-imaged BlueStore OSDs) without disrupting the + distribution of data across neighboring devices. + - ``ceph osd set-require-min-compat-client `` configures + the oldest client release the cluster is required to support. + Other changes, like CRUSH tunables, will fail with an error if + they would violate this setting. Changing this setting also + fails if clients older than the specified release are currently + connected to the cluster. + - ``ceph config-key dump`` dumps config-key entries and their + contents. (The existing ``ceph config-key list`` only dumps the key + names, not the values.) + - ``ceph osd set-{full,nearfull,backfillfull}-ratio`` sets the + cluster-wide ratio for various full thresholds (when the cluster + refuses IO, when the cluster warns about being close to full, + when an OSD will defer rebalancing a PG to itself, + respectively). + - ``ceph osd reweightn`` will specify the `reweight` values for + multiple OSDs in a single command. This is equivalent to a series of + ``ceph osd reweight`` commands. + - ``ceph osd crush class {create,rm,ls,rename}`` manage the new + CRUSH *device class* feature. ``ceph crush set-device-class + [...]`` will set the class for particular devices. + - ``ceph osd crush rule create-replicated`` replaces the old + ``ceph osd crush rule create-simple`` command to create a CRUSH + rule for a replicated pool. Notably it takes a `class` argument + for the *device class* the rule should target (e.g., `ssd` or + `hdd`). + - ``ceph mon feature ls`` will list monitor features recorded in the + MonMap. ``ceph mon feature set`` will set an optional feature (none of + these exist yet). + - ``ceph tell help`` will now return a usage summary. + +.. _Read more about EC overwrites: ../rados/operations/erasure-code/#erasure-coding-with-overwrites + +Major Changes from Jewel +------------------------ + +- *RADOS*: + + * We now default to the AsyncMessenger (``ms type = async``) instead + of the legacy SimpleMessenger.  The most noticeable difference is + that we now use a fixed sized thread pool for network connections + (instead of two threads per socket with SimpleMessenger). + * Some OSD failures are now detected almost immediately, whereas + previously the heartbeat timeout (which defaults to 20 seconds) + had to expire.  This prevents IO from blocking for an extended + period for failures where the host remains up but the ceph-osd + process is no longer running. + * The size of encoded OSDMaps has been reduced. + * The OSDs now quiesce scrubbing when recovery or rebalancing is in progress. + +- *RGW*: + + * RGW now supports the S3 multipart object copy-part API. + * It is possible now to reshard an existing bucket offline. Offline + bucket resharding currently requires that all IO (especially + writes) to the specific bucket is quiesced. (For automatic online + resharding, see the new feature in Luminous above.) + * RGW now supports data compression for objects. + * Civetweb version has been upgraded to 1.8 + * The Swift static website API is now supported (S3 support has been added + previously). + * S3 bucket lifecycle API has been added. Note that currently it only supports + object expiration. + * Support for custom search filters has been added to the LDAP auth + implementation. + * Support for NFS version 3 has been added to the RGW NFS gateway. + * A Python binding has been created for librgw. + +- *RBD*: + + * The rbd-mirror daemon now supports replicating dynamic image + feature updates and image metadata key/value pairs from the + primary image to the non-primary image. + * The number of image snapshots can be optionally restricted to a + configurable maximum. + * The rbd Python API now supports asynchronous IO operations. + +- *CephFS*: + + * libcephfs function definitions have been changed to enable proper + uid/gid control. The library version has been increased to reflect the + interface change. + * Standby replay MDS daemons now consume less memory on workloads + doing deletions. + * Scrub now repairs backtrace, and populates `damage ls` with + discovered errors. + * A new `pg_files` subcommand to `cephfs-data-scan` can identify + files affected by a damaged or lost RADOS PG. + * The false-positive "failing to respond to cache pressure" warnings have + been fixed. + + +Upgrade from Jewel or Kraken +---------------------------- +.. _Upgrading: + +#. Ensure that the ``sortbitwise`` flag is enabled:: + + # ceph osd set sortbitwise + +#. Make sure your cluster is stable and healthy (no down or + recoverying OSDs). (Optional, but recommended.) + +#. Do not create any new erasure-code pools while upgrading the monitors. + +#. Set the ``noout`` flag for the duration of the upgrade. (Optional + but recommended.):: + + # ceph osd set noout + +#. Upgrade monitors by installing the new packages and restarting the + monitor daemons. Note that, unlike prior releases, the ceph-mon + daemons *must* be upgraded first.:: + + # systemctl restart ceph-mon.target + + Verify the monitor upgrade is complete once all monitors are up by + looking for the ``luminous`` feature string in the mon map. For + example:: + + # ceph mon feature ls + + should include `luminous` under persistent features:: + + on current monmap (epoch NNN) + persistent: [kraken,luminous] + required: [kraken,luminous] + +#. Add or restart ``ceph-mgr`` daemons. If you are upgrading from + kraken, upgrade packages and restart ceph-mgr daemons with:: + + # systemctl restart ceph-mgr.target + + If you are upgrading from kraken, you may already have ceph-mgr + daemons deployed. If not, or if you are upgrading from jewel, you + can deploy new daemons with tools like ceph-deploy or ceph-ansible. + For example,:: + + # ceph-deploy mgr create HOST + + Verify the ceph-mgr daemons are running by checking ``ceph -s``:: + + # ceph -s + + ... + services: + mon: 3 daemons, quorum foo,bar,baz + mgr: foo(active), standbys: bar, baz + ... + +#. Upgrade all OSDs by installing the new packages and restarting the + ceph-osd daemons on all hosts.:: + + # systemctl restart ceph-osd.target + + You can monitor the progress of the OSD upgrades with the new + ``ceph osd versions`` command.:: + + # ceph osd versions + { + "ceph version 12.2.0 (...) luminous (stable)": 12, + "ceph version 10.2.6 (...)": 3, + } + +#. Upgrade all CephFS daemons by upgrading packages and restarting + daemons on all hosts.:: + + # systemctl restart ceph-mds.target + +#. Upgrade all radosgw daemons by upgrading packages and restarting + daemons on all hosts.:: + + # systemctl restart radosgw.target + +#. Complete the upgrade by disallowing pre-luminous OSDs:: + + # ceph osd require-osd-release luminous + + If you set ``noout`` at the beginning, be sure to clear it with:: + + # ceph osd unset noout + +#. Verify the cluster is healthy with ``ceph health``. + + +Upgrading from pre-Jewel releases (like Hammer) +----------------------------------------------- + +You *must* first upgrade to Jewel (10.2.z) before attempting an +upgrade to Luminous. + + +Upgrade compatibility notes, Kraken to Luminous +----------------------------------------------- + +* We no longer test the FileStore ceph-osd backend in combination with + ``btrfs``. We recommend against using btrfs. If you are using + btrfs-based OSDs and want to upgrade to luminous you will need to + add the follwing to your ceph.conf:: + + enable experimental unrecoverable data corrupting features = btrfs + + The code is mature and unlikely to change, but we are only + continuing to test the Jewel stable branch against btrfs. We + recommend moving these OSDs to FileStore with XFS or BlueStore. +* The ``ruleset-*`` properties for the erasure code profiles have been + renamed to ``crush-*`` to (1) move away from the obsolete 'ruleset' + term and to be more clear about their purpose. There is also a new + optional ``crush-device-class`` property to specify a CRUSH device + class to use for the erasure coded pool. Existing erasure code + profiles will be converted automatically when upgrade completes + (when the ``ceph osd require-osd-release luminous`` command is run) + but any provisioning tools that create erasure coded pools may need + to be updated. * When assigning a network to the public network and not to the cluster network the network specification of the public network will be used for the cluster network as well. @@ -80,9 +490,6 @@ Major Changes from Kraken string will no longer be able to set quotas or any layout fields. This flag previously only restricted modification of the pool and namespace fields in layouts. - * CephFS directory fragmentation (large directory support) is enabled - by default on new filesystems. To enable it on existing filesystems - use "ceph fs set allow_dirfrags". * CephFS will generate a health warning if you have fewer standby daemons than it thinks you wanted. By default this will be 1 if you ever had a standby, and 0 if you did not. You can customize this using @@ -91,40 +498,45 @@ Major Changes from Kraken * The "ceph mds tell ..." command has been removed. It is superceded by "ceph tell mds. ..." -- *MGR* - * ceph-mgr supports a default dashboard - * ceph-mgr introduces a new pecan based rest API +Notable Changes since Kraken +---------------------------- -- *RGW*: +build consolidated list before final release - * RGW introduces server side encryption of uploaded objects with 3 options for - the management of encryption keys, automatic encryption (only recommended for - test setups), customer provided keys similar to Amazon SSE-C specification and - using a key management service (Openstack Barbician) similar to Amazon SSE-KMS - specification. - * RGW's metadata search with ElasticSearch now supports end user requests - serviced via RGW itself and now supports custom metadata fields - * RGW has consolidated the several metadata index pools via the use of rados - namespaces - * RGW now supports dynamic bucket index sharding +Notable Changes since v12.0.3 +----------------------------- -Notable Changes ---------------- * bluestore: ceph-disk: add --filestore argument, default to --bluestore (`pr#15437 `_, Loic Dachary, Sage Weil) * bluestore,core: os/bluestore: fix warning (`pr#15435 `_, Sage Weil) * bluestore,core: os/bluestore: improve mempool usage (`pr#15402 `_, Sage Weil) * bluestore,core: os/bluestore: write "mkfs_done" into disk only if we pass fsck() tests (`pr#15238 `_, xie xingguo) * bluestore,core: os: remove experimental status for BlueStore (`pr#15177 `_, Sage Weil) +* bluestore: os/bluestore: better debug output on unsharing blobs (`issue#20227 `_, `pr#15746 `_, Sage Weil) * bluestore: os/bluestore/BlockDevice: support pmem device as bluestore backend (`pr#15102 `_, Jianpeng Ma) +* bluestore: os/bluestore/BlueFS: Rebuild memcopy for bufferlist::page_aligned_app… (`pr#15728 `_, Jianpeng Ma, Sage Weil) +* bluestore: os/bluestore/BlueFS: .slow should be compared with dirname (`pr#15595 `_, zhanglei) +* bluestore: os/bluestore/BlueStore: no device no symlink. (`pr#15721 `_, Jianpeng Ma) +* bluestore: os/bluestore: cleanup bluestore_types (`pr#15680 `_, xie xingguo) +* bluestore: os/bluestore: configure rocksdb cache via bluestore_cache_kv_ratio (`pr#15580 `_, Sage Weil) * bluestore: os/bluestore: fix a typo about bleustore (`pr#15357 `_, Dongsheng Yang) * bluestore: os/bluestore: fix BitMapAllocator assert on out-of-bound hint value (`pr#15289 `_, Igor Fedotov) * bluestore: os/bluestore: fix buffers pinned by indefinitely deferred writes (`pr#15398 `_, Sage Weil) * bluestore: os/bluestore: fix false assert in IOContext::aio_wake (`pr#15268 `_, Igor Fedotov) * bluestore: os/bluestore: fix false asserts in Cache::trim_all() (`pr#15470 `_, xie xingguo) * bluestore: os/bluestore: fix fsck deferred_replay (`pr#15295 `_, Sage Weil) +* bluestore: os/bluestore: fix possible out of order shard(offset == 0); add sanity check (`pr#15658 `_, xie xingguo) +* bluestore: os/bluestore: fix potential access violation (`pr#15657 `_, xie xingguo) +* bluestore: os/bluestore: fix unsharing blob dirty_range args (`issue#20227 `_, `pr#15766 `_, Sage Weil) +* bluestore: os/bluestore: handle rounding error in cache ratios (`pr#15672 `_, Sage Weil) +* bluestore: os/bluestore: initialize finishers properly (`pr#15666 `_, xie xingguo) * bluestore: os/bluestore/KernelDevice: fix comments (`pr#15264 `_, xie xingguo) * bluestore: os/bluestore/KernelDevice: helpful warning when aio limit exhausted (`pr#15116 `_, Sage Weil) +* bluestore: os/bluestore: move sharedblob to new collection in same shard (`issue#20358 `_, `pr#15783 `_, Sage Weil) +* bluestore: os/bluestore: refactor BlueStore::_do_write; kill dead ExtentMap::find_lextent() method (`pr#15750 `_, xie xingguo) +* bluestore: os/bluestore: remove unused variables (`pr#15718 `_, zhanglei) +* bluestore: os/bluestore: stop calculating bound if we must reshard; narrow shard combination condition (`pr#15631 `_, xie xingguo) +* bluestore: os/bluestore: target_bytes should scale with meta/data ratios. (`pr#15708 `_, Mark Nelson) * bluestore,performance: os/bluestore: avoid overloading extents during reshard; atomic deferred_batch_ops (`pr#15502 `_, xie xingguo) * bluestore,performance: os/bluestore: batch throttle (`pr#15284 `_, Jianpeng Ma) * bluestore,performance: os/bluestore: keep statfs replica in RAM to avoid expensive KV retrieval (`pr#15309 `_, Igor Fedotov) @@ -133,6 +545,9 @@ Notable Changes * bluestore,performance: os/bluestore: put bluefs in the middle of the shared device (`pr#14873 `_, Sage Weil) * bluestore,performance: os/bluestore: separate kv_sync_thread into two parts (`pr#14035 `_, Jianpeng Ma, Igor Fedotov, Sage Weil) * bluestore,performance: os/bluestore: try to unshare blobs for EC overwrite workload (`pr#14239 `_, Sage Weil) +* bluestore,tests: qa/objectstore/bluestore*: fsck on mount (`pr#15785 `_, Sage Weil) +* bluestore,tests: test/unittest_bluefs: When fsync ret is less than 0, fsync can not be… (`pr#15365 `_, shiqi) +* bluestore: wrap blob id when it reaches maximum value of int16_t (`issue#19555 `_, `pr#15654 `_, Xiaoyan Li) * build/ops: 12.0.3 (`pr#15600 `_, Jenkins Build Slave User) * build/ops: build: move bash_completion.d/ceph to ceph-common (`pr#15148 `_, Leo Zhang) * build/ops: build: remove ceph-disk-udev entirely (`pr#15259 `_, Leo Zhang) @@ -142,16 +557,22 @@ Notable Changes * build/ops,common: build: Adds C++ warning flag for C Variable-Length Arrays. (`pr#15342 `_, Jesse Williamson) * build/ops,common: common/blkdev.cc: propagate get_device_by_fd to different OSes (`pr#15547 `_, Willem Jan Withagen) * build/ops: conditionalize rgw Beast frontend so it isn't built on s390x architecture (`issue#20048 `_, `pr#15225 `_, Willem Jan Withagen, Nathan Cutler, Kefu Chai, Tim Serong, Casey Bodley) +* build/ops,core: common/freebsd_errno.cc: fix missing ; (`pr#15741 `_, Willem Jan Withagen) +* build/ops,core: erasure-code: update ec_isa version + add missing AVX512 ISA-L sources (`pr#15636 `_, Ganesh Mahalingam, Tushar Gohad) * build/ops,core,tests: osd/dmclock/testing: reorganize testing, building now optional (`pr#15375 `_, J. Eric Ivancich) * build/ops: debian: ceph-mgr: fix package description (`pr#15513 `_, Fabian Grünbichler) * build/ops: debian: sync logrotate packaging with downstream (`issue#19938 `_, `pr#15567 `_, Fabian Grünbichler) * build/ops: do_cmake.sh: enable ccache if installed (`pr#15274 `_, Sage Weil) * build/ops: drop libfcgi build dependency (`pr#15285 `_, Nathan Cutler) +* build/ops: .gitignore: exclude rpm files (`pr#15745 `_, Leo Zhang) * build/ops: install-deps.sh: workaround setuptools' dependency on six (`pr#15406 `_, Kefu Chai) +* build/ops: miscellaneous cleanups and fixes (run-make-check.sh, ceph.spec.in) (`issue#20091 `_, `issue#20127 `_, `pr#15399 `_, Nathan Cutler) +* build/ops,rbd,tests: test/librbd: decouple ceph_test_librbd_api from libceph-common (`issue#20175 `_, `pr#15611 `_, Kefu Chai) * build/ops: rpm: apply epoch only if %epoch macro is defined (`pr#15286 `_, Nathan Cutler) * build/ops: rpm: make librbd1 %post scriptlet depend on coreutils (`issue#20052 `_, `pr#15231 `_, Giacomo Comes, Nathan Cutler) * build/ops: rpm: move _epoch_prefix below Epoch definition (`pr#15417 `_, Nathan Cutler) * build/ops: rpm: move RDMA and python-prettytables build dependencies to distro-conditional section (`pr#15200 `_, Nathan Cutler) +* build/ops: rpm: package COPYING, move sample ceph.conf to ceph-common (`pr#15596 `_, Nathan Cutler) * build/ops: selinux: Allow read on var_run_t (`issue#16674 `_, `pr#15523 `_, Boris Ranto) * build/ops: selinux: Do parallel relabel on package install (`issue#20077 `_, `pr#14871 `_, Boris Ranto) * build/ops: selinux: Install ceph-base before ceph-selinux (`issue#20184 `_, `pr#15490 `_, Boris Ranto) @@ -160,22 +581,36 @@ Notable Changes * build/ops: yasm-wrapper: filter -pthread (`pr#15249 `_, Alessandro Barbieri) * cephfs: #17980: MDS client blacklisting and blacklist on eviction (`issue#17980 `_, `issue#9754 `_, `pr#14610 `_, John Spray) * cephfs: ceph: simplify CInode::maybe_export_pin() (`pr#15106 `_, "Yan, Zheng") +* cephfs: client: avoid returning negative space available (`issue#20178 `_, `pr#15481 `_, John Spray) +* cephfs: client: call the lru_remove() twice,when trim cache (`pr#15662 `_, huanwen ren) +* cephfs: client: check for luminous MDS before sending FLUSH_MDLOG (`pr#15805 `_, John Spray) +* cephfs: client: fix Dentry::dump (`pr#15779 `_, huanwen ren) * cephfs: client: fix display ino in the ldout (`pr#15314 `_, huanwen ren) * cephfs: client/inode: fix the dump type of Inode::dump() (`pr#15198 `_, huanwen ren) * cephfs,common,rbd: blkin: librbd trace hooks (`pr#15053 `_, Victor Araujo, Jason Dillaman) +* cephfs: mds/MDBalancer: remove useless check_targets and hit_targets logic from MDS balancer (`issue#20131 `_, `pr#15407 `_, Zhi Zhang) +* cephfs,mgr: pybind/mgr/fsstatus: use mds_mem.dn as dentry counter (`pr#15255 `_, Zhi Zhang) * cephfs: mon/FSCommand: fix indentation (`pr#15423 `_, Sage Weil) * cephfs: mon/MDSMonitor: respect mds_standby_for_rank config (`pr#15129 `_, "Yan, Zheng") * cephfs: osdc/Journaler: avoid executing on_safe contexts prematurely (`issue#20055 `_, `pr#15240 `_, "Yan, Zheng") +* cephfs: osdc/Journaler: fix memory leak in Journaler::_issue_read() (`issue#20338 `_, `pr#15776 `_, "Yan, Zheng") +* cephfs: osdc/Objecter: fix inflight_ops update (`pr#15768 `_, "Yan, Zheng") * cephfs: qa/cephfs: disable mds_bal_frag for TestStrays.test_purge_queue_op_rate (`issue#19892 `_, `pr#15105 `_, "Yan, Zheng") * cephfs: qa/tasks/cephfs: use getattr to guarantee inode is in client cache (`issue#19912 `_, `pr#15062 `_, "Yan, Zheng") * cephfs: qa: update log whitelists for kcephfs suite (`pr#14922 `_, "Yan, Zheng") +* cephfs,tests: ceph-object-corpus: mark MMDSSlaveRequest incompat change (`pr#15730 `_, Sage Weil) * cephfs,tests: qa: fix float parse error in test_fragment (`pr#15122 `_, Patrick Donnelly) +* cephfs,tests: qa: misc cephfs test improvements (`issue#20131 `_, `pr#15411 `_, John Spray) * cephfs,tests: qa: silence upgrade test failure (`issue#19934 `_, `pr#15126 `_, Patrick Donnelly) * cephfs,tests: qa: simplify TestJournalRepair (`pr#15096 `_, John Spray) +* cephfs: tools/cephfs: remove `apply` mode of cephfs-journal-tool (`pr#15715 `_, John Spray) * cleanup: src: put-to operator function - const input cleanup (`issue#3977 `_, `pr#15364 `_, Jos Collin) * cmake: Add -finstrument-functions flag to OSD code (`pr#15055 `_, Mohamad Gebai) +* cmake: build boost as an external project (`pr#15376 `_, Kefu Chai) * cmake: check the existence of gperf before using it (`pr#15164 `_, Kefu Chai) +* cmake: do not add dependencies to INTERFACE library on cmake < 3.3 (`pr#15813 `_, Kefu Chai) * cmake: do not link libcommon against some libs (`pr#15340 `_, Willem Jan Withagen) +* cmake: exclude \*.css while generating ctags (`pr#15663 `_, Leo Zhang) * cmake: fix boost components for WITH_SYSTEM_BOOST (`pr#15160 `_, Bassam Tabbara) * cmake: improved build speed by 5x when using ccache (`pr#15147 `_, Bassam Tabbara) * cmake: link against fcgi only if enabled (`pr#15425 `_, Yao Zongyou) @@ -188,13 +623,16 @@ Notable Changes * common: cmdparse: more constness (`pr#15023 `_, Kefu Chai) * common: common/ceph_context: 'config diff get' option added (`pr#10736 `_, Daniel Oliveira) * common: common/ceph_context: fix leak of registered commands on exit (`pr#15302 `_, xie xingguo) +* common: common/freebsd_errno.cc: fixed again a stupid typo (`pr#15742 `_, Willem Jan Withagen) * common: common/iso_8601.cc: Make return expression Clang compatible (`pr#15336 `_, Willem Jan Withagen) * common: common/LogEntry: include EntityName in log entries (`pr#15395 `_, Sage Weil) * common: common,osdc: remove atomic_t completely (`pr#15562 `_, Kefu Chai) * common: common/perf_counters: add average time for PERFCOUNTER_TIME (`pr#15478 `_, xie xingguo) * common: common/perf_counters: make schema more friendly and update docs (`pr#14933 `_, Sage Weil) * common: common,test: migrate atomic_t to std::atomic (`pr#14866 `_, Jesse Williamson) +* common: config_opt: use bool instead of int for the default value of filestore_debug_omap_check (`pr#15651 `_, Leo Zhang) * common,core: ceph_test_rados_api_misc: fix LibRadosMiscConnectFailure.ConnectFailure retry (`issue#19901 `_, `pr#15522 `_, Sage Weil) +* common: core/common: Fix ENODATA for FreeBSD with compat.h (`issue#19883 `_, `pr#15685 `_, Willem Jan Withagen) * common,core: osd/OSDMap: make osd_state 32 bits wide (`pr#15390 `_, Sage Weil) * common,core: osd/OSDMap: replace require_*_osds flags with a single require_osd_release field (`pr#15068 `_, Sage Weil) * common,core: osd/OSDMap: replace string-based min_compat_client with a CEPH_RELEASE_* uint8_t (`pr#15351 `_, Sage Weil) @@ -202,31 +640,41 @@ Notable Changes * common: crush/CrushWrapper: fix has_incompat_choose_args (`pr#15218 `_, Sage Weil) * common: crush/CrushWrapper: fix has_incompat_choose_args() (`pr#15244 `_, Sage Weil) * common: denc: add encode/decode for basic_sstring (`pr#15135 `_, Kefu Chai, Casey Bodley) +* common: fix typo in option of rados_mon_op_timeout's comment (`pr#15681 `_, Leo Zhang) * common: get_process_name: use getprogname on bsd systems (`pr#15338 `_, Mykola Golub) * common: Improved CRC calculation for zero buffers (`pr#11966 `_, Adam Kupczyk) * common: include/lru.h: add const to member functions (`pr#15408 `_, yonghengdexin735) * common: include/rados: Fix typo in rados_ioctx_cct() doc (`pr#15220 `_, Jos Collin) * common: include: Redo some includes for FreeBSD (`issue#19883 `_, `pr#15337 `_, Willem Jan Withagen) +* common: initialize _hash in LogEntryKey() (`pr#15615 `_, Jos Collin) * common: int_types.h: remove hacks to workaround old systems (`pr#15069 `_, Kefu Chai) * common: librados,libradosstriper,test: migrate atomic_t to std::atomic (baragon) (`pr#14658 `_, Jesse Williamson) * common: libradosstriper: Add example code (`pr#15350 `_, Logan Blyth) * common: mempool: improve dump; fix buffer accounting bugs (`pr#15403 `_, Sage Weil) +* common: mgr/PyFormatter: implement dump_format_va (`pr#15634 `_, Sage Weil) * common,mon: messenger,client,compressor: migrate atomic_t to std::atomic (`pr#14657 `_, Jesse Williamson) * common,mon: mon,crush: add 'osd crush swap-bucket' command (`pr#15072 `_, Sage Weil) +* common: msg/async: add assert of ms_async_op_threads > 0 (`pr#15629 `_, linbing) * common,performance: buffer: allow buffers to be accounted in arbitrary mempools (`pr#15352 `_, Sage Weil) * common,performance: crc32c: Add ppc64le fast zero optimized assembly. (`pr#15100 `_, Andrew Solomon) * common,performance: inline_memory: optimized mem_is_zero for non-x64 (`pr#15307 `_, Piotr Dałek) * common,performance: kv/rocksdb: supports SliceParts interface (`pr#15058 `_, Haomai Wang) * common,performance: osd/OSDMap: make pg_temp more efficient (`pr#15291 `_, Sage Weil) +* common,rdma: msg/async/rdma: automatically set RDMAV_HUGEPAGES_SAFE according to conf (`pr#15755 `_, DanielBar-On) * common: Remove redundant includes - 2 (`issue#19883 `_, `pr#15169 `_, Jos Collin) * common: Remove redundant includes - 3 (`issue#19883 `_, `pr#15204 `_, Jos Collin) +* common: Remove redundant includes - 4 (`issue#19883 `_, `pr#15251 `_, Jos Collin) * common: Remove redundant includes - 5 (`issue#19883 `_, `pr#15267 `_, Jos Collin) * common: Remove redundant includes - 6 (`issue#19883 `_, `pr#15299 `_, Jos Collin) * common: Remove redundant includes (`issue#19883 `_, `pr#15042 `_, Brad Hubbard) * common: Remove redundant includes (`issue#19883 `_, `pr#15086 `_, Jos Collin) +* common: src/common/ceph_string: stringify new osd states (`pr#15751 `_, xie xingguo) * common,tests: ceph_test_rados_api_list: more fix LibRadosListNP.ListObjectsError (`issue#19963 `_, `pr#15138 `_, Sage Weil) +* common,tests: test: Make screencandy optional for FreeBSD (`pr#15444 `_, Willem Jan Withagen) * common: xio: migrate atomic_t to std::atomic<> (`pr#15230 `_, Jesse Williamson) +* core: ceph-dencoder: Silence coverity CID 1412579 (`pr#15744 `_, Brad Hubbard) * core: ceph-disk: do not setup_statedir on trigger (`issue#19941 `_, `pr#15410 `_, Loic Dachary) +* core: ceph-objectstore-tool: do not populate snapmapper with missing clones (`issue#19943 `_, `pr#15787 `_, Sage Weil) * core: compressor: add LZ4 support (`pr#15434 `_, Haomai Wang) * core: compressor: optimize header file dependency (`pr#15187 `_, Brad Hubbard, Xiaowei Chen) * core: crush, mon: make jewel the lower bound for client/crush compat for new clusters (`pr#15370 `_, Sage Weil) @@ -235,36 +683,65 @@ Notable Changes * core: filestore: migrate atomic_t to std::atomic<> (`pr#15228 `_, Jesse Williamson) * core: include/types.h, introduce host_to_ceph_errno (`pr#15496 `_, Willem Jan Withagen) * core: Install Pecan for FreeBSD (`pr#15610 `_, Willem Jan Withagen) +* core: introduce (and fix) code to pass errno to other OSes (`pr#15495 `_, Willem Jan Withagen) +* core: messages/MOSDPing: initialize MOSDPing padding (`issue#20323 `_, `pr#15714 `_, Sage Weil) * core,mgr: mgr/DaemonServer: stop spamming log with pg stats (`pr#15487 `_, Sage Weil) * core,mgr,mon: mon/PGMap: fix osd_epoch update when removing osd_stat (`issue#20208 `_, `pr#15573 `_, Sage Weil) +* core,mgr,tests: qa/suites/rados/rest: test restful mgr module (`pr#15604 `_, Sage Weil) +* core: mon,mgr: fix "ceph osd df", add some tools to find untested commands (`issue#20256 `_, `pr#15675 `_, Greg Farnum) * core,mon: mon/LogMonitor: 'log last' command (`pr#15497 `_, Sage Weil) +* core,mon: mon/MgrStatMonitor: keep mgrstat version ahead of pgmon (`issue#20219 `_, `pr#15584 `_, Sage Weil) +* core,mon: mon,osd: add crush_version to OSDMap, and allow crush map updates to gate on crush_version (`pr#15533 `_, Sage Weil) * core,mon: mon/OSDMonitor: cancel mapping job from update_from_paxos (`issue#20067 `_, `pr#15320 `_, Sage Weil) * core,mon: mon/OSDMonitor: use up set instead of acting set in reweight_by_utilization (`pr#13802 `_, Mingxin Liu) * core,mon: mon/PGMap: call blocked requests ERR not WARN (`pr#15501 `_, Sage Weil) +* core: mon/OSDMonitor: batch noup/noin osds support (`pr#15725 `_, xie xingguo) +* core: mon/OSDMonitor: batch OSDs nodown/noout support (`pr#15381 `_, xie xingguo) * core: mon/OSDMonitor: change info in 'osd failed' messages (`pr#15321 `_, Sage Weil) * core: mon,osd/OSDMap: a couple pg-upmap fixes (`pr#15319 `_, Sage Weil) * core: msg/async: avoid requeue racing with handle_write (`issue#20093 `_, `pr#15324 `_, Haomai Wang) +* core: msg/async: fix deleted_conn is out of sync with conns (`issue#20230 `_, `pr#15645 `_, Haomai Wang) +* core: objclass-sdk: use namespace ceph for bufferlist (`pr#15581 `_, Neha Ojha) +* core: osd/ECTransaction: only read partial stripes when below *original* object size (`issue#19882 `_, `pr#15712 `_, Sage Weil) * core: osd,librados: add manifest, redirect (`pr#15325 `_, Sage Weil) +* core: osd, messages/MOSDPing: bunch of fixes related to ping inflation (`pr#15727 `_, Piotr Dałek) +* core: osd/OSD: bump up current version; conditionally encoding manifest into oi (`pr#15687 `_, xie xingguo) +* core: osd/OSDMap: Change *pg_to_* to return void (`pr#15684 `_, Brad Hubbard) * core: osd/OSDMap: improve upmap calculation (`issue#19818 `_, `pr#14902 `_, Sage Weil) * core: osd/PG: drop pre-firefly compat_mode for choose_*_acting (`pr#15057 `_, Sage Weil) * core: osd/pglog: remove loop through empty collection (`pr#15121 `_, J. Eric Ivancich) +* core: osd/PG: make non-empty PastIntervals non-fatal (`issue#20167 `_, `pr#15639 `_, Sage Weil) +* core: osd/PrimaryLogPG: clear oi from trim_object() (`issue#19947 `_, `pr#15519 `_, Sage Weil) +* core: osd/PrimaryLogPG: fix oi reset during trim_object (`issue#19947 `_, `pr#15696 `_, Sage Weil) +* core: osd/PrimaryLogPG: record prior_version for DELETE events (`issue#20274 `_, `pr#15649 `_, Sage Weil) +* core: os/filestore: when print log, use __func__ instead of hard code function name (`pr#15261 `_, mychoxin) +* core: os/filestore: zfs add get_name() (`pr#15650 `_, Yanhu Cao) * core,performance: msg/async: reduce write_lock contention (`pr#15092 `_, Haomai Wang) +* core,performance: osd/OSD.h: requeue the scrub job with higher priority to shorten the blocking time of related requests (`pr#15552 `_, Jin Cai) +* core: qa: do not restrict valgrind runs to centos (`issue#18126 `_, `pr#15389 `_, Greg Farnum) * core,rgw: qa: Removed all 'default_idle_timeout' due to chnage in rwg task (`pr#15420 `_, Yuri Weinstein) * core,rgw,tests: qa/rgw_snaps: move default_idle_timeout config under the client (`issue#20128 `_, `pr#15400 `_, Yehuda Sadeh) * core: src/ceph.in: Use env(CEPH_DEV) to suppress noise from ceph (`pr#14746 `_, Willem Jan Withagen) * core,tests: ceph-disk: sensible default for block.db (`pr#15576 `_, Loic Dachary) -* core,tests: qa/suites/rados/*/at-end: wait for healthy before scrubbing (`pr#15245 `_, Sage Weil) +* core,tests: ceph_test_rados_api_*: wait for snap trim on ENOENT during cleanup (`issue#19948 `_, `pr#15638 `_, Sage Weil) +* core,tests: qa/suites/rados/\*/at-end: wait for healthy before scrubbing (`pr#15245 `_, Sage Weil) * core,tests: qa/suites/rados/singleton-nomsg/health-warnings: behave on ext4 (`issue#20043 `_, `pr#15207 `_, Sage Weil) * core,tests: qa/suites/rados: temporarily remove scrub_test from basic/ until post-luminous (`issue#19935 `_, `pr#15202 `_, Sage Weil) * core,tests: qa/suites/upgrade/kraken-x: enable experimental for bluestore (`pr#15359 `_, Sage Weil) +* core,tests: qa/tasks/ceph_manager: get osds all in after thrashing (`pr#15784 `_, Sage Weil) +* core,tests: qa/tasks/ceph: osd_scrub_pgs: reissue scrub requests in loop (`issue#20326 `_, `pr#15747 `_, Sage Weil) +* core,tests: qa/tasks/ceph.py: tolerate active+clean+something (`pr#15717 `_, Sage Weil) * core,tests: qa/workunits/cephtool/test.sh: fix osd full health detail grep (`issue#20187 `_, `pr#15494 `_, Sage Weil) * core,tests: qa/workunits/rados/test_health_warning: misc fixes (`issue#19990 `_, `pr#15201 `_, Sage Weil) +* core,tests: Revert "qa: do not restrict valgrind runs to centos" (`issue#20360 `_, `pr#15791 `_, Sage Weil) * core,tests: test/osd/TestRados.cc: run set-redirect test after finishing setup (`issue#20114 `_, `pr#15385 `_, Myoungwon Oh) * core,tools: osdmaptool: require --upmap-save before modifying input osdmap (`pr#15247 `_, Sage Weil) * crush: add missing tunable in tests (`pr#15412 `_, Loic Dachary) +* crush: detect and (usually) fix ruleset != rule id (`pr#13683 `_, Sage Weil) * crush: encode can override weights with weight set (`issue#19836 `_, `pr#15002 `_, Loic Dachary) * crush: optimize header file dependency (`pr#9307 `_, Xiaowei Chen) * crush: update choose_args when items are added/removed (`pr#15311 `_, Loic Dachary) +* doc: 12.1.0/release notes 2 (`pr#15627 `_, Abhishek Lekshmanan) * doc: add descriptions for mon/mgr options (`pr#15032 `_, Kefu Chai) * doc: add FreeBSD manual install (`pr#14941 `_, Willem Jan Withagen) * doc: add new cn ceph mirror to doc and mirroring (`pr#15089 `_, Shengjing Zhu) @@ -273,18 +750,24 @@ Notable Changes * doc: AUTHORS: update with release manager, backport team (`pr#15391 `_, Sage Weil) * doc: Change the default values of some OSD options (`issue#20199 `_, `pr#15566 `_, Bara Ancincova) * doc: describe CephFS max_file_size (`pr#15287 `_, Ken Dreyer) +* doc: describe mark_events logging available via the OSD's OpTracker (`pr#15095 `_, Greg Farnum) * doc: dev improve the s3tests doc to reflect current scripts (`pr#15180 `_, Abhishek Lekshmanan) * doc: doc/cephfs: mention RADOS object size limit (`pr#15550 `_, John Spray) * doc: doc/release-notes: update which jewel version does sortbitwise warning (`pr#15209 `_, Sage Weil) +* doc: doc/release-note: update release-note (`pr#15748 `_, liuchang0812) * doc: doc/rgw: remove fastcgi page and sample configs (`pr#15133 `_, Casey Bodley) +* doc: doc/rgw: remove Federated Configuration, clean up multisite (`issue#19504 `_, `issue#18082 `_, `pr#15132 `_, Casey Bodley) * doc: Documentation Fixes for http://tracker.ceph.com/issues/19879 (`issue#20057 `_, `issue#19879 `_, `pr#15606 `_, Sameer Tiwari) * doc: document perf historgrams (`pr#15150 `_, Piotr Dałek) * doc: Document RGW quota cache options (`issue#18747 `_, `pr#13395 `_, Daniel Gryniewicz) +* doc: document the setup of restful and dashboard plugins (`issue#20239 `_, `pr#15707 `_, Kefu Chai) * doc: fix broken link in erasure-code.rst (`issue#19972 `_, `pr#15143 `_, MinSheng Lin) * doc: fix factual inaccuracy in doc/architecture.rst (`pr#15235 `_, Nathan Cutler, Sage Weil) * doc: fixing an error in 12.0.3 release notes (`pr#15195 `_, Abhishek Lekshmanan) * doc: fix syntax on code snippets in cephfs/multimds (`pr#15499 `_, John Spray) +* doc: freshen mgr docs (`pr#15690 `_, John Spray) * doc: kill some broken links (`pr#15203 `_, liuchang0812) +* doc: mailmap for v12.0.2 (`pr#14753 `_, Abhishek Lekshmanan) * doc: mailmap: Leo Zhang infomation and affiliation (`pr#15145 `_, Leo Zhang) * doc: mention certain conf vars should be in global (`pr#15119 `_, Ali Maredia) * doc: Merge pull request from stiwari/wip-19879 (`issue#19879 `_, `pr#15609 `_, Sameer Tiwari) @@ -293,15 +776,19 @@ Notable Changes * doc: PendingReleaseNotes: warning about 'osd rm ...' and #19119 (`issue#19119 `_, `pr#13731 `_, Sage Weil) * doc: release-notes clarify about rgw encryption (`pr#14800 `_, Abhishek Lekshmanan) * doc: release notes for v12.0.3 (dev) (`pr#15090 `_, Abhishek Lekshmanan) +* doc: remove some non-existent and fix the default value according to … (`pr#15664 `_, Leo Zhang) * docs document "osd recovery max single start" setting (`issue#17396 `_, `pr#15275 `_, Ken Dreyer) +* doc: tools/cephfs: fix cephfs-journal-tool --help (`pr#15614 `_, John Spray) * doc: typo fixes on hyperlink/words (`pr#15144 `_, Drunkard Zhang) * doc: update sample explaning "%" operator in test suites (`pr#15511 `_, Kefu Chai) * doc: Update some RGW documentation (`pr#15175 `_, Jens Rosenboom) * doc: update the usage of 'ceph-deploy purge' (`pr#15080 `_, Yu Shengzuo) * doc: use do_cmake.sh instead of `cmake ..` (`pr#15110 `_, Kefu Chai) +* librbd: add create timestamp metadata for image (`pr#15757 `_, runsisi) * librbd: discard related IO should skip op if object non-existent (`issue#19962 `_, `pr#15239 `_, Mykola Golub) * librbd: do not raise an error if trash list returns -ENOENT (`pr#15085 `_, runsisi) * librbd: filter expected error codes from is_exclusive_lock_owner (`issue#20182 `_, `pr#15483 `_, Jason Dillaman) +* librbd: fix issues with image removal state machine (`pr#15734 `_, Jason Dillaman) * librbd: fix valgrind errors and ensure tests detect future leaks (`pr#15415 `_, Jason Dillaman) * librbd: optimize copy-up to add hints only once to object op (`issue#19875 `_, `pr#15037 `_, Mykola Golub) * librbd: potential read IO hang when image is flattened (`issue#19832 `_, `pr#15234 `_, Jason Dillaman) @@ -310,41 +797,60 @@ Notable Changes * librbd: remove unused rbd_image_options_t ostream operator (`pr#15443 `_, Mykola Golub) * mds: change the type of data_pools (`pr#15278 `_, Vicente Cheng) * mds: check export pin during replay (`issue#20039 `_, `pr#15205 `_, Patrick Donnelly) +* mds: Client syncfs is slow (waits for next MDS tick) (`issue#20129 `_, `pr#15544 `_, dongdong tao) +* mds: explicitly output error msg for dump cache asok command (`pr#15592 `_, Zhi Zhang) * mds: fix CDir::merge() for mds_debug_auth_pins (`issue#19946 `_, `pr#15130 `_, "Yan, Zheng") * mds: fix client ID truncation (`pr#15258 `_, Henry Chang) +* mds: fix hangs involving re-entrant calls to journaler (`issue#20165 `_, `pr#15430 `_, John Spray) +* mds: improvements for stray reintegration (`pr#15548 `_, "Yan, Zheng") * mds: limit client writable range increment (`issue#19955 `_, `pr#15131 `_, "Yan, Zheng") +* mds: mds perf item 'l_mdl_expos' always behind journaler (`pr#15621 `_, redickwang) +* mds: miscellaneous multimds fixes part2 (`pr#15125 `_, "Yan, Zheng") * mds: miscellaneous multimds fixes (`pr#14550 `_, "Yan, Zheng") +* mds: multimds flock fixes (`pr#15440 `_, "Yan, Zheng") * mds: Pass empty string to clear mantle balancer (`issue#20076 `_, `pr#15282 `_, Zhi Zhang) * mds: properly create aux subtrees for pinned directory (`issue#20083 `_, `pr#15300 `_, "Yan, Zheng") +* mds: save projected path into inode_t::stray_prior_path (`issue#20340 `_, `pr#15800 `_, "Yan, Zheng") * mgr: ceph-create-keys: update client.admin if it already exists (`issue#19940 `_, `pr#15112 `_, John Spray) * mgr: ceph: introduce "tell x help" subcommand (`issue#19885 `_, `pr#15111 `_, liuchang0812) * mgr: ceph-mgr: Implement new pecan-based rest api (`pr#14457 `_, Boris Ranto) * mgr: cleanup, stop clients sending in perf counters (`pr#15578 `_, John Spray) * mgr: dashboard code cleanup (`pr#15577 `_, John Spray) * mgr: dashboard GUI module (`pr#14946 `_, John Spray, Dan Mick) +* mgr: fix MgrStandby eating messages (`pr#15716 `_, John Spray) * mgr: load modules in separate python sub-interpreters (`pr#14971 `_, Tim Serong) * mgr: Mark session connections down on shutdown (`issue#19900 `_, `pr#15192 `_, Brad Hubbard) * mgr: mgr/DaemonServer.cc: log daemon type string as well as id (`pr#15560 `_, Dan Mick) +* mgr: mgr/dashboard: fix type error in get_rate function (`issue#20276 `_, `pr#15668 `_, liuchang0812) +* mgr: mgr/dashboard: load log lines on startup, split out audit log (`pr#15709 `_, John Spray) * mgr: mgr/MgrStandby: prevent use-after-free on just-shut-down Mgr (`issue#19595 `_, `pr#15297 `_, Sage Weil) * mgr: mgr/MgrStandby: respawn when deactivated (`issue#19595 `_, `issue#19549 `_, `pr#15557 `_, Sage Weil) * mgr: mgr,osd: ceph-mgr --help, unify usage text of other daemons (`pr#15176 `_, Tim Serong) * mgr,mon: mon,mgr: extricate PGmap from monitor (`issue#20067 `_, `issue#20174 `_, `issue#20050 `_, `pr#15073 `_, Kefu Chai, Sage Weil, Greg Farnum) * mgr,mon: mon/MgrMonitor: add 'mgr dump [epoch]' command (`pr#15158 `_, Sage Weil) +* mgr,mon: mon,mgr: print pgmap reports to debug (not cluster) log (`pr#15740 `_, Sage Weil) * mgr: optimize DaemonStateIndex::cull() a little bit (`pr#14967 `_, Kefu Chai) +* mgr: print a more helpful error message for when users lack mgr ceph caps (`issue#20296 `_, `pr#15697 `_, Greg Farnum) * mgr: pybind/mgr/dashboard: monkeypatch os.exit to stop cherrypy from taking down mgr (`issue#20216 `_, `pr#15588 `_, Sage Weil) * mgr: pybind/mgr: Delete `rest` module (`pr#15429 `_, John Spray) * mgr: pybind/mgr/restful: improve cert handling; work with vstart (`pr#15405 `_, Sage Weil) +* mgr: raise python exception on failure in send_command() (`pr#15704 `_, Kefu Chai) +* mgr: remove default cert; disable both restful and dashboard by default (`pr#15601 `_, Boris Ranto, Sage Weil) +* mgr,tests: qa/upgrade/jewel-x/point-to-point: add a mgr during final upgrade (`pr#15637 `_, Sage Weil) * mon: add crush type down health warnings (`pr#14914 `_, Neha Ojha) * mon: Add override for FsNewHandler::handle() (`pr#15331 `_, yonghengdexin735) * mon: cleanups (`pr#15272 `_, Kefu Chai) * mon: delete useless function definition (`pr#15188 `_, shiqi) +* mon: DIVIDE_BY_ZERO in PGMapDigest::dump_pool_stats_full() (`pr#15622 `_, Jos Collin) * mon: don't prefix mgr summary with epoch number (`pr#15512 `_, John Spray) * mon: fix accesing pending_fsmap from peon (`issue#20040 `_, `pr#15213 `_, John Spray) * mon: fix a few bugs with the osd health reporting (`pr#15179 `_, Sage Weil) * mon: Fixed typo in function comment blocks and in other comments (`pr#15304 `_, linbing) * mon: Fixed typo in @post of _active() (`pr#15191 `_, Linbing) * mon: fix mon_keyvaluedb application (`pr#15059 `_, Sage Weil) +* mon: Incorrect expression in PGMap::get_health() (`pr#15648 `_, Jos Collin) * mon: it's no need to get pg action_primary osd twice in pg scrub (`pr#15313 `_, linbing) +* mon: Log errors at startup (`issue#14088 `_, `pr#15723 `_, Ziye Yang) * mon: mon/MgrMonitor: send digests only if is_active() (`pr#15109 `_, Kefu Chai) * mon: mon/MonClient: cancel pending commands on shutdown (`issue#20051 `_, `pr#15227 `_, Kefu Chai, Sage Weil) * mon: {mon,osd,mds} {versions,count-metadata} (`pr#15436 `_, Sage Weil) @@ -358,6 +864,8 @@ Notable Changes * msg: do not enable client-side binding by default (`issue#20049 `_, `pr#15392 `_, Jason Dillaman) * msg: don't set msgr addr when disabing client bind (`pr#15243 `_, Haomai Wang) * msgr: msg/async: Lower down the AsyncMessenger's standby warning from debug (`pr#15242 `_, Pan Liu) +* msgr: msg/async/rdma: check if fin message completed (`pr#15624 `_, Alexander Mikheev, Adir Lev) +* msgr: msg/async/rdma: handle buffers after close msg (`pr#15749 `_, DanielBar-On, Alexander Mikheev, Adir Lev) * msgr: msg/async: remove false alert "assert" (`pr#15288 `_, Haomai Wang) * osd: don't leak pgrefs or reservations in SnapTrimmer (`issue#19931 `_, `pr#15214 `_, Greg Farnum) * osd: fix argument-dependent lookup of swap() (`pr#15124 `_, Casey Bodley) @@ -383,6 +891,7 @@ Notable Changes * pybind: pybind/rados: avoid call free() on invalid pointer (`pr#15159 `_, Mingxin Liu) * pybind,rbd: pybind/rbd: OSError should be picklable (`issue#20223 `_, `pr#15574 `_, Jason Dillaman) * pybind: support mon target in pybind (`pr#15409 `_, liuchang0812) +* qa: test/osd/osd-dup.sh: use wait_for_clean (`pr#15722 `_, Dan Mick) * rbd-mirror: coordinate image syncs with leader (`issue#18789 `_, `pr#14745 `_, Mykola Golub) * rbd-mirror: lock loss during sync should wait for in-flight copies (`pr#15532 `_, Jason Dillaman) * rbd-mirror: permit release of local image exclusive lock after force promotion (`issue#18963 `_, `pr#15140 `_, Jason Dillaman) @@ -424,6 +933,7 @@ Notable Changes * rgw: rgw_file: add lock protection for readdir against gc (`issue#20121 `_, `pr#15329 `_, Gui Hecheng) * rgw: rgw_file cleanup names (`pr#15568 `_, Gui Hecheng) * rgw: rgw_file: fix flags set on unsuccessful unlink (`pr#15222 `_, Gui Hecheng) +* rgw: rgw_file: prevent conflict of mkdir between restarts (`issue#20275 `_, `pr#15655 `_, Gui Hecheng) * rgw: rgw_file: release rgw_fh lock and ref on ENOTEMPTY (`issue#20061 `_, `pr#15246 `_, Matt Benjamin) * rgw: rgw_file: removed extra rele() on fs in rgw_umount() (`pr#15152 `_, Gui Hecheng) * rgw: rgw_file: remove hidden uxattr objects from buckets on delete (`issue#20045 `_, `pr#15210 `_, Matt Benjamin) @@ -453,7 +963,7 @@ Notable Changes * tests: qa/suites/rados/thrash: make sure osds have map before legacy scrub (`pr#15117 `_, Sage Weil) * tests: qa/suites/rados/upgrade: restart mds (`pr#15517 `_, Sage Weil) * tests: qa/tasks/ceph_manager: 'ceph $service tell ...' is obsolete (`pr#15252 `_, Sage Weil) -* tests: qa/tasks/rebuild_mondb: grant "mgr:allow *" to client.admin (`issue#19439 `_, `pr#14284 `_, Kefu Chai) +* tests: qa/tasks/rebuild_mondb: grant "mgr:allow \*" to client.admin (`issue#19439 `_, `pr#14284 `_, Kefu Chai) * tests: qa/tasks/repair_test: unset flags we set (`pr#15296 `_, Sage Weil) * tests: qa/workunits/ceph-helpers.sh: use syntax understood by jq 1.3 (`pr#15530 `_, Kefu Chai) * tests: Rename FileJournal object to distinguish (`pr#15279 `_, Jos Collin) @@ -468,15 +978,19 @@ Notable Changes * tests: test: test_denc.cc: silence warning from -Wsign-compare (`pr#15355 `_, Jos Collin) * tests: test: Test fix for SnapSet change (`pr#15161 `_, David Zafman) * tests: test/unittest_bluefs: check whether mounted success (`pr#14988 `_, shiqi) +* tools: ceph-disk: command invocation needs all fields separate (`pr#15733 `_, Willem Jan Withagen) * tools: ceph.in: adjust usage width according to user's tty (`pr#15190 `_, Kefu Chai) * tools: ceph.in: assert(state==connected) before help_for_target() (`pr#15156 `_, Kefu Chai) * tools: ceph.in: drop the compatiiblity to handle non json commands (`pr#15508 `_, Kefu Chai) * tools: ceph.in: print return code when json_command failed (`pr#15378 `_, liuchang0812) +* tools: ceph-rest-api: be more tolerant on network failure (`issue#20115 `_, `pr#15706 `_, Kefu Chai) +* tools: fio_ceph_objectstore: Print db_statistics when rocksdb_perf is enabled (`pr#15796 `_, Xiaoyan Li) * tools: tools/ceph_kvstore_tool: add "bluestore-kv" to usage (`pr#15326 `_, xie xingguo) * tools: tools/crushtool: replicated-rule API support (`pr#15011 `_, xie xingguo) * tools: vstart: "debug_ms=1" for mgr by default (`pr#15127 `_, Kefu Chai) * tools: vstart: print "start osd.$id" instead of "start osd$id" (`pr#15427 `_, Kefu Chai) + v12.0.3 Luminous (dev) ====================== @@ -743,7 +1257,7 @@ Notable Changes * rbd,tests: qa: krbd write-after-checksum tests (`pr#14836 `_, Ilya Dryomov) * rbd,tests: qa/workunits/rbd: increased trash deferment period (`pr#14846 `_, Jason Dillaman) * rbd,tests: qa/workunits: switch to OpenStack Ocata release for RBD testing (`pr#14465 `_, Jason Dillaman) -* rbd,tests: test/librbd/test_librbd.cc: set *features even if RBD_FEATURES is unset (`issue#19865 `_, `pr#14965 `_, Dan Mick) +* rbd,tests: test/librbd/test_librbd.cc: set \*features even if RBD_FEATURES is unset (`issue#19865 `_, `pr#14965 `_, Dan Mick) * rbd,tests: test/librbd/test_notify.py: don't disable feature in slave (`issue#19716 `_, `pr#14751 `_, Mykola Golub) * rbd,tests: test/rbd_mirror: race in TestMockLeaderWatcher.AcquireError (`issue#19405 `_, `pr#14741 `_, Mykola Golub) * rbd,tests: test: remove hard-coded image name from RBD metadata test (`issue#19798 `_, `pr#14848 `_, Jason Dillaman) @@ -1049,7 +1563,7 @@ Notable Changes * msg/async: Postpone bind if network stack is not ready (`pr#14414 `_, Amir Vadai, Haomai Wang) * msg: src/msg/async: Update fix broken compilation for Posix (`pr#14336 `_, Sarit Zubakov) * NVMEDevice: remove unnessary dpdk header file (`pr#14650 `_, optimistyzy) -* osd: add "heap *" admin command (`issue#15475 `_, `pr#13073 `_, Jesse Williamson) +* osd: add "heap \*" admin command (`issue#15475 `_, `pr#13073 `_, Jesse Williamson) * osd: add override in headers files (`pr#13962 `_, liuchang0812) * osd: Cleanup-Updated OSDMap.cc with C++11 style range-for loops (`pr#14381 `_, Jos Collin) * osd: combine unstable stats with info.stats when publish stats to osd (`pr#14060 `_, Mingxin Liu) @@ -4130,7 +4644,7 @@ Notable Changes * tests: Add test for global static non-POD segfault (`pr#10486 `_, Brad Hubbard) * tests: populate /dev/disk/by-partuuid for scsi_debug (`issue#17100 `_, `pr#10824 `_, Loic Dachary) * tests: use a fixture for memstore clone testing (`pr#11190 `_, Kefu Chai) -* tests: run-*make-check.sh: Make DRY_RUN actually mean a dry run (`pr#11074 `_, Brad Hubbard) +* tests: run-\*make-check.sh: Make DRY_RUN actually mean a dry run (`pr#11074 `_, Brad Hubbard) * tests: run-cmake-check.sh: Actually run the tests (`pr#11075 `_, Brad Hubbard) * tests: run-cmake-check.sh: Init submodules (`pr#11091 `_, Brad Hubbard) * tests: run-make-check.sh: Make DRY_RUN actually do a dry run (`pr#11092 `_, Brad Hubbard) @@ -4169,6 +4683,198 @@ Notable Changes * test: ceph_test_rados_api_tmap_migrate: remove test for tmap_upgrade (`pr#10234 `_, Kefu Chai) +v10.2.9 Jewel +============= + +This point release fixes a regression introduced in v10.2.8. + +We recommend that all Jewel users upgrade. + +For more detailed information, see :download:`the complete changelog `. + + +Notable Changes +--------------- + +* cephfs: Damaged MDS with 10.2.8 (`issue#20599 `_, `pr#16282 `_, Nathan Cutler) + + + +v10.2.8 Jewel +============= + +This point release brought a number of important bugfixes in all major +components of Ceph. However, it also introduced a regression that could cause +MDS damage, and a new release, v10.2.9, was published to address this. +Therefore, Jewel users should *not* upgrade to this version - instead, we +recommend upgrading directly to v10.2.9. + +For more detailed information, see :download:`the complete changelog `. + +OSD Removal Caveat +------------------ + +There was a bug introduced in Jewel (#19119) that broke the mapping behavior +when an "out" OSD that still existed in the CRUSH map was removed with 'osd rm'. +This could result in 'misdirected op' and other errors. The bug is now fixed, +but the fix itself introduces the same risk because the behavior may vary between +clients and OSDs. To avoid problems, please ensure that all OSDs are removed +from the CRUSH map before deleting them. That is, be sure to do:: + + ceph osd crush rm osd.123 + +before:: + + ceph osd rm osd.123 + +Snap Trimmer Improvements +------------------------- + +This release greatly improves control and throttling of the snap trimmer. It +introduces the "osd max trimming pgs" option (defaulting to 2), which limits +how many PGs on an OSD can be trimming snapshots at a time. And it restores +the safe use of the "osd snap trim sleep" option, wihch defaults to 0 but +otherwise adds the given number of seconds in delay between every dispatch +of trim operations to the underlying system. + +Other Notable Changes +--------------------- + +* build/ops: "osd marked itself down" will not recognised if host runs mon + osd on shutdown/reboot (`issue#18516 `_, `pr#13492 `_, Boris Ranto) +* build/ops: ceph-base package missing dependency for psmisc (`issue#19129 `_, `pr#13786 `_, Nathan Cutler) +* build/ops: enable build of ceph-resource-agents package on rpm-based os (`issue#17613 `_, `issue#19546 `_, `pr#13606 `_, Nathan Cutler) +* build/ops: rbdmap.service not included in debian packaging (jewel-only) (`issue#19547 `_, `pr#14383 `_, Ken Dreyer) +* cephfs: Journaler may execute on_safe contexts prematurely (`issue#20055 `_, `pr#15468 `_, "Yan, Zheng") +* cephfs: MDS assert failed when shutting down (`issue#19204 `_, `pr#14683 `_, John Spray) +* cephfs: MDS goes readonly writing backtrace for a file whose data pool has been removed (`issue#19401 `_, `pr#14682 `_, John Spray) +* cephfs: MDS server crashes due to inconsistent metadata (`issue#19406 `_, `pr#14676 `_, John Spray) +* cephfs: No output for ceph mds rmfailed 0 --yes-i-really-mean-it command (`issue#16709 `_, `pr#14674 `_, John Spray) +* cephfs: Test failure: test_data_isolated (tasks.cephfs.test_volume_client.TestVolumeClient) (`issue#18914 `_, `pr#14685 `_, "Yan, Zheng") +* cephfs: Test failure: test_open_inode (`issue#18661 `_, `pr#14669 `_, John Spray) +* cephfs: The mount point break off when mds switch hanppened (`issue#19437 `_, `pr#14679 `_, Guan yunfei) +* cephfs: ceph-fuse does not recover after lost connection to MDS (`issue#16743 `_, `issue#18757 `_, `pr#14698 `_, Kefu Chai, Henrik Korkuc, Patrick Donnelly) +* cephfs: client: fix the cross-quota rename boundary check conditions (`issue#18699 `_, `pr#14667 `_, Greg Farnum) +* cephfs: mds is crushed, after I set about 400 64KB xattr kv pairs to a file (`issue#19033 `_, `pr#14684 `_, Yang Honggang) +* cephfs: non-local quota changes not visible until some IO is done (`issue#17939 `_, `pr#15466 `_, John Spray, Nathan Cutler) +* cephfs: normalize file open flags internally used by cephfs (`issue#18872 `_, `issue#19890 `_, `pr#15000 `_, Jan Fajerski, "Yan, Zheng") +* common: monitor creation with IPv6 public network segfaults (`issue#19371 `_, `pr#14324 `_, Fabian Grünbichler) +* common: radosstriper: protect aio_write API from calls with 0 bytes (`issue#14609 `_, `pr#13254 `_, Sebastien Ponce) +* core: Objecter::epoch_barrier isn't respected in _op_submit() (`issue#19396 `_, `pr#14332 `_, Ilya Dryomov) +* core: clear divergent_priors set off disk (`issue#17916 `_, `pr#14596 `_, Greg Farnum) +* core: improve snap trimming, enable restriction of parallelism (`issue#19241 `_, `pr#14492 `_, Samuel Just, Greg Farnum) +* core: os/filestore/HashIndex: be loud about splits (`issue#18235 `_, `pr#13788 `_, Dan van der Ster) +* core: os/filestore: fix clang static check warn use-after-free (`issue#19311 `_, `pr#14044 `_, liuchang0812, yaoning) +* core: transient jerasure unit test failures (`issue#18070 `_, `issue#17762 `_, `issue#18128 `_, `issue#17951 `_, `pr#14701 `_, Kefu Chai, Pan Liu, Loic Dachary, Jason Dillaman) +* core: two instances of omap_digest mismatch (`issue#18533 `_, `pr#14204 `_, Samuel Just, David Zafman) +* doc: Improvements to crushtool manpage (`issue#19649 `_, `pr#14635 `_, Loic Dachary, Nathan Cutler) +* doc: PendingReleaseNotes: note about 19119 (`issue#19119 `_, `pr#13732 `_, Sage Weil) +* doc: admin ops: fix the quota section (`issue#19397 `_, `pr#14654 `_, Chu, Hua-Rong) +* doc: radosgw-admin: add the 'object stat' command to usage (`issue#19013 `_, `pr#13872 `_, Pavan Rallabhandi) +* doc: rgw S3 create bucket should not do response in json (`issue#18889 `_, `pr#13874 `_, Abhishek Lekshmanan) +* fs: Invalid error code returned by MDS is causing a kernel client WARNING (`issue#19205 `_, `pr#13831 `_, Jan Fajerski, xie xingguo) +* librbd: Incomplete declaration for ContextWQ in librbd/Journal.h (`issue#18862 `_, `pr#14152 `_, Boris Ranto) +* librbd: Issues with C API image metadata retrieval functions (`issue#19588 `_, `pr#14666 `_, Mykola Golub) +* librbd: Possible deadlock performing a synchronous API action while refresh in-progress (`issue#18419 `_, `pr#13154 `_, Jason Dillaman) +* librbd: is_exclusive_lock_owner API should ping OSD (`issue#19287 `_, `pr#14481 `_, Jason Dillaman) +* librbd: remove image header lock assertions (`issue#18244 `_, `pr#13809 `_, Jason Dillaman) +* mds: C_MDSInternalNoop::complete doesn't free itself (`issue#19501 `_, `pr#14677 `_, "Yan, Zheng") +* mds: Too many stat ops when trying to probe a large file (`issue#19955 `_, `pr#15472 `_, "Yan, Zheng") +* mds: avoid reusing deleted inode in StrayManager::_purge_stray_logged (`issue#18877 `_, `pr#14670 `_, Zhi Zhang) +* mds: enable start when session ino info is corrupt (`issue#19708 `_, `issue#16842 `_, `pr#14700 `_, John Spray) +* mds: fragment space check can cause replayed request fail (`issue#18660 `_, `pr#14668 `_, "Yan, Zheng") +* mds: heartbeat timeout during rejoin, when working with large amount of caps/inodes (`issue#19118 `_, `pr#14672 `_, John Spray) +* mds: issue new caps when sending reply to client (`issue#19635 `_, `pr#15438 `_, "Yan, Zheng") +* mon: OSDMonitor: make 'osd crush move ...' work on osds (`issue#18587 `_, `pr#13261 `_, Sage Weil) +* mon: fix 'sortbitwise' warning on jewel (`issue#20578 `_, `pr#15208 `_, huanwen ren, Sage Weil) +* mon: make get_mon_log_message() atomic (`issue#19427 `_, `pr#14587 `_, Kefu Chai) +* mon: remove bad rocksdb option (`issue#19392 `_, `pr#14236 `_, Sage Weil) +* msg: IPv6 Heartbeat packets are not marked with DSCP QoS - simple messenger (`issue#18887 `_, `pr#13450 `_, Yan Jun, Robin H. Johnson) +* msg: set close on exec flag (`issue#16390 `_, `pr#13585 `_, Kefu Chai) +* osd: --flush-journal: sporadic segfaults on exit (`issue#18820 `_, `pr#13477 `_, Alexey Sheplyakov) +* osd: Give requested scrubs a higher priority (`issue#15789 `_, `pr#14686 `_, David Zafman) +* osd: Implement asynchronous scrub sleep (`issue#19986 `_, `issue#19497 `_, `pr#15529 `_, Brad Hubbard) +* osd: Object level shard errors are tracked and used if no auth available (`issue#20089 `_, `pr#15416 `_, David Zafman) +* osd: ReplicatedPG: try with pool's use-gmt setting if hitset archive not found (`issue#19185 `_, `pr#13827 `_, Kefu Chai) +* osd: allow client throttler to be adjusted on-fly, without restart (`issue#18791 `_, `pr#13214 `_, Piotr Dałek) +* osd: bypass readonly ops when osd full (`issue#19394 `_, `pr#14181 `_, Jianpeng Ma, yaoning) +* osd: degraded and misplaced status output inaccurate (`issue#18619 `_, `pr#14325 `_, David Zafman) +* osd: new added OSD always down when full flag is set (`issue#15025 `_, `pr#14326 `_, Mingxin Liu) +* osd: pg_pool_t::encode(): be compatible with Hammer <= 0.94.6 (`issue#19508 `_, `pr#14392 `_, Alexey Sheplyakov) +* osd: pre-jewel "osd rm" incrementals are misinterpreted (`issue#19119 `_, `pr#13884 `_, Ilya Dryomov) +* osd: preserve allocation hint attribute during recovery (`issue#19083 `_, `pr#13647 `_, yaoning) +* osd: promote throttle parameters are reversed (`issue#19773 `_, `pr#14791 `_, Mark Nelson) +* osd: reindex properly on pg log split (`issue#18975 `_, `pr#14047 `_, Alexey Sheplyakov) +* osd: restrict want_acting to up+acting on recovery completion (`issue#18929 `_, `pr#13541 `_, Sage Weil) +* rbd-nbd: check /sys/block/nbdX/size to ensure kernel mapped correctly (`issue#18335 `_, `pr#13932 `_, Mykola Golub, Alexey Sheplyakov) +* rbd: [api] temporarily restrict (rbd_)mirror_peer_add from adding multiple peers (`issue#19256 `_, `pr#14664 `_, Jason Dillaman) +* rbd: qemu crash triggered by network issues (`issue#18436 `_, `pr#13244 `_, Jason Dillaman) +* rbd: rbd --pool=x rename y z does not work (`issue#18326 `_, `pr#14148 `_, Gaurav Kumar Garg) +* rbd: systemctl stop rbdmap unmaps all rbds and not just the ones in /etc/ceph/rbdmap (`issue#18884 `_, `issue#18262 `_, `pr#14083 `_, David Disseldorp, Nathan Cutler) +* rgw: "cluster [WRN] bad locator @X on object @X...." in cluster log (`issue#18980 `_, `pr#14064 `_, Casey Bodley) +* rgw: 'radosgw-admin sync status' on master zone of non-master zonegroup (`issue#18091 `_, `pr#13779 `_, Jing Wenjun) +* rgw: Change loglevel to 20 for 'System already converted' message (`issue#18919 `_, `pr#13834 `_, Vikhyat Umrao) +* rgw: Use decoded URI when verifying TempURL (`issue#18590 `_, `pr#13724 `_, Alexey Sheplyakov) +* rgw: a few cases where rgw_obj is incorrectly initialized (`issue#19096 `_, `pr#13842 `_, Yehuda Sadeh) +* rgw: add apis to support ragweed suite (`issue#19804 `_, `pr#14851 `_, Yehuda Sadeh) +* rgw: add bucket size limit check to radosgw-admin (`issue#17925 `_, `pr#14787 `_, Matt Benjamin) +* rgw: allow system users to read SLO parts (`issue#19027 `_, `pr#14752 `_, Casey Bodley) +* rgw: don't return skew time in pre-signed url (`issue#18828 `_, `issue#18829 `_, `pr#14605 `_, liuchang0812) +* rgw: failure to create s3 type subuser from admin rest api (`issue#16682 `_, `pr#14815 `_, snakeAngel2015) +* rgw: fix break inside of yield in RGWFetchAllMetaCR (`issue#17655 `_, `pr#14066 `_, Casey Bodley) +* rgw: fix failed to create bucket if a non-master zonegroup has a single zone (`issue#19756 `_, `pr#14766 `_, weiqiaomiao) +* rgw: health check errors out incorrectly (`issue#19025 `_, `pr#13865 `_, Pavan Rallabhandi) +* rgw: list_plain_entries() stops before bi_log entries (`issue#19876 `_, `pr#15383 `_, Casey Bodley) +* rgw: multisite: fetch_remote_obj() gets wrong version when copying from remote (`issue#19599 `_, `pr#14607 `_, Zhang Shaowen, Casey Bodley) +* rgw: multisite: some yields in RGWMetaSyncShardCR::full_sync() resume in incremental_sync() (`issue#18076 `_, `pr#13837 `_, Casey Bodley, Abhishek Lekshmanan) +* rgw: only append zonegroups to rest params if not empty (`issue#20078 `_, `pr#15312 `_, Yehuda Sadeh, Karol Mroz) +* rgw: pullup civet chunked (`issue#19736 `_, `pr#14776 `_, Matt Benjamin) +* rgw: rgw_file: fix event expire check, don't expire directories being read (`issue#19623 `_, `issue#19270 `_, `issue#19625 `_, `issue#19624 `_, `issue#19634 `_, `issue#19435 `_, `pr#14653 `_, Gui Hecheng, Matt Benjamin) +* rgw: swift: disable revocation thread under certain circumstances (`issue#19499 `_, `issue#9493 `_, `pr#14789 `_, Marcus Watts) +* rgw: the swift container acl does not support field .ref (`issue#18484 `_, `pr#13833 `_, Jing Wenjun) +* rgw: typo in rgw_admin.cc (`issue#19026 `_, `pr#13863 `_, Ronak Jain) +* rgw: unsafe access in RGWListBucket_ObjStore_SWIFT::send_response() (`issue#19249 `_, `pr#14661 `_, Yehuda Sadeh) +* rgw: upgrade to multisite v2 fails if there is a zone without zone info (`issue#19231 `_, `pr#14136 `_, Danny Al-Gaaf, Orit Wasserman) +* rgw: use separate http_manager for read_sync_status (`issue#19236 `_, `pr#14195 `_, Casey Bodley, Shasha Lu) +* rgw: when converting region_map we need to use rgw_zone_root_pool (`issue#19195 `_, `pr#14143 `_, Orit Wasserman) +* rgw: zonegroupmap set does not work (`issue#19498 `_, `issue#18725 `_, `pr#14660 `_, Orit Wasserman, Casey Bodley) +* rgw:fix memory leaks in data/md sync (`issue#20088 `_, `pr#15382 `_, weiqiaomiao) +* tests: 'ceph auth import -i' overwrites caps, should alert user before overwrite (`issue#18932 `_, `pr#13544 `_, Vikhyat Umrao) +* tests: New upgrade test for #19508 (`issue#19829 `_, `issue#19508 `_, `pr#14930 `_, Nathan Cutler) +* tests: [ FAILED ] TestLibRBD.ImagePollIO in upgrade:client-upgrade-kraken-distro-basic-smithi (`issue#18617 `_, `pr#13107 `_, Jason Dillaman) +* tests: [librados_test_stub] cls_cxx_map_get_XYZ methods don't return correct value (`issue#19597 `_, `pr#14665 `_, Jason Dillaman) +* tests: additional rbd-mirror test stability improvements (`issue#18935 `_, `pr#14154 `_, Jason Dillaman) +* tests: api_misc: [ FAILED ] LibRadosMiscConnectFailure.ConnectFailure (`issue#15368 `_, `pr#14763 `_, Sage Weil) +* tests: buffer overflow in test LibCephFS.DirLs (`issue#18941 `_, `pr#14671 `_, "Yan, Zheng") +* tests: clone workunit using the branch specified by task (`issue#19429 `_, `pr#14371 `_, Kefu Chai, Dan Mick) +* tests: drop upgrade/hammer-jewel-x (`issue#20574 `_, `pr#15933 `_, Nathan Cutler) +* tests: dummy suite fails in OpenStack (`issue#18259 `_, `pr#14070 `_, Nathan Cutler) +* tests: eliminate race condition in Thrasher constructor (`issue#18799 `_, `pr#13608 `_, Nathan Cutler) +* tests: enable quotas for pre-luminous quota tests (`issue#20412 `_, `pr#15936 `_, Patrick Donnelly) +* tests: fix oversight in yaml comment (`issue#20581 `_, `pr#14449 `_, Nathan Cutler) +* tests: move swift.py task from teuthology to ceph, phase one (jewel) (`issue#20392 `_, `pr#15870 `_, Nathan Cutler, Sage Weil, Warren Usui, Greg Farnum, Ali Maredia, Tommi Virtanen, Zack Cerza, Sam Lang, Yehuda Sadeh, Joe Buck, Josh Durgin) +* tests: qa/Fixed upgrade sequence to 10.2.0 -> 10.2.7 -> latest -x (10.2.8) (`issue#20572 `_, `pr#16089 `_, Yuri Weinstein) +* tests: qa/suites/upgrade/hammer-x: set "sortbitwise" for jewel clusters (`issue#20342 `_, `pr#15842 `_, Nathan Cutler) +* tests: qa/workunits/rados/test-upgrade-\*: whitelist tests for master (part 1) (`issue#20577 `_, `pr#15360 `_, Sage Weil) +* tests: qa/workunits/rados/test-upgrade-\*: whitelist tests for master (part 2) (`issue#20576 `_, `pr#15778 `_, Kefu Chai) +* tests: qa/workunits/rados/test-upgrade-\*: whitelist tests the right way (`issue#20575 `_, `pr#15824 `_, Kefu Chai) +* tests: rados: sleep before ceph tell osd.0 flush_pg_stats after restart (`issue#16239 `_, `issue#20489 `_, `pr#14710 `_, Kefu Chai, Nathan Cutler) +* tests: run upgrade/client-upgrade on latest CentOS 7.3 (`issue#20573 `_, `pr#16088 `_, Nathan Cutler) +* tests: run-rbd-unit-tests.sh assert in lockdep_will_lock, TestLibRBD.ObjectMapConsistentSnap (`issue#17447 `_, `pr#14150 `_, Jason Dillaman) +* tests: systemd test backport to jewel (`issue#19717 `_, `pr#14694 `_, Vasu Kulkarni) +* tests: test/librados/tmap_migrate: g_ceph_context->put() upon return (`issue#20579 `_, `pr#14809 `_, Kefu Chai) +* tests: test_notify.py: rbd.InvalidArgument: error updating features for image test_notify_clone2 (`issue#19692 `_, `pr#14680 `_, Jason Dillaman) +* tests: upgrade/hammer-x failing with OSD has the store locked when Thrasher runs ceph-objectstore-tool on down PG (`issue#19556 `_, `pr#14416 `_, Nathan Cutler) +* tests: upgrade:hammer-x/stress-split-erasure-code-x86_64 fails in 10.2.8 integration testing (`issue#20413 `_, `pr#15904 `_, Nathan Cutler) +* tools: brag fails to count "in" mds (`issue#19192 `_, `pr#14112 `_, Oleh Prypin, Peng Zhang) +* tools: ceph-disk does not support cluster names different than 'ceph' (`issue#17821 `_, `pr#14765 `_, Loic Dachary) +* tools: ceph-disk: Racing between partition creation and device node creation (`issue#19428 `_, `pr#14329 `_, Erwan Velu) +* tools: ceph-disk: bluestore --setgroup incorrectly set with user (`issue#18955 `_, `pr#13489 `_, craigchi) +* tools: ceph-disk: ceph-disk list reports mount error for OSD having mount options with SELinux context (`issue#17331 `_, `pr#14402 `_, Brad Hubbard) +* tools: ceph-disk: do not setup_statedir on trigger (`issue#19941 `_, `pr#15504 `_, Loic Dachary) +* tools: ceph-disk: enable directory backed OSD at boot time (`issue#19628 `_, `pr#14602 `_, Loic Dachary) +* tools: rados: RadosImport::import should return an error if Rados::connect fails (`issue#19319 `_, `pr#14113 `_, Brad Hubbard) + + v10.2.7 Jewel ============= @@ -4511,7 +5217,7 @@ For more detailed information, see :download:`the complete changelog `_, `pr#10860 `_, Kefu Chai) * osd: condition OSDMap encoding on features (`issue#18015 `_, `pr#12167 `_, Sage Weil) * osd: PG::_update_calc_stats wrong for CRUSH_ITEM_NONE up set items (`issue#16998 `_, `pr#10883 `_, Samuel Just) -* osd: PG::choose_acting valgrind error or ./common/hobject.h: 182: FAILED assert(!max || (*this == hobject_t(hobject_t::get_max()))) (`issue#13967 `_, `pr#10885 `_, Tao Chang) +* osd: PG::choose_acting valgrind error or ./common/hobject.h: 182: FAILED assert(!max || (\*this == hobject_t(hobject_t::get_max()))) (`issue#13967 `_, `pr#10885 `_, Tao Chang) * osd: Potential crash during journal::Replay shut down (`issue#16433 `_, `pr#10645 `_, Jason Dillaman) * osd: add peer_addr in heartbeat_check log message (`issue#15762 `_, `pr#9739 `_, Vikhyat Umrao, Sage Weil) * osd: adjust scrub boundary to object without SnapSet (`issue#17470 `_, `pr#11311 `_, Samuel Just) @@ -6554,7 +7260,7 @@ Notable Changes since Infernalis * tests: unittest_bufferlist: fix hexdump test (`pr#7152 `_, Sage Weil) * tests: unittest_ipaddr: fix segv (`pr#7154 `_, Sage Weil) * test/system/rados_list_parallel: print oid if rados_write fails (`issue#15240 `_, `pr#8309 `_, Kefu Chai) -* test/system/*: use dynamically generated pool name (`issue#15240 `_, `pr#8318 `_, Kefu Chai) +* test/system/\*: use dynamically generated pool name (`issue#15240 `_, `pr#8318 `_, Kefu Chai) * test/test-erasure-code.sh: disable pg_temp priming (`issue#15211 `_, `pr#8260 `_, Sage Weil) * test: TestMirroringWatcher test cases were not closing images (`pr#8435 `_, Jason Dillaman) * test/TestPGLog: fix the FTBFS (`issue#14930 `_, `pr#7855 `_, Kefu Chai) @@ -7268,7 +7974,7 @@ Notable Changes since v10.1.0 * script: subscription-manager support (`issue#14972 `_, `pr#7907 `_, Loic Dachary) * set 128MB tcmalloc cache size by bytes (`pr#8427 `_, Star Guo) * systemd: set up environment in rbdmap unit file (`issue#14984 `_, `pr#8222 `_, Nathan Cutler) -* test/system/*: use dynamically generated pool name (`issue#15240 `_, `pr#8318 `_, Kefu Chai) +* test/system/\*: use dynamically generated pool name (`issue#15240 `_, `pr#8318 `_, Kefu Chai) * test/system/rados_list_parallel: print oid if rados_write fails (`issue#15240 `_, `pr#8309 `_, Kefu Chai) * test/test-erasure-code.sh: disable pg_temp priming (`issue#15211 `_, `pr#8260 `_, Sage Weil) * test/test_pool_create.sh: fix port (`pr#8361 `_, Sage Weil) @@ -10111,7 +10817,7 @@ Other Notable Changes * msgr: OpTracker needs to release the message throttle in _unregistered (`issue#14248 `_, `pr#11938 `_, Samuel Just) * msgr: simple/Pipe: error decoding addr (`issue#18072 `_, `pr#12266 `_, Sage Weil) * osd: PG::_update_calc_stats wrong for CRUSH_ITEM_NONE up set items (`issue#16998 `_, `pr#11933 `_, Samuel Just) -* osd: PG::choose_acting valgrind error or ./common/hobject.h: 182: FAILED assert(!max || (*this == hobject_t(hobject_t::get_max()))) (`issue#13967 `_, `pr#11932 `_, Tao Chang) +* osd: PG::choose_acting valgrind error or ./common/hobject.h: 182: FAILED assert(!max || (\*this == hobject_t(hobject_t::get_max()))) (`issue#13967 `_, `pr#11932 `_, Tao Chang) * osd: ReplicatedBackend::build_push_op: add a second config to limit omap entries/chunk independently of object data (`issue#16128 `_, `pr#12417 `_, Wanlong Gao) * osd: crash on EIO during deep-scrubbing (`issue#16034 `_, `pr#11935 `_, Nathan Cutler) * osd: filestore: FALLOC_FL_PUNCH_HOLE must be used with FALLOC_FL_KEEP_SIZE (`issue#18446 `_, `pr#13041 `_, xinxin shu) @@ -10179,7 +10885,7 @@ For more detailed information, see :download:`the complete changelog `_, Sage Weil, Kefu Chai) +* build/ops: rocksdb do not link against tcmalloc if it's disabled (`issue#14799 `_, `pr#10750 `_, Sage Weil, Kefu Chai) * build/ops: Add -D_LARGEFILE64_SOURCE to Linux build. (`issue#16611 `_, `pr#10182 `_, Ira Cooper) * build/ops: boost uuid makes valgrind complain (`issue#12736 `_, `pr#9741 `_, Sage Weil, Rohan Mars) * build/ops: ceph-disk s/by-parttype-uuid/by-parttypeuuid/ (`issue#15867 `_, `pr#9107 `_, Nathan Cutler) diff --git a/ceph/doc/releases.rst b/ceph/doc/releases.rst index d36ea6f8a..7a0e78167 100644 --- a/ceph/doc/releases.rst +++ b/ceph/doc/releases.rst @@ -20,18 +20,28 @@ Timeline +----------------------------+-----------+-----------+-----------+-----------+-----------+--------------+-----------+-----------+ +----------------+-----------+-----------+-----------+-----------+-----------+-----------+--------------+-----------+-----------+ -| |Development|`Dumpling`_|`Emperor`_ |`Firefly`_ |`Giant`_ |`Hammer`_ |`Infernalis`_ |`Jewel`_ |`Kraken` | +| |Development|`Dumpling`_|`Emperor`_ |`Firefly`_ |`Giant`_ |`Hammer`_ |`Infernalis`_ |`Jewel`_ |`Kraken`_ | | |Testing |LTS |Stable |LTS |Stable |LTS |Stable |LTS |Stable | +----------------+-----------+-----------+-----------+-----------+-----------+-----------+--------------+-----------+-----------+ -| February 2017 | `12.0.0`_ | | | | |`0.94.10`_ | | | | +| June 2017 |`12.1.0`_ | | | | | | | | | +----------------+-----------+-----------+-----------+-----------+-----------+-----------+--------------+-----------+-----------+ -| January 2017 | | | | | | | | |`11.2.0`_ | +| May 2017 |`12.0.3`_ | | | | | | | | | +----------------+-----------+-----------+-----------+-----------+-----------+-----------+--------------+-----------+-----------+ -| December 2016 | | | | | | | |`10.2.5`_ | | +| April 2017 |`12.0.2`_ | | | | | | |`10.2.7`_ | | ++----------------+-----------+-----------+-----------+-----------+-----------+-----------+--------------+-----------+-----------+ +| March 2017 |`12.0.1`_ | | | | | | |`10.2.6`_ | | ++----------------+-----------+-----------+-----------+-----------+-----------+-----------+--------------+-----------+-----------+ +| February 2017 |`12.0.0`_ | | | | |`0.94.10`_ | | | | ++----------------+-----------+-----------+-----------+-----------+-----------+-----------+--------------+-----------+-----------+ +| January 2017 | 11.1.1 | | | | | | | |`11.2.0`_ | ++----------------+-----------+-----------+-----------+-----------+-----------+-----------+--------------+-----------+-----------+ +| December 2016 | 11.1.0 | | | | | | |`10.2.5`_ | | + +-----------+-----------+-----------+-----------+-----------+-----------+--------------+-----------+-----------+ | | | | | | | | |`10.2.4`_ | | +----------------+-----------+-----------+-----------+-----------+-----------+-----------+--------------+-----------+-----------+ -| October 2016 | | | | | | | | |`11.0.2`_ | +| October 2016 |`11.0.2`_ | | | | | | | | | ++ +-----------+-----------+-----------+-----------+-----------+-----------+--------------+-----------+-----------+ +| | 11.0.1 | | | | | | | | | +----------------+-----------+-----------+-----------+-----------+-----------+-----------+--------------+-----------+-----------+ | September 2016 | | | | | | | |`10.2.3`_ | | +----------------+-----------+-----------+-----------+-----------+-----------+-----------+--------------+-----------+-----------+ @@ -149,19 +159,26 @@ Timeline +----------------+-----------+-----------+-----------+-----------+-----------+-----------+--------------+-----------+-----------+ -.. _12.0.0: ../release-notes#v12.0.0-luminous-dev +.. _12.1.0: ../release-notes#v12-1-0-luminous-rc +.. _12.0.3: ../release-notes#v12-0-3-luminous-dev +.. _12.0.2: ../release-notes#v12-0-2-luminous-dev +.. _12.0.1: ../release-notes#v12-0-1-luminous-dev +.. _12.0.0: ../release-notes#v12-0-0-luminous-dev + +.. _11.2.0: ../release-notes#v11-2-0-kraken +.. _Kraken: ../release-notes#v11-2-0-kraken -.. _11.2.0: ../release-notes#v11.2.0-kraken -.. _11.0.2: ../release-notes#v11.0.2-kraken -.. _Kraken: ../release-notes#v11.0.2-kraken +.. _11.0.2: ../release-notes#v11-0-2-kraken -.. _10.2.5: ../release-notes#v10.2.5-jewel -.. _10.2.4: ../release-notes#v10.2.4-jewel -.. _10.2.3: ../release-notes#v10.2.3-jewel -.. _10.2.2: ../release-notes#v10.2.2-jewel -.. _10.2.1: ../release-notes#v10.2.1-jewel -.. _10.2.0: ../release-notes#v10.2.0-jewel -.. _Jewel: ../release-notes#v10.2.0-jewel +.. _10.2.7: ../release-notes#v10-2-7-jewel +.. _10.2.6: ../release-notes#v10-2-6-jewel +.. _10.2.5: ../release-notes#v10-2-5-jewel +.. _10.2.4: ../release-notes#v10-2-4-jewel +.. _10.2.3: ../release-notes#v10-2-3-jewel +.. _10.2.2: ../release-notes#v10-2-2-jewel +.. _10.2.1: ../release-notes#v10-2-1-jewel +.. _10.2.0: ../release-notes#v10-2-0-jewel +.. _Jewel: ../release-notes#v10-2-0-jewel .. _10.1.2: ../release-notes#v10-1-2-jewel-release-candidate .. _10.1.1: ../release-notes#v10-1-1-jewel-release-candidate @@ -174,7 +191,7 @@ Timeline .. _9.2.1: ../release-notes#v9-2-1-infernalis .. _9.2.0: ../release-notes#v9-2-0-infernalis -.. _Infernalis: ../release-notes#v9.2.0-infernalis +.. _Infernalis: ../release-notes#v9-2-0-infernalis .. _9.1.0: ../release-notes#v9-1-0 .. _9.0.3: ../release-notes#v9-0-3 diff --git a/ceph/doc/start/hardware-recommendations.rst b/ceph/doc/start/hardware-recommendations.rst index 779cf8fd5..dda222843 100644 --- a/ceph/doc/start/hardware-recommendations.rst +++ b/ceph/doc/start/hardware-recommendations.rst @@ -52,10 +52,7 @@ Data Storage Plan your data storage configuration carefully. There are significant cost and performance tradeoffs to consider when planning for data storage. Simultaneous OS operations, and simultaneous request for read and write operations from -multiple daemons against a single drive can slow performance considerably. There -are also file system limitations to consider: btrfs is not quite stable enough -for production, but it has the ability to journal and write data simultaneously, -whereas XFS does not. +multiple daemons against a single drive can slow performance considerably. .. important:: Since Ceph has to write all data to the journal before it can send an ACK (for XFS at least), having the journal and OSD @@ -99,8 +96,7 @@ You may run multiple Ceph OSD Daemons per hard disk drive, but this will likely lead to resource contention and diminish the overall throughput. You may store a journal and object data on the same drive, but this may increase the time it takes to journal a write and ACK to the client. Ceph must write to the journal -before it can ACK the write. The btrfs filesystem can write journal data and -object data simultaneously, whereas XFS cannot. +before it can ACK the write. Ceph best practices dictate that you should run operating systems, OSD data and OSD journals on separate drives. diff --git a/ceph/doc/start/index.rst b/ceph/doc/start/index.rst index f0e80b055..3e99bb804 100644 --- a/ceph/doc/start/index.rst +++ b/ceph/doc/start/index.rst @@ -1,6 +1,6 @@ -====================== - Installation (Quick) -====================== +============================ + Installation (ceph-deploy) +============================ .. raw:: html diff --git a/ceph/doc/start/intro.rst b/ceph/doc/start/intro.rst index 688a6c514..95b51dd83 100644 --- a/ceph/doc/start/intro.rst +++ b/ceph/doc/start/intro.rst @@ -2,42 +2,57 @@ Intro to Ceph =============== -Whether you want to provide :term:`Ceph Object Storage` and/or :term:`Ceph Block -Device` services to :term:`Cloud Platforms`, deploy a :term:`Ceph Filesystem` or -use Ceph for another purpose, all :term:`Ceph Storage Cluster` deployments begin -with setting up each :term:`Ceph Node`, your network and the Ceph Storage -Cluster. A Ceph Storage Cluster requires at least one Ceph Monitor and at least -two Ceph OSD Daemons. The Ceph Metadata Server is essential when running Ceph -Filesystem clients. - -.. ditaa:: +---------------+ +---------------+ +---------------+ - | OSDs | | Monitor | | MDS | - +---------------+ +---------------+ +---------------+ - -- **Ceph OSDs**: A :term:`Ceph OSD Daemon` (Ceph OSD) stores data, handles data - replication, recovery, backfilling, rebalancing, and provides some monitoring - information to Ceph Monitors by checking other Ceph OSD Daemons for a - heartbeat. A Ceph Storage Cluster requires at least two Ceph OSD Daemons to - achieve an ``active + clean`` state when the cluster makes two copies of your - data (Ceph makes 3 copies by default, but you can adjust it). - -- **Monitors**: A :term:`Ceph Monitor` maintains maps of the cluster state, - including the monitor map, the OSD map, the Placement Group (PG) map, and the - CRUSH map. Ceph maintains a history (called an "epoch") of each state change - in the Ceph Monitors, Ceph OSD Daemons, and PGs. - -- **MDSs**: A :term:`Ceph Metadata Server` (MDS) stores metadata on behalf of - the :term:`Ceph Filesystem` (i.e., Ceph Block Devices and Ceph Object Storage - do not use MDS). Ceph Metadata Servers make it feasible for POSIX file system - users to execute basic commands like ``ls``, ``find``, etc. without placing - an enormous burden on the Ceph Storage Cluster. - -Ceph stores a client's data as objects within storage pools. Using the CRUSH -algorithm, Ceph calculates which placement group should contain the object, -and further calculates which Ceph OSD Daemon should store the placement group. -The CRUSH algorithm enables the Ceph Storage Cluster to scale, rebalance, and -recover dynamically. - +Whether you want to provide :term:`Ceph Object Storage` and/or +:term:`Ceph Block Device` services to :term:`Cloud Platforms`, deploy +a :term:`Ceph Filesystem` or use Ceph for another purpose, all +:term:`Ceph Storage Cluster` deployments begin with setting up each +:term:`Ceph Node`, your network, and the Ceph Storage Cluster. A Ceph +Storage Cluster requires at least one Ceph Monitor, Ceph Manager, and +Ceph OSD (Object Storage Daemon). The Ceph Metadata Server is also +required when running Ceph Filesystem clients. + +.. ditaa:: +---------------+ +------------+ +------------+ +---------------+ + | OSDs | | Monitors | | Managers | | MDSs | + +---------------+ +------------+ +------------+ +---------------+ + +- **Monitors**: A :term:`Ceph Monitor` (``ceph-mon``) maintains maps + of the cluster state, including the monitor map, manager map, the + OSD map, and the CRUSH map. These maps are critical cluster state + required for Ceph daemons to coordinate with each other. Monitors + are also responsible for managing authentication between daemons and + clients. At least three monitors are normally required for + redundancy and high availability. + +- **Managers**: A :term:`Ceph Manager` daemon (``ceph-mgr``) is + responsible for keeping track of runtime metrics and the current + state of the Ceph cluster, including storage utilization, current + performance metrics, and system load. The Ceph Manager daemons also + host python-based plugins to manage and expose Ceph cluster + information, including a web-based `dashboard`_ and `REST API`_. At + least two managers are normally required for high availability. + +- **Ceph OSDs**: A :term:`Ceph OSD` (object storage daemon, + ``ceph-osd``) stores data, handles data replication, recovery, + rebalancing, and provides some monitoring information to Ceph + Monitors and Managers by checking other Ceph OSD Daemons for a + heartbeat. At least 3 Ceph OSDs are normally required for redundancy + and high availability. + +- **MDSs**: A :term:`Ceph Metadata Server` (MDS, ``ceph-mds``) stores + metadata on behalf of the :term:`Ceph Filesystem` (i.e., Ceph Block + Devices and Ceph Object Storage do not use MDS). Ceph Metadata + Servers allow POSIX file system users to execute basic commands (like + ``ls``, ``find``, etc.) without placing an enormous burden on the + Ceph Storage Cluster. + +Ceph stores data as objects within logical storage pools. Using the +:term:`CRUSH` algorithm, Ceph calculates which placement group should +contain the object, and further calculates which Ceph OSD Daemon +should store the placement group. The CRUSH algorithm enables the +Ceph Storage Cluster to scale, rebalance, and recover dynamically. + +.. _dashboard: ../../mgr/dashboard +.. _REST API: ../../mgr/restful .. raw:: html diff --git a/ceph/doc/start/os-recommendations.rst b/ceph/doc/start/os-recommendations.rst index 32d7fcf53..3aea814f5 100644 --- a/ceph/doc/start/os-recommendations.rst +++ b/ceph/doc/start/os-recommendations.rst @@ -13,9 +13,10 @@ Linux Kernel - **Ceph Kernel Client** - If you are using the kernel client, the general advice is to *track* "stable" - or "longterm maintenance" kernel series provided by either http://kernel.org - or your distribution on the kernel client machines. + If you are using the kernel client to map RBD block devices or mount + CephFS, the general advice is to use a "stable" or "longterm + maintenance" kernel series provided by either http://kernel.org or + your Linux distribution on any client hosts. For RBD, if you choose to *track* long-term kernels, we currently recommend 4.x-based "longterm maintenance" kernel series: @@ -23,19 +24,12 @@ Linux Kernel - 4.9.z - 4.4.z - These are considered pretty old, but if you must: - - - 3.16.z - - 3.10.z - For CephFS, see `CephFS best practices`_ for kernel version guidance. - Older kernel client versions may not support your `CRUSH tunables`_ profile. - -- **B-tree File System (Btrfs)** + Older kernel client versions may not support your `CRUSH tunables`_ profile + or other newer features of the Ceph cluster, requiring the storage cluster + to be configured with those features disabled. - If you use the ``btrfs`` file system with Ceph, we recommend using a - recent Linux kernel (3.14 or later). Platforms ========= @@ -45,13 +39,35 @@ platforms. Generally speaking, there is very little dependence on specific distributions aside from the kernel and system initialization package (i.e., sysvinit, upstart, systemd). -Infernalis (9.2.z) and Jewel (10.2.z) -------------------------------------- +Luminous (12.2.z) +----------------- + ++----------+----------+--------------------+--------------+---------+------------+ +| Distro | Release | Code Name | Kernel | Notes | Testing | ++==========+==========+====================+==============+=========+============+ +| CentOS | 7 | N/A | linux-3.10.0 | 3 | B, I, C | ++----------+----------+--------------------+--------------+---------+------------+ +| Debian | 8.0 | Jessie | linux-3.16.0 | 1, 2 | B, I | ++----------+----------+--------------------+--------------+---------+------------+ +| Debian | 9.0 | Stretch | linux-4.9 | 1, 2 | B, I | ++----------+----------+--------------------+--------------+---------+------------+ +| Fedora | 22 | N/A | linux-3.14.0 | | B, I | ++----------+----------+--------------------+--------------+---------+------------+ +| RHEL | 7 | Maipo | linux-3.10.0 | | B, I | ++----------+----------+--------------------+--------------+---------+------------+ +| Ubuntu | 14.04 | Trusty Tahr | linux-3.13.0 | | B, I, C | ++----------+----------+--------------------+--------------+---------+------------+ +| Ubuntu | 16.04 | Xenial Xerus | linux-4.4.0 | 3 | B, I, C | ++----------+----------+--------------------+--------------+---------+------------+ + + +Jewel (10.2.z) +-------------- +----------+----------+--------------------+--------------+---------+------------+ | Distro | Release | Code Name | Kernel | Notes | Testing | +==========+==========+====================+==============+=========+============+ -| CentOS | 7 | N/A | linux-3.10.0 | | B, I, C | +| CentOS | 7 | N/A | linux-3.10.0 | 3 | B, I, C | +----------+----------+--------------------+--------------+---------+------------+ | Debian | 8.0 | Jessie | linux-3.16.0 | 1, 2 | B, I | +----------+----------+--------------------+--------------+---------+------------+ @@ -62,8 +78,8 @@ Infernalis (9.2.z) and Jewel (10.2.z) | Ubuntu | 14.04 | Trusty Tahr | linux-3.13.0 | | B, I, C | +----------+----------+--------------------+--------------+---------+------------+ -Hammer (0.94) -------------- +Hammer (0.94.z) +--------------- +----------+----------+--------------------+--------------+---------+------------+ | Distro | Release | Code Name | Kernel | Notes | Testing | @@ -79,8 +95,8 @@ Hammer (0.94) | Ubuntu | 14.04 | Trusty Tahr | linux-3.13.0 | | B, I, C | +----------+----------+--------------------+--------------+---------+------------+ -Firefly (0.80) --------------- +Firefly (0.80.z) +---------------- +----------+----------+--------------------+--------------+---------+------------+ | Distro | Release | Code Name | Kernel | Notes | Testing | @@ -108,13 +124,16 @@ Notes ----- - **1**: The default kernel has an older version of ``btrfs`` that we do not - recommend for ``ceph-osd`` storage nodes. Upgrade to a recommended - kernel or use ``XFS``. + recommend for ``ceph-osd`` storage nodes. We recommend using ``XFS``. - **2**: The default kernel has an old Ceph client that we do not recommend for kernel client (kernel RBD or the Ceph file system). Upgrade to a recommended kernel. +- **3**: The default kernel regularly fails in QA when the ``btrfs`` + file system is used. We do not recommend using ``btrfs`` for + backing Ceph OSDs. + Testing ------- diff --git a/ceph/doc/start/quick-ceph-deploy.rst b/ceph/doc/start/quick-ceph-deploy.rst index e2bf65975..cc3899a70 100644 --- a/ceph/doc/start/quick-ceph-deploy.rst +++ b/ceph/doc/start/quick-ceph-deploy.rst @@ -9,9 +9,9 @@ explore Ceph functionality. .. include:: quick-common.rst -As a first exercise, create a Ceph Storage Cluster with one Ceph Monitor and two +As a first exercise, create a Ceph Storage Cluster with one Ceph Monitor and three Ceph OSD Daemons. Once the cluster reaches a ``active + clean`` state, expand it -by adding a third Ceph OSD Daemon, a Metadata Server and two more Ceph Monitors. +by adding a fourth Ceph OSD Daemon, a Metadata Server and two more Ceph Monitors. For best results, create a directory on your admin node for maintaining the configuration files and keys that ``ceph-deploy`` generates for your cluster. :: @@ -25,17 +25,9 @@ are in this directory when executing ``ceph-deploy``. if you are logged in as a different user, because it will not issue ``sudo`` commands needed on the remote host. -.. topic:: Disable ``requiretty`` - On some distributions (e.g., CentOS), you may receive an error while trying - to execute ``ceph-deploy`` commands. If ``requiretty`` is set - by default, disable it by executing ``sudo visudo`` and locate the - ``Defaults requiretty`` setting. Change it to ``Defaults:ceph !requiretty`` to - ensure that ``ceph-deploy`` can connect using the ``ceph`` user and execute - commands with ``sudo``. - -Create a Cluster -================ +Starting over +============= If at any point you run into trouble and you want to start over, execute the following to purge the Ceph packages, and erase all its data and configuration:: @@ -43,162 +35,126 @@ the following to purge the Ceph packages, and erase all its data and configurati ceph-deploy purge {ceph-node} [{ceph-node}] ceph-deploy purgedata {ceph-node} [{ceph-node}] ceph-deploy forgetkeys + rm ceph.* -If you execute ``purge``, you must re-install Ceph. +If you execute ``purge``, you must re-install Ceph. The last ``rm`` +command removes any files that were written out by ceph-deploy locally +during a previous installation. + + +Create a Cluster +================ On your admin node from the directory you created for holding your configuration details, perform the following steps using ``ceph-deploy``. #. Create the cluster. :: - ceph-deploy new {initial-monitor-node(s)} + ceph-deploy new {initial-monitor-node(s)} Specify node(s) as hostname, fqdn or hostname:fqdn. For example:: - ceph-deploy new node1 - - Check the output of ``ceph-deploy`` with ``ls`` and ``cat`` in the current - directory. You should see a Ceph configuration file, a monitor secret - keyring, and a log file for the new cluster. See `ceph-deploy new -h`_ - for additional details. - -#. Change the default number of replicas in the Ceph configuration file from - ``3`` to ``2`` so that Ceph can achieve an ``active + clean`` state with - just two Ceph OSDs. Add the following line under the ``[global]`` section:: + ceph-deploy new node1 - osd pool default size = 2 + Check the output of ``ceph-deploy`` with ``ls`` and ``cat`` in the + current directory. You should see a Ceph configuration file + (``ceph.conf``), a monitor secret keyring (``ceph.mon.keyring``), + and a log file for the new cluster. See `ceph-deploy new -h`_ for + additional details. #. If you have more than one network interface, add the ``public network`` setting under the ``[global]`` section of your Ceph configuration file. See the `Network Configuration Reference`_ for details. :: - public network = {ip-address}/{netmask} - -#. Install Ceph. :: - - ceph-deploy install {ceph-node}[{ceph-node} ...] + public network = {ip-address}/{bits} - For example:: - - ceph-deploy install admin-node node1 node2 node3 - - The ``ceph-deploy`` utility will install Ceph on each node. - **NOTE**: If you use ``ceph-deploy purge``, you must re-execute this step - to re-install Ceph. - - -#. Add the initial monitor(s) and gather the keys:: - - ceph-deploy mon create-initial - - Once you complete the process, your local directory should have the following - keyrings: + For example,:: - - ``{cluster-name}.client.admin.keyring`` - - ``{cluster-name}.bootstrap-osd.keyring`` - - ``{cluster-name}.bootstrap-mds.keyring`` - - ``{cluster-name}.bootstrap-rgw.keyring`` + public network = 10.1.2.0/24 -.. note:: The bootstrap-rgw keyring is only created during installation of clusters - running Hammer or newer + to use IPs in the 10.1.2.0/24 (or 10.1.2.0/255.255.255.0) network. -.. note:: If this process fails with a message similar to - "Unable to find /etc/ceph/ceph.client.admin.keyring", please ensure that the IP - listed for the monitor node in ceph.conf is the Public IP, not the Private IP. +#. If you are deploying in an IPv6 environment, add the following to + ``ceph.conf`` in the local directory:: -#. Add two OSDs. For fast setup, this quick start uses a directory rather - than an entire disk per Ceph OSD Daemon. See `ceph-deploy osd`_ for - details on using separate disks/partitions for OSDs and journals. - Login to the Ceph Nodes and create a directory for - the Ceph OSD Daemon. :: + echo ms bind ipv6 = true >> ceph.conf - ssh node2 - sudo mkdir /var/local/osd0 - exit +#. Install Ceph packages.:: - ssh node3 - sudo mkdir /var/local/osd1 - exit - - Then, from your admin node, use ``ceph-deploy`` to prepare the OSDs. :: - - ceph-deploy osd prepare {ceph-node}:/path/to/directory + ceph-deploy install {ceph-node} [...] For example:: - ceph-deploy osd prepare node2:/var/local/osd0 node3:/var/local/osd1 + ceph-deploy install node1 node2 node3 - Finally, activate the OSDs. :: + The ``ceph-deploy`` utility will install Ceph on each node. - ceph-deploy osd activate {ceph-node}:/path/to/directory +#. Deploy the initial monitor(s) and gather the keys:: - For example:: + ceph-deploy mon create-initial + + Once you complete the process, your local directory should have the following + keyrings: - ceph-deploy osd activate node2:/var/local/osd0 node3:/var/local/osd1 + - ``ceph.client.admin.keyring`` + - ``ceph.bootstrap-mgr.keyring`` + - ``ceph.bootstrap-osd.keyring`` + - ``ceph.bootstrap-mds.keyring`` + - ``ceph.bootstrap-rgw.keyring`` +.. note:: If this process fails with a message similar to "Unable to + find /etc/ceph/ceph.client.admin.keyring", please ensure that the + IP listed for the monitor node in ceph.conf is the Public IP, not + the Private IP. #. Use ``ceph-deploy`` to copy the configuration file and admin key to your admin node and your Ceph Nodes so that you can use the ``ceph`` CLI without having to specify the monitor address and ``ceph.client.admin.keyring`` each time you execute a command. :: - ceph-deploy admin {admin-node} {ceph-node} + ceph-deploy admin {ceph-node(s)} For example:: - ceph-deploy admin admin-node node1 node2 node3 - + ceph-deploy admin node1 node2 node3 - When ``ceph-deploy`` is talking to the local admin host (``admin-node``), - it must be reachable by its hostname. If necessary, modify ``/etc/hosts`` - to add the name of the admin host. +#. Deploy a manager daemon.:: -#. Ensure that you have the correct permissions for the - ``ceph.client.admin.keyring``. :: + ceph-deploy mgr create node1 - sudo chmod +r /etc/ceph/ceph.client.admin.keyring - -#. Check your cluster's health. :: +#. Add three OSDs. For the purposes of these instructions, we assume you have an + unused disk in each node called ``/dev/vdb``. *Be sure that the device is not currently in use and does not contain any important data.* - ceph health + ceph-deploy osd create {ceph-node}:{device} - Your cluster should return an ``active + clean`` state when it - has finished peering. + For example:: + ceph-deploy osd create node1:vdb node2:vdb node3:vdb -Operating Your Cluster -====================== +#. Check your cluster's health. :: -Deploying a Ceph cluster with ``ceph-deploy`` automatically starts the cluster. -To operate the cluster daemons with Debian/Ubuntu distributions, see -`Running Ceph with Upstart`_. To operate the cluster daemons with CentOS, -Red Hat, Fedora, and SLES distributions, see `Running Ceph with sysvinit`_. + ssh node1 sudo ceph health -To learn more about peering and cluster health, see `Monitoring a Cluster`_. -To learn more about Ceph OSD Daemon and placement group health, see -`Monitoring OSDs and PGs`_. To learn more about managing users, see -`User Management`_. + Your cluster should report ``HEALTH_OK``. You can view a more complete + cluster status with:: -Once you deploy a Ceph cluster, you can try out some of the administration -functionality, the ``rados`` object store command line, and then proceed to -Quick Start guides for Ceph Block Device, Ceph Filesystem, and the Ceph Object -Gateway. + ssh node1 sudo ceph -s Expanding Your Cluster ====================== -Once you have a basic cluster up and running, the next step is to expand -cluster. Add a Ceph OSD Daemon and a Ceph Metadata Server to ``node1``. -Then add a Ceph Monitor to ``node2`` and ``node3`` to establish a -quorum of Ceph Monitors. +Once you have a basic cluster up and running, the next step is to +expand cluster. Add a Ceph Metadata Server to ``node1``. Then add a +Ceph Monitor and Ceph Manager to ``node2`` and ``node3`` to improve reliability and availability. .. ditaa:: /------------------\ /----------------\ | ceph-deploy | | node1 | | Admin Node | | cCCC | | +-------->+ mon.node1 | - | | | osd.2 | + | | | osd.0 | + | | | mgr.node1 | | | | mds.node1 | \---------+--------/ \----------------/ | @@ -218,60 +174,68 @@ quorum of Ceph Monitors. | mon.node3 | \----------------/ -Adding an OSD -------------- - -Since you are running a 3-node cluster for demonstration purposes, add the OSD -to the monitor node. :: - - ssh node1 - sudo mkdir /var/local/osd2 - exit +Add a Metadata Server +--------------------- -Then, from your ``ceph-deploy`` node, prepare the OSD. :: +To use CephFS, you need at least one metadata server. Execute the following to +create a metadata server:: - ceph-deploy osd prepare {ceph-node}:/path/to/directory + ceph-deploy mds create {ceph-node} For example:: - ceph-deploy osd prepare node1:/var/local/osd2 + ceph-deploy mds create node1 + +Adding Monitors +--------------- -Finally, activate the OSDs. :: +A Ceph Storage Cluster requires at least one Ceph Monitor and Ceph +Manager to run. For high availability, Ceph Storage Clusters typically +run multiple Ceph Monitors so that the failure of a single Ceph +Monitor will not bring down the Ceph Storage Cluster. Ceph uses the +Paxos algorithm, which requires a majority of monitors (i.e., greather +than *N/2* where *N* is the number of monitors) to form a quorum. +Odd numbers of monitors tend to be better, although this is not required. - ceph-deploy osd activate {ceph-node}:/path/to/directory +.. tip: If you did not define the ``public network`` option above then + the new monitor will not know which IP address to bind to on the + new hosts. You can add this line to your ``ceph.conf`` by editing + it now and then push it out to each node with + ``ceph-deploy --overwrite-conf config push {ceph-nodes}``. -For example:: +Add two Ceph Monitors to your cluster:: - ceph-deploy osd activate node1:/var/local/osd2 + ceph-deploy mon add {ceph-nodes} +For example:: -Once you have added your new OSD, Ceph will begin rebalancing the cluster by -migrating placement groups to your new OSD. You can observe this process with -the ``ceph`` CLI. :: + ceph-deploy mon add node2 node3 - ceph -w +Once you have added your new Ceph Monitors, Ceph will begin synchronizing +the monitors and form a quorum. You can check the quorum status by executing +the following:: -You should see the placement group states change from ``active+clean`` to active -with some degraded objects, and finally ``active+clean`` when migration -completes. (Control-c to exit.) + ceph quorum_status --format json-pretty -Add a Metadata Server ---------------------- +.. tip:: When you run Ceph with multiple monitors, you SHOULD install and + configure NTP on each monitor host. Ensure that the + monitors are NTP peers. -To use CephFS, you need at least one metadata server. Execute the following to -create a metadata server:: +Adding Managers +--------------- - ceph-deploy mds create {ceph-node} +The Ceph Manager daemons operate in an active/standby pattern. Deploying +additional manager daemons ensures that if one daemon or host fails, another +one can take over without interrupting service. -For example:: +To deploy additional manager daemons:: - ceph-deploy mds create node1 + ceph-deploy mgr create node2 node3 +You should see the standby managers in the output from:: -.. note:: Currently Ceph runs in production with one metadata server only. You - may use more, but there is currently no commercial support for a cluster - with multiple metadata servers. + ssh node1 sudo ceph -s Add an RGW Instance @@ -287,9 +251,6 @@ For example:: ceph-deploy rgw create node1 -.. note:: This functionality is new with the **Hammer** release, and also with - ``ceph-deploy`` v1.5.23. - By default, the :term:`RGW` instance will listen on port 7480. This can be changed by editing ceph.conf on the node running the :term:`RGW` as follows: @@ -306,35 +267,6 @@ To use an IPv6 address, use: rgw frontends = civetweb port=[::]:80 -Adding Monitors ---------------- - -A Ceph Storage Cluster requires at least one Ceph Monitor to run. For high -availability, Ceph Storage Clusters typically run multiple Ceph -Monitors so that the failure of a single Ceph Monitor will not bring down the -Ceph Storage Cluster. Ceph uses the Paxos algorithm, which requires a majority -of monitors (i.e., 1, 2:3, 3:4, 3:5, 4:6, etc.) to form a quorum. - -Add two Ceph Monitors to your cluster. :: - - ceph-deploy mon add {ceph-node} - -For example:: - - ceph-deploy mon add node2 - ceph-deploy mon add node3 - -Once you have added your new Ceph Monitors, Ceph will begin synchronizing -the monitors and form a quorum. You can check the quorum status by executing -the following:: - - ceph quorum_status --format json-pretty - - -.. tip:: When you run Ceph with multiple monitors, you SHOULD install and - configure NTP on each monitor host. Ensure that the - monitors are NTP peers. - Storing/Retrieving Object Data ============================== @@ -350,41 +282,50 @@ how to assign the placement group to a Ceph OSD Daemon dynamically. To find the object location, all you need is the object name and the pool name. For example:: - ceph osd map {poolname} {object-name} + ceph osd map {poolname} {object-name} .. topic:: Exercise: Locate an Object - As an exercise, lets create an object. Specify an object name, a path to - a test file containing some object data and a pool name using the - ``rados put`` command on the command line. For example:: + As an exercise, lets create an object. Specify an object name, a path to + a test file containing some object data and a pool name using the + ``rados put`` command on the command line. For example:: - echo {Test-data} > testfile.txt - rados mkpool data - rados put {object-name} {file-path} --pool=data - rados put test-object-1 testfile.txt --pool=data + echo {Test-data} > testfile.txt + ceph osd pool create mytest 8 + rados put {object-name} {file-path} --pool=mytest + rados put test-object-1 testfile.txt --pool=mytest - To verify that the Ceph Storage Cluster stored the object, execute - the following:: + To verify that the Ceph Storage Cluster stored the object, execute + the following:: - rados -p data ls + rados -p mytest ls - Now, identify the object location:: + Now, identify the object location:: - ceph osd map {pool-name} {object-name} - ceph osd map data test-object-1 + ceph osd map {pool-name} {object-name} + ceph osd map mytest test-object-1 + + Ceph should output the object's location. For example:: + + osdmap e537 pool 'mytest' (1) object 'test-object-1' -> pg 1.d1743484 (1.4) -> up [1,0] acting [1,0] + + To remove the test object, simply delete it using the ``rados rm`` + command. + + For example:: - Ceph should output the object's location. For example:: + rados rm test-object-1 --pool=mytest - osdmap e537 pool 'data' (0) object 'test-object-1' -> pg 0.d1743484 (0.4) -> up [1,0] acting [1,0] + To delete the ``mytest`` pool:: - To remove the test object, simply delete it using the ``rados rm`` - command. For example:: + ceph osd pool rm mytest - rados rm test-object-1 --pool=data + (For safety reasons you will need to supply additional arguments as + prompted; deleting pools destroys data.) As the cluster evolves, the object location may change dynamically. One benefit of Ceph's dynamic rebalancing is that Ceph relieves you from having to perform -the migration manually. +data migration or balancing manually. .. _Preflight Checklist: ../quick-start-preflight diff --git a/ceph/doc/start/quick-common.rst b/ceph/doc/start/quick-common.rst index a2afa13e1..22cf501e3 100644 --- a/ceph/doc/start/quick-common.rst +++ b/ceph/doc/start/quick-common.rst @@ -1,19 +1,20 @@ .. ditaa:: - /------------------\ /----------------\ - | admin-node | | node1 | - | +-------->+ cCCC | - | ceph-deploy | | mon.node1 | - \---------+--------/ \----------------/ + /------------------\ /-----------------\ + | admin-node | | node1 | + | +-------->+ cCCC | + | ceph-deploy | | mon.node1 | + | | | osd.0 | + \---------+--------/ \-----------------/ | | /----------------\ | | node2 | +----------------->+ cCCC | - | | osd.0 | + | | osd.1 | | \----------------/ | | /----------------\ | | node3 | +----------------->| cCCC | - | osd.1 | + | osd.2 | \----------------/ diff --git a/ceph/doc/start/quick-rbd.rst b/ceph/doc/start/quick-rbd.rst index 59c70cd12..11d85262f 100644 --- a/ceph/doc/start/quick-rbd.rst +++ b/ceph/doc/start/quick-rbd.rst @@ -47,6 +47,10 @@ Install Ceph directory. Ensure that the keyring file has appropriate read permissions (e.g., ``sudo chmod +r /etc/ceph/ceph.client.admin.keyring``). +Create an rbd pool +================== +#. On the admin node, use the ``ceph`` tool to `Create a Pool`_ + (we recommend the name 'rbd'). Configure a Block Device ======================== @@ -78,6 +82,7 @@ Configure a Block Device See `block devices`_ for additional details. +.. _Create a Pool: ../../rados/operations/pools#createpool .. _Storage Cluster Quick Start: ../quick-ceph-deploy .. _block devices: ../../rbd/rbd .. _FAQ: http://wiki.ceph.com/How_Can_I_Give_Ceph_a_Try diff --git a/ceph/doc/start/quick-start-preflight.rst b/ceph/doc/start/quick-start-preflight.rst index aea60bf12..f4b246e7a 100644 --- a/ceph/doc/start/quick-start-preflight.rst +++ b/ceph/doc/start/quick-start-preflight.rst @@ -2,23 +2,16 @@ Preflight Checklist ===================== -.. versionadded:: 0.60 - -Thank you for trying Ceph! We recommend setting up a ``ceph-deploy`` admin -:term:`node` and a 3-node :term:`Ceph Storage Cluster` to explore the basics of -Ceph. This **Preflight Checklist** will help you prepare a ``ceph-deploy`` -admin node and three Ceph Nodes (or virtual machines) that will host your Ceph -Storage Cluster. Before proceeding any further, see `OS Recommendations`_ to -verify that you have a supported distribution and version of Linux. When -you use a single Linux distribution and version across the cluster, it will -make it easier for you to troubleshoot issues that arise in production. +The ``ceph-deploy`` tool operates out of a directory on an admin +:term:`node`. Any host with network connectivity and a modern python +environment and ssh (such as Linux) should work. In the descriptions below, :term:`Node` refers to a single machine. .. include:: quick-common.rst -Ceph Deploy Setup +Ceph-deploy Setup ================= Add Ceph repositories to the ``ceph-deploy`` admin node. Then, install @@ -33,18 +26,23 @@ For Debian and Ubuntu distributions, perform the following steps: wget -q -O- 'https://download.ceph.com/keys/release.asc' | sudo apt-key add - -#. Add the Ceph packages to your repository. Replace ``{ceph-stable-release}`` - with a stable Ceph release (e.g., ``hammer``, ``jewel``, etc.) - For example:: +#. Add the Ceph packages to your repository:: + + echo deb https://download.ceph.com/debian/ $(lsb_release -sc) main | sudo tee /etc/apt/sources.list.d/ceph.list + + The above URL contains the latest stable release of Ceph. If you + would like to select a specific release, use the command below and + replace ``{ceph-stable-release}`` with a stable Ceph release (e.g., + ``luminous``.) For example:: echo deb https://download.ceph.com/debian-{ceph-stable-release}/ $(lsb_release -sc) main | sudo tee /etc/apt/sources.list.d/ceph.list #. Update your repository and install ``ceph-deploy``:: - sudo apt-get update && sudo apt-get install ceph-deploy + sudo apt update + sudo apt install ceph-deploy -.. note:: You can also use the EU mirror eu.ceph.com for downloading your packages. - Simply replace ``http://ceph.com/`` by ``http://eu.ceph.com/`` +.. note:: You can also use the EU mirror eu.ceph.com for downloading your packages by replacing ``https://ceph.com/`` by ``http://eu.ceph.com/`` RHEL/CentOS @@ -52,7 +50,9 @@ RHEL/CentOS For CentOS 7, perform the following steps: -#. On Red Hat Enterprise Linux 7, register the target machine with ``subscription-manager``, verify your subscriptions, and enable the "Extras" repository for package dependencies. For example:: +#. On Red Hat Enterprise Linux 7, register the target machine with + ``subscription-manager``, verify your subscriptions, and enable the + "Extras" repository for package dependencies. For example:: sudo subscription-manager repos --enable=rhel-7-server-extras-rpms @@ -63,35 +63,25 @@ For CentOS 7, perform the following steps: Please see the `EPEL wiki`_ page for more information. +#. Add the Ceph repository to your yum configuration file at ``/etc/yum.repos.d/ceph.repo`` with the following command:: -#. Add the package to your repository. Open a text editor and create a - Yellowdog Updater, Modified (YUM) entry. Use the file path - ``/etc/yum.repos.d/ceph.repo``. For example:: - - sudo vim /etc/yum.repos.d/ceph.repo - - Paste the following example code. Replace ``{ceph-release}`` with - the recent major release of Ceph (e.g., ``jewel``). Replace ``{distro}`` - with your Linux distribution (e.g., ``el7`` for CentOS 7). Finally, save the - contents to the - ``/etc/yum.repos.d/ceph.repo`` file. :: - - [ceph-noarch] - name=Ceph noarch packages - baseurl=https://download.ceph.com/rpm-{ceph-release}/{distro}/noarch - enabled=1 - gpgcheck=1 - type=rpm-md - gpgkey=https://download.ceph.com/keys/release.asc + cat >/etc/yum.repos.d/ceph.repro + [ceph-noarch] + name=Ceph noarch packages + baseurl=https://download.ceph.com/rpm/el7/noarch + enabled=1 + gpgcheck=1 + type=rpm-md + gpgkey=https://download.ceph.com/keys/release.asc + and then this *Control-D*. This will use the latest stable Ceph release. If you would like to install a different release, replace ``https://download.ceph.com/rpm/el7/noarch`` with ``https://download.ceph.com/rpm-{ceph-release}/el7/noarch`` where ``{ceph-release}`` is a release name like ``luminous``. #. Update your repository and install ``ceph-deploy``:: - sudo yum update && sudo yum install ceph-deploy - + sudo yum update + sudo yum install ceph-deploy -.. note:: You can also use the EU mirror eu.ceph.com for downloading your packages. - Simply replace ``http://ceph.com/`` by ``http://eu.ceph.com/`` +.. note:: You can also use the EU mirror eu.ceph.com for downloading your packages by replacing ``https://ceph.com/`` by ``http://eu.ceph.com/`` openSUSE @@ -137,7 +127,7 @@ On CentOS / RHEL, execute:: On Debian / Ubuntu, execute:: - sudo apt-get install ntp + sudo apt install ntp Ensure that you enable the NTP service. Ensure that each Ceph Node uses the same NTP time server. See `NTP`_ for details. @@ -150,7 +140,7 @@ For **ALL** Ceph Nodes perform the following steps: #. Install an SSH server (if necessary) on each Ceph Node:: - sudo apt-get install openssh-server + sudo apt install openssh-server or:: diff --git a/ceph/install-deps.sh b/ceph/install-deps.sh index 626cbc9e3..315848d90 100755 --- a/ceph/install-deps.sh +++ b/ceph/install-deps.sh @@ -43,6 +43,7 @@ if [ x`uname`x = xFreeBSDx ]; then ftp/curl \ misc/e2fsprogs-libuuid \ misc/getopt \ + net/socat \ textproc/expat2 \ textproc/gsed \ textproc/libxml2 \ diff --git a/ceph/qa/cephfs/overrides/whitelist_wrongly_marked_down.yaml b/ceph/qa/cephfs/overrides/whitelist_wrongly_marked_down.yaml index 4f2d6df18..155ca7245 100644 --- a/ceph/qa/cephfs/overrides/whitelist_wrongly_marked_down.yaml +++ b/ceph/qa/cephfs/overrides/whitelist_wrongly_marked_down.yaml @@ -1,7 +1,12 @@ overrides: ceph: log-whitelist: + - overall HEALTH_ + - (OSD_DOWN) + - (OSD_ - wrongly marked me down +# MDS daemon 'b' is not responding, replacing it as rank 0 with standby 'a' + - is not responding conf: mds: debug mds: 20 diff --git a/ceph/qa/erasure-code/ec-rados-plugin=isa-k=2-m=1.yaml b/ceph/qa/erasure-code/ec-rados-plugin=isa-k=2-m=1.yaml index f69963933..64b59705c 100644 --- a/ceph/qa/erasure-code/ec-rados-plugin=isa-k=2-m=1.yaml +++ b/ceph/qa/erasure-code/ec-rados-plugin=isa-k=2-m=1.yaml @@ -12,7 +12,7 @@ tasks: k: 2 m: 1 technique: reed_sol_van - ruleset-failure-domain: osd + crush-failure-domain: osd op_weights: read: 100 write: 0 diff --git a/ceph/qa/erasure-code/ec-rados-plugin=jerasure-k=2-m=1.yaml b/ceph/qa/erasure-code/ec-rados-plugin=jerasure-k=2-m=1.yaml index 4fa8d9f35..d61b1c8af 100644 --- a/ceph/qa/erasure-code/ec-rados-plugin=jerasure-k=2-m=1.yaml +++ b/ceph/qa/erasure-code/ec-rados-plugin=jerasure-k=2-m=1.yaml @@ -11,7 +11,7 @@ tasks: k: 2 m: 1 technique: reed_sol_van - ruleset-failure-domain: osd + crush-failure-domain: osd op_weights: read: 100 write: 0 diff --git a/ceph/qa/erasure-code/ec-rados-plugin=jerasure-k=3-m=1.yaml b/ceph/qa/erasure-code/ec-rados-plugin=jerasure-k=3-m=1.yaml index 3c31a8b30..2ca53a799 100644 --- a/ceph/qa/erasure-code/ec-rados-plugin=jerasure-k=3-m=1.yaml +++ b/ceph/qa/erasure-code/ec-rados-plugin=jerasure-k=3-m=1.yaml @@ -17,7 +17,7 @@ tasks: k: 3 m: 1 technique: reed_sol_van - ruleset-failure-domain: osd + crush-failure-domain: osd op_weights: read: 100 write: 0 diff --git a/ceph/qa/erasure-code/ec-rados-plugin=lrc-k=4-m=2-l=3.yaml b/ceph/qa/erasure-code/ec-rados-plugin=lrc-k=4-m=2-l=3.yaml index 3463a01ac..86ae0568c 100644 --- a/ceph/qa/erasure-code/ec-rados-plugin=lrc-k=4-m=2-l=3.yaml +++ b/ceph/qa/erasure-code/ec-rados-plugin=lrc-k=4-m=2-l=3.yaml @@ -11,7 +11,7 @@ tasks: k: 4 m: 2 l: 3 - ruleset-failure-domain: osd + crush-failure-domain: osd op_weights: read: 100 write: 0 diff --git a/ceph/qa/erasure-code/ec-rados-plugin=shec-k=4-m=3-c=2.yaml b/ceph/qa/erasure-code/ec-rados-plugin=shec-k=4-m=3-c=2.yaml index 696baedda..ee74c6e98 100644 --- a/ceph/qa/erasure-code/ec-rados-plugin=shec-k=4-m=3-c=2.yaml +++ b/ceph/qa/erasure-code/ec-rados-plugin=shec-k=4-m=3-c=2.yaml @@ -11,7 +11,7 @@ tasks: k: 4 m: 3 c: 2 - ruleset-failure-domain: osd + crush-failure-domain: osd op_weights: read: 100 write: 0 diff --git a/ceph/qa/objectstore/bluestore-comp.yaml b/ceph/qa/objectstore/bluestore-comp.yaml index 274962f0f..16767efac 100644 --- a/ceph/qa/objectstore/bluestore-comp.yaml +++ b/ceph/qa/objectstore/bluestore-comp.yaml @@ -14,6 +14,11 @@ overrides: debug rocksdb: 10 bluestore compression mode: aggressive bluestore fsck on mount: true + # lower the full ratios since we can fill up a 100gb osd so quickly + mon osd full ratio: .9 + mon osd backfillfull_ratio: .85 + mon osd nearfull ratio: .8 + osd failsafe full ratio: .95 # this doesn't work with failures bc the log writes are not atomic across the two backends # bluestore bluefs env mirror: true diff --git a/ceph/qa/objectstore/bluestore.yaml b/ceph/qa/objectstore/bluestore.yaml index d7f59aa45..794d9e9d0 100644 --- a/ceph/qa/objectstore/bluestore.yaml +++ b/ceph/qa/objectstore/bluestore.yaml @@ -13,6 +13,10 @@ overrides: debug bluefs: 20 debug rocksdb: 10 bluestore fsck on mount: true - + # lower the full ratios since we can fill up a 100gb osd so quickly + mon osd full ratio: .9 + mon osd backfillfull_ratio: .85 + mon osd nearfull ratio: .8 + osd failsafe full ratio: .95 # this doesn't work with failures bc the log writes are not atomic across the two backends # bluestore bluefs env mirror: true diff --git a/ceph/qa/objectstore/filestore-btrfs.yaml b/ceph/qa/objectstore/filestore-btrfs.yaml deleted file mode 100644 index 8eea43e3b..000000000 --- a/ceph/qa/objectstore/filestore-btrfs.yaml +++ /dev/null @@ -1,7 +0,0 @@ -overrides: - ceph: - fs: btrfs - conf: - osd: - osd objectstore: filestore - osd op thread timeout: 60 diff --git a/ceph/qa/rgw_pool_type/ec-profile.yaml b/ceph/qa/rgw_pool_type/ec-profile.yaml index 52798f85e..05384cb53 100644 --- a/ceph/qa/rgw_pool_type/ec-profile.yaml +++ b/ceph/qa/rgw_pool_type/ec-profile.yaml @@ -5,6 +5,6 @@ overrides: name: testprofile k: 3 m: 1 - ruleset-failure-domain: osd + crush-failure-domain: osd s3tests: slow_backend: true diff --git a/ceph/qa/suites/ceph-disk/basic/tasks/ceph-disk.yaml b/ceph/qa/suites/ceph-disk/basic/tasks/ceph-disk.yaml index 98adab33e..b79ce8dc0 100644 --- a/ceph/qa/suites/ceph-disk/basic/tasks/ceph-disk.yaml +++ b/ceph/qa/suites/ceph-disk/basic/tasks/ceph-disk.yaml @@ -17,6 +17,9 @@ tasks: - ceph: fs: xfs # this implicitly means /dev/vd? are used instead of directories wait-for-scrub: false + log-whitelist: + - (OSD_ + - (PG_ conf: global: mon pg warn min per osd: 2 diff --git a/ceph/qa/suites/fs/basic_functional/overrides/whitelist_health.yaml b/ceph/qa/suites/fs/basic_functional/overrides/whitelist_health.yaml new file mode 100644 index 000000000..b5bf1fa7b --- /dev/null +++ b/ceph/qa/suites/fs/basic_functional/overrides/whitelist_health.yaml @@ -0,0 +1,9 @@ +overrides: + ceph: + log-whitelist: + - overall HEALTH_ + - (FS_DEGRADED) + - (MDS_FAILED) + - (MDS_DEGRADED) + - (FS_WITH_FAILED_MDS) + - (MDS_DAMAGE) diff --git a/ceph/qa/suites/fs/basic_functional/tasks/cephfs_scrub_tests.yaml b/ceph/qa/suites/fs/basic_functional/tasks/cephfs_scrub_tests.yaml index 3b2714689..30b3a96e2 100644 --- a/ceph/qa/suites/fs/basic_functional/tasks/cephfs_scrub_tests.yaml +++ b/ceph/qa/suites/fs/basic_functional/tasks/cephfs_scrub_tests.yaml @@ -4,6 +4,8 @@ overrides: - Scrub error on inode - Behind on trimming - Metadata damage detected + - overall HEALTH_ + - (MDS_TRIM) conf: mds: mds log max segments: 1 diff --git a/ceph/qa/suites/fs/basic_functional/tasks/cfuse_workunit_quota.yaml b/ceph/qa/suites/fs/basic_functional/tasks/cfuse_workunit_quota.yaml index 7908bc88c..8801454db 100644 --- a/ceph/qa/suites/fs/basic_functional/tasks/cfuse_workunit_quota.yaml +++ b/ceph/qa/suites/fs/basic_functional/tasks/cfuse_workunit_quota.yaml @@ -4,9 +4,3 @@ tasks: clients: all: - fs/quota - -overrides: - ceph: - conf: - client: - client quota: true diff --git a/ceph/qa/suites/fs/thrash/overrides/whitelist_health.yaml b/ceph/qa/suites/fs/thrash/overrides/whitelist_health.yaml new file mode 100644 index 000000000..fc8119dac --- /dev/null +++ b/ceph/qa/suites/fs/thrash/overrides/whitelist_health.yaml @@ -0,0 +1,8 @@ +overrides: + ceph: + log-whitelist: + - overall HEALTH_ + - (FS_DEGRADED) + - (MDS_FAILED) + - (MDS_DEGRADED) + - (FS_WITH_FAILED_MDS) diff --git a/ceph/qa/suites/fs/verify/validater/valgrind.yaml b/ceph/qa/suites/fs/verify/validater/valgrind.yaml index 82a657475..6982cedfc 100644 --- a/ceph/qa/suites/fs/verify/validater/valgrind.yaml +++ b/ceph/qa/suites/fs/verify/validater/valgrind.yaml @@ -1,3 +1,5 @@ +# see http://tracker.ceph.com/issues/20360 and http://tracker.ceph.com/issues/18126 +os_type: centos # Valgrind makes everything slow, so ignore slow requests overrides: @@ -5,7 +7,6 @@ overrides: log-whitelist: - slow requests are blocked -os_type: centos # xenial valgrind buggy, see http://tracker.ceph.com/issues/18126 overrides: install: ceph: @@ -15,6 +16,8 @@ overrides: conf: global: osd heartbeat grace: 40 + mon: + mon osd crush smoke test: false valgrind: mon: [--tool=memcheck, --leak-check=full, --show-reachable=yes] osd: [--tool=memcheck] diff --git a/ceph/qa/suites/krbd/rbd/tasks/rbd_workunit_suites_fsstress_btrfs.yaml b/ceph/qa/suites/krbd/rbd/tasks/rbd_workunit_suites_fsstress_btrfs.yaml deleted file mode 100644 index f3930a898..000000000 --- a/ceph/qa/suites/krbd/rbd/tasks/rbd_workunit_suites_fsstress_btrfs.yaml +++ /dev/null @@ -1,10 +0,0 @@ -tasks: -- install: -- ceph: -- rbd: - all: - fs_type: btrfs -- workunit: - clients: - all: - - suites/fsstress.sh diff --git a/ceph/qa/suites/powercycle/osd/tasks/radosbench.yaml b/ceph/qa/suites/powercycle/osd/tasks/radosbench.yaml index 1788ff762..91573f907 100644 --- a/ceph/qa/suites/powercycle/osd/tasks/radosbench.yaml +++ b/ceph/qa/suites/powercycle/osd/tasks/radosbench.yaml @@ -2,25 +2,37 @@ tasks: - full_sequential: - radosbench: clients: [client.0] - time: 150 + time: 90 - radosbench: clients: [client.0] - time: 150 + time: 90 - radosbench: clients: [client.0] - time: 150 + time: 90 - radosbench: clients: [client.0] - time: 150 + time: 90 - radosbench: clients: [client.0] - time: 150 + time: 90 - radosbench: clients: [client.0] - time: 150 + time: 90 - radosbench: clients: [client.0] - time: 150 + time: 90 - radosbench: clients: [client.0] - time: 150 + time: 90 + - radosbench: + clients: [client.0] + time: 90 + - radosbench: + clients: [client.0] + time: 90 + - radosbench: + clients: [client.0] + time: 90 + - radosbench: + clients: [client.0] + time: 90 diff --git a/ceph/qa/suites/rados/basic-luminous/scrub_test.yaml b/ceph/qa/suites/rados/basic-luminous/scrub_test.yaml index 07f039aae..d87f5bfdd 100644 --- a/ceph/qa/suites/rados/basic-luminous/scrub_test.yaml +++ b/ceph/qa/suites/rados/basic-luminous/scrub_test.yaml @@ -15,6 +15,12 @@ overrides: - 'attr name mistmatch' - 'deep-scrub 1 missing, 0 inconsistent objects' - 'failed to pick suitable auth object' + - overall HEALTH_ + - (OSDMAP_FLAGS) + - (OSD_ + - (PG_ + - (OSD_SCRUB_ERRORS) + - (TOO_FEW_PGS) conf: osd: osd deep scrub update digest min age: 0 diff --git a/ceph/qa/suites/rados/basic/tasks/rados_api_tests.yaml b/ceph/qa/suites/rados/basic/tasks/rados_api_tests.yaml index b66423988..1d77207d2 100644 --- a/ceph/qa/suites/rados/basic/tasks/rados_api_tests.yaml +++ b/ceph/qa/suites/rados/basic/tasks/rados_api_tests.yaml @@ -3,6 +3,11 @@ overrides: log-whitelist: - reached quota - wrongly marked me down + - overall HEALTH_ + - (POOL_FULL) + - (SMALLER_PGP_NUM) + - (CACHE_POOL_NO_HIT_SET) + - (CACHE_POOL_NEAR_FULL) tasks: - workunit: clients: diff --git a/ceph/qa/suites/rados/basic/tasks/rados_python.yaml b/ceph/qa/suites/rados/basic/tasks/rados_python.yaml index d8b332b34..aa22ccd16 100644 --- a/ceph/qa/suites/rados/basic/tasks/rados_python.yaml +++ b/ceph/qa/suites/rados/basic/tasks/rados_python.yaml @@ -2,6 +2,11 @@ overrides: ceph: log-whitelist: - wrongly marked me down + - overall HEALTH_ + - (OSDMAP_FLAGS) + - (PG_ + - (OSD_ + - (OBJECT_ tasks: - workunit: clients: diff --git a/ceph/qa/suites/rados/basic/tasks/rados_stress_watch.yaml b/ceph/qa/suites/rados/basic/tasks/rados_stress_watch.yaml index 0e1ba010c..ded794c17 100644 --- a/ceph/qa/suites/rados/basic/tasks/rados_stress_watch.yaml +++ b/ceph/qa/suites/rados/basic/tasks/rados_stress_watch.yaml @@ -1,3 +1,9 @@ +overrides: + ceph: + log-whitelist: + - overall HEALTH_ + - (CACHE_POOL_NO_HIT_SET) + - (TOO_FEW_PGS) tasks: - workunit: clients: diff --git a/ceph/qa/suites/rados/basic/tasks/repair_test.yaml b/ceph/qa/suites/rados/basic/tasks/repair_test.yaml index f69866994..8401c1a30 100644 --- a/ceph/qa/suites/rados/basic/tasks/repair_test.yaml +++ b/ceph/qa/suites/rados/basic/tasks/repair_test.yaml @@ -17,6 +17,10 @@ overrides: - 'size 1 != size' - attr name mismatch - Regular scrub request, losing deep-scrub details + - overall HEALTH_ + - (OSDMAP_FLAGS) + - (OSD_ + - (PG_ conf: osd: filestore debug inject read err: true diff --git a/ceph/qa/suites/rados/mgr/tasks/failover.yaml b/ceph/qa/suites/rados/mgr/tasks/failover.yaml index e02b8bf2c..fd5eb8515 100644 --- a/ceph/qa/suites/rados/mgr/tasks/failover.yaml +++ b/ceph/qa/suites/rados/mgr/tasks/failover.yaml @@ -4,7 +4,11 @@ tasks: - ceph: # tests may leave mgrs broken, so don't try and call into them # to invoke e.g. pg dump during teardown. - wait-for-scrub: false + wait-for-scrub: false + log-whitelist: + - overall HEALTH_ + - (MGR_DOWN) + - (PG_ - cephfs_test_runner: modules: - tasks.mgr.test_failover diff --git a/ceph/qa/suites/rados/monthrash/thrashers/force-sync-many.yaml b/ceph/qa/suites/rados/monthrash/thrashers/force-sync-many.yaml index 2867f2db5..38570fcf6 100644 --- a/ceph/qa/suites/rados/monthrash/thrashers/force-sync-many.yaml +++ b/ceph/qa/suites/rados/monthrash/thrashers/force-sync-many.yaml @@ -1,3 +1,9 @@ +overrides: + ceph: + log-whitelist: + - overall HEALTH_ + - (MON_DOWN) + - (TOO_FEW_PGS) tasks: - mon_thrash: revive_delay: 90 diff --git a/ceph/qa/suites/rados/monthrash/thrashers/many.yaml b/ceph/qa/suites/rados/monthrash/thrashers/many.yaml index fe52bb2bb..e940c42ad 100644 --- a/ceph/qa/suites/rados/monthrash/thrashers/many.yaml +++ b/ceph/qa/suites/rados/monthrash/thrashers/many.yaml @@ -1,5 +1,8 @@ overrides: ceph: + log-whitelist: + - overall HEALTH_ + - (MON_DOWN) conf: osd: mon client ping interval: 4 diff --git a/ceph/qa/suites/rados/monthrash/thrashers/one.yaml b/ceph/qa/suites/rados/monthrash/thrashers/one.yaml index 2ce44c860..92c9eb3a8 100644 --- a/ceph/qa/suites/rados/monthrash/thrashers/one.yaml +++ b/ceph/qa/suites/rados/monthrash/thrashers/one.yaml @@ -1,3 +1,8 @@ +overrides: + ceph: + log-whitelist: + - overall HEALTH_ + - (MON_DOWN) tasks: - mon_thrash: revive_delay: 20 diff --git a/ceph/qa/suites/rados/monthrash/thrashers/sync-many.yaml b/ceph/qa/suites/rados/monthrash/thrashers/sync-many.yaml index 9868f1815..68020cd66 100644 --- a/ceph/qa/suites/rados/monthrash/thrashers/sync-many.yaml +++ b/ceph/qa/suites/rados/monthrash/thrashers/sync-many.yaml @@ -1,5 +1,8 @@ overrides: ceph: + log-whitelist: + - overall HEALTH_ + - (MON_DOWN) conf: mon: paxos min: 10 diff --git a/ceph/qa/suites/rados/monthrash/thrashers/sync.yaml b/ceph/qa/suites/rados/monthrash/thrashers/sync.yaml index 1e7054c27..b07f8b511 100644 --- a/ceph/qa/suites/rados/monthrash/thrashers/sync.yaml +++ b/ceph/qa/suites/rados/monthrash/thrashers/sync.yaml @@ -1,5 +1,8 @@ overrides: ceph: + log-whitelist: + - overall HEALTH_ + - (MON_DOWN) conf: mon: paxos min: 10 diff --git a/ceph/qa/suites/rados/monthrash/workloads/rados_api_tests.yaml b/ceph/qa/suites/rados/monthrash/workloads/rados_api_tests.yaml index b536557fd..0834f9c34 100644 --- a/ceph/qa/suites/rados/monthrash/workloads/rados_api_tests.yaml +++ b/ceph/qa/suites/rados/monthrash/workloads/rados_api_tests.yaml @@ -2,6 +2,12 @@ overrides: ceph: log-whitelist: - reached quota + - overall HEALTH_ + - (CACHE_POOL_NO_HIT_SET) + - (POOL_FULL) + - (REQUEST_SLOW) + - (MON_DOWN) + - (PG_ conf: global: debug objecter: 20 diff --git a/ceph/qa/suites/rados/monthrash/workloads/rados_mon_workunits.yaml b/ceph/qa/suites/rados/monthrash/workloads/rados_mon_workunits.yaml index 31465cffe..86818b58d 100644 --- a/ceph/qa/suites/rados/monthrash/workloads/rados_mon_workunits.yaml +++ b/ceph/qa/suites/rados/monthrash/workloads/rados_mon_workunits.yaml @@ -2,6 +2,9 @@ overrides: ceph: log-whitelist: - wrongly marked me down + - overall HEALTH_ + - (PG_ + - (MON_DOWN) tasks: - workunit: clients: diff --git a/ceph/qa/suites/rados/multimon/tasks/mon_clock_no_skews.yaml b/ceph/qa/suites/rados/multimon/tasks/mon_clock_no_skews.yaml index e86bdde1d..ec761e295 100644 --- a/ceph/qa/suites/rados/multimon/tasks/mon_clock_no_skews.yaml +++ b/ceph/qa/suites/rados/multimon/tasks/mon_clock_no_skews.yaml @@ -5,5 +5,7 @@ tasks: - slow request - .*clock.*skew.* - clocks not synchronized + - overall HEALTH_ + - (MON_CLOCK_SKEW) - mon_clock_skew_check: expect-skew: false diff --git a/ceph/qa/suites/rados/multimon/tasks/mon_clock_with_skews.yaml b/ceph/qa/suites/rados/multimon/tasks/mon_clock_with_skews.yaml index 1c6c1538b..2bba60715 100644 --- a/ceph/qa/suites/rados/multimon/tasks/mon_clock_with_skews.yaml +++ b/ceph/qa/suites/rados/multimon/tasks/mon_clock_with_skews.yaml @@ -9,5 +9,7 @@ tasks: - slow request - .*clock.*skew.* - clocks not synchronized + - overall HEALTH_ + - (MON_CLOCK_SKEW) - mon_clock_skew_check: expect-skew: true diff --git a/ceph/qa/suites/rados/multimon/tasks/mon_recovery.yaml b/ceph/qa/suites/rados/multimon/tasks/mon_recovery.yaml index 94721ea53..4234bf73e 100644 --- a/ceph/qa/suites/rados/multimon/tasks/mon_recovery.yaml +++ b/ceph/qa/suites/rados/multimon/tasks/mon_recovery.yaml @@ -1,4 +1,7 @@ tasks: - install: - ceph: + log-whitelist: + - overall HEALTH_ + - (MON_DOWN) - mon_recovery: diff --git a/ceph/qa/suites/rados/objectstore/ceph_objectstore_tool.yaml b/ceph/qa/suites/rados/objectstore/ceph_objectstore_tool.yaml index 215d0f08f..2001faa3f 100644 --- a/ceph/qa/suites/rados/objectstore/ceph_objectstore_tool.yaml +++ b/ceph/qa/suites/rados/objectstore/ceph_objectstore_tool.yaml @@ -12,5 +12,11 @@ tasks: global: osd max object name len: 460 osd max object namespace len: 64 + log-whitelist: + - overall HEALTH_ + - (OSDMAP_FLAGS) + - (OSD_ + - (PG_ + - (TOO_FEW_PGS) - ceph_objectstore_tool: objects: 20 diff --git a/ceph/qa/suites/rados/rest/mgr-restful.yaml b/ceph/qa/suites/rados/rest/mgr-restful.yaml index 571857c25..f202976e8 100644 --- a/ceph/qa/suites/rados/rest/mgr-restful.yaml +++ b/ceph/qa/suites/rados/rest/mgr-restful.yaml @@ -3,10 +3,11 @@ roles: tasks: - install: - ceph: + log-whitelist: + - overall HEALTH_ + - (MGR_DOWN) - exec: mon.a: - - ceph config-key put mgr/restful/x/server_addr 127.0.0.1 - - ceph config-key put mgr/restful/x/server_port 9999 - ceph tell mgr.x restful create-key admin - ceph tell mgr.x restful create-self-signed-cert - ceph.restart: [mgr.x] diff --git a/ceph/qa/suites/rados/singleton-bluestore/all/cephtool.yaml b/ceph/qa/suites/rados/singleton-bluestore/all/cephtool.yaml index 880628f4f..7e1a1f7b3 100644 --- a/ceph/qa/suites/rados/singleton-bluestore/all/cephtool.yaml +++ b/ceph/qa/suites/rados/singleton-bluestore/all/cephtool.yaml @@ -21,6 +21,11 @@ tasks: - must scrub before tier agent can activate - failsafe engaged, dropping updates - failsafe disengaged, no longer dropping updates + - overall HEALTH_ + - (OSDMAP_FLAGS) + - (OSD_ + - (PG_ + - (SMALLER_PG_NUM) - workunit: clients: all: diff --git a/ceph/qa/suites/rados/singleton-nomsgr/all/admin_socket_output.yaml b/ceph/qa/suites/rados/singleton-nomsgr/all/admin_socket_output.yaml index 969c40902..3aaca8759 100644 --- a/ceph/qa/suites/rados/singleton-nomsgr/all/admin_socket_output.yaml +++ b/ceph/qa/suites/rados/singleton-nomsgr/all/admin_socket_output.yaml @@ -5,6 +5,10 @@ overrides: log-whitelist: - MDS in read-only mode - force file system read-only + - overall HEALTH_ + - (OSDMAP_FLAGS) + - (OSD_FULL) + - (MDS_READ_ONLY) tasks: - install: - ceph: diff --git a/ceph/qa/suites/rados/singleton-nomsgr/all/cache-fs-trunc.yaml b/ceph/qa/suites/rados/singleton-nomsgr/all/cache-fs-trunc.yaml index 5009ee617..ac64165aa 100644 --- a/ceph/qa/suites/rados/singleton-nomsgr/all/cache-fs-trunc.yaml +++ b/ceph/qa/suites/rados/singleton-nomsgr/all/cache-fs-trunc.yaml @@ -3,6 +3,9 @@ roles: tasks: - install: - ceph: + log-whitelist: + - overall HEALTH_ + - (CACHE_POOL_NO_HIT_SET) conf: global: osd max object name len: 460 diff --git a/ceph/qa/suites/rados/singleton-nomsgr/all/export-after-evict.yaml b/ceph/qa/suites/rados/singleton-nomsgr/all/export-after-evict.yaml index e0badd4d3..1b777ab0f 100644 --- a/ceph/qa/suites/rados/singleton-nomsgr/all/export-after-evict.yaml +++ b/ceph/qa/suites/rados/singleton-nomsgr/all/export-after-evict.yaml @@ -8,6 +8,9 @@ roles: tasks: - install: - ceph: + log-whitelist: + - overall HEALTH_ + - (CACHE_POOL_NO_HIT_SET) conf: global: osd max object name len: 460 diff --git a/ceph/qa/suites/rados/singleton-nomsgr/all/full-tiering.yaml b/ceph/qa/suites/rados/singleton-nomsgr/all/full-tiering.yaml index 9dc1fe7dc..5eb42f4dd 100644 --- a/ceph/qa/suites/rados/singleton-nomsgr/all/full-tiering.yaml +++ b/ceph/qa/suites/rados/singleton-nomsgr/all/full-tiering.yaml @@ -5,6 +5,10 @@ overrides: ceph: log-whitelist: - is full + - overall HEALTH_ + - (POOL_FULL) + - (POOL_NEAR_FULL) + - (CACHE_POOL_NO_HIT_SET) tasks: - install: - ceph: diff --git a/ceph/qa/suites/rados/singleton-nomsgr/all/health-warnings.yaml b/ceph/qa/suites/rados/singleton-nomsgr/all/health-warnings.yaml index 4c8228b0c..749bd8d39 100644 --- a/ceph/qa/suites/rados/singleton-nomsgr/all/health-warnings.yaml +++ b/ceph/qa/suites/rados/singleton-nomsgr/all/health-warnings.yaml @@ -10,6 +10,10 @@ tasks: osd max object namespace len: 64 log-whitelist: - wrongly marked me down + - overall HEALTH_ + - (OSDMAP_FLAGS) + - (OSD_ + - (PG_ - workunit: clients: all: diff --git a/ceph/qa/suites/rados/singleton-nomsgr/all/multi-backfill-reject.yaml b/ceph/qa/suites/rados/singleton-nomsgr/all/multi-backfill-reject.yaml index b73899738..cadf3044a 100644 --- a/ceph/qa/suites/rados/singleton-nomsgr/all/multi-backfill-reject.yaml +++ b/ceph/qa/suites/rados/singleton-nomsgr/all/multi-backfill-reject.yaml @@ -11,6 +11,11 @@ roles: tasks: - install: - ceph: + log-whitelist: + - overall HEALTH_ + - (PG_ + - (OSD_ + - (OBJECT_ conf: osd: osd debug reject backfill probability: .3 diff --git a/ceph/qa/suites/rados/singleton-nomsgr/all/valgrind-leaks.yaml b/ceph/qa/suites/rados/singleton-nomsgr/all/valgrind-leaks.yaml index c05ad133b..347c49952 100644 --- a/ceph/qa/suites/rados/singleton-nomsgr/all/valgrind-leaks.yaml +++ b/ceph/qa/suites/rados/singleton-nomsgr/all/valgrind-leaks.yaml @@ -1,16 +1,23 @@ -os_type: centos # xenial valgrind buggy, see http://tracker.ceph.com/issues/18126 +# see http://tracker.ceph.com/issues/20360 and http://tracker.ceph.com/issues/18126 +os_type: centos + overrides: install: ceph: flavor: notcmalloc debuginfo: true ceph: + log-whitelist: + - overall HEALTH_ + - (PG_ conf: global: osd heartbeat grace: 40 debug deliberately leak memory: true osd max object name len: 460 osd max object namespace len: 64 + mon: + mon osd crush smoke test: false valgrind: mon: [--tool=memcheck, --leak-check=full, --show-reachable=yes] osd: [--tool=memcheck] diff --git a/ceph/qa/suites/rados/singleton/all/divergent_priors.yaml b/ceph/qa/suites/rados/singleton/all/divergent_priors.yaml index bb7c2b57f..f15fb8896 100644 --- a/ceph/qa/suites/rados/singleton/all/divergent_priors.yaml +++ b/ceph/qa/suites/rados/singleton/all/divergent_priors.yaml @@ -12,6 +12,12 @@ openstack: overrides: ceph: + log-whitelist: + - overall HEALTH_ + - (OSDMAP_FLAGS) + - (OSD_ + - (PG_ + - (OBJECT_DEGRADED) conf: osd: debug osd: 5 diff --git a/ceph/qa/suites/rados/singleton/all/divergent_priors2.yaml b/ceph/qa/suites/rados/singleton/all/divergent_priors2.yaml index ab749f1b5..90d8b1838 100644 --- a/ceph/qa/suites/rados/singleton/all/divergent_priors2.yaml +++ b/ceph/qa/suites/rados/singleton/all/divergent_priors2.yaml @@ -12,6 +12,12 @@ openstack: overrides: ceph: + log-whitelist: + - overall HEALTH_ + - (OSDMAP_FLAGS) + - (OSD_ + - (PG_ + - (OBJECT_DEGRADED) conf: osd: debug osd: 5 diff --git a/ceph/qa/suites/rados/singleton/all/dump-stuck.yaml b/ceph/qa/suites/rados/singleton/all/dump-stuck.yaml index 7d3b44302..f3900e121 100644 --- a/ceph/qa/suites/rados/singleton/all/dump-stuck.yaml +++ b/ceph/qa/suites/rados/singleton/all/dump-stuck.yaml @@ -11,5 +11,9 @@ tasks: - install: - ceph: log-whitelist: - - wrongly marked me down + - wrongly marked me down + - overall HEALTH_ + - (OSDMAP_FLAGS) + - (OSD_ + - (PG_ - dump_stuck: diff --git a/ceph/qa/suites/rados/singleton/all/ec-lost-unfound.yaml b/ceph/qa/suites/rados/singleton/all/ec-lost-unfound.yaml index 6ceefe122..e095fd0d5 100644 --- a/ceph/qa/suites/rados/singleton/all/ec-lost-unfound.yaml +++ b/ceph/qa/suites/rados/singleton/all/ec-lost-unfound.yaml @@ -15,5 +15,10 @@ tasks: - install: - ceph: log-whitelist: - - objects unfound and apparently lost + - objects unfound and apparently lost + - overall HEALTH_ + - (OSDMAP_FLAGS) + - (OSD_ + - (PG_ + - (OBJECT_ - ec_lost_unfound: diff --git a/ceph/qa/suites/rados/singleton/all/lost-unfound-delete.yaml b/ceph/qa/suites/rados/singleton/all/lost-unfound-delete.yaml index 15f4710bd..5502b5c9b 100644 --- a/ceph/qa/suites/rados/singleton/all/lost-unfound-delete.yaml +++ b/ceph/qa/suites/rados/singleton/all/lost-unfound-delete.yaml @@ -14,5 +14,10 @@ tasks: - install: - ceph: log-whitelist: - - objects unfound and apparently lost + - objects unfound and apparently lost + - overall HEALTH_ + - (OSDMAP_FLAGS) + - (OSD_ + - (PG_ + - (OBJECT_ - rep_lost_unfound_delete: diff --git a/ceph/qa/suites/rados/singleton/all/lost-unfound.yaml b/ceph/qa/suites/rados/singleton/all/lost-unfound.yaml index 3f22ba3c0..bb0bb2c0a 100644 --- a/ceph/qa/suites/rados/singleton/all/lost-unfound.yaml +++ b/ceph/qa/suites/rados/singleton/all/lost-unfound.yaml @@ -14,5 +14,10 @@ tasks: - install: - ceph: log-whitelist: - - objects unfound and apparently lost + - objects unfound and apparently lost + - overall HEALTH_ + - (OSDMAP_FLAGS) + - (OSD_ + - (PG_ + - (OBJECT_ - lost_unfound: diff --git a/ceph/qa/suites/rados/singleton/all/mon-auth-caps.yaml b/ceph/qa/suites/rados/singleton/all/mon-auth-caps.yaml new file mode 100644 index 000000000..318af5ee6 --- /dev/null +++ b/ceph/qa/suites/rados/singleton/all/mon-auth-caps.yaml @@ -0,0 +1,14 @@ +roles: +- - mon.a + - mgr.x + - osd.0 + - osd.1 + - osd.2 + - client.0 +tasks: +- install: +- ceph: +- workunit: + clients: + all: + - mon/auth_caps.sh diff --git a/ceph/qa/suites/rados/singleton/all/mon-thrasher.yaml b/ceph/qa/suites/rados/singleton/all/mon-thrasher.yaml index 1b4622998..66a1e905f 100644 --- a/ceph/qa/suites/rados/singleton/all/mon-thrasher.yaml +++ b/ceph/qa/suites/rados/singleton/all/mon-thrasher.yaml @@ -13,6 +13,10 @@ openstack: tasks: - install: - ceph: + log-whitelist: + - overall HEALTH_ + - (MON_DOWN) + - (PG_ - mon_thrash: revive_delay: 20 thrash_delay: 1 diff --git a/ceph/qa/suites/rados/singleton/all/osd-backfill.yaml b/ceph/qa/suites/rados/singleton/all/osd-backfill.yaml index f84a0df8d..84e2273d3 100644 --- a/ceph/qa/suites/rados/singleton/all/osd-backfill.yaml +++ b/ceph/qa/suites/rados/singleton/all/osd-backfill.yaml @@ -14,7 +14,12 @@ tasks: - install: - ceph: log-whitelist: - - wrongly marked me down + - wrongly marked me down + - overall HEALTH_ + - (OSDMAP_FLAGS) + - (OSD_ + - (PG_ + - (OBJECT_ conf: osd: osd min pg log entries: 5 diff --git a/ceph/qa/suites/rados/singleton/all/osd-recovery-incomplete.yaml b/ceph/qa/suites/rados/singleton/all/osd-recovery-incomplete.yaml index 773cb2480..60789d5ca 100644 --- a/ceph/qa/suites/rados/singleton/all/osd-recovery-incomplete.yaml +++ b/ceph/qa/suites/rados/singleton/all/osd-recovery-incomplete.yaml @@ -15,7 +15,12 @@ tasks: - install: - ceph: log-whitelist: - - wrongly marked me down + - wrongly marked me down + - overall HEALTH_ + - (OSDMAP_FLAGS) + - (OSD_ + - (PG_ + - (OBJECT_ conf: osd: osd min pg log entries: 5 diff --git a/ceph/qa/suites/rados/singleton/all/osd-recovery.yaml b/ceph/qa/suites/rados/singleton/all/osd-recovery.yaml index 214d7f20c..d6e5e957f 100644 --- a/ceph/qa/suites/rados/singleton/all/osd-recovery.yaml +++ b/ceph/qa/suites/rados/singleton/all/osd-recovery.yaml @@ -14,7 +14,12 @@ tasks: - install: - ceph: log-whitelist: - - wrongly marked me down + - wrongly marked me down + - overall HEALTH_ + - (OSDMAP_FLAGS) + - (OSD_ + - (PG_ + - (OBJECT_DEGRADED) conf: osd: osd min pg log entries: 5 diff --git a/ceph/qa/suites/rados/singleton/all/peer.yaml b/ceph/qa/suites/rados/singleton/all/peer.yaml index 6e22b4456..e87cd543c 100644 --- a/ceph/qa/suites/rados/singleton/all/peer.yaml +++ b/ceph/qa/suites/rados/singleton/all/peer.yaml @@ -17,5 +17,9 @@ tasks: global: osd pool default min size : 1 log-whitelist: - - objects unfound and apparently lost + - objects unfound and apparently lost + - overall HEALTH_ + - (OSDMAP_FLAGS) + - (OSD_ + - (PG_ - peer: diff --git a/ceph/qa/suites/rados/singleton/all/pg-removal-interruption.yaml b/ceph/qa/suites/rados/singleton/all/pg-removal-interruption.yaml index f7e61c962..856b08dd4 100644 --- a/ceph/qa/suites/rados/singleton/all/pg-removal-interruption.yaml +++ b/ceph/qa/suites/rados/singleton/all/pg-removal-interruption.yaml @@ -13,8 +13,12 @@ tasks: - install: - ceph: log-whitelist: - - wrongly marked me down - - slow request + - wrongly marked me down + - slow request + - overall HEALTH_ + - (OSDMAP_FLAGS) + - (OSD_ + - (PG_ - exec: client.0: - sudo ceph osd pool create foo 128 128 diff --git a/ceph/qa/suites/rados/singleton/all/radostool.yaml b/ceph/qa/suites/rados/singleton/all/radostool.yaml index 8bc9dbdcd..700b3a33a 100644 --- a/ceph/qa/suites/rados/singleton/all/radostool.yaml +++ b/ceph/qa/suites/rados/singleton/all/radostool.yaml @@ -17,6 +17,8 @@ tasks: - had wrong client addr - had wrong cluster addr - reached quota + - overall HEALTH_ + - (POOL_FULL) - workunit: clients: all: diff --git a/ceph/qa/suites/rados/singleton/all/random-eio.yaml b/ceph/qa/suites/rados/singleton/all/random-eio.yaml new file mode 100644 index 000000000..954730b11 --- /dev/null +++ b/ceph/qa/suites/rados/singleton/all/random-eio.yaml @@ -0,0 +1,39 @@ +roles: +- - mon.a + - mgr.x + - osd.0 + - osd.1 + - osd.2 +- - osd.3 + - osd.4 + - osd.5 + - client.0 +openstack: + - volumes: # attached to each instance + count: 3 + size: 10 # GB +tasks: +- install: +- ceph: + log-whitelist: + - missing primary copy of + - objects unfound and apparently lost +- full_sequential: + - exec: + client.0: + - sudo ceph tell osd.1 injectargs -- --filestore_debug_random_read_err=0.33 + - sudo ceph tell osd.1 injectargs -- --bluestore_debug_random_read_err=0.33 + - sudo ceph osd pool create test 16 16 + - sudo ceph osd pool set test size 3 + - sudo ceph pg dump pgs --format=json-pretty + - radosbench: + clients: [client.0] + time: 360 + type: rand + objectsize: 1048576 + pool: test + create_pool: false + - exec: + client.0: + - sudo ceph tell osd.1 injectargs -- --filestore_debug_random_read_err=0.0 + - sudo ceph tell osd.1 injectargs -- --bluestore_debug_random_read_err=0.0 diff --git a/ceph/qa/suites/rados/singleton/all/rebuild-mondb.yaml b/ceph/qa/suites/rados/singleton/all/rebuild-mondb.yaml index c3be13ae6..6847cef8d 100644 --- a/ceph/qa/suites/rados/singleton/all/rebuild-mondb.yaml +++ b/ceph/qa/suites/rados/singleton/all/rebuild-mondb.yaml @@ -15,7 +15,12 @@ tasks: - install: - ceph: log-whitelist: - - no reply from + - no reply from + - overall HEALTH_ + - (MON_DOWN) + - (OSDMAP_FLAGS) + - (OSD_ + - (PG_ - full_sequential: - radosbench: clients: [client.0] diff --git a/ceph/qa/suites/rados/singleton/all/reg11184.yaml b/ceph/qa/suites/rados/singleton/all/reg11184.yaml index 5521a27f0..1abf5739f 100644 --- a/ceph/qa/suites/rados/singleton/all/reg11184.yaml +++ b/ceph/qa/suites/rados/singleton/all/reg11184.yaml @@ -15,7 +15,13 @@ overrides: conf: osd: debug osd: 5 - + log-whitelist: + - overall HEALTH_ + - (OSDMAP_FLAGS) + - (OSD_ + - (PG_ + - (SMALLER_PGP_NUM) + - (OBJECT_ tasks: - install: - ceph: diff --git a/ceph/qa/suites/rados/singleton/all/resolve_stuck_peering.yaml b/ceph/qa/suites/rados/singleton/all/resolve_stuck_peering.yaml index c64593212..97da13790 100644 --- a/ceph/qa/suites/rados/singleton/all/resolve_stuck_peering.yaml +++ b/ceph/qa/suites/rados/singleton/all/resolve_stuck_peering.yaml @@ -6,5 +6,11 @@ tasks: - install: - ceph: fs: xfs + log-whitelist: + - overall HEALTH_ + - (OSDMAP_FLAGS) + - (OSD_ + - (PG_ + - (OBJECT_DEGRADED) - resolve_stuck_peering: diff --git a/ceph/qa/suites/rados/singleton/all/rest-api.yaml b/ceph/qa/suites/rados/singleton/all/rest-api.yaml index cbd90e409..77c881b0e 100644 --- a/ceph/qa/suites/rados/singleton/all/rest-api.yaml +++ b/ceph/qa/suites/rados/singleton/all/rest-api.yaml @@ -16,8 +16,13 @@ tasks: - install: - ceph: log-whitelist: - - wrongly marked me down - - had wrong client addr + - wrongly marked me down + - had wrong client addr + - overall HEALTH_ + - (OSDMAP_FLAGS) + - (OSD_ + - (PG_ + - (OBJECT_DEGRADED) conf: client.rest0: debug ms: 1 diff --git a/ceph/qa/suites/rados/singleton/all/thrash-eio.yaml b/ceph/qa/suites/rados/singleton/all/thrash-eio.yaml new file mode 100644 index 000000000..6ff629033 --- /dev/null +++ b/ceph/qa/suites/rados/singleton/all/thrash-eio.yaml @@ -0,0 +1,43 @@ +roles: +- - mon.a + - mgr.x + - osd.0 + - osd.1 + - osd.2 +- - osd.3 + - osd.4 + - osd.5 + - client.0 +openstack: + - volumes: # attached to each instance + count: 3 + size: 10 # GB +override: + ceph: + conf: + mon: + osd default pool size: 3 +tasks: +- install: +- ceph: + log-whitelist: + - wrongly marked me down + - missing primary copy of + - objects unfound and apparently lost + - overall HEALTH_ + - (OSDMAP_FLAGS) + - (REQUEST_SLOW) + - (PG_ + - (OSD_ +- thrashosds: + op_delay: 30 + clean_interval: 120 + chance_down: .5 + random_eio: .33 + min_live: 5 + min_in: 5 +- radosbench: + clients: [client.0] + time: 720 + type: rand + objectsize: 1048576 diff --git a/ceph/qa/suites/rados/singleton/all/thrash-rados/+ b/ceph/qa/suites/rados/singleton/all/thrash-rados/+ new file mode 100644 index 000000000..e69de29bb diff --git a/ceph/qa/suites/rados/singleton/all/thrash-rados.yaml b/ceph/qa/suites/rados/singleton/all/thrash-rados/thrash-rados.yaml similarity index 92% rename from ceph/qa/suites/rados/singleton/all/thrash-rados.yaml rename to ceph/qa/suites/rados/singleton/all/thrash-rados/thrash-rados.yaml index 49e3e8799..f61897eaa 100644 --- a/ceph/qa/suites/rados/singleton/all/thrash-rados.yaml +++ b/ceph/qa/suites/rados/singleton/all/thrash-rados/thrash-rados.yaml @@ -16,7 +16,7 @@ tasks: - install: - ceph: log-whitelist: - - wrongly marked me down + - wrongly marked me down - thrashosds: op_delay: 30 clean_interval: 120 diff --git a/ceph/qa/suites/rados/singleton/all/thrash-rados/thrashosds-health.yaml b/ceph/qa/suites/rados/singleton/all/thrash-rados/thrashosds-health.yaml new file mode 120000 index 000000000..0b1d7b060 --- /dev/null +++ b/ceph/qa/suites/rados/singleton/all/thrash-rados/thrashosds-health.yaml @@ -0,0 +1 @@ +../../../../../tasks/thrashosds-health.yaml \ No newline at end of file diff --git a/ceph/qa/suites/rados/singleton/all/thrash_cache_writeback_proxy_none.yaml b/ceph/qa/suites/rados/singleton/all/thrash_cache_writeback_proxy_none.yaml index 1875da409..02fee3e88 100644 --- a/ceph/qa/suites/rados/singleton/all/thrash_cache_writeback_proxy_none.yaml +++ b/ceph/qa/suites/rados/singleton/all/thrash_cache_writeback_proxy_none.yaml @@ -16,8 +16,10 @@ tasks: - install: - ceph: log-whitelist: - - wrongly marked me down - - slow request + - wrongly marked me down + - slow request + - overall HEALTH_ + - (CACHE_POOL_ - exec: client.0: - sudo ceph osd pool create base 4 diff --git a/ceph/qa/suites/rados/singleton/all/watch-notify-same-primary.yaml b/ceph/qa/suites/rados/singleton/all/watch-notify-same-primary.yaml index ad1fd17d5..3efdb955f 100644 --- a/ceph/qa/suites/rados/singleton/all/watch-notify-same-primary.yaml +++ b/ceph/qa/suites/rados/singleton/all/watch-notify-same-primary.yaml @@ -22,6 +22,11 @@ tasks: debug objecter: 20 debug rados: 20 log-whitelist: - - objects unfound and apparently lost + - objects unfound and apparently lost + - overall HEALTH_ + - (OSDMAP_FLAGS) + - (OSD_ + - (PG_ + - (OBJECT_DEGRADED) - watch_notify_same_primary: clients: [client.0] diff --git a/ceph/qa/suites/rados/thrash-erasure-code-big/thrashosds-health.yaml b/ceph/qa/suites/rados/thrash-erasure-code-big/thrashosds-health.yaml new file mode 120000 index 000000000..ebf7f34f3 --- /dev/null +++ b/ceph/qa/suites/rados/thrash-erasure-code-big/thrashosds-health.yaml @@ -0,0 +1 @@ +../../../tasks/thrashosds-health.yaml \ No newline at end of file diff --git a/ceph/qa/suites/rados/thrash-erasure-code-isa/thrashosds-health.yaml b/ceph/qa/suites/rados/thrash-erasure-code-isa/thrashosds-health.yaml new file mode 120000 index 000000000..ebf7f34f3 --- /dev/null +++ b/ceph/qa/suites/rados/thrash-erasure-code-isa/thrashosds-health.yaml @@ -0,0 +1 @@ +../../../tasks/thrashosds-health.yaml \ No newline at end of file diff --git a/ceph/qa/suites/rados/thrash-erasure-code-overwrites/thrashosds-health.yaml b/ceph/qa/suites/rados/thrash-erasure-code-overwrites/thrashosds-health.yaml new file mode 120000 index 000000000..ebf7f34f3 --- /dev/null +++ b/ceph/qa/suites/rados/thrash-erasure-code-overwrites/thrashosds-health.yaml @@ -0,0 +1 @@ +../../../tasks/thrashosds-health.yaml \ No newline at end of file diff --git a/ceph/qa/suites/rados/thrash-erasure-code-shec/thrashosds-health.yaml b/ceph/qa/suites/rados/thrash-erasure-code-shec/thrashosds-health.yaml new file mode 120000 index 000000000..ebf7f34f3 --- /dev/null +++ b/ceph/qa/suites/rados/thrash-erasure-code-shec/thrashosds-health.yaml @@ -0,0 +1 @@ +../../../tasks/thrashosds-health.yaml \ No newline at end of file diff --git a/ceph/qa/suites/rados/thrash-erasure-code/thrashosds-health.yaml b/ceph/qa/suites/rados/thrash-erasure-code/thrashosds-health.yaml new file mode 120000 index 000000000..ebf7f34f3 --- /dev/null +++ b/ceph/qa/suites/rados/thrash-erasure-code/thrashosds-health.yaml @@ -0,0 +1 @@ +../../../tasks/thrashosds-health.yaml \ No newline at end of file diff --git a/ceph/qa/suites/rados/thrash-luminous/thrashosds-health.yaml b/ceph/qa/suites/rados/thrash-luminous/thrashosds-health.yaml new file mode 120000 index 000000000..ebf7f34f3 --- /dev/null +++ b/ceph/qa/suites/rados/thrash-luminous/thrashosds-health.yaml @@ -0,0 +1 @@ +../../../tasks/thrashosds-health.yaml \ No newline at end of file diff --git a/ceph/qa/suites/rados/thrash/thrashosds-health.yaml b/ceph/qa/suites/rados/thrash/thrashosds-health.yaml new file mode 120000 index 000000000..ebf7f34f3 --- /dev/null +++ b/ceph/qa/suites/rados/thrash/thrashosds-health.yaml @@ -0,0 +1 @@ +../../../tasks/thrashosds-health.yaml \ No newline at end of file diff --git a/ceph/qa/suites/rados/thrash/workloads/cache-agent-big.yaml b/ceph/qa/suites/rados/thrash/workloads/cache-agent-big.yaml index 047ee7c6c..492ab8d45 100644 --- a/ceph/qa/suites/rados/thrash/workloads/cache-agent-big.yaml +++ b/ceph/qa/suites/rados/thrash/workloads/cache-agent-big.yaml @@ -5,7 +5,7 @@ overrides: tasks: - exec: client.0: - - sudo ceph osd erasure-code-profile set teuthologyprofile ruleset-failure-domain=osd m=1 k=2 + - sudo ceph osd erasure-code-profile set teuthologyprofile crush-failure-domain=osd m=1 k=2 - sudo ceph osd pool create base 4 4 erasure teuthologyprofile - sudo ceph osd pool set base min_size 2 - sudo ceph osd pool create cache 4 diff --git a/ceph/qa/suites/rados/thrash/workloads/cache-pool-snaps-readproxy.yaml b/ceph/qa/suites/rados/thrash/workloads/cache-pool-snaps-readproxy.yaml index 0f5462b7b..007775cee 100644 --- a/ceph/qa/suites/rados/thrash/workloads/cache-pool-snaps-readproxy.yaml +++ b/ceph/qa/suites/rados/thrash/workloads/cache-pool-snaps-readproxy.yaml @@ -25,9 +25,9 @@ tasks: write: 100 delete: 50 copy_from: 50 - flush: 50 - try_flush: 50 - evict: 50 + cache_flush: 50 + cache_try_flush: 50 + cache_evict: 50 snap_create: 50 snap_remove: 50 rollback: 50 diff --git a/ceph/qa/suites/rados/thrash/workloads/cache-pool-snaps.yaml b/ceph/qa/suites/rados/thrash/workloads/cache-pool-snaps.yaml index bf0229f22..a568a3402 100644 --- a/ceph/qa/suites/rados/thrash/workloads/cache-pool-snaps.yaml +++ b/ceph/qa/suites/rados/thrash/workloads/cache-pool-snaps.yaml @@ -27,9 +27,9 @@ tasks: write: 100 delete: 50 copy_from: 50 - flush: 50 - try_flush: 50 - evict: 50 + cache_flush: 50 + cache_try_flush: 50 + cache_evict: 50 snap_create: 50 snap_remove: 50 rollback: 50 diff --git a/ceph/qa/suites/rados/thrash/workloads/cache-snaps.yaml b/ceph/qa/suites/rados/thrash/workloads/cache-snaps.yaml index ee6849098..f4e2ffe13 100644 --- a/ceph/qa/suites/rados/thrash/workloads/cache-snaps.yaml +++ b/ceph/qa/suites/rados/thrash/workloads/cache-snaps.yaml @@ -25,9 +25,9 @@ tasks: write: 100 delete: 50 copy_from: 50 - flush: 50 - try_flush: 50 - evict: 50 + cache_flush: 50 + cache_try_flush: 50 + cache_evict: 50 snap_create: 50 snap_remove: 50 rollback: 50 diff --git a/ceph/qa/suites/rados/thrash/workloads/cache.yaml b/ceph/qa/suites/rados/thrash/workloads/cache.yaml index 8087e1cd4..4c5c1b605 100644 --- a/ceph/qa/suites/rados/thrash/workloads/cache.yaml +++ b/ceph/qa/suites/rados/thrash/workloads/cache.yaml @@ -25,6 +25,6 @@ tasks: write: 100 delete: 50 copy_from: 50 - flush: 50 - try_flush: 50 - evict: 50 + cache_flush: 50 + cache_try_flush: 50 + cache_evict: 50 diff --git a/ceph/qa/suites/rados/upgrade/jewel-x-singleton/1-jewel-install/jewel.yaml b/ceph/qa/suites/rados/upgrade/jewel-x-singleton/1-jewel-install/jewel.yaml index a617f91d1..c138b9be4 100644 --- a/ceph/qa/suites/rados/upgrade/jewel-x-singleton/1-jewel-install/jewel.yaml +++ b/ceph/qa/suites/rados/upgrade/jewel-x-singleton/1-jewel-install/jewel.yaml @@ -7,4 +7,5 @@ tasks: - print: "**** done install jewel" - ceph: skip_mgr_daemons: true + add_osds_to_crush: true - print: "**** done ceph" diff --git a/ceph/qa/suites/rados/upgrade/jewel-x-singleton/6-finish-upgrade.yaml b/ceph/qa/suites/rados/upgrade/jewel-x-singleton/6-finish-upgrade.yaml index 8dff34589..d4c69463c 100644 --- a/ceph/qa/suites/rados/upgrade/jewel-x-singleton/6-finish-upgrade.yaml +++ b/ceph/qa/suites/rados/upgrade/jewel-x-singleton/6-finish-upgrade.yaml @@ -13,3 +13,5 @@ tasks: daemons: [mds.a] wait-for-up: true wait-for-healthy: false +- install.upgrade: + client.0: diff --git a/ceph/qa/suites/rados/upgrade/jewel-x-singleton/8-workload/rbd-python.yaml b/ceph/qa/suites/rados/upgrade/jewel-x-singleton/8-workload/rbd-python.yaml index 8da34579c..56ba21d7a 100644 --- a/ceph/qa/suites/rados/upgrade/jewel-x-singleton/8-workload/rbd-python.yaml +++ b/ceph/qa/suites/rados/upgrade/jewel-x-singleton/8-workload/rbd-python.yaml @@ -3,7 +3,6 @@ meta: librbd python api tests tasks: - workunit: - branch: jewel clients: client.0: - rbd/test_librbd_python.sh diff --git a/ceph/qa/suites/rados/upgrade/jewel-x-singleton/thrashosds-health.yaml b/ceph/qa/suites/rados/upgrade/jewel-x-singleton/thrashosds-health.yaml new file mode 120000 index 000000000..e0426dbe4 --- /dev/null +++ b/ceph/qa/suites/rados/upgrade/jewel-x-singleton/thrashosds-health.yaml @@ -0,0 +1 @@ +../../../../tasks/thrashosds-health.yaml \ No newline at end of file diff --git a/ceph/qa/suites/rados/verify/d-thrash/default/+ b/ceph/qa/suites/rados/verify/d-thrash/default/+ new file mode 100644 index 000000000..e69de29bb diff --git a/ceph/qa/suites/rados/verify/d-thrash/default.yaml b/ceph/qa/suites/rados/verify/d-thrash/default/default.yaml similarity index 100% rename from ceph/qa/suites/rados/verify/d-thrash/default.yaml rename to ceph/qa/suites/rados/verify/d-thrash/default/default.yaml diff --git a/ceph/qa/suites/rados/verify/d-thrash/default/thrashosds-health.yaml b/ceph/qa/suites/rados/verify/d-thrash/default/thrashosds-health.yaml new file mode 120000 index 000000000..0b1d7b060 --- /dev/null +++ b/ceph/qa/suites/rados/verify/d-thrash/default/thrashosds-health.yaml @@ -0,0 +1 @@ +../../../../../tasks/thrashosds-health.yaml \ No newline at end of file diff --git a/ceph/qa/suites/rados/verify/tasks/mon_recovery.yaml b/ceph/qa/suites/rados/verify/tasks/mon_recovery.yaml index 698630340..412db8630 100644 --- a/ceph/qa/suites/rados/verify/tasks/mon_recovery.yaml +++ b/ceph/qa/suites/rados/verify/tasks/mon_recovery.yaml @@ -1,2 +1,9 @@ +overrides: + ceph: + log-whitelist: + - overall HEALTH_ + - (MON_DOWN) + - (OSDMAP_FLAGS) + - (SMALLER_PGP_NUM) tasks: - mon_recovery: diff --git a/ceph/qa/suites/rados/verify/tasks/rados_api_tests.yaml b/ceph/qa/suites/rados/verify/tasks/rados_api_tests.yaml index 11e3858f6..7c06248d2 100644 --- a/ceph/qa/suites/rados/verify/tasks/rados_api_tests.yaml +++ b/ceph/qa/suites/rados/verify/tasks/rados_api_tests.yaml @@ -2,6 +2,12 @@ overrides: ceph: log-whitelist: - reached quota + - overall HEALTH_ + - (CACHE_POOL_NO_HIT_SET) + - (POOL_FULL) + - (SMALLER_PGP_NUM) + - (REQUEST_SLOW) + - (CACHE_POOL_NEAR_FULL) conf: client: debug ms: 1 diff --git a/ceph/qa/suites/rados/verify/validater/valgrind.yaml b/ceph/qa/suites/rados/verify/validater/valgrind.yaml index ef5ef7bd7..b2095b0c9 100644 --- a/ceph/qa/suites/rados/verify/validater/valgrind.yaml +++ b/ceph/qa/suites/rados/verify/validater/valgrind.yaml @@ -1,4 +1,6 @@ -os_type: centos # xenial valgrind buggy, see http://tracker.ceph.com/issues/18126 +# see http://tracker.ceph.com/issues/20360 and http://tracker.ceph.com/issues/18126 +os_type: centos + overrides: install: ceph: @@ -8,6 +10,8 @@ overrides: conf: global: osd heartbeat grace: 40 + mon: + mon osd crush smoke test: false valgrind: mon: [--tool=memcheck, --leak-check=full, --show-reachable=yes] osd: [--tool=memcheck] diff --git a/ceph/qa/suites/rbd/basic/cachepool/small.yaml b/ceph/qa/suites/rbd/basic/cachepool/small.yaml index 8262be330..5c8f924ab 100644 --- a/ceph/qa/suites/rbd/basic/cachepool/small.yaml +++ b/ceph/qa/suites/rbd/basic/cachepool/small.yaml @@ -1,3 +1,8 @@ +overrides: + ceph: + log-whitelist: + - overall HEALTH_ + - (CACHE_POOL_NO_HIT_SET) tasks: - exec: client.0: diff --git a/ceph/qa/suites/rbd/basic/tasks/rbd_api_tests_old_format.yaml b/ceph/qa/suites/rbd/basic/tasks/rbd_api_tests_old_format.yaml index a98768540..9d34002a1 100644 --- a/ceph/qa/suites/rbd/basic/tasks/rbd_api_tests_old_format.yaml +++ b/ceph/qa/suites/rbd/basic/tasks/rbd_api_tests_old_format.yaml @@ -1,3 +1,8 @@ +overrides: + ceph: + log-whitelist: + - overall HEALTH_ + - (CACHE_POOL_NO_HIT_SET) tasks: - workunit: clients: diff --git a/ceph/qa/suites/rbd/basic/tasks/rbd_python_api_tests_old_format.yaml b/ceph/qa/suites/rbd/basic/tasks/rbd_python_api_tests_old_format.yaml index 263b784e2..f60a5ffa7 100644 --- a/ceph/qa/suites/rbd/basic/tasks/rbd_python_api_tests_old_format.yaml +++ b/ceph/qa/suites/rbd/basic/tasks/rbd_python_api_tests_old_format.yaml @@ -1,3 +1,7 @@ +overrides: + ceph: + log-whitelist: + - (REQUEST_SLOW) tasks: - workunit: clients: diff --git a/ceph/qa/suites/rbd/cli/pool/ec-data-pool.yaml b/ceph/qa/suites/rbd/cli/pool/ec-data-pool.yaml index 9558cc63a..32dd2ab90 100644 --- a/ceph/qa/suites/rbd/cli/pool/ec-data-pool.yaml +++ b/ceph/qa/suites/rbd/cli/pool/ec-data-pool.yaml @@ -1,7 +1,7 @@ tasks: - exec: client.0: - - sudo ceph osd erasure-code-profile set teuthologyprofile ruleset-failure-domain=osd m=1 k=2 + - sudo ceph osd erasure-code-profile set teuthologyprofile crush-failure-domain=osd m=1 k=2 - sudo ceph osd pool create datapool 4 4 erasure teuthologyprofile - sudo ceph osd pool set datapool allow_ec_overwrites true @@ -11,6 +11,9 @@ overrides: bdev_inject_crash_probability: .5 ceph: fs: xfs + log-whitelist: + - overall HEALTH_ + - (CACHE_POOL_NO_HIT_SET) conf: client: rbd default data pool: datapool diff --git a/ceph/qa/suites/rbd/cli/pool/small-cache-pool.yaml b/ceph/qa/suites/rbd/cli/pool/small-cache-pool.yaml index 8262be330..5c8f924ab 100644 --- a/ceph/qa/suites/rbd/cli/pool/small-cache-pool.yaml +++ b/ceph/qa/suites/rbd/cli/pool/small-cache-pool.yaml @@ -1,3 +1,8 @@ +overrides: + ceph: + log-whitelist: + - overall HEALTH_ + - (CACHE_POOL_NO_HIT_SET) tasks: - exec: client.0: diff --git a/ceph/qa/suites/rbd/librbd/pool/ec-data-pool.yaml b/ceph/qa/suites/rbd/librbd/pool/ec-data-pool.yaml index 9558cc63a..75dfc6a45 100644 --- a/ceph/qa/suites/rbd/librbd/pool/ec-data-pool.yaml +++ b/ceph/qa/suites/rbd/librbd/pool/ec-data-pool.yaml @@ -1,7 +1,7 @@ tasks: - exec: client.0: - - sudo ceph osd erasure-code-profile set teuthologyprofile ruleset-failure-domain=osd m=1 k=2 + - sudo ceph osd erasure-code-profile set teuthologyprofile crush-failure-domain=osd m=1 k=2 - sudo ceph osd pool create datapool 4 4 erasure teuthologyprofile - sudo ceph osd pool set datapool allow_ec_overwrites true diff --git a/ceph/qa/suites/rbd/librbd/pool/small-cache-pool.yaml b/ceph/qa/suites/rbd/librbd/pool/small-cache-pool.yaml index 8262be330..5c8f924ab 100644 --- a/ceph/qa/suites/rbd/librbd/pool/small-cache-pool.yaml +++ b/ceph/qa/suites/rbd/librbd/pool/small-cache-pool.yaml @@ -1,3 +1,8 @@ +overrides: + ceph: + log-whitelist: + - overall HEALTH_ + - (CACHE_POOL_NO_HIT_SET) tasks: - exec: client.0: diff --git a/ceph/qa/suites/rbd/librbd/workloads/c_api_tests.yaml b/ceph/qa/suites/rbd/librbd/workloads/c_api_tests.yaml index 188ddc56c..b70e8d52b 100644 --- a/ceph/qa/suites/rbd/librbd/workloads/c_api_tests.yaml +++ b/ceph/qa/suites/rbd/librbd/workloads/c_api_tests.yaml @@ -1,3 +1,8 @@ +overrides: + ceph: + log-whitelist: + - overall HEALTH_ + - (CACHE_POOL_NO_HIT_SET) tasks: - workunit: clients: diff --git a/ceph/qa/suites/rbd/librbd/workloads/c_api_tests_with_defaults.yaml b/ceph/qa/suites/rbd/librbd/workloads/c_api_tests_with_defaults.yaml index ee1de610a..c2af3573d 100644 --- a/ceph/qa/suites/rbd/librbd/workloads/c_api_tests_with_defaults.yaml +++ b/ceph/qa/suites/rbd/librbd/workloads/c_api_tests_with_defaults.yaml @@ -1,3 +1,8 @@ +overrides: + ceph: + log-whitelist: + - overall HEALTH_ + - (CACHE_POOL_NO_HIT_SET) tasks: - workunit: clients: diff --git a/ceph/qa/suites/rbd/librbd/workloads/c_api_tests_with_journaling.yaml b/ceph/qa/suites/rbd/librbd/workloads/c_api_tests_with_journaling.yaml index eda2b5e8a..f1121a403 100644 --- a/ceph/qa/suites/rbd/librbd/workloads/c_api_tests_with_journaling.yaml +++ b/ceph/qa/suites/rbd/librbd/workloads/c_api_tests_with_journaling.yaml @@ -1,3 +1,8 @@ +overrides: + ceph: + log-whitelist: + - overall HEALTH_ + - (CACHE_POOL_NO_HIT_SET) tasks: - workunit: clients: diff --git a/ceph/qa/suites/rbd/maintenance/workloads/dynamic_features_no_cache.yaml b/ceph/qa/suites/rbd/maintenance/workloads/dynamic_features_no_cache.yaml new file mode 100644 index 000000000..3f31b18e1 --- /dev/null +++ b/ceph/qa/suites/rbd/maintenance/workloads/dynamic_features_no_cache.yaml @@ -0,0 +1,13 @@ +tasks: +- ceph: + conf: + client: + rbd cache: false +op_workload: + sequential: + - workunit: + clients: + client.0: + - rbd/qemu_dynamic_features.sh + env: + IMAGE_NAME: client.0.1-clone diff --git a/ceph/qa/suites/rbd/nbd/thrashosds-health.yaml b/ceph/qa/suites/rbd/nbd/thrashosds-health.yaml new file mode 120000 index 000000000..ebf7f34f3 --- /dev/null +++ b/ceph/qa/suites/rbd/nbd/thrashosds-health.yaml @@ -0,0 +1 @@ +../../../tasks/thrashosds-health.yaml \ No newline at end of file diff --git a/ceph/qa/suites/rbd/openstack/workloads/devstack-tempest-gate.yaml b/ceph/qa/suites/rbd/openstack/workloads/devstack-tempest-gate.yaml index f7c3413a7..26ddda9ed 100644 --- a/ceph/qa/suites/rbd/openstack/workloads/devstack-tempest-gate.yaml +++ b/ceph/qa/suites/rbd/openstack/workloads/devstack-tempest-gate.yaml @@ -26,6 +26,10 @@ tasks: - "ALL=(root) NOPASSWD:/usr/bin/ovsdb-client" - | #!/bin/bash -ex + wget -q -O- "http://git.ceph.com/?p=ceph.git;a=blob_plain;f=keys/autobuild.asc" | apt-key add - + wget -q -O /etc/apt/sources.list.d/ceph.list "https://shaman.ceph.com/api/repos/ceph/{ceph_branch}/{ceph_sha1}/ubuntu/xenial/repo" + apt-get update + mount --bind /mnt/test_b /opt mkdir /opt/stack chown -R stack:stack /home/stack @@ -34,3 +38,14 @@ tasks: mkdir /mnt/log/stack chmod a+rwx /mnt/log/stack chown -R stack:stack /mnt/log/stack + + apt-get install -y ceph-common librbd1 + + mkdir /mnt/log/stack/ceph + chown -R stack:stack /mnt/log/stack/ceph + chmod a+rwx /mnt/log/stack/ceph + + # sanity check that the cluster is reachable from the VM + echo '[client]' >> /etc/ceph/ceph.conf + echo 'log file = /mnt/log/stack/ceph/$name.$pid.log' >> /etc/ceph/ceph.conf + rbd --debug-ms=10 --debug-rbd=20 info client.0.1 diff --git a/ceph/qa/suites/rbd/qemu/pool/ec-cache-pool.yaml b/ceph/qa/suites/rbd/qemu/pool/ec-cache-pool.yaml index 554aba3b5..09e8bc3f2 100644 --- a/ceph/qa/suites/rbd/qemu/pool/ec-cache-pool.yaml +++ b/ceph/qa/suites/rbd/qemu/pool/ec-cache-pool.yaml @@ -1,7 +1,12 @@ +overrides: + ceph: + log-whitelist: + - overall HEALTH_ + - (CACHE_POOL_NO_HIT_SET) tasks: - exec: client.0: - - sudo ceph osd erasure-code-profile set teuthologyprofile ruleset-failure-domain=osd m=1 k=2 + - sudo ceph osd erasure-code-profile set teuthologyprofile crush-failure-domain=osd m=1 k=2 - sudo ceph osd pool delete rbd rbd --yes-i-really-really-mean-it - sudo ceph osd pool create rbd 4 4 erasure teuthologyprofile - sudo ceph osd pool create cache 4 diff --git a/ceph/qa/suites/rbd/qemu/pool/ec-data-pool.yaml b/ceph/qa/suites/rbd/qemu/pool/ec-data-pool.yaml index 9558cc63a..75dfc6a45 100644 --- a/ceph/qa/suites/rbd/qemu/pool/ec-data-pool.yaml +++ b/ceph/qa/suites/rbd/qemu/pool/ec-data-pool.yaml @@ -1,7 +1,7 @@ tasks: - exec: client.0: - - sudo ceph osd erasure-code-profile set teuthologyprofile ruleset-failure-domain=osd m=1 k=2 + - sudo ceph osd erasure-code-profile set teuthologyprofile crush-failure-domain=osd m=1 k=2 - sudo ceph osd pool create datapool 4 4 erasure teuthologyprofile - sudo ceph osd pool set datapool allow_ec_overwrites true diff --git a/ceph/qa/suites/rbd/qemu/pool/small-cache-pool.yaml b/ceph/qa/suites/rbd/qemu/pool/small-cache-pool.yaml index 8262be330..5c8f924ab 100644 --- a/ceph/qa/suites/rbd/qemu/pool/small-cache-pool.yaml +++ b/ceph/qa/suites/rbd/qemu/pool/small-cache-pool.yaml @@ -1,3 +1,8 @@ +overrides: + ceph: + log-whitelist: + - overall HEALTH_ + - (CACHE_POOL_NO_HIT_SET) tasks: - exec: client.0: diff --git a/ceph/qa/suites/rbd/singleton/all/rbd_mirror.yaml b/ceph/qa/suites/rbd/singleton/all/rbd_mirror.yaml index 21624164b..5006dd801 100644 --- a/ceph/qa/suites/rbd/singleton/all/rbd_mirror.yaml +++ b/ceph/qa/suites/rbd/singleton/all/rbd_mirror.yaml @@ -4,6 +4,9 @@ tasks: - install: - ceph: fs: xfs + log-whitelist: + - overall HEALTH_ + - (CACHE_POOL_NO_HIT_SET) - workunit: clients: all: [rbd/test_rbd_mirror.sh] diff --git a/ceph/qa/suites/rbd/thrash/thrashosds-health.yaml b/ceph/qa/suites/rbd/thrash/thrashosds-health.yaml new file mode 120000 index 000000000..ebf7f34f3 --- /dev/null +++ b/ceph/qa/suites/rbd/thrash/thrashosds-health.yaml @@ -0,0 +1 @@ +../../../tasks/thrashosds-health.yaml \ No newline at end of file diff --git a/ceph/qa/suites/rbd/thrash/workloads/rbd_api_tests.yaml b/ceph/qa/suites/rbd/thrash/workloads/rbd_api_tests.yaml index ee1de610a..c2af3573d 100644 --- a/ceph/qa/suites/rbd/thrash/workloads/rbd_api_tests.yaml +++ b/ceph/qa/suites/rbd/thrash/workloads/rbd_api_tests.yaml @@ -1,3 +1,8 @@ +overrides: + ceph: + log-whitelist: + - overall HEALTH_ + - (CACHE_POOL_NO_HIT_SET) tasks: - workunit: clients: diff --git a/ceph/qa/suites/rbd/thrash/workloads/rbd_api_tests_copy_on_read.yaml b/ceph/qa/suites/rbd/thrash/workloads/rbd_api_tests_copy_on_read.yaml index cfa0a25a7..7f64ef3f1 100644 --- a/ceph/qa/suites/rbd/thrash/workloads/rbd_api_tests_copy_on_read.yaml +++ b/ceph/qa/suites/rbd/thrash/workloads/rbd_api_tests_copy_on_read.yaml @@ -7,6 +7,9 @@ tasks: RBD_FEATURES: "61" overrides: ceph: + log-whitelist: + - overall HEALTH_ + - (CACHE_POOL_NO_HIT_SET) conf: client: rbd clone copy on read: true diff --git a/ceph/qa/suites/rbd/thrash/workloads/rbd_api_tests_journaling.yaml b/ceph/qa/suites/rbd/thrash/workloads/rbd_api_tests_journaling.yaml index eda2b5e8a..f1121a403 100644 --- a/ceph/qa/suites/rbd/thrash/workloads/rbd_api_tests_journaling.yaml +++ b/ceph/qa/suites/rbd/thrash/workloads/rbd_api_tests_journaling.yaml @@ -1,3 +1,8 @@ +overrides: + ceph: + log-whitelist: + - overall HEALTH_ + - (CACHE_POOL_NO_HIT_SET) tasks: - workunit: clients: diff --git a/ceph/qa/suites/rbd/thrash/workloads/rbd_api_tests_no_locking.yaml b/ceph/qa/suites/rbd/thrash/workloads/rbd_api_tests_no_locking.yaml index 188ddc56c..b70e8d52b 100644 --- a/ceph/qa/suites/rbd/thrash/workloads/rbd_api_tests_no_locking.yaml +++ b/ceph/qa/suites/rbd/thrash/workloads/rbd_api_tests_no_locking.yaml @@ -1,3 +1,8 @@ +overrides: + ceph: + log-whitelist: + - overall HEALTH_ + - (CACHE_POOL_NO_HIT_SET) tasks: - workunit: clients: diff --git a/ceph/qa/suites/rbd/valgrind/validator/memcheck.yaml b/ceph/qa/suites/rbd/valgrind/validator/memcheck.yaml index c5348269a..c660dce62 100644 --- a/ceph/qa/suites/rbd/valgrind/validator/memcheck.yaml +++ b/ceph/qa/suites/rbd/valgrind/validator/memcheck.yaml @@ -1,4 +1,6 @@ -os_type: centos # xenial valgrind buggy, see http://tracker.ceph.com/issues/18126 +# see http://tracker.ceph.com/issues/20360 and http://tracker.ceph.com/issues/18126 +os_type: centos + overrides: install: ceph: diff --git a/ceph/qa/suites/rbd/valgrind/workloads/c_api_tests.yaml b/ceph/qa/suites/rbd/valgrind/workloads/c_api_tests.yaml index 188ddc56c..b70e8d52b 100644 --- a/ceph/qa/suites/rbd/valgrind/workloads/c_api_tests.yaml +++ b/ceph/qa/suites/rbd/valgrind/workloads/c_api_tests.yaml @@ -1,3 +1,8 @@ +overrides: + ceph: + log-whitelist: + - overall HEALTH_ + - (CACHE_POOL_NO_HIT_SET) tasks: - workunit: clients: diff --git a/ceph/qa/suites/rbd/valgrind/workloads/c_api_tests_with_defaults.yaml b/ceph/qa/suites/rbd/valgrind/workloads/c_api_tests_with_defaults.yaml index ee1de610a..c2af3573d 100644 --- a/ceph/qa/suites/rbd/valgrind/workloads/c_api_tests_with_defaults.yaml +++ b/ceph/qa/suites/rbd/valgrind/workloads/c_api_tests_with_defaults.yaml @@ -1,3 +1,8 @@ +overrides: + ceph: + log-whitelist: + - overall HEALTH_ + - (CACHE_POOL_NO_HIT_SET) tasks: - workunit: clients: diff --git a/ceph/qa/suites/rbd/valgrind/workloads/c_api_tests_with_journaling.yaml b/ceph/qa/suites/rbd/valgrind/workloads/c_api_tests_with_journaling.yaml index eda2b5e8a..f1121a403 100644 --- a/ceph/qa/suites/rbd/valgrind/workloads/c_api_tests_with_journaling.yaml +++ b/ceph/qa/suites/rbd/valgrind/workloads/c_api_tests_with_journaling.yaml @@ -1,3 +1,8 @@ +overrides: + ceph: + log-whitelist: + - overall HEALTH_ + - (CACHE_POOL_NO_HIT_SET) tasks: - workunit: clients: diff --git a/ceph/qa/suites/rbd/valgrind/workloads/python_api_tests.yaml b/ceph/qa/suites/rbd/valgrind/workloads/python_api_tests.yaml index a7b3ce7d3..0fa86ad3c 100644 --- a/ceph/qa/suites/rbd/valgrind/workloads/python_api_tests.yaml +++ b/ceph/qa/suites/rbd/valgrind/workloads/python_api_tests.yaml @@ -1,3 +1,5 @@ +os_type: centos +os_version: "7.3" tasks: - workunit: clients: diff --git a/ceph/qa/suites/rbd/valgrind/workloads/python_api_tests_with_defaults.yaml b/ceph/qa/suites/rbd/valgrind/workloads/python_api_tests_with_defaults.yaml index 40b2312f6..ec1eddd6c 100644 --- a/ceph/qa/suites/rbd/valgrind/workloads/python_api_tests_with_defaults.yaml +++ b/ceph/qa/suites/rbd/valgrind/workloads/python_api_tests_with_defaults.yaml @@ -1,3 +1,5 @@ +os_type: centos +os_version: "7.3" tasks: - workunit: clients: diff --git a/ceph/qa/suites/rbd/valgrind/workloads/python_api_tests_with_journaling.yaml b/ceph/qa/suites/rbd/valgrind/workloads/python_api_tests_with_journaling.yaml index d0e905ff4..b7de1bceb 100644 --- a/ceph/qa/suites/rbd/valgrind/workloads/python_api_tests_with_journaling.yaml +++ b/ceph/qa/suites/rbd/valgrind/workloads/python_api_tests_with_journaling.yaml @@ -1,3 +1,5 @@ +os_type: centos +os_version: "7.3" tasks: - workunit: clients: diff --git a/ceph/qa/suites/rbd/valgrind/workloads/rbd_mirror.yaml b/ceph/qa/suites/rbd/valgrind/workloads/rbd_mirror.yaml index 4a2ee40e3..8adc7209a 100644 --- a/ceph/qa/suites/rbd/valgrind/workloads/rbd_mirror.yaml +++ b/ceph/qa/suites/rbd/valgrind/workloads/rbd_mirror.yaml @@ -1,3 +1,8 @@ +overrides: + ceph: + log-whitelist: + - overall HEALTH_ + - (CACHE_POOL_NO_HIT_SET) tasks: - workunit: clients: diff --git a/ceph/qa/suites/rgw/hadoop-s3a/s3a-hadoop-v28.yaml b/ceph/qa/suites/rgw/hadoop-s3a/s3a-hadoop-v28.yaml new file mode 100644 index 000000000..41dfa408b --- /dev/null +++ b/ceph/qa/suites/rgw/hadoop-s3a/s3a-hadoop-v28.yaml @@ -0,0 +1,31 @@ +os_type: centos +os_version: "7.3" +machine_type: vps +overrides: + ceph_ansible: + vars: + ceph_conf_overrides: + global: + osd default pool size: 2 + osd pool default pg num: 128 + osd pool default pgp num: 128 + debug rgw: 20 + debug ms: 1 + ceph_test: true + ceph_dev: true + ceph_dev_key: https://download.ceph.com/keys/autobuild.asc + ceph_origin: upstream + journal_collocation: true + osd_auto_discovery: false + journal_size: 1024 + +roles: +- [mon.a, osd.0, osd.1, osd.2, rgw.0] +- [osd.3, osd.4, osd.5] +- [osd.6, osd.7, osd.8] +- [mgr.x] +tasks: +- ssh-keys: +- ceph-ansible: +- s3a-hadoop: + hadoop-version: '2.8.0' diff --git a/ceph/qa/suites/rgw/hadoop-s3a/s3a-hadoop.yaml b/ceph/qa/suites/rgw/hadoop-s3a/s3a-hadoop.yaml new file mode 100644 index 000000000..171cc66e2 --- /dev/null +++ b/ceph/qa/suites/rgw/hadoop-s3a/s3a-hadoop.yaml @@ -0,0 +1,29 @@ +os_type: centos +os_version: "7.3" +machine_type: vps +overrides: + ceph_ansible: + vars: + ceph_conf_overrides: + global: + osd default pool size: 2 + osd pool default pg num: 128 + osd pool default pgp num: 128 + debug rgw: 20 + debug ms: 1 + ceph_test: true + ceph_dev: true + ceph_dev_key: https://download.ceph.com/keys/autobuild.asc + ceph_origin: upstream + journal_collocation: true + osd_auto_discovery: false + journal_size: 1024 +roles: +- [mon.a, osd.0, osd.1, osd.2, rgw.0] +- [osd.3, osd.4, osd.5] +- [osd.6, osd.7, osd.8] +- [mgr.x] +tasks: +- ssh-keys: +- ceph-ansible: +- s3a-hadoop: diff --git a/ceph/qa/suites/rgw/multisite/tasks/test_multi.yaml b/ceph/qa/suites/rgw/multisite/tasks/test_multi.yaml index 508c06a52..a8f897873 100644 --- a/ceph/qa/suites/rgw/multisite/tasks/test_multi.yaml +++ b/ceph/qa/suites/rgw/multisite/tasks/test_multi.yaml @@ -1,3 +1,6 @@ +# see http://tracker.ceph.com/issues/20360 and http://tracker.ceph.com/issues/18126 +os_type: centos + tasks: - install: - ceph: {cluster: c1} diff --git a/ceph/qa/suites/rgw/multisite/valgrind.yaml b/ceph/qa/suites/rgw/multisite/valgrind.yaml index 1e17c783a..08fad9da0 100644 --- a/ceph/qa/suites/rgw/multisite/valgrind.yaml +++ b/ceph/qa/suites/rgw/multisite/valgrind.yaml @@ -1,4 +1,6 @@ -os_type: centos # xenial valgrind buggy, see http://tracker.ceph.com/issues/18126 +# see http://tracker.ceph.com/issues/20360 and http://tracker.ceph.com/issues/18126 +os_type: centos + overrides: install: ceph: @@ -7,6 +9,8 @@ overrides: conf: global: osd heartbeat grace: 40 + mon: + mon osd crush smoke test: false valgrind: mon: [--tool=memcheck, --leak-check=full, --show-reachable=yes] osd: [--tool=memcheck] diff --git a/ceph/qa/suites/rgw/singleton/filestore-xfs.yaml b/ceph/qa/suites/rgw/singleton/filestore-xfs.yaml deleted file mode 120000 index 59ef7e484..000000000 --- a/ceph/qa/suites/rgw/singleton/filestore-xfs.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../objectstore/filestore-xfs.yaml \ No newline at end of file diff --git a/ceph/qa/suites/rgw/thrash/thrashosds-health.yaml b/ceph/qa/suites/rgw/thrash/thrashosds-health.yaml new file mode 120000 index 000000000..ebf7f34f3 --- /dev/null +++ b/ceph/qa/suites/rgw/thrash/thrashosds-health.yaml @@ -0,0 +1 @@ +../../../tasks/thrashosds-health.yaml \ No newline at end of file diff --git a/ceph/qa/suites/rgw/verify/tasks/rgw_s3tests.yaml b/ceph/qa/suites/rgw/verify/tasks/rgw_s3tests.yaml index 6d3c1370b..bed9f0e19 100644 --- a/ceph/qa/suites/rgw/verify/tasks/rgw_s3tests.yaml +++ b/ceph/qa/suites/rgw/verify/tasks/rgw_s3tests.yaml @@ -1,4 +1,6 @@ -os_type: centos # xenial valgrind buggy, see http://tracker.ceph.com/issues/18126 +# see http://tracker.ceph.com/issues/20360 and http://tracker.ceph.com/issues/18126 +os_type: centos + tasks: - install: flavor: notcmalloc diff --git a/ceph/qa/suites/rgw/verify/tasks/rgw_swift.yaml b/ceph/qa/suites/rgw/verify/tasks/rgw_swift.yaml index 6e6e9eee6..9b3aa6feb 100644 --- a/ceph/qa/suites/rgw/verify/tasks/rgw_swift.yaml +++ b/ceph/qa/suites/rgw/verify/tasks/rgw_swift.yaml @@ -1,4 +1,6 @@ -os_type: centos # xenial valgrind buggy, see http://tracker.ceph.com/issues/18126 +# see http://tracker.ceph.com/issues/20360 and http://tracker.ceph.com/issues/18126 +os_type: centos + tasks: - install: flavor: notcmalloc diff --git a/ceph/qa/suites/rgw/verify/validater/valgrind.yaml b/ceph/qa/suites/rgw/verify/validater/valgrind.yaml index ef5ef7bd7..b2095b0c9 100644 --- a/ceph/qa/suites/rgw/verify/validater/valgrind.yaml +++ b/ceph/qa/suites/rgw/verify/validater/valgrind.yaml @@ -1,4 +1,6 @@ -os_type: centos # xenial valgrind buggy, see http://tracker.ceph.com/issues/18126 +# see http://tracker.ceph.com/issues/20360 and http://tracker.ceph.com/issues/18126 +os_type: centos + overrides: install: ceph: @@ -8,6 +10,8 @@ overrides: conf: global: osd heartbeat grace: 40 + mon: + mon osd crush smoke test: false valgrind: mon: [--tool=memcheck, --leak-check=full, --show-reachable=yes] osd: [--tool=memcheck] diff --git a/ceph/qa/suites/smoke/basic/tasks/cfuse_workunit_suites_fsstress.yaml b/ceph/qa/suites/smoke/basic/tasks/cfuse_workunit_suites_fsstress.yaml index cd12eaef5..b58487c07 100644 --- a/ceph/qa/suites/smoke/basic/tasks/cfuse_workunit_suites_fsstress.yaml +++ b/ceph/qa/suites/smoke/basic/tasks/cfuse_workunit_suites_fsstress.yaml @@ -1,7 +1,6 @@ tasks: - install: - ceph: - fs: btrfs - ceph-fuse: - workunit: clients: diff --git a/ceph/qa/suites/smoke/basic/tasks/cfuse_workunit_suites_iozone.yaml b/ceph/qa/suites/smoke/basic/tasks/cfuse_workunit_suites_iozone.yaml index c4be4cd1d..dc6df2f70 100644 --- a/ceph/qa/suites/smoke/basic/tasks/cfuse_workunit_suites_iozone.yaml +++ b/ceph/qa/suites/smoke/basic/tasks/cfuse_workunit_suites_iozone.yaml @@ -1,7 +1,6 @@ tasks: - install: - ceph: - fs: btrfs - ceph-fuse: [client.0] - workunit: clients: diff --git a/ceph/qa/suites/smoke/basic/tasks/kclient_workunit_direct_io.yaml b/ceph/qa/suites/smoke/basic/tasks/kclient_workunit_direct_io.yaml index 29ccf4630..21820071d 100644 --- a/ceph/qa/suites/smoke/basic/tasks/kclient_workunit_direct_io.yaml +++ b/ceph/qa/suites/smoke/basic/tasks/kclient_workunit_direct_io.yaml @@ -6,7 +6,6 @@ overrides: tasks: - install: - ceph: - fs: btrfs - kclient: - workunit: clients: diff --git a/ceph/qa/suites/smoke/basic/tasks/libcephfs_interface_tests.yaml b/ceph/qa/suites/smoke/basic/tasks/libcephfs_interface_tests.yaml index 4996d33ca..aa2e7679a 100644 --- a/ceph/qa/suites/smoke/basic/tasks/libcephfs_interface_tests.yaml +++ b/ceph/qa/suites/smoke/basic/tasks/libcephfs_interface_tests.yaml @@ -10,7 +10,6 @@ overrides: tasks: - install: - ceph: - fs: btrfs - ceph-fuse: - workunit: clients: diff --git a/ceph/qa/suites/smoke/basic/tasks/rados_cache_snaps.yaml b/ceph/qa/suites/smoke/basic/tasks/rados_cache_snaps.yaml index a060fbc7d..fa593f496 100644 --- a/ceph/qa/suites/smoke/basic/tasks/rados_cache_snaps.yaml +++ b/ceph/qa/suites/smoke/basic/tasks/rados_cache_snaps.yaml @@ -1,7 +1,6 @@ tasks: - install: null - ceph: - fs: btrfs log-whitelist: - wrongly marked me down - objects unfound and apparently lost @@ -27,13 +26,13 @@ tasks: op_weights: copy_from: 50 delete: 50 - evict: 50 - flush: 50 + cache_evict: 50 + cache_flush: 50 read: 100 rollback: 50 snap_create: 50 snap_remove: 50 - try_flush: 50 + cache_try_flush: 50 write: 100 ops: 4000 pool_snaps: true diff --git a/ceph/qa/suites/smoke/basic/tasks/rados_python.yaml b/ceph/qa/suites/smoke/basic/tasks/rados_python.yaml index 399967cc1..862f21466 100644 --- a/ceph/qa/suites/smoke/basic/tasks/rados_python.yaml +++ b/ceph/qa/suites/smoke/basic/tasks/rados_python.yaml @@ -1,7 +1,6 @@ tasks: - install: - ceph: - fs: btrfs log-whitelist: - wrongly marked me down - ceph-fuse: diff --git a/ceph/qa/suites/smoke/basic/tasks/rbd_python_api_tests.yaml b/ceph/qa/suites/smoke/basic/tasks/rbd_python_api_tests.yaml index 7ed61d0a3..9714a6e40 100644 --- a/ceph/qa/suites/smoke/basic/tasks/rbd_python_api_tests.yaml +++ b/ceph/qa/suites/smoke/basic/tasks/rbd_python_api_tests.yaml @@ -1,7 +1,6 @@ tasks: - install: - ceph: - fs: btrfs - ceph-fuse: - workunit: clients: diff --git a/ceph/qa/suites/smoke/basic/tasks/rbd_workunit_suites_iozone.yaml b/ceph/qa/suites/smoke/basic/tasks/rbd_workunit_suites_iozone.yaml index e4961dd3d..237aa4b31 100644 --- a/ceph/qa/suites/smoke/basic/tasks/rbd_workunit_suites_iozone.yaml +++ b/ceph/qa/suites/smoke/basic/tasks/rbd_workunit_suites_iozone.yaml @@ -8,7 +8,6 @@ overrides: tasks: - install: - ceph: - fs: btrfs - rbd: all: image_size: 20480 diff --git a/ceph/qa/suites/smoke/basic/tasks/rgw_ec_s3tests.yaml b/ceph/qa/suites/smoke/basic/tasks/rgw_ec_s3tests.yaml index 2d14cc893..dc8fb6f54 100644 --- a/ceph/qa/suites/smoke/basic/tasks/rgw_ec_s3tests.yaml +++ b/ceph/qa/suites/smoke/basic/tasks/rgw_ec_s3tests.yaml @@ -6,7 +6,6 @@ overrides: tasks: - install: - ceph: - fs: btrfs - rgw: [client.0] - s3tests: client.0: diff --git a/ceph/qa/suites/upgrade/hammer-jewel-x/parallel/0-cluster/start.yaml b/ceph/qa/suites/upgrade/hammer-jewel-x/parallel/0-cluster/start.yaml index 9fa3ca310..41f2afffb 100644 --- a/ceph/qa/suites/upgrade/hammer-jewel-x/parallel/0-cluster/start.yaml +++ b/ceph/qa/suites/upgrade/hammer-jewel-x/parallel/0-cluster/start.yaml @@ -11,6 +11,7 @@ roles: - - mon.a - osd.0 - osd.1 + - mgr.x - - mon.b - mon.c - osd.2 diff --git a/ceph/qa/suites/upgrade/hammer-jewel-x/parallel/1-hammer-jewel-install/hammer-jewel.yaml b/ceph/qa/suites/upgrade/hammer-jewel-x/parallel/1-hammer-jewel-install/hammer-jewel.yaml index d743c89a5..c57e071ca 100644 --- a/ceph/qa/suites/upgrade/hammer-jewel-x/parallel/1-hammer-jewel-install/hammer-jewel.yaml +++ b/ceph/qa/suites/upgrade/hammer-jewel-x/parallel/1-hammer-jewel-install/hammer-jewel.yaml @@ -6,6 +6,7 @@ tasks: - ceph: fs: xfs skip_mgr_daemons: true + add_osds_to_crush: true - install.upgrade: exclude_packages: ['ceph-mgr','libcephfs2','libcephfs-devel','libcephfs-dev'] osd.0: diff --git a/ceph/qa/suites/upgrade/hammer-jewel-x/parallel/6-workload/ec-rados-default.yaml b/ceph/qa/suites/upgrade/hammer-jewel-x/parallel/6-workload/ec-rados-default.yaml index 15168a186..98185415e 100644 --- a/ceph/qa/suites/upgrade/hammer-jewel-x/parallel/6-workload/ec-rados-default.yaml +++ b/ceph/qa/suites/upgrade/hammer-jewel-x/parallel/6-workload/ec-rados-default.yaml @@ -9,7 +9,7 @@ workload2: name: teuthologyprofile2 k: 2 m: 1 - ruleset-failure-domain: osd + crush-failure-domain: osd clients: [client.0] ops: 4000 objects: 50 diff --git a/ceph/qa/suites/upgrade/hammer-jewel-x/parallel/7-upgrade-sequence/upgrade-all.yaml b/ceph/qa/suites/upgrade/hammer-jewel-x/parallel/7-upgrade-sequence/upgrade-all.yaml index ddbb9ff43..356f8adb5 100644 --- a/ceph/qa/suites/upgrade/hammer-jewel-x/parallel/7-upgrade-sequence/upgrade-all.yaml +++ b/ceph/qa/suites/upgrade/hammer-jewel-x/parallel/7-upgrade-sequence/upgrade-all.yaml @@ -7,9 +7,4 @@ upgrade-sequence2: daemons: [mon.a, mon.b, mon.c, osd.0, osd.1, osd.2, osd.3] wait-for-healthy: false wait-for-osds-up: true - - exec: - mon.a: - - ceph osd set require_kraken_osds - - ceph.restart: - daemons: [osd.0] - print: "**** done ceph.restart all" diff --git a/ceph/qa/suites/upgrade/hammer-jewel-x/parallel/7-upgrade-sequence/upgrade-by-daemon.yaml b/ceph/qa/suites/upgrade/hammer-jewel-x/parallel/7-upgrade-sequence/upgrade-by-daemon.yaml index f59a152dc..0a69a7fa4 100644 --- a/ceph/qa/suites/upgrade/hammer-jewel-x/parallel/7-upgrade-sequence/upgrade-by-daemon.yaml +++ b/ceph/qa/suites/upgrade/hammer-jewel-x/parallel/7-upgrade-sequence/upgrade-by-daemon.yaml @@ -2,13 +2,13 @@ meta: - desc: | upgrade the ceph cluster, upgrate in two steps - step one ordering: mon.a, osd.0, osd.1 - step two ordering: mon.b, mon.c, osd.2, osd.3 + step one ordering: mon.a, mon.b, mon.c, osd.0, osd.1 + step two ordering: osd.2, osd.3 ceph expected to be healthy state after each step upgrade-sequence2: sequential: - ceph.restart: - daemons: [mon.a] + daemons: [mon.a, mon.b, mon.c] wait-for-healthy: true - sleep: duration: 60 @@ -22,18 +22,9 @@ upgrade-sequence2: mon.b: - sudo ceph osd crush tunables jewel - print: "**** done ceph osd crush tunables jewel" - - ceph.restart: - daemons: [mon.b, mon.c] - wait-for-healthy: true - - sleep: - duration: 60 - ceph.restart: daemons: [osd.2, osd.3] wait-for-healthy: false wait-for-osds-up: true - - exec: - mon.a: - - ceph osd set require_kraken_osds - - ceph.restart: [osd.3] - sleep: duration: 60 diff --git a/ceph/qa/suites/upgrade/hammer-jewel-x/parallel/8-kraken.yaml b/ceph/qa/suites/upgrade/hammer-jewel-x/parallel/8-kraken.yaml deleted file mode 120000 index a890722e1..000000000 --- a/ceph/qa/suites/upgrade/hammer-jewel-x/parallel/8-kraken.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../../releases/kraken.yaml \ No newline at end of file diff --git a/ceph/qa/suites/upgrade/hammer-jewel-x/parallel/8-luminous.yaml b/ceph/qa/suites/upgrade/hammer-jewel-x/parallel/8-luminous.yaml new file mode 120000 index 000000000..5283ac73e --- /dev/null +++ b/ceph/qa/suites/upgrade/hammer-jewel-x/parallel/8-luminous.yaml @@ -0,0 +1 @@ +../../../../releases/luminous.yaml \ No newline at end of file diff --git a/ceph/qa/suites/upgrade/hammer-jewel-x/stress-split/1-hammer-install-and-upgrade-to-jewel/hammer-to-jewel.yaml b/ceph/qa/suites/upgrade/hammer-jewel-x/stress-split/1-hammer-install-and-upgrade-to-jewel/hammer-to-jewel.yaml index b69da11c5..212b8ff5c 100644 --- a/ceph/qa/suites/upgrade/hammer-jewel-x/stress-split/1-hammer-install-and-upgrade-to-jewel/hammer-to-jewel.yaml +++ b/ceph/qa/suites/upgrade/hammer-jewel-x/stress-split/1-hammer-install-and-upgrade-to-jewel/hammer-to-jewel.yaml @@ -10,6 +10,7 @@ tasks: - ceph: fs: xfs skip_mgr_daemons: true + add_osds_to_crush: true - install.upgrade: exclude_packages: - ceph-mgr diff --git a/ceph/qa/suites/upgrade/hammer-jewel-x/tiering/1-install-hammer-and-upgrade-to-jewel/hammer-to-jewel.yaml b/ceph/qa/suites/upgrade/hammer-jewel-x/tiering/1-install-hammer-and-upgrade-to-jewel/hammer-to-jewel.yaml index 4c58e5f0d..7485dcef5 100644 --- a/ceph/qa/suites/upgrade/hammer-jewel-x/tiering/1-install-hammer-and-upgrade-to-jewel/hammer-to-jewel.yaml +++ b/ceph/qa/suites/upgrade/hammer-jewel-x/tiering/1-install-hammer-and-upgrade-to-jewel/hammer-to-jewel.yaml @@ -10,3 +10,4 @@ tasks: - ceph: fs: xfs skip_mgr_daemons: true + add_osds_to_crush: true diff --git a/ceph/qa/suites/upgrade/hammer-jewel-x/tiering/2-setup-cache-tiering/0-create-base-tier/create-ec-pool.yaml b/ceph/qa/suites/upgrade/hammer-jewel-x/tiering/2-setup-cache-tiering/0-create-base-tier/create-ec-pool.yaml index 9ab479d39..f0043afbd 100644 --- a/ceph/qa/suites/upgrade/hammer-jewel-x/tiering/2-setup-cache-tiering/0-create-base-tier/create-ec-pool.yaml +++ b/ceph/qa/suites/upgrade/hammer-jewel-x/tiering/2-setup-cache-tiering/0-create-base-tier/create-ec-pool.yaml @@ -1,5 +1,5 @@ tasks: - exec: client.0: - - ceph osd erasure-code-profile set t-profile ruleset-failure-domain=osd k=2 m=1 + - ceph osd erasure-code-profile set t-profile crush-failure-domain=osd k=2 m=1 - ceph osd pool create base-pool 4 4 erasure t-profile diff --git a/ceph/qa/suites/upgrade/hammer-jewel-x/tiering/3-upgrade.yaml b/ceph/qa/suites/upgrade/hammer-jewel-x/tiering/3-upgrade.yaml index 3af3cfd72..b2fc171cc 100644 --- a/ceph/qa/suites/upgrade/hammer-jewel-x/tiering/3-upgrade.yaml +++ b/ceph/qa/suites/upgrade/hammer-jewel-x/tiering/3-upgrade.yaml @@ -16,9 +16,9 @@ workload: write: 100 delete: 50 copy_from: 50 - flush: 50 - try_flush: 50 - evict: 50 + cache_flush: 50 + cache_try_flush: 50 + cache_evict: 50 - print: "**** done rados" upgrade-sequence: diff --git a/ceph/qa/suites/upgrade/jewel-x/parallel/1-jewel-install/jewel.yaml b/ceph/qa/suites/upgrade/jewel-x/parallel/1-jewel-install/jewel.yaml index f5eec07e5..61b6f81f3 100644 --- a/ceph/qa/suites/upgrade/jewel-x/parallel/1-jewel-install/jewel.yaml +++ b/ceph/qa/suites/upgrade/jewel-x/parallel/1-jewel-install/jewel.yaml @@ -10,6 +10,7 @@ tasks: - print: "**** done installing jewel" - ceph: skip_mgr_daemons: true + add_osds_to_crush: true - print: "**** done ceph" - install.upgrade: mon.a: diff --git a/ceph/qa/suites/upgrade/jewel-x/parallel/2-workload/cache-pool-snaps.yaml b/ceph/qa/suites/upgrade/jewel-x/parallel/2-workload/cache-pool-snaps.yaml index 8e633e690..dfbcbeaf6 100644 --- a/ceph/qa/suites/upgrade/jewel-x/parallel/2-workload/cache-pool-snaps.yaml +++ b/ceph/qa/suites/upgrade/jewel-x/parallel/2-workload/cache-pool-snaps.yaml @@ -30,9 +30,9 @@ workload: write: 100 delete: 50 copy_from: 50 - flush: 50 - try_flush: 50 - evict: 50 + cache_flush: 50 + cache_try_flush: 50 + cache_evict: 50 snap_create: 50 snap_remove: 50 rollback: 50 diff --git a/ceph/qa/suites/upgrade/jewel-x/point-to-point-x/point-to-point-upgrade.yaml b/ceph/qa/suites/upgrade/jewel-x/point-to-point-x/point-to-point-upgrade.yaml index fd4a1d8f6..67d57f7b3 100644 --- a/ceph/qa/suites/upgrade/jewel-x/point-to-point-x/point-to-point-upgrade.yaml +++ b/ceph/qa/suites/upgrade/jewel-x/point-to-point-x/point-to-point-upgrade.yaml @@ -49,6 +49,7 @@ tasks: - ceph: fs: xfs skip_mgr_daemons: true + add_osds_to_crush: true - print: "**** done ceph xfs" - sequential: - workload diff --git a/ceph/qa/suites/upgrade/jewel-x/stress-split-erasure-code/7-final-workload/ec-rados-plugin=jerasure-k=3-m=1.yaml b/ceph/qa/suites/upgrade/jewel-x/stress-split-erasure-code/7-final-workload/ec-rados-plugin=jerasure-k=3-m=1.yaml index ab439d521..a82f11be7 100644 --- a/ceph/qa/suites/upgrade/jewel-x/stress-split-erasure-code/7-final-workload/ec-rados-plugin=jerasure-k=3-m=1.yaml +++ b/ceph/qa/suites/upgrade/jewel-x/stress-split-erasure-code/7-final-workload/ec-rados-plugin=jerasure-k=3-m=1.yaml @@ -21,7 +21,7 @@ tasks: k: 3 m: 1 technique: reed_sol_van - ruleset-failure-domain: osd + crush-failure-domain: osd op_weights: read: 100 write: 0 diff --git a/ceph/qa/suites/upgrade/jewel-x/stress-split/1-jewel-install/jewel.yaml b/ceph/qa/suites/upgrade/jewel-x/stress-split/1-jewel-install/jewel.yaml index a617f91d1..c138b9be4 100644 --- a/ceph/qa/suites/upgrade/jewel-x/stress-split/1-jewel-install/jewel.yaml +++ b/ceph/qa/suites/upgrade/jewel-x/stress-split/1-jewel-install/jewel.yaml @@ -7,4 +7,5 @@ tasks: - print: "**** done install jewel" - ceph: skip_mgr_daemons: true + add_osds_to_crush: true - print: "**** done ceph" diff --git a/ceph/qa/suites/upgrade/kraken-x/stress-split-erasure-code/7-final-workload.yaml b/ceph/qa/suites/upgrade/kraken-x/stress-split-erasure-code/7-final-workload.yaml index 8f5c95afc..50a146507 100644 --- a/ceph/qa/suites/upgrade/kraken-x/stress-split-erasure-code/7-final-workload.yaml +++ b/ceph/qa/suites/upgrade/kraken-x/stress-split-erasure-code/7-final-workload.yaml @@ -21,7 +21,7 @@ tasks: k: 3 m: 1 technique: reed_sol_van - ruleset-failure-domain: osd + crush-failure-domain: osd op_weights: read: 100 write: 0 diff --git a/ceph/qa/tasks/ceph.py b/ceph/qa/tasks/ceph.py index fa43530a6..5318643d2 100644 --- a/ceph/qa/tasks/ceph.py +++ b/ceph/qa/tasks/ceph.py @@ -326,6 +326,24 @@ def crush_setup(ctx, config): yield +@contextlib.contextmanager +def create_rbd_pool(ctx, config): + cluster_name = config['cluster'] + first_mon = teuthology.get_first_mon(ctx, config, cluster_name) + (mon_remote,) = ctx.cluster.only(first_mon).remotes.iterkeys() + log.info('Waiting for OSDs to come up') + teuthology.wait_until_osds_up( + ctx, + cluster=ctx.cluster, + remote=mon_remote, + ceph_cluster=cluster_name, + ) + log.info('Creating RBD pool') + mon_remote.run( + args=['sudo', 'ceph', '--cluster', cluster_name, + 'osd', 'pool', 'create', 'rbd', '8']) + yield + @contextlib.contextmanager def cephfs_setup(ctx, config): cluster_name = config['cluster'] @@ -346,7 +364,6 @@ def cephfs_setup(ctx, config): all_roles = [item for remote_roles in mdss.remotes.values() for item in remote_roles] num_active = len([r for r in all_roles if is_active_mds(r)]) - fs.set_allow_multimds(True) fs.set_max_mds(num_active) fs.set_allow_dirfrags(True) @@ -577,28 +594,6 @@ def cluster(ctx, config): log.info('Setting up mon nodes...') mons = ctx.cluster.only(teuthology.is_type('mon', cluster_name)) - osdmap_path = '{tdir}/{cluster}.osdmap'.format(tdir=testdir, - cluster=cluster_name) - run.wait( - mons.run( - args=[ - 'adjust-ulimits', - 'ceph-coverage', - coverage_dir, - 'osdmaptool', - '-c', conf_path, - '--clobber', - '--createsimple', '{num:d}'.format( - num=teuthology.num_instances_of_type(ctx.cluster, 'osd', - cluster_name), - ), - osdmap_path, - '--pg_bits', '2', - '--pgp_bits', '4', - ], - wait=False, - ), - ) if not config.get('skip_mgr_daemons', False): log.info('Setting up mgr nodes...') @@ -872,7 +867,6 @@ def cluster(ctx, config): '--mkfs', '-i', id_, '--monmap', monmap_path, - '--osdmap', osdmap_path, '--keyring', keyring_path, ], ) @@ -883,7 +877,6 @@ def cluster(ctx, config): 'rm', '--', monmap_path, - osdmap_path, ], wait=False, ), @@ -1012,7 +1005,6 @@ def cluster(ctx, config): keyring_path, data_dir, monmap_path, - osdmap_path, run.Raw('{tdir}/../*.pid'.format(tdir=testdir)), ], wait=False, @@ -1042,7 +1034,7 @@ def osd_scrub_pgs(ctx, config): all_clean = True break log.info( - "Waiting for all osds to be active and clean, waiting on %s" % bad) + "Waiting for all PGs to be active and clean, waiting on %s" % bad) time.sleep(delays) if not all_clean: raise RuntimeError("Scrubbing terminated -- not all pgs were active and clean.") @@ -1125,6 +1117,38 @@ def run_daemon(ctx, config, type_): continue _, _, id_ = teuthology.split_role(role) + if type_ == 'osd': + datadir='/var/lib/ceph/osd/{cluster}-{id}'.format( + cluster=cluster_name, id=id_) + osd_uuid = teuthology.get_file( + remote=remote, + path=datadir + '/fsid', + sudo=True, + ).strip() + try: + remote.run( + args=[ + 'sudo', 'ceph', '--cluster', cluster_name, + 'osd', 'new', osd_uuid, id_, + ] + ) + except: + # fallback to pre-luminous (hammer or jewel) + remote.run( + args=[ + 'sudo', 'ceph', '--cluster', cluster_name, + 'osd', 'create', osd_uuid, + ] + ) + if config.get('add_osds_to_crush'): + remote.run( + args=[ + 'sudo', 'ceph', '--cluster', cluster_name, + 'osd', 'crush', 'create-or-move', 'osd.' + id_, + '1.0', 'host=localhost', 'root=default', + ] + ) + run_cmd = [ 'sudo', 'adjust-ulimits', @@ -1579,6 +1603,7 @@ def task(ctx, config): lambda: run_daemon(ctx=ctx, config=config, type_='mgr'), lambda: crush_setup(ctx=ctx, config=config), lambda: run_daemon(ctx=ctx, config=config, type_='osd'), + lambda: create_rbd_pool(ctx=ctx, config=config), lambda: cephfs_setup(ctx=ctx, config=config), lambda: run_daemon(ctx=ctx, config=config, type_='mds'), ] @@ -1603,3 +1628,20 @@ def task(ctx, config): finally: if config.get('wait-for-scrub', True): osd_scrub_pgs(ctx, config) + + # stop logging health to clog during shutdown, or else we generate + # a bunch of scary messages unrelated to our actual run. + firstmon = teuthology.get_first_mon(ctx, config, config['cluster']) + (mon0_remote,) = ctx.cluster.only(firstmon).remotes.keys() + mon0_remote.run( + args=[ + 'sudo', + 'ceph', + '--cluster', config['cluster'], + 'tell', + 'mon.*', + 'injectargs', + '--', + '--no-mon-health-to-clog', + ] + ) diff --git a/ceph/qa/tasks/ceph_deploy.py b/ceph/qa/tasks/ceph_deploy.py index 3e5d2aba5..1b4040425 100644 --- a/ceph/qa/tasks/ceph_deploy.py +++ b/ceph/qa/tasks/ceph_deploy.py @@ -241,7 +241,10 @@ def build_ceph_cluster(ctx, config): mds_nodes = " ".join(mds_nodes) mon_node = get_nodes_using_role(ctx, 'mon') mon_nodes = " ".join(mon_node) + mgr_nodes = get_nodes_using_role(ctx, 'mgr') + mgr_nodes = " ".join(mgr_nodes) new_mon = './ceph-deploy new' + " " + mon_nodes + mgr_create = './ceph-deploy mgr create' + " " + mgr_nodes mon_hostname = mon_nodes.split(' ')[0] mon_hostname = str(mon_hostname) gather_keys = './ceph-deploy gatherkeys' + " " + mon_hostname @@ -294,6 +297,7 @@ def build_ceph_cluster(ctx, config): # are taking way more than a minute/monitor to form quorum, so lets # try the next block which will wait up to 15 minutes to gatherkeys. execute_ceph_deploy(mon_create_nodes) + execute_ceph_deploy(mgr_create) # create-keys is explicit now # http://tracker.ceph.com/issues/16036 diff --git a/ceph/qa/tasks/ceph_manager.py b/ceph/qa/tasks/ceph_manager.py index 465da73d2..964dc7344 100644 --- a/ceph/qa/tasks/ceph_manager.py +++ b/ceph/qa/tasks/ceph_manager.py @@ -125,6 +125,7 @@ class Thrasher: self.chance_thrash_cluster_full = self.config.get('chance_thrash_cluster_full', .05) self.chance_thrash_pg_upmap = self.config.get('chance_thrash_pg_upmap', 1.0) self.chance_thrash_pg_upmap_items = self.config.get('chance_thrash_pg_upmap', 1.0) + self.random_eio = self.config.get('random_eio') num_osds = self.in_osds + self.out_osds self.max_pgs = self.config.get("max_pgs_per_pool_osd", 1200) * num_osds @@ -435,6 +436,12 @@ class Thrasher: skip_admin_check=skip_admin_check) self.dead_osds.remove(osd) self.live_osds.append(osd) + if self.random_eio > 0 and osd is self.rerrosd: + self.ceph_manager.raw_cluster_cmd('tell', 'osd.'+str(self.rerrosd), + 'injectargs', '--', '--filestore_debug_random_read_err='+str(self.random_eio)) + self.ceph_manager.raw_cluster_cmd('tell', 'osd.'+str(self.rerrosd), + 'injectargs', '--', '--bluestore_debug_random_read_err='+str(self.random_eio)) + def out_osd(self, osd=None): """ @@ -955,6 +962,12 @@ class Thrasher: scrubint = self.config.get("scrub_interval", -1) maxdead = self.config.get("max_dead", 0) delay = self.config.get("op_delay", 5) + self.rerrosd = self.live_osds[0] + if self.random_eio > 0: + self.ceph_manager.raw_cluster_cmd('tell', 'osd.'+str(self.rerrosd), + 'injectargs', '--', '--filestore_debug_random_read_err='+str(self.random_eio)) + self.ceph_manager.raw_cluster_cmd('tell', 'osd.'+str(self.rerrosd), + 'injectargs', '--', '--bluestore_debug_random_read_err='+str(self.random_eio)) self.log("starting do_thrash") while not self.stopping: to_log = [str(x) for x in ["in_osds: ", self.in_osds, @@ -982,6 +995,11 @@ class Thrasher: Scrubber(self.ceph_manager, self.config) self.choose_action()() time.sleep(delay) + if self.random_eio > 0: + self.ceph_manager.raw_cluster_cmd('tell', 'osd.'+str(self.rerrosd), + 'injectargs', '--', '--filestore_debug_random_read_err=0.0') + self.ceph_manager.raw_cluster_cmd('tell', 'osd.'+str(self.rerrosd), + 'injectargs', '--', '--bluestore_debug_random_read_err=0.0') for pool in list(self.pools_to_fix_pgp_num): if self.ceph_manager.get_pool_pg_num(pool) > 0: self.fix_pgp_num(pool) @@ -1159,7 +1177,7 @@ class CephManager: "-w"], wait=False, stdout=StringIO(), stdin=run.PIPE) - def flush_pg_stats(self, osds, no_wait=None, wait_for_mon=3*5): + def flush_pg_stats(self, osds, no_wait=None, wait_for_mon=300): """ Flush pg stats from a list of OSD ids, ensuring they are reflected all the way to the monitor. Luminous and later only. @@ -1171,7 +1189,7 @@ class CephManager: stat seq from monitor anymore. in that case, you need to pass a blacklist. :param wait_for_mon: wait for mon to be synced with mgr. 0 to disable - it. (3 * mon_mgr_digest_period, by default) + it. (5 min by default) """ seq = {osd: self.raw_cluster_cmd('tell', 'osd.%d' % osd, 'flush_pg_stats') for osd in osds} diff --git a/ceph/qa/tasks/ceph_test_case.py b/ceph/qa/tasks/ceph_test_case.py index 270c18553..47f392134 100644 --- a/ceph/qa/tasks/ceph_test_case.py +++ b/ceph/qa/tasks/ceph_test_case.py @@ -83,7 +83,8 @@ class CephTestCase(unittest.TestCase): """ def seen_health_warning(): health = self.ceph_cluster.mon_manager.get_mon_health() - summary_strings = [s['summary'] for s in health['summary']] + codes = [s for s in health['checks']] + summary_strings = [s[1]['message'] for s in health['checks'].iteritems()] if len(summary_strings) == 0: log.debug("Not expected number of summary strings ({0})".format(summary_strings)) return False @@ -91,6 +92,8 @@ class CephTestCase(unittest.TestCase): for ss in summary_strings: if pattern in ss: return True + if pattern in codes: + return True log.debug("Not found expected summary strings yet ({0})".format(summary_strings)) return False @@ -103,7 +106,7 @@ class CephTestCase(unittest.TestCase): """ def is_clear(): health = self.ceph_cluster.mon_manager.get_mon_health() - return len(health['summary']) == 0 + return len(health['checks']) == 0 self.wait_until_true(is_clear, timeout) diff --git a/ceph/qa/tasks/cephfs/filesystem.py b/ceph/qa/tasks/cephfs/filesystem.py index 01e1ca588..0d3fc547b 100644 --- a/ceph/qa/tasks/cephfs/filesystem.py +++ b/ceph/qa/tasks/cephfs/filesystem.py @@ -425,9 +425,6 @@ class Filesystem(MDSCluster): def set_allow_dirfrags(self, yes): self.mon_manager.raw_cluster_cmd("fs", "set", self.name, "allow_dirfrags", str(yes).lower(), '--yes-i-really-mean-it') - def set_allow_multimds(self, yes): - self.mon_manager.raw_cluster_cmd("fs", "set", self.name, "allow_multimds", str(yes).lower(), '--yes-i-really-mean-it') - def get_pgs_per_fs_pool(self): """ Calculate how many PGs to use when creating a pool, in order to avoid raising any diff --git a/ceph/qa/tasks/cephfs/test_auto_repair.py b/ceph/qa/tasks/cephfs/test_auto_repair.py index 033d8dde9..c0aa2e4c7 100644 --- a/ceph/qa/tasks/cephfs/test_auto_repair.py +++ b/ceph/qa/tasks/cephfs/test_auto_repair.py @@ -81,7 +81,7 @@ class TestMDSAutoRepair(CephFSTestCase): self.assertTrue(writer.finished) # The MDS should report its readonly health state to the mon - self.wait_for_health("MDS in read-only mode", timeout=30) + self.wait_for_health("MDS_READ_ONLY", timeout=30) # restart mds to make it writable self.fs.mds_fail_restart() diff --git a/ceph/qa/tasks/cephfs/test_client_limits.py b/ceph/qa/tasks/cephfs/test_client_limits.py index f25cb4a21..d8675fdad 100644 --- a/ceph/qa/tasks/cephfs/test_client_limits.py +++ b/ceph/qa/tasks/cephfs/test_client_limits.py @@ -62,12 +62,12 @@ class TestClientLimits(CephFSTestCase): # MDS should not be happy about that, as the client is failing to comply # with the SESSION_RECALL messages it is being sent mds_recall_state_timeout = int(self.fs.get_config("mds_recall_state_timeout")) - self.wait_for_health("failing to respond to cache pressure", + self.wait_for_health("MDS_HEALTH_CLIENT_RECALL", mds_recall_state_timeout + 10) # We can also test that the MDS health warning for oversized # cache is functioning as intended. - self.wait_for_health("Too many inodes in cache", + self.wait_for_health("MDS_CACHE_OVERSIZED", mds_recall_state_timeout + 10) # When the client closes the files, it should retain only as many caps as allowed @@ -123,7 +123,7 @@ class TestClientLimits(CephFSTestCase): # After mds_revoke_cap_timeout, we should see a health warning (extra lag from # MDS beacon period) mds_revoke_cap_timeout = int(self.fs.get_config("mds_revoke_cap_timeout")) - self.wait_for_health("failing to respond to capability release", mds_revoke_cap_timeout + 10) + self.wait_for_health("MDS_CLIENT_RECALL", mds_revoke_cap_timeout + 10) # Client B should still be stuck self.assertFalse(rproc.finished) @@ -163,7 +163,7 @@ class TestClientLimits(CephFSTestCase): self.mount_a.create_n_files("testdir/file2", 5, True) # Wait for the health warnings. Assume mds can handle 10 request per second at least - self.wait_for_health("failing to advance its oldest client/flush tid", max_requests / 10) + self.wait_for_health("MDS_CLIENT_OLDEST_TID", max_requests / 10) def _test_client_cache_size(self, mount_subdir): """ diff --git a/ceph/qa/tasks/cephfs/test_exports.py b/ceph/qa/tasks/cephfs/test_exports.py index 80f876ebc..774dd8ffe 100644 --- a/ceph/qa/tasks/cephfs/test_exports.py +++ b/ceph/qa/tasks/cephfs/test_exports.py @@ -23,8 +23,8 @@ class TestExports(CephFSTestCase): raise RuntimeError("rank {0} failed to reach desired subtree state", rank) def test_export_pin(self): - self.fs.set_allow_multimds(True) self.fs.set_max_mds(2) + self.fs.wait_for_daemons() status = self.fs.status() diff --git a/ceph/qa/tasks/cephfs/test_failover.py b/ceph/qa/tasks/cephfs/test_failover.py index faefec458..53c2d5e30 100644 --- a/ceph/qa/tasks/cephfs/test_failover.py +++ b/ceph/qa/tasks/cephfs/test_failover.py @@ -112,7 +112,7 @@ class TestFailover(CephFSTestCase): victim = standbys.pop() self.fs.mds_stop(victim) log.info("waiting for insufficient standby daemon warning") - self.wait_for_health("insufficient standby daemons available", grace*2) + self.wait_for_health("MDS_INSUFFICIENT_STANDBY", grace*2) # restart the standby, see that he becomes a standby, check health clears self.fs.mds_restart(victim) @@ -127,7 +127,7 @@ class TestFailover(CephFSTestCase): self.assertGreaterEqual(len(standbys), 1) self.fs.mon_manager.raw_cluster_cmd('fs', 'set', self.fs.name, 'standby_count_wanted', str(len(standbys)+1)) log.info("waiting for insufficient standby daemon warning") - self.wait_for_health("insufficient standby daemons available", grace*2) + self.wait_for_health("MDS_INSUFFICIENT_STANDBY", grace*2) # Set it to 0 self.fs.mon_manager.raw_cluster_cmd('fs', 'set', self.fs.name, 'standby_count_wanted', '0') @@ -257,7 +257,6 @@ class TestStandbyReplay(CephFSTestCase): # Create FS alpha and get mds_a to come up as active fs_a = self.mds_cluster.newfs("alpha") - fs_a.set_allow_multimds(True) fs_a.set_max_mds(2) self.mds_cluster.mds_restart(mds_a) @@ -412,8 +411,6 @@ class TestMultiFilesystems(CephFSTestCase): def test_grow_shrink(self): # Usual setup... fs_a, fs_b = self._setup_two() - fs_a.set_allow_multimds(True) - fs_b.set_allow_multimds(True) # Increase max_mds on fs_b, see a standby take up the role fs_b.set_max_mds(2) @@ -570,10 +567,8 @@ class TestMultiFilesystems(CephFSTestCase): # Create two filesystems which should have two ranks each fs_a = self.mds_cluster.newfs("alpha") - fs_a.set_allow_multimds(True) fs_b = self.mds_cluster.newfs("bravo") - fs_b.set_allow_multimds(True) fs_a.set_max_mds(2) fs_b.set_max_mds(2) diff --git a/ceph/qa/tasks/cephfs/test_journal_repair.py b/ceph/qa/tasks/cephfs/test_journal_repair.py index 1b03afc0f..62cbbb068 100644 --- a/ceph/qa/tasks/cephfs/test_journal_repair.py +++ b/ceph/qa/tasks/cephfs/test_journal_repair.py @@ -160,7 +160,6 @@ class TestJournalRepair(CephFSTestCase): """ # Set max_mds to 2 - self.fs.set_allow_multimds(True) self.fs.set_max_mds(2) # See that we have two active MDSs diff --git a/ceph/qa/tasks/cephfs/test_mantle.py b/ceph/qa/tasks/cephfs/test_mantle.py index 8e0526332..6cd86ad12 100644 --- a/ceph/qa/tasks/cephfs/test_mantle.py +++ b/ceph/qa/tasks/cephfs/test_mantle.py @@ -9,7 +9,6 @@ success = "mantle balancer version changed: " class TestMantle(CephFSTestCase): def start_mantle(self): self.wait_for_health_clear(timeout=30) - self.fs.set_allow_multimds(True) self.fs.set_max_mds(2) self.wait_until_equal(lambda: len(self.fs.get_active_names()), 2, 30, reject_fn=lambda v: v > 2 or v < 1) diff --git a/ceph/qa/tasks/cephfs/test_misc.py b/ceph/qa/tasks/cephfs/test_misc.py index beb3ab844..2774423da 100644 --- a/ceph/qa/tasks/cephfs/test_misc.py +++ b/ceph/qa/tasks/cephfs/test_misc.py @@ -61,12 +61,13 @@ class TestMisc(CephFSTestCase): self.fs.put_metadata_object_raw("key", dummyfile) - timeout = 10 + def get_pool_df(fs, name): + try: + return fs.get_pool_df(name)['objects'] > 0 + except RuntimeError as e: + return False - get_pool_df = self.fs.get_pool_df - self.wait_until_true( - lambda: get_pool_df(self.fs.metadata_pool_name)['objects'] > 0, - timeout=timeout) + self.wait_until_true(lambda: get_pool_df(self.fs, self.fs.metadata_pool_name), timeout=30) try: self.fs.mon_manager.raw_cluster_cmd('fs', 'new', self.fs.name, diff --git a/ceph/qa/tasks/cephfs/test_sessionmap.py b/ceph/qa/tasks/cephfs/test_sessionmap.py index e9b4b646d..9d12ab6d8 100644 --- a/ceph/qa/tasks/cephfs/test_sessionmap.py +++ b/ceph/qa/tasks/cephfs/test_sessionmap.py @@ -99,7 +99,6 @@ class TestSessionMap(CephFSTestCase): self.fs.wait_for_daemons() # I would like two MDSs, so that I can do an export dir later - self.fs.set_allow_multimds(True) self.fs.set_max_mds(2) self.fs.wait_for_daemons() diff --git a/ceph/qa/tasks/cephfs/test_strays.py b/ceph/qa/tasks/cephfs/test_strays.py index 3335d89dd..b8538f535 100644 --- a/ceph/qa/tasks/cephfs/test_strays.py +++ b/ceph/qa/tasks/cephfs/test_strays.py @@ -4,6 +4,8 @@ import logging from textwrap import dedent import datetime import gevent +import datetime + from teuthology.orchestra.run import CommandFailedError, Raw from tasks.cephfs.cephfs_test_case import CephFSTestCase, for_teuthology @@ -492,7 +494,6 @@ class TestStrays(CephFSTestCase): def _setup_two_ranks(self): # Set up two MDSs - self.fs.set_allow_multimds(True) self.fs.set_max_mds(2) # See that we have two active MDSs @@ -1011,3 +1012,33 @@ class TestStrays(CephFSTestCase): self.fs.wait_for_daemons() time.sleep(10) self.assertEqual(self.get_stat("purge_queue", "pq_executed"), 0) + + def test_replicated_delete_speed(self): + """ + That deletions of replicated metadata are not pathologically slow + """ + rank_0_id, rank_1_id = self._setup_two_ranks() + + self.set_conf("mds.{0}".format(rank_1_id), 'mds_max_purge_files', "0") + self.mds_cluster.mds_fail_restart(rank_1_id) + self.fs.wait_for_daemons() + + file_count = 10 + + self.mount_a.create_n_files("delete_me/file", file_count) + + self._force_migrate(rank_1_id, "delete_me", + self.mount_a.path_to_ino("delete_me/file_0")) + + begin = datetime.datetime.now() + self.mount_a.run_shell(["rm", "-rf", Raw("delete_me/*")]) + end = datetime.datetime.now() + + # What we're really checking here is that we are completing client + # operations immediately rather than delaying until the next tick. + tick_period = float(self.fs.get_config("mds_tick_interval", + service_type="mds")) + + duration = (end - begin).total_seconds() + self.assertLess(duration, (file_count * tick_period) * 0.25) + diff --git a/ceph/qa/tasks/divergent_priors2.py b/ceph/qa/tasks/divergent_priors2.py index 26b8120f0..0e645c7c4 100644 --- a/ceph/qa/tasks/divergent_priors2.py +++ b/ceph/qa/tasks/divergent_priors2.py @@ -156,13 +156,13 @@ def task(ctx, config): format(fpath=FSPATH, jpath=JPATH)) pid = os.getpid() expfile = os.path.join(testdir, "exp.{pid}.out".format(pid=pid)) - cmd = ((prefix + "--op export --pgid 1.0 --file {file}"). + cmd = ((prefix + "--op export --pgid 2.0 --file {file}"). format(id=divergent, file=expfile)) proc = exp_remote.run(args=cmd, wait=True, check_status=False, stdout=StringIO()) assert proc.exitstatus == 0 - cmd = ((prefix + "--op remove --pgid 1.0"). + cmd = ((prefix + "--op remove --pgid 2.0"). format(id=divergent, file=expfile)) proc = exp_remote.run(args=cmd, wait=True, check_status=False, stdout=StringIO()) diff --git a/ceph/qa/tasks/dump_stuck.py b/ceph/qa/tasks/dump_stuck.py index 8da634b5d..5d467512c 100644 --- a/ceph/qa/tasks/dump_stuck.py +++ b/ceph/qa/tasks/dump_stuck.py @@ -63,6 +63,7 @@ def task(ctx, config): # '--mon-osd-report-timeout 90', '--mon-pg-stuck-threshold 10') + # all active+clean check_stuck( manager, num_inactive=0, @@ -76,10 +77,11 @@ def task(ctx, config): manager.flush_pg_stats([1]) manager.wait_for_recovery(timeout) + # all active+clean+remapped check_stuck( manager, num_inactive=0, - num_unclean=num_pgs, + num_unclean=0, num_stale=0, ) @@ -87,6 +89,7 @@ def task(ctx, config): manager.flush_pg_stats([0, 1]) manager.wait_for_clean(timeout) + # all active+clean check_stuck( manager, num_inactive=0, diff --git a/ceph/qa/tasks/ec_lost_unfound.py b/ceph/qa/tasks/ec_lost_unfound.py index d7a55fcab..cc0bdb258 100644 --- a/ceph/qa/tasks/ec_lost_unfound.py +++ b/ceph/qa/tasks/ec_lost_unfound.py @@ -34,7 +34,7 @@ def task(ctx, config): profile = config.get('erasure_code_profile', { 'k': '2', 'm': '2', - 'ruleset-failure-domain': 'osd' + 'crush-failure-domain': 'osd' }) profile_name = profile.get('name', 'lost_unfound') manager.create_erasure_code_profile(profile_name, profile) diff --git a/ceph/qa/tasks/mds_thrash.py b/ceph/qa/tasks/mds_thrash.py index 8714967b9..1fcc9fc6a 100644 --- a/ceph/qa/tasks/mds_thrash.py +++ b/ceph/qa/tasks/mds_thrash.py @@ -360,15 +360,17 @@ class MDSThrasher(Greenlet): self.fs.set_max_mds(new_max_mds) stats['max_mds'] += 1 - # Now randomly deactivate mds if we shrank - # TODO: it's desirable to deactivate in order. Make config to do random. - targets = filter(lambda r: r['rank'] > 0, status.get_ranks(self.fs.id)) # can't deactivate 0 - for target in random.sample(targets, max(0, max_mds-new_max_mds)): - self.log("deactivating rank %d" % target['rank']) - self.fs.deactivate(target['rank']) - stats['deactivate'] += 1 - - status = self.wait_for_stable()[0] + targets = filter(lambda r: r['rank'] >= new_max_mds, status.get_ranks(self.fs.id)) + if len(targets) > 0: + # deactivate mds in decending order + targets = sorted(targets, key=lambda r: r['rank'], reverse=True) + for target in targets: + self.log("deactivating rank %d" % target['rank']) + self.fs.deactivate(target['rank']) + stats['deactivate'] += 1 + status = self.wait_for_stable()[0] + else: + status = self.wait_for_stable()[0] count = 0 for info in status.get_ranks(self.fs.id): diff --git a/ceph/qa/tasks/mon_clock_skew_check.py b/ceph/qa/tasks/mon_clock_skew_check.py index 891e6ec48..547339f79 100644 --- a/ceph/qa/tasks/mon_clock_skew_check.py +++ b/ceph/qa/tasks/mon_clock_skew_check.py @@ -13,43 +13,19 @@ log = logging.getLogger(__name__) class ClockSkewCheck: """ - Periodically check if there are any clock skews among the monitors in the - quorum. By default, assume no skews are supposed to exist; that can be - changed using the 'expect-skew' option. If 'fail-on-skew' is set to false, - then we will always succeed and only report skews if any are found. - - This class does not spawn a thread. It assumes that, if that is indeed - wanted, it should be done by a third party (for instance, the task using - this class). We intend it as such in order to reuse this class if need be. + Check if there are any clock skews among the monitors in the + quorum. This task accepts the following options: - interval amount of seconds to wait in-between checks. (default: 30.0) - max-skew maximum skew, in seconds, that is considered tolerable before - issuing a warning. (default: 0.05) + interval amount of seconds to wait before check. (default: 30.0) expect-skew 'true' or 'false', to indicate whether to expect a skew during the run or not. If 'true', the test will fail if no skew is found, and succeed if a skew is indeed found; if 'false', it's the other way around. (default: false) - never-fail Don't fail the run if a skew is detected and we weren't - expecting it, or if no skew is detected and we were expecting - it. (default: False) - - at-least-once Runs at least once, even if we are told to stop. - (default: True) - at-least-once-timeout If we were told to stop but we are attempting to - run at least once, timeout after this many seconds. - (default: 600) - - Example: - Expect a skew higher than 0.05 seconds, but only report it without - failing the teuthology run. - mon_clock_skew_check: - interval: 30 - max-skew: 0.05 - expect_skew: true - never-fail: true + expect-skew: true """ def __init__(self, ctx, manager, config, logger): @@ -63,181 +39,15 @@ class ClockSkewCheck: if self.config is None: self.config = dict() - self.check_interval = float(self.config.get('interval', 30.0)) - - first_mon = teuthology.get_first_mon(ctx, config) - remote = ctx.cluster.only(first_mon).remotes.keys()[0] - proc = remote.run( - args=[ - 'sudo', - 'ceph-mon', - '-i', first_mon[4:], - '--show-config-value', 'mon_clock_drift_allowed' - ], stdout=StringIO(), wait=True - ) - self.max_skew = self.config.get('max-skew', float(proc.stdout.getvalue())) - - self.expect_skew = self.config.get('expect-skew', False) - self.never_fail = self.config.get('never-fail', False) - self.at_least_once = self.config.get('at-least-once', True) - self.at_least_once_timeout = self.config.get('at-least-once-timeout', 600.0) - - def info(self, x): - """ - locally define logger for info messages - """ - self.logger.info(x) - - def warn(self, x): - """ - locally define logger for warnings - """ - self.logger.warn(x) - - def debug(self, x): - """ - locally define logger for debug messages - """ - self.logger.info(x) - self.logger.debug(x) - - def finish(self): - """ - Break out of the do_check loop. - """ - self.stopping = True - - def sleep_interval(self): - """ - If a sleep interval is set, sleep for that amount of time. - """ - if self.check_interval > 0.0: - self.debug('sleeping for {s} seconds'.format( - s=self.check_interval)) - time.sleep(self.check_interval) - - def print_skews(self, skews): - """ - Display skew values. - """ - total = len(skews) - if total > 0: - self.info('---------- found {n} skews ----------'.format(n=total)) - for mon_id, values in skews.iteritems(): - self.info('mon.{id}: {v}'.format(id=mon_id, v=values)) - self.info('-------------------------------------') - else: - self.info('---------- no skews were found ----------') - - def do_check(self): - """ - Clock skew checker. Loops until finish() is called. - """ - self.info('start checking for clock skews') - skews = dict() - ran_once = False - - started_on = None - - while not self.stopping or (self.at_least_once and not ran_once): - - if self.at_least_once and not ran_once and self.stopping: - if started_on is None: - self.info('kicking-off timeout (if any)') - started_on = time.time() - elif self.at_least_once_timeout > 0.0: - assert time.time() - started_on < self.at_least_once_timeout, \ - 'failed to obtain a timecheck before timeout expired' - - quorum_size = len(teuthology.get_mon_names(self.ctx)) - self.manager.wait_for_mon_quorum_size(quorum_size) - - health = self.manager.get_mon_health(True) - timechecks = health['timechecks'] - - clean_check = False - if timechecks['round_status'] == 'finished': - assert (timechecks['round'] % 2) == 0, \ - 'timecheck marked as finished but round ' \ - 'disagrees (r {r})'.format( - r=timechecks['round']) - clean_check = True - else: - assert timechecks['round_status'] == 'on-going', \ - 'timecheck status expected \'on-going\' ' \ - 'but found \'{s}\' instead'.format( - s=timechecks['round_status']) - if 'mons' in timechecks.keys() and len(timechecks['mons']) > 1: - self.info('round still on-going, but there are available reports') - else: - self.info('no timechecks available just yet') - self.sleep_interval() - continue - - assert len(timechecks['mons']) > 1, \ - 'there are not enough reported timechecks; ' \ - 'expected > 1 found {n}'.format(n=len(timechecks['mons'])) - - for check in timechecks['mons']: - mon_skew = float(check['skew']) - mon_health = check['health'] - mon_id = check['name'] - if abs(mon_skew) > self.max_skew: - assert mon_health == 'HEALTH_WARN', \ - 'mon.{id} health is \'{health}\' but skew {s} > max {ms}'.format( - id=mon_id,health=mon_health,s=abs(mon_skew),ms=self.max_skew) - - log_str = 'mon.{id} with skew {s} > max {ms}'.format( - id=mon_id,s=abs(mon_skew),ms=self.max_skew) - - """ add to skew list """ - details = check['details'] - skews[mon_id] = {'skew': mon_skew, 'details': details} - - if self.expect_skew: - self.info('expected skew: {str}'.format(str=log_str)) - else: - self.warn('unexpected skew: {str}'.format(str=log_str)) - - if clean_check or (self.expect_skew and len(skews) > 0): - ran_once = True - self.print_skews(skews) - self.sleep_interval() - - total = len(skews) - self.print_skews(skews) - - error_str = '' - found_error = False - - if self.expect_skew: - if total == 0: - error_str = 'We were expecting a skew, but none was found!' - found_error = True - else: - if total > 0: - error_str = 'We were not expecting a skew, but we did find it!' - found_error = True - - if found_error: - self.info(error_str) - if not self.never_fail: - assert False, error_str - -@contextlib.contextmanager def task(ctx, config): - """ - Use clas ClockSkewCheck to check for clock skews on the monitors. - This task will spawn a thread running ClockSkewCheck's do_check(). - - All the configuration will be directly handled by ClockSkewCheck, - so please refer to the class documentation for further information. - """ if config is None: config = {} assert isinstance(config, dict), \ 'mon_clock_skew_check task only accepts a dict for configuration' + interval = float(config.get('interval', 30.0)) + expect_skew = config.get('expect-skew', False) + log.info('Beginning mon_clock_skew_check...') first_mon = teuthology.get_first_mon(ctx, config) (mon,) = ctx.cluster.only(first_mon).remotes.iterkeys() @@ -247,15 +57,20 @@ def task(ctx, config): logger=log.getChild('ceph_manager'), ) - skew_check = ClockSkewCheck(ctx, - manager, config, - logger=log.getChild('mon_clock_skew_check')) - skew_check_thread = gevent.spawn(skew_check.do_check) - try: - yield - finally: - log.info('joining mon_clock_skew_check') - skew_check.finish() - skew_check_thread.get() - + quorum_size = len(teuthology.get_mon_names(ctx)) + manager.wait_for_mon_quorum_size(quorum_size) + + # wait a bit + log.info('sleeping for {s} seconds'.format( + s=interval)) + time.sleep(interval) + + health = manager.get_mon_health(True) + log.info('got health %s' % health) + if expect_skew: + if 'MON_CLOCK_SKEW' not in health['checks']: + raise RuntimeError('expected MON_CLOCK_SKEW but got none') + else: + if 'MON_CLOCK_SKEW' in health['checks']: + raise RuntimeError('got MON_CLOCK_SKEW but expected none') diff --git a/ceph/qa/tasks/qemu.py b/ceph/qa/tasks/qemu.py index aac51d5f5..82252e1e9 100644 --- a/ceph/qa/tasks/qemu.py +++ b/ceph/qa/tasks/qemu.py @@ -170,6 +170,9 @@ def generate_iso(ctx, config): /mnt/cdrom/test.sh > /mnt/log/test.log 2>&1 && touch /mnt/log/success """ + test_teardown + user_data = user_data.format( + ceph_branch=ctx.config.get('branch'), + ceph_sha1=ctx.config.get('sha1')) teuthology.write_file(remote, userdata_path, StringIO(user_data)) with file(os.path.join(src_dir, 'metadata.yaml'), 'rb') as f: @@ -383,7 +386,7 @@ def run_qemu(ctx, config): ceph_config = ctx.ceph['ceph'].conf.get('global', {}) ceph_config.update(ctx.ceph['ceph'].conf.get('client', {})) ceph_config.update(ctx.ceph['ceph'].conf.get(client, {})) - if ceph_config.get('rbd cache'): + if ceph_config.get('rbd cache', True): if ceph_config.get('rbd cache max dirty', 1) > 0: cachemode = 'writeback' else: @@ -424,6 +427,16 @@ def run_qemu(ctx, config): log.debug('checking that qemu tests succeeded...') for client in config.iterkeys(): (remote,) = ctx.cluster.only(client).remotes.keys() + + # ensure we have permissions to all the logs + log_dir = '{tdir}/archive/qemu/{client}'.format(tdir=testdir, + client=client) + remote.run( + args=[ + 'sudo', 'chmod', 'a+rw', '-R', log_dir + ] + ) + # teardown nfs mount _teardown_nfs_mount(remote, client) # check for test status diff --git a/ceph/qa/tasks/rados.py b/ceph/qa/tasks/rados.py index 0732c0705..3ab93d6fb 100644 --- a/ceph/qa/tasks/rados.py +++ b/ceph/qa/tasks/rados.py @@ -62,7 +62,7 @@ def task(ctx, config): name: teuthologyprofile k: 2 m: 1 - ruleset-failure-domain: osd + crush-failure-domain: osd pool_snaps: true write_fadvise_dontneed: true runs: 10 diff --git a/ceph/qa/tasks/radosbench.py b/ceph/qa/tasks/radosbench.py index 3db57af83..530a6f149 100644 --- a/ceph/qa/tasks/radosbench.py +++ b/ceph/qa/tasks/radosbench.py @@ -21,15 +21,17 @@ def task(ctx, config): time: pool: size: write size to use + objectsize: object size to use unique_pool: use a unique pool, defaults to False ec_pool: create an ec pool, defaults to False - create_pool: create pool, defaults to False + create_pool: create pool, defaults to True erasure_code_profile: name: teuthologyprofile k: 2 m: 1 - ruleset-failure-domain: osd + crush-failure-domain: osd cleanup: false (defaults to true) + type: (defaults to write) example: tasks: @@ -46,6 +48,7 @@ def task(ctx, config): testdir = teuthology.get_testdir(ctx) manager = ctx.managers['ceph'] + runtype = config.get('type', 'write') create_pool = config.get('create_pool', True) for role in config.get('clients', ['client.0']): @@ -73,6 +76,34 @@ def task(ctx, config): else: pool = manager.create_pool_with_unique_name(erasure_code_profile_name=profile_name) + osize = config.get('objectsize', 0) + if osize is 0: + objectsize = [] + else: + objectsize = ['-o', str(osize)] + size = ['-b', str(config.get('size', 4<<20))] + # If doing a reading run then populate data + if runtype != "write": + proc = remote.run( + args=[ + "/bin/sh", "-c", + " ".join(['adjust-ulimits', + 'ceph-coverage', + '{tdir}/archive/coverage', + 'rados', + '--no-log-to-stderr', + '--name', role] + + size + objectsize + + ['-p' , pool, + 'bench', str(60), "write", "--no-cleanup" + ]).format(tdir=testdir), + ], + logger=log.getChild('radosbench.{id}'.format(id=id_)), + wait=True + ) + size = [] + objectsize = [] + proc = remote.run( args=[ "/bin/sh", "-c", @@ -81,10 +112,10 @@ def task(ctx, config): '{tdir}/archive/coverage', 'rados', '--no-log-to-stderr', - '--name', role, - '-b', str(config.get('size', 4<<20)), - '-p' , pool, - 'bench', str(config.get('time', 360)), 'write', + '--name', role] + + size + objectsize + + ['-p' , pool, + 'bench', str(config.get('time', 360)), runtype, ] + cleanup).format(tdir=testdir), ], logger=log.getChild('radosbench.{id}'.format(id=id_)), @@ -96,7 +127,7 @@ def task(ctx, config): try: yield finally: - timeout = config.get('time', 360) * 5 + 180 + timeout = config.get('time', 360) * 30 + 300 log.info('joining radosbench (timing out after %ss)', timeout) run.wait(radosbench.itervalues(), timeout=timeout) diff --git a/ceph/qa/tasks/rbd_mirror.py b/ceph/qa/tasks/rbd_mirror.py index 7e0bdb718..851b64fe4 100644 --- a/ceph/qa/tasks/rbd_mirror.py +++ b/ceph/qa/tasks/rbd_mirror.py @@ -91,7 +91,7 @@ class RBDMirror(Task): ) args.extend([ - 'rbd-mirror', + 'rbd-mirror', '--foreground', '--cluster', self.cluster_name, '--id', diff --git a/ceph/qa/tasks/reg11184.py b/ceph/qa/tasks/reg11184.py index 03db1b064..b0c6dc11a 100644 --- a/ceph/qa/tasks/reg11184.py +++ b/ceph/qa/tasks/reg11184.py @@ -40,7 +40,8 @@ def task(ctx, config): while len(manager.get_osd_status()['up']) < 3: time.sleep(10) - manager.flush_pg_stats([0, 1, 2]) + osds = [0, 1, 2] + manager.flush_pg_stats(osds) manager.raw_cluster_cmd('osd', 'set', 'noout') manager.raw_cluster_cmd('osd', 'set', 'noin') manager.raw_cluster_cmd('osd', 'set', 'nodown') @@ -55,7 +56,9 @@ def task(ctx, config): log.info('creating foo') manager.raw_cluster_cmd('osd', 'pool', 'create', 'foo', '1') - osds = [0, 1, 2] + # Remove extra pool to simlify log output + manager.raw_cluster_cmd('osd', 'pool', 'delete', 'rbd', 'rbd', '--yes-i-really-really-mean-it') + for i in osds: manager.set_config(i, osd_min_pg_log_entries=10) manager.set_config(i, osd_max_pg_log_entries=10) @@ -153,6 +156,8 @@ def task(ctx, config): manager.raw_cluster_cmd('osd', 'pool', 'set', 'foo', 'pg_num', '2') time.sleep(5) + manager.raw_cluster_cmd('pg','dump') + # Export a pg (exp_remote,) = ctx.\ cluster.only('osd.{o}'.format(o=divergent)).remotes.iterkeys() @@ -165,27 +170,34 @@ def task(ctx, config): format(fpath=FSPATH, jpath=JPATH)) pid = os.getpid() expfile = os.path.join(testdir, "exp.{pid}.out".format(pid=pid)) - cmd = ((prefix + "--op export --pgid 1.0 --file {file}"). + cmd = ((prefix + "--op export --pgid 2.0 --file {file}"). format(id=divergent, file=expfile)) proc = exp_remote.run(args=cmd, wait=True, check_status=False, stdout=StringIO()) assert proc.exitstatus == 0 # Remove the same pg that was exported - cmd = ((prefix + "--op remove --pgid 1.0"). - format(id=divergent, file=expfile)) + cmd = ((prefix + "--op remove --pgid 2.0"). + format(id=divergent)) proc = exp_remote.run(args=cmd, wait=True, check_status=False, stdout=StringIO()) assert proc.exitstatus == 0 # Kill one of non-divergent OSDs - log.info('killing osd.%d' % non_divergent[1]) - manager.kill_osd(non_divergent[1]) - manager.mark_down_osd(non_divergent[1]) - # manager.mark_out_osd(non_divergent[1]) + log.info('killing osd.%d' % non_divergent[0]) + manager.kill_osd(non_divergent[0]) + manager.mark_down_osd(non_divergent[0]) + # manager.mark_out_osd(non_divergent[0]) + + # An empty collection for pg 2.0 needs to be cleaned up + cmd = ((prefix + "--op remove --pgid 2.0"). + format(id=non_divergent[0])) + proc = exp_remote.run(args=cmd, wait=True, + check_status=False, stdout=StringIO()) + assert proc.exitstatus == 0 cmd = ((prefix + "--op import --file {file}"). - format(id=non_divergent[1], file=expfile)) + format(id=non_divergent[0], file=expfile)) proc = exp_remote.run(args=cmd, wait=True, check_status=False, stdout=StringIO()) assert proc.exitstatus == 0 @@ -194,8 +206,8 @@ def task(ctx, config): log.info("revive divergent %d", divergent) manager.revive_osd(divergent) manager.mark_in_osd(divergent) - log.info("revive %d", non_divergent[1]) - manager.revive_osd(non_divergent[1]) + log.info("revive %d", non_divergent[0]) + manager.revive_osd(non_divergent[0]) while len(manager.get_osd_status()['up']) < 3: time.sleep(10) diff --git a/ceph/qa/tasks/rgw.py b/ceph/qa/tasks/rgw.py index 3656c673d..d6a818170 100644 --- a/ceph/qa/tasks/rgw.py +++ b/ceph/qa/tasks/rgw.py @@ -21,13 +21,13 @@ from util.rados import (rados, create_ec_pool, log = logging.getLogger(__name__) @contextlib.contextmanager -def start_rgw(ctx, config): +def start_rgw(ctx, config, clients): """ Start rgw on remote sites. """ log.info('Starting rgw...') testdir = teuthology.get_testdir(ctx) - for client in config.keys(): + for client in clients: (remote,) = ctx.cluster.only(client).remotes.iterkeys() cluster_name, daemon_type, client_id = teuthology.split_role(client) client_with_id = daemon_type + '.' + client_id @@ -130,11 +130,12 @@ def assign_ports(ctx, config): return role_endpoints @contextlib.contextmanager -def create_pools(ctx, config): +def create_pools(ctx, clients): """Create replicated or erasure coded data pools for rgw.""" log.info('Creating data pools') - for client in config.keys(): + for client in clients: + log.debug("Obtaining remote for client {}".format(client)) (remote,) = ctx.cluster.only(client).remotes.iterkeys() data_pool = '.rgw.buckets' cluster_name, daemon_type, client_id = teuthology.split_role(client) @@ -151,10 +152,10 @@ def create_pools(ctx, config): yield @contextlib.contextmanager -def configure_compression(ctx, config, compression): +def configure_compression(ctx, clients, compression): """ set a compression type in the default zone placement """ log.info('Configuring compression type = %s', compression) - for client, c_config in config.iteritems(): + for client in clients: # XXX: the 'default' zone and zonegroup aren't created until we run RGWRados::init_complete(). # issue a 'radosgw-admin user list' command to trigger this rgwadmin(ctx, client, cmd=['user', 'list'], check_status=True) @@ -206,6 +207,8 @@ def task(ctx, config): elif isinstance(config, list): config = dict((name, None) for name in config) + clients = config.keys() # http://tracker.ceph.com/issues/20417 + overrides = ctx.config.get('overrides', {}) teuthology.deep_merge(config, overrides.get('rgw', {})) @@ -220,16 +223,18 @@ def task(ctx, config): ctx.rgw.compression_type = config.pop('compression type', None) ctx.rgw.config = config + log.debug("config is {}".format(config)) + log.debug("client list is {}".format(clients)) subtasks = [ - lambda: create_pools(ctx=ctx, config=config), + lambda: create_pools(ctx=ctx, clients=clients), ] if ctx.rgw.compression_type: subtasks.extend([ - lambda: configure_compression(ctx=ctx, config=config, + lambda: configure_compression(ctx=ctx, clients=clients, compression=ctx.rgw.compression_type), ]) subtasks.extend([ - lambda: start_rgw(ctx=ctx, config=config), + lambda: start_rgw(ctx=ctx, config=config, clients=clients), ]) with contextutil.nested(*subtasks): diff --git a/ceph/qa/tasks/s3a_hadoop.py b/ceph/qa/tasks/s3a_hadoop.py new file mode 100644 index 000000000..b969a36a8 --- /dev/null +++ b/ceph/qa/tasks/s3a_hadoop.py @@ -0,0 +1,341 @@ +import contextlib +import logging +import time +from teuthology import misc +from teuthology.orchestra import run + +log = logging.getLogger(__name__) + + +@contextlib.contextmanager +def task(ctx, config): + """ + Run Hadoop S3A tests using Ceph + usage: + -tasks: + ceph-ansible: + s3a-hadoop: + maven-version: '3.3.9' (default) + hadoop-version: '2.7.3' + bucket-name: 's3atest' (default) + access-key: 'anykey' (uses a default value) + secret-key: 'secretkey' ( uses a default value) + """ + if config is None: + config = {} + + assert isinstance(config, dict), \ + "task only supports a dictionary for configuration" + + overrides = ctx.config.get('overrides', {}) + misc.deep_merge(config, overrides.get('s3a-hadoop', {})) + testdir = misc.get_testdir(ctx) + rgws = ctx.cluster.only(misc.is_type('rgw')) + # use the first rgw node to test s3a + rgw_node = rgws.remotes.keys()[0] + # get versions + maven_major = config.get('maven-major', 'maven-3') + maven_version = config.get('maven-version', '3.3.9') + hadoop_ver = config.get('hadoop-version', '2.7.3') + bucket_name = config.get('bucket-name', 's3atest') + access_key = config.get('access-key', 'EGAQRD2ULOIFKFSKCT4F') + secret_key = config.get( + 'secret-key', + 'zi816w1vZKfaSM85Cl0BxXTwSLyN7zB4RbTswrGb') + + # set versions for cloning the repo + apache_maven = 'apache-maven-{maven_version}-bin.tar.gz'.format( + maven_version=maven_version) + maven_link = 'http://mirror.jax.hugeserver.com/apache/maven/' + \ + '{maven_major}/{maven_version}/binaries/'.format(maven_major=maven_major, maven_version=maven_version) + apache_maven + hadoop_git = 'https://github.com/apache/hadoop' + hadoop_rel = 'hadoop-{ver} rel/release-{ver}'.format(ver=hadoop_ver) + install_prereq(rgw_node) + rgw_node.run( + args=[ + 'cd', + testdir, + run.Raw('&&'), + 'wget', + maven_link, + run.Raw('&&'), + 'tar', + '-xvf', + apache_maven, + run.Raw('&&'), + 'git', + 'clone', + run.Raw(hadoop_git), + run.Raw('&&'), + 'cd', + 'hadoop', + run.Raw('&&'), + 'git', + 'checkout', + '-b', + run.Raw(hadoop_rel) + ] + ) + dnsmasq_name = 's3.ceph.com' + configure_s3a(rgw_node, dnsmasq_name, access_key, secret_key, bucket_name, testdir) + setup_dnsmasq(rgw_node, dnsmasq_name) + fix_rgw_config(rgw_node, dnsmasq_name) + setup_user_bucket(rgw_node, dnsmasq_name, access_key, secret_key, bucket_name, testdir) + if hadoop_ver.startswith('2.8'): + test_options = '-Dit.test=ITestS3A* -Dparallel-tests -Dscale -Dfs.s3a.scale.test.huge.filesize=128M verify' + else: + test_options = 'test -Dtest=S3a*,TestS3A*' + try: + run_s3atest(rgw_node, maven_version, testdir, test_options) + yield + finally: + log.info("Done s3a testing, Cleaning up") + for fil in ['apache*', 'hadoop*', 'venv*', 'create*']: + rgw_node.run(args=['rm', run.Raw('-rf'), run.Raw('{tdir}/{file}'.format(tdir=testdir, file=fil))]) + # restart and let NM restore original config + rgw_node.run(args=['sudo', 'systemctl', 'stop', 'dnsmasq']) + rgw_node.run(args=['sudo', 'systemctl', 'restart', 'network.service'], check_status=False) + rgw_node.run(args=['sudo', 'systemctl', 'status', 'network.service'], check_status=False) + + +def install_prereq(client): + """ + Install pre requisites for RHEL and CentOS + TBD: Ubuntu + """ + if client.os.name == 'rhel' or client.os.name == 'centos': + client.run( + args=[ + 'sudo', + 'yum', + 'install', + '-y', + 'protobuf-c.x86_64', + 'java', + 'java-1.8.0-openjdk-devel', + 'dnsmasq' + ] + ) + + +def setup_dnsmasq(client, name): + """ + Setup simple dnsmasq name eg: s3.ceph.com + Local RGW host can then be used with whatever name has been setup with. + """ + resolv_conf = "nameserver 127.0.0.1\n" + dnsmasq_template = """address=/{name}/{ip_address} +server=8.8.8.8 +server=8.8.4.4 +""".format(name=name, ip_address=client.ip_address) + dnsmasq_config_path = '/etc/dnsmasq.d/ceph' + # point resolv.conf to local dnsmasq + misc.sudo_write_file( + remote=client, + path='/etc/resolv.conf', + data=resolv_conf, + ) + misc.sudo_write_file( + remote=client, + path=dnsmasq_config_path, + data=dnsmasq_template, + ) + client.run(args=['cat', dnsmasq_config_path]) + # restart dnsmasq + client.run(args=['sudo', 'systemctl', 'restart', 'dnsmasq']) + client.run(args=['sudo', 'systemctl', 'status', 'dnsmasq']) + time.sleep(5) + # verify dns name is set + client.run(args=['ping', '-c', '4', name]) + + +def fix_rgw_config(client, name): + """ + Fix RGW config in ceph.conf, we need rgw dns name entry + and also modify the port to use :80 for s3a tests to work + """ + rgw_dns_name = 'rgw dns name = {name}'.format(name=name) + ceph_conf_path = '/etc/ceph/ceph.conf' + # append rgw_dns_name + client.run( + args=[ + 'sudo', + 'sed', + run.Raw('-i'), + run.Raw("'/client.rgw*/a {rgw_name}'".format(rgw_name=rgw_dns_name)), + ceph_conf_path + + ] + ) + # listen on port 80 + client.run( + args=[ + 'sudo', + 'sed', + run.Raw('-i'), + run.Raw('s/:8080/:80/'), + ceph_conf_path + ] + ) + client.run(args=['cat', ceph_conf_path]) + client.run(args=['sudo', 'systemctl', 'restart', 'ceph-radosgw.target']) + client.run(args=['sudo', 'systemctl', 'status', 'ceph-radosgw.target']) + + +def setup_user_bucket(client, dns_name, access_key, secret_key, bucket_name, testdir): + """ + Create user with access_key and secret_key that will be + used for the s3a testdir + """ + client.run( + args=[ + 'sudo', + 'radosgw-admin', + 'user', + 'create', + run.Raw('--uid'), + 's3a', + run.Raw('--display-name=s3a cephtests'), + run.Raw('--access-key={access_key}'.format(access_key=access_key)), + run.Raw('--secret-key={secret_key}'.format(secret_key=secret_key)), + run.Raw('--email=s3a@ceph.com'), + ] + ) + client.run( + args=[ + 'virtualenv', + '{testdir}/venv'.format(testdir=testdir), + run.Raw('&&'), + run.Raw('{testdir}/venv/bin/pip'.format(testdir=testdir)), + 'install', + 'boto' + ] + ) + create_bucket = """ +#!/usr/bin/env python +import boto +import boto.s3.connection +access_key = '{access_key}' +secret_key = '{secret_key}' + +conn = boto.connect_s3( + aws_access_key_id = access_key, + aws_secret_access_key = secret_key, + host = '{dns_name}', + is_secure=False, + calling_format = boto.s3.connection.OrdinaryCallingFormat(), + ) +bucket = conn.create_bucket('{bucket_name}') +for bucket in conn.get_all_buckets(): + print bucket.name + "\t" + bucket.creation_date +""".format(access_key=access_key, secret_key=secret_key, dns_name=dns_name, bucket_name=bucket_name) + py_bucket_file = '{testdir}/create_bucket.py'.format(testdir=testdir) + misc.sudo_write_file( + remote=client, + path=py_bucket_file, + data=create_bucket, + perms='0744', + ) + client.run( + args=[ + 'cat', + '{testdir}/create_bucket.py'.format(testdir=testdir), + ] + ) + client.run( + args=[ + '{testdir}/venv/bin/python'.format(testdir=testdir), + '{testdir}/create_bucket.py'.format(testdir=testdir), + ] + ) + + +def run_s3atest(client, maven_version, testdir, test_options): + """ + Finally run the s3a test + """ + aws_testdir = '{testdir}/hadoop/hadoop-tools/hadoop-aws/'.format(testdir=testdir) + run_test = '{testdir}/apache-maven-{maven_version}/bin/mvn'.format(testdir=testdir, maven_version=maven_version) + client.run( + args=[ + 'cd', + run.Raw(aws_testdir), + run.Raw('&&'), + run.Raw(run_test), + run.Raw(test_options) + ] + ) + + +def configure_s3a(client, dns_name, access_key, secret_key, bucket_name, testdir): + """ + Use the template to configure s3a test, Fill in access_key, secret_key + and other details required for test. + """ + config_template = """ + +fs.s3a.endpoint +{name} + + + +fs.s3a.connection.ssl.enabled +false + + + +test.fs.s3n.name +s3n://{bucket_name}/ + + + +test.fs.s3a.name +s3a://{bucket_name}/ + + + +test.fs.s3.name +s3://{bucket_name}/ + + + +fs.s3.awsAccessKeyId +{access_key} + + + +fs.s3.awsSecretAccessKey +{secret_key} + + + +fs.s3n.awsAccessKeyId +{access_key} + + + +fs.s3n.awsSecretAccessKey +{secret_key} + + + +fs.s3a.access.key +AWS access key ID. Omit for Role-based authentication. +{access_key} + + + +fs.s3a.secret.key +AWS secret key. Omit for Role-based authentication. +{secret_key} + + +""".format(name=dns_name, bucket_name=bucket_name, access_key=access_key, secret_key=secret_key) + config_path = testdir + '/hadoop/hadoop-tools/hadoop-aws/src/test/resources/auth-keys.xml' + misc.write_file( + remote=client, + path=config_path, + data=config_template, + ) + # output for debug + client.run(args=['cat', config_path]) diff --git a/ceph/qa/tasks/swift.py b/ceph/qa/tasks/swift.py new file mode 100644 index 000000000..28f75dd0a --- /dev/null +++ b/ceph/qa/tasks/swift.py @@ -0,0 +1,263 @@ +""" +Test Swift API +""" +from cStringIO import StringIO +from configobj import ConfigObj +import base64 +import contextlib +import logging +import os + +from teuthology import misc as teuthology +from teuthology import contextutil +from teuthology.config import config as teuth_config +from teuthology.orchestra import run +from teuthology.orchestra.connection import split_user + +log = logging.getLogger(__name__) + + +@contextlib.contextmanager +def download(ctx, config): + """ + Download the Swift API. + """ + testdir = teuthology.get_testdir(ctx) + assert isinstance(config, list) + log.info('Downloading swift...') + for client in config: + ctx.cluster.only(client).run( + args=[ + 'git', 'clone', + teuth_config.ceph_git_base_url + 'swift.git', + '{tdir}/swift'.format(tdir=testdir), + ], + ) + try: + yield + finally: + log.info('Removing swift...') + testdir = teuthology.get_testdir(ctx) + for client in config: + ctx.cluster.only(client).run( + args=[ + 'rm', + '-rf', + '{tdir}/swift'.format(tdir=testdir), + ], + ) + +def _config_user(testswift_conf, account, user, suffix): + """ + Configure a swift user + + :param account: Swift account + :param user: User name + :param suffix: user name and email suffixes. + """ + testswift_conf['func_test'].setdefault('account{s}'.format(s=suffix), account) + testswift_conf['func_test'].setdefault('username{s}'.format(s=suffix), user) + testswift_conf['func_test'].setdefault('email{s}'.format(s=suffix), '{account}+test@test.test'.format(account=account)) + testswift_conf['func_test'].setdefault('display_name{s}'.format(s=suffix), 'Mr. {account} {user}'.format(account=account, user=user)) + testswift_conf['func_test'].setdefault('password{s}'.format(s=suffix), base64.b64encode(os.urandom(40))) + +@contextlib.contextmanager +def create_users(ctx, config): + """ + Create rgw users to interact with the swift interface. + """ + assert isinstance(config, dict) + log.info('Creating rgw users...') + testdir = teuthology.get_testdir(ctx) + users = {'': 'foo', '2': 'bar'} + for client in config['clients']: + cluster_name, daemon_type, client_id = teuthology.split_role(client) + testswift_conf = config['testswift_conf'][client] + for suffix, user in users.iteritems(): + _config_user(testswift_conf, '{user}.{client}'.format(user=user, client=client), user, suffix) + ctx.cluster.only(client).run( + args=[ + 'adjust-ulimits', + 'ceph-coverage', + '{tdir}/archive/coverage'.format(tdir=testdir), + 'radosgw-admin', + '-n', client, + '--cluster', cluster_name, + 'user', 'create', + '--subuser', '{account}:{user}'.format(account=testswift_conf['func_test']['account{s}'.format(s=suffix)],user=user), + '--display-name', testswift_conf['func_test']['display_name{s}'.format(s=suffix)], + '--secret', testswift_conf['func_test']['password{s}'.format(s=suffix)], + '--email', testswift_conf['func_test']['email{s}'.format(s=suffix)], + '--key-type', 'swift', + '--access', 'full', + ], + ) + try: + yield + finally: + for client in config['clients']: + for user in users.itervalues(): + uid = '{user}.{client}'.format(user=user, client=client) + cluster_name, daemon_type, client_id = teuthology.split_role(client) + ctx.cluster.only(client).run( + args=[ + 'adjust-ulimits', + 'ceph-coverage', + '{tdir}/archive/coverage'.format(tdir=testdir), + 'radosgw-admin', + '-n', client, + '--cluster', cluster_name, + 'user', 'rm', + '--uid', uid, + '--purge-data', + ], + ) + +@contextlib.contextmanager +def configure(ctx, config): + """ + Configure rgw and Swift + """ + assert isinstance(config, dict) + log.info('Configuring testswift...') + testdir = teuthology.get_testdir(ctx) + for client, properties in config['clients'].iteritems(): + log.info('client={c}'.format(c=client)) + log.info('config={c}'.format(c=config)) + testswift_conf = config['testswift_conf'][client] + if properties is not None and 'rgw_server' in properties: + host = None + for target, roles in zip(ctx.config['targets'].iterkeys(), ctx.config['roles']): + log.info('roles: ' + str(roles)) + log.info('target: ' + str(target)) + if properties['rgw_server'] in roles: + _, host = split_user(target) + assert host is not None, "Invalid client specified as the rgw_server" + testswift_conf['func_test']['auth_host'] = host + else: + testswift_conf['func_test']['auth_host'] = 'localhost' + + log.info(client) + (remote,) = ctx.cluster.only(client).remotes.keys() + remote.run( + args=[ + 'cd', + '{tdir}/swift'.format(tdir=testdir), + run.Raw('&&'), + './bootstrap', + ], + ) + conf_fp = StringIO() + testswift_conf.write(conf_fp) + teuthology.write_file( + remote=remote, + path='{tdir}/archive/testswift.{client}.conf'.format(tdir=testdir, client=client), + data=conf_fp.getvalue(), + ) + yield + + +@contextlib.contextmanager +def run_tests(ctx, config): + """ + Run an individual Swift test. + """ + assert isinstance(config, dict) + testdir = teuthology.get_testdir(ctx) + for client, client_config in config.iteritems(): + args = [ + 'SWIFT_TEST_CONFIG_FILE={tdir}/archive/testswift.{client}.conf'.format(tdir=testdir, client=client), + '{tdir}/swift/virtualenv/bin/nosetests'.format(tdir=testdir), + '-w', + '{tdir}/swift/test/functional'.format(tdir=testdir), + '-v', + '-a', '!fails_on_rgw', + ] + if client_config is not None and 'extra_args' in client_config: + args.extend(client_config['extra_args']) + + ctx.cluster.only(client).run( + args=args, + ) + yield + +@contextlib.contextmanager +def task(ctx, config): + """ + Run the testswift suite against rgw. + + To run all tests on all clients:: + + tasks: + - ceph: + - rgw: + - testswift: + + To restrict testing to particular clients:: + + tasks: + - ceph: + - rgw: [client.0] + - testswift: [client.0] + + To run against a server on client.1:: + + tasks: + - ceph: + - rgw: [client.1] + - testswift: + client.0: + rgw_server: client.1 + + To pass extra arguments to nose (e.g. to run a certain test):: + + tasks: + - ceph: + - rgw: [client.0] + - testswift: + client.0: + extra_args: ['test.functional.tests:TestFileUTF8', '-m', 'testCopy'] + client.1: + extra_args: ['--exclude', 'TestFile'] + """ + assert config is None or isinstance(config, list) \ + or isinstance(config, dict), \ + "task testswift only supports a list or dictionary for configuration" + all_clients = ['client.{id}'.format(id=id_) + for id_ in teuthology.all_roles_of_type(ctx.cluster, 'client')] + if config is None: + config = all_clients + if isinstance(config, list): + config = dict.fromkeys(config) + clients = config.keys() + + log.info('clients={c}'.format(c=clients)) + + testswift_conf = {} + for client in clients: + testswift_conf[client] = ConfigObj( + indent_type='', + infile={ + 'func_test': + { + 'auth_port' : 7280, + 'auth_ssl' : 'no', + 'auth_prefix' : '/auth/', + }, + } + ) + + with contextutil.nested( + lambda: download(ctx=ctx, config=clients), + lambda: create_users(ctx=ctx, config=dict( + clients=clients, + testswift_conf=testswift_conf, + )), + lambda: configure(ctx=ctx, config=dict( + clients=config, + testswift_conf=testswift_conf, + )), + lambda: run_tests(ctx=ctx, config=config), + ): + pass + yield diff --git a/ceph/qa/tasks/thrashosds-health.yaml b/ceph/qa/tasks/thrashosds-health.yaml new file mode 100644 index 000000000..7113e5948 --- /dev/null +++ b/ceph/qa/tasks/thrashosds-health.yaml @@ -0,0 +1,13 @@ +overrides: + ceph: + log-whitelist: + - overall HEALTH_ + - (OSDMAP_FLAGS) + - (OSD_ + - (PG_ + - (POOL_ + - (CACHE_POOL_ + - (SMALLER_PGP_NUM) + - (OBJECT_ + - (REQUEST_SLOW) + - (TOO_FEW_PGS) diff --git a/ceph/qa/tasks/thrashosds.py b/ceph/qa/tasks/thrashosds.py index 2cd98145e..8e09dd6a2 100644 --- a/ceph/qa/tasks/thrashosds.py +++ b/ceph/qa/tasks/thrashosds.py @@ -149,6 +149,8 @@ def task(ctx, config): config['dump_ops_enable'] = config.get('dump_ops_enable', "true") # add default value for noscrub_toggle_delay config['noscrub_toggle_delay'] = config.get('noscrub_toggle_delay', 2.0) + # add default value for random_eio + config['random_eio'] = config.get('random_eio', 0.0) log.info("config is {config}".format(config=str(config))) diff --git a/ceph/qa/tasks/util/rados.py b/ceph/qa/tasks/util/rados.py index 2d9d263d4..88ee45aa1 100644 --- a/ceph/qa/tasks/util/rados.py +++ b/ceph/qa/tasks/util/rados.py @@ -57,7 +57,7 @@ def cmd_erasure_code_profile(profile_name, profile): If profile is {}, it is replaced with - { 'k': '2', 'm': '1', 'ruleset-failure-domain': 'osd'} + { 'k': '2', 'm': '1', 'crush-failure-domain': 'osd'} for backward compatibility. In previous versions of teuthology, these values were hardcoded as function arguments and some yaml @@ -71,7 +71,7 @@ def cmd_erasure_code_profile(profile_name, profile): profile = { 'k': '2', 'm': '1', - 'ruleset-failure-domain': 'osd' + 'crush-failure-domain': 'osd' } return [ 'osd', 'erasure-code-profile', 'set', diff --git a/ceph/qa/tasks/workunit.py b/ceph/qa/tasks/workunit.py index 888b75eef..ffd8b2202 100644 --- a/ceph/qa/tasks/workunit.py +++ b/ceph/qa/tasks/workunit.py @@ -4,6 +4,7 @@ Workunit task -- Run ceph on sets of specific clients import logging import pipes import os +import re from copy import deepcopy from util import get_remote_for_role @@ -377,9 +378,12 @@ def _run_tests(ctx, refspec, role, tests, env, subdir=None, timeout=None): remote.run(logger=log.getChild(role), args=refspec.clone(git_url, clonedir)) except CommandFailedError: - if not git_url.endswith('/ceph-ci.git'): + if git_url.endswith('/ceph-ci.git'): + alt_git_url = git_url.replace('/ceph-ci.git', '/ceph.git') + elif git_url.endswith('/ceph-ci'): + alt_git_url = re.sub(r'/ceph-ci$', '/ceph.git', git_url) + else: raise - alt_git_url = git_url.replace('/ceph-ci.git', '/ceph.git') log.info( "failed to check out '%s' from %s; will also try in %s", refspec, diff --git a/ceph/qa/workunits/ceph-disk/ceph-disk-test.py b/ceph/qa/workunits/ceph-disk/ceph-disk-test.py index b80e1da89..6c476ead9 100644 --- a/ceph/qa/workunits/ceph-disk/ceph-disk-test.py +++ b/ceph/qa/workunits/ceph-disk/ceph-disk-test.py @@ -80,20 +80,21 @@ class CephDisk: stderr=subprocess.STDOUT, shell=True, bufsize=1) - lines = [] - with proc.stdout: - for line in iter(proc.stdout.readline, b''): - line = line.decode('utf-8') - if 'dangerous and experimental' in line: - LOG.debug('SKIP dangerous and experimental') - continue - lines.append(line) - LOG.debug(line.strip().encode('ascii', 'ignore')) - if proc.wait() != 0: + output, _ = proc.communicate() + if proc.poll(): + LOG.warning(output.decode('utf-8')) raise subprocess.CalledProcessError( returncode=proc.returncode, - cmd=command + cmd=command, + output=output, ) + lines = [] + for line in output.decode('utf-8').split('\n'): + if 'dangerous and experimental' in line: + LOG.debug('SKIP dangerous and experimental') + continue + lines.append(line) + LOG.debug(line.strip().encode('ascii', 'ignore')) return "".join(lines) def unused_disks(self, pattern='[vs]d.'): diff --git a/ceph/qa/workunits/ceph-helpers.sh b/ceph/qa/workunits/ceph-helpers.sh index bb681bf44..2c260255d 100755 --- a/ceph/qa/workunits/ceph-helpers.sh +++ b/ceph/qa/workunits/ceph-helpers.sh @@ -236,7 +236,7 @@ function test_kill_daemon() { # kill the mon and verify it cannot be reached # kill_daemon $pidfile TERM || return 1 - ! timeout 60 ceph --connect-timeout 60 status || return 1 + ! timeout 5 ceph status || return 1 done teardown $dir || return 1 @@ -317,7 +317,7 @@ function test_kill_daemons() { # kill the mon and verify it cannot be reached # kill_daemons $dir TERM || return 1 - ! timeout 60 ceph --connect-timeout 60 status || return 1 + ! timeout 5 ceph status || return 1 teardown $dir || return 1 } @@ -363,7 +363,7 @@ function test_kill_daemons() { # @param ... can be any option valid for ceph-mon # @return 0 on success, 1 on error # -function run_mon() { +function run_mon_no_pool() { local dir=$1 shift local id=$1 @@ -403,6 +403,18 @@ function run_mon() { fsid = $(get_config mon $id fsid) mon host = $(get_config mon $id mon_host) EOF +} + +function run_mon() { + local dir=$1 + shift + local id=$1 + shift + + run_mon_no_pool $dir $id "$@" || return 1 + + ceph osd pool create rbd 8 + if test -z "$(get_config mon $id mon_initial_members)" ; then ceph osd pool delete rbd rbd --yes-i-really-really-mean-it || return 1 ceph osd pool create rbd $PG_NUM || return 1 @@ -417,12 +429,12 @@ function test_run_mon() { run_mon $dir a --mon-initial-members=a || return 1 # rbd has not been deleted / created, hence it has pool id 0 - ceph osd dump | grep "pool 0 'rbd'" || return 1 + ceph osd dump | grep "pool 1 'rbd'" || return 1 kill_daemons $dir || return 1 run_mon $dir a || return 1 # rbd has been deleted / created, hence it does not have pool id 0 - ! ceph osd dump | grep "pool 0 'rbd'" || return 1 + ! ceph osd dump | grep "pool 1 'rbd'" || return 1 local size=$(CEPH_ARGS='' ceph --format=json daemon $dir/ceph-mon.a.asok \ config get osd_pool_default_size) test "$size" = '{"osd_pool_default_size":"3"}' || return 1 @@ -674,6 +686,7 @@ function activate_osd() { ceph_args+=" --pid-file=$dir/\$name.pid" ceph_args+=" --osd-max-object-name-len 460" ceph_args+=" --osd-max-object-namespace-len 64" + ceph_args+=" --enable-experimental-unrecoverable-data-corrupting-features *" ceph_args+=" " ceph_args+="$@" mkdir -p $osd_data @@ -1160,7 +1173,7 @@ function test_get_last_scrub_stamp() { run_mgr $dir x || return 1 run_osd $dir 0 || return 1 wait_for_clean || return 1 - stamp=$(get_last_scrub_stamp 1.0) + stamp=$(get_last_scrub_stamp 2.0) test -n "$stamp" || return 1 teardown $dir || return 1 } @@ -1323,8 +1336,10 @@ function test_wait_for_health_ok() { setup $dir || return 1 run_mon $dir a --osd_pool_default_size=1 --osd_failsafe_full_ratio=.99 --mon_pg_warn_min_per_osd=0 || return 1 run_mgr $dir x --mon_pg_warn_min_per_osd=0 || return 1 - ! TIMEOUT=1 wait_for_health_ok || return 1 run_osd $dir 0 || return 1 + kill_daemons $dir TERM osd || return 1 + ! TIMEOUT=1 wait_for_health_ok || return 1 + activate_osd $dir 0 || return 1 wait_for_health_ok || return 1 teardown $dir || return 1 } @@ -1355,9 +1370,9 @@ function test_repair() { run_mgr $dir x || return 1 run_osd $dir 0 || return 1 wait_for_clean || return 1 - repair 1.0 || return 1 + repair 2.0 || return 1 kill_daemons $dir KILL osd || return 1 - ! TIMEOUT=1 repair 1.0 || return 1 + ! TIMEOUT=1 repair 2.0 || return 1 teardown $dir || return 1 } ####################################################################### @@ -1394,9 +1409,9 @@ function test_pg_scrub() { run_mgr $dir x || return 1 run_osd $dir 0 || return 1 wait_for_clean || return 1 - pg_scrub 1.0 || return 1 + pg_scrub 2.0 || return 1 kill_daemons $dir KILL osd || return 1 - ! TIMEOUT=1 pg_scrub 1.0 || return 1 + ! TIMEOUT=1 pg_scrub 2.0 || return 1 teardown $dir || return 1 } @@ -1485,7 +1500,7 @@ function test_wait_for_scrub() { run_mgr $dir x || return 1 run_osd $dir 0 || return 1 wait_for_clean || return 1 - local pgid=1.0 + local pgid=2.0 ceph pg repair $pgid local last_scrub=$(get_last_scrub_stamp $pgid) wait_for_scrub $pgid "$last_scrub" || return 1 @@ -1761,6 +1776,46 @@ if test "$1" = TESTS ; then run_tests "$@" fi +# NOTE: +# jq only support --exit-status|-e from version 1.4 forwards, which makes +# returning on error waaaay prettier and straightforward. +# However, the current automated upstream build is running with v1.3, +# which has no idea what -e is. Hence the convoluted error checking we +# need. Sad. +# The next time someone changes this code, please check if v1.4 is now +# a thing, and, if so, please change these to use -e. Thanks. + +# jq '.all.supported | select([.[] == "foo"] | any)' +function jq_success() { + input="$1" + filter="$2" + expects="\"$3\"" + + in_escaped=$(printf %s "$input" | sed "s/'/'\\\\''/g") + filter_escaped=$(printf %s "$filter" | sed "s/'/'\\\\''/g") + + ret=$(echo "$in_escaped" | jq "$filter_escaped") + if [[ "$ret" == "true" ]]; then + return 0 + elif [[ -n "$expects" ]]; then + if [[ "$ret" == "$expects" ]]; then + return 0 + fi + fi + return 1 + input=$1 + filter=$2 + expects="$3" + + ret="$(echo $input | jq \"$filter\")" + if [[ "$ret" == "true" ]]; then + return 0 + elif [[ -n "$expects" && "$ret" == "$expects" ]]; then + return 0 + fi + return 1 +} + # Local Variables: # compile-command: "cd ../../src ; make -j4 && ../qa/workunits/ceph-helpers.sh TESTS # test_get_config" # End: diff --git a/ceph/qa/workunits/ceph-tests/ceph-admin-commands.sh b/ceph/qa/workunits/ceph-tests/ceph-admin-commands.sh index 30e74cce5..4d850c391 100755 --- a/ceph/qa/workunits/ceph-tests/ceph-admin-commands.sh +++ b/ceph/qa/workunits/ceph-tests/ceph-admin-commands.sh @@ -5,6 +5,7 @@ ceph -s #list pools rados lspools #lisr rbd images +ceph osd pool create rbd 128 128 rbd ls #check that the monitors work ceph osd set nodown diff --git a/ceph/qa/workunits/cephtool/test.sh b/ceph/qa/workunits/cephtool/test.sh index 36fb92a31..2395f1bae 100755 --- a/ceph/qa/workunits/cephtool/test.sh +++ b/ceph/qa/workunits/cephtool/test.sh @@ -216,11 +216,18 @@ function test_mon_injectargs() expect_failure $TEMP_DIR "Option --osd_op_history_duration requires an argument" \ ceph tell osd.0 injectargs -- '--osd_op_history_duration' + ceph tell osd.0 injectargs -- '--osd_deep_scrub_interval 2419200' >& $TMPFILE || return 1 + check_response "osd_deep_scrub_interval = '2419200.000000' (not observed, change may require restart)" + + ceph tell osd.0 injectargs -- '--mon_probe_timeout 2' >& $TMPFILE || return 1 + check_response "mon_probe_timeout = '2.000000' (not observed, change may require restart)" + ceph tell osd.0 injectargs -- '--mon-lease 6' >& $TMPFILE || return 1 - check_response "mon_lease = '6' (not observed, change may require restart)" + check_response "mon_lease = '6.000000' (not observed, change may require restart)" # osd-scrub-auto-repair-num-errors is an OPT_U32, so -1 is not a valid setting - expect_false ceph tell osd.0 injectargs --osd-scrub-auto-repair-num-errors -1 + expect_false ceph tell osd.0 injectargs --osd-scrub-auto-repair-num-errors -1 >& $TMPFILE || return 1 + check_response "Error EINVAL: Parse error setting osd_scrub_auto_repair_num_errors to '-1' using injectargs" } function test_mon_injectargs_SI() @@ -699,6 +706,8 @@ function test_mon_misc() ceph health --format json-pretty ceph health detail --format xml-pretty + ceph time-sync-status + ceph node ls for t in mon osd mds ; do ceph node ls $t @@ -712,6 +721,12 @@ function test_mon_misc() ceph_watch_wait "$mymsg" ceph mgr dump + ceph mgr module ls + ceph mgr module enable restful + expect_false ceph mgr module enable foodne + ceph mgr module enable foodne --force + ceph mgr module disable foodne + ceph mgr module disable foodnebizbangbash ceph mon metadata a ceph mon metadata @@ -897,8 +912,9 @@ function test_mon_mds() ceph mds remove_data_pool $data3_pool ceph osd pool delete data2 data2 --yes-i-really-really-mean-it ceph osd pool delete data3 data3 --yes-i-really-really-mean-it + ceph mds set allow_multimds false expect_false ceph mds set_max_mds 4 - ceph mds set allow_multimds true --yes-i-really-mean-it + ceph mds set allow_multimds true ceph mds set_max_mds 4 ceph mds set_max_mds 3 ceph mds set_max_mds 256 @@ -1117,7 +1133,7 @@ function test_mon_mon() ceph mon_status # test mon features - ceph mon feature list + ceph mon feature ls ceph mon feature set kraken --yes-i-really-mean-it expect_false ceph mon feature set abcd expect_false ceph mon feature set abcd --yes-i-really-mean-it @@ -1423,21 +1439,21 @@ function test_mon_osd() ceph osd find 0 ceph osd add-nodown 0 1 - ceph health detail | grep 'nodown osd(s).*0.*1' + ceph health detail | grep 'NODOWN' ceph osd rm-nodown 0 1 - ! ceph health detail | grep 'nodown osd(s).*0.*1' + ! ceph health detail | grep 'NODOWN' ceph osd out 0 # so we can mark it as noin later ceph osd add-noin 0 - ceph health detail | grep 'noin osd(s).*0' + ceph health detail | grep 'NOIN' ceph osd rm-noin 0 - ! ceph health detail | grep 'noin osd(s).*0' + ! ceph health detail | grep 'NOIN' ceph osd in 0 ceph osd add-noout 0 - ceph health detail | grep 'noout osd(s).*0' + ceph health detail | grep 'NOOUT' ceph osd rm-noout 0 - ! ceph health detail | grep 'noout osds(s).*0' + ! ceph health detail | grep 'NOOUT' # test osd id parse expect_false ceph osd add-noup 797er @@ -1456,12 +1472,12 @@ function test_mon_osd() ceph osd add-nodown $osd ceph osd add-noout $osd done - ceph -s | grep 'nodown osd(s)' - ceph -s | grep 'noout osd(s)' + ceph -s | grep 'NODOWN' + ceph -s | grep 'NOOUT' ceph osd rm-nodown any ceph osd rm-noout all - ! ceph -s | grep 'nodown osd(s)' - ! ceph -s | grep 'noout osd(s)' + ! ceph -s | grep 'NODOWN' + ! ceph -s | grep 'NOOUT' # make sure mark out preserves weight ceph osd reweight osd.0 .5 @@ -1710,7 +1726,7 @@ function test_mon_pg() ceph pg debug unfound_objects_exist ceph pg debug degraded_pgs_exist - ceph pg deep-scrub 0.0 + ceph pg deep-scrub 1.0 ceph pg dump ceph pg dump pgs_brief --format=json ceph pg dump pgs --format=json @@ -1728,31 +1744,31 @@ function test_mon_pg() ceph pg dump_stuck undersized ceph pg dump_stuck degraded ceph pg ls - ceph pg ls 0 + ceph pg ls 1 ceph pg ls stale expect_false ceph pg ls scrubq ceph pg ls active stale repair recovering - ceph pg ls 0 active - ceph pg ls 0 active stale + ceph pg ls 1 active + ceph pg ls 1 active stale ceph pg ls-by-primary osd.0 - ceph pg ls-by-primary osd.0 0 + ceph pg ls-by-primary osd.0 1 ceph pg ls-by-primary osd.0 active ceph pg ls-by-primary osd.0 active stale - ceph pg ls-by-primary osd.0 0 active stale + ceph pg ls-by-primary osd.0 1 active stale ceph pg ls-by-osd osd.0 - ceph pg ls-by-osd osd.0 0 + ceph pg ls-by-osd osd.0 1 ceph pg ls-by-osd osd.0 active ceph pg ls-by-osd osd.0 active stale - ceph pg ls-by-osd osd.0 0 active stale + ceph pg ls-by-osd osd.0 1 active stale ceph pg ls-by-pool rbd ceph pg ls-by-pool rbd active stale # can't test this... # ceph pg force_create_pg ceph pg getmap -o $TEMP_DIR/map.$$ [ -s $TEMP_DIR/map.$$ ] - ceph pg map 0.0 | grep acting - ceph pg repair 0.0 - ceph pg scrub 0.0 + ceph pg map 1.0 | grep acting + ceph pg repair 1.0 + ceph pg scrub 1.0 ceph osd set-full-ratio .962 ceph osd dump | grep '^full_ratio 0.962' @@ -1763,34 +1779,43 @@ function test_mon_pg() # Check health status ceph osd set-nearfull-ratio .913 - ceph health | grep 'HEALTH_ERR.*Full ratio(s) out of order' - ceph health detail | grep 'backfillfull_ratio (0.912) < nearfull_ratio (0.913), increased' + ceph health -f json | grep OSD_OUT_OF_ORDER_FULL + ceph health detail | grep OSD_OUT_OF_ORDER_FULL ceph osd set-nearfull-ratio .892 ceph osd set-backfillfull-ratio .963 - ceph health detail | grep 'full_ratio (0.962) < backfillfull_ratio (0.963), increased' + ceph health -f json | grep OSD_OUT_OF_ORDER_FULL + ceph health detail | grep OSD_OUT_OF_ORDER_FULL ceph osd set-backfillfull-ratio .912 # Check injected full results $SUDO ceph --admin-daemon $(get_admin_socket osd.0) injectfull nearfull - wait_for_health "HEALTH_WARN.*1 nearfull osd(s)" + wait_for_health "OSD_NEARFULL" + ceph health detail | grep "osd.0 is near full" + $SUDO ceph --admin-daemon $(get_admin_socket osd.0) injectfull none + wait_for_health_ok + $SUDO ceph --admin-daemon $(get_admin_socket osd.1) injectfull backfillfull - wait_for_health "HEALTH_WARN.*1 backfillfull osd(s)" + wait_for_health "OSD_BACKFILLFULL" + ceph health detail | grep "osd.1 is backfill full" + $SUDO ceph --admin-daemon $(get_admin_socket osd.1) injectfull none + wait_for_health_ok + $SUDO ceph --admin-daemon $(get_admin_socket osd.2) injectfull failsafe # failsafe and full are the same as far as the monitor is concerned - wait_for_health "HEALTH_ERR.*1 full osd(s)" + wait_for_health "OSD_FULL" + ceph health detail | grep "osd.2 is full" + $SUDO ceph --admin-daemon $(get_admin_socket osd.2) injectfull none + wait_for_health_ok + $SUDO ceph --admin-daemon $(get_admin_socket osd.0) injectfull full - wait_for_health "HEALTH_ERR.*2 full osd(s)" + wait_for_health "OSD_FULL" ceph health detail | grep "osd.0 is full" - ceph health detail | grep "osd.2 is full" - ceph health detail | grep "osd.1 is backfill full" $SUDO ceph --admin-daemon $(get_admin_socket osd.0) injectfull none - $SUDO ceph --admin-daemon $(get_admin_socket osd.1) injectfull none - $SUDO ceph --admin-daemon $(get_admin_socket osd.2) injectfull none wait_for_health_ok ceph pg stat | grep 'pgs:' - ceph pg 0.0 query - ceph tell 0.0 query + ceph pg 1.0 query + ceph tell 1.0 query ceph quorum enter ceph quorum_status ceph report | grep osd_stats @@ -1817,11 +1842,13 @@ function test_mon_pg() expect_false ceph osd primary-affinity osd.9999 .5 ceph osd primary-affinity osd.0 1 - ceph osd pg-temp 0.0 0 1 2 - ceph osd pg-temp 0.0 osd.1 osd.0 osd.2 + ceph osd pool set rbd size 2 + ceph osd pg-temp 1.0 0 1 + ceph osd pg-temp 1.0 osd.1 osd.0 + expect_false ceph osd pg-temp 1.0 0 1 2 expect_false ceph osd pg-temp asdf qwer - expect_false ceph osd pg-temp 0.0 asdf - expect_false ceph osd pg-temp 0.0 + expect_false ceph osd pg-temp 1.0 asdf + expect_false ceph osd pg-temp 1.0 # don't test ceph osd primary-temp for now } @@ -1943,6 +1970,40 @@ function test_mon_osd_pool_set() ceph osd pool delete $TEST_POOL_GETSET $TEST_POOL_GETSET --yes-i-really-really-mean-it ceph osd pool get rbd crush_rule | grep 'crush_rule: ' + + ceph osd pool get $TEST_POOL_GETSET compression_mode | expect_false grep '.' + ceph osd pool set $TEST_POOL_GETSET compression_mode aggressive + ceph osd pool get $TEST_POOL_GETSET compression_mode | grep 'aggressive' + ceph osd pool set $TEST_POOL_GETSET compression_mode unset + ceph osd pool get $TEST_POOL_GETSET compression_mode | expect_false grep '.' + + ceph osd pool get $TEST_POOL_GETSET compression_algorithm | expect_false grep '.' + ceph osd pool set $TEST_POOL_GETSET compression_algorithm zlib + ceph osd pool get $TEST_POOL_GETSET compression_algorithm | grep 'zlib' + ceph osd pool set $TEST_POOL_GETSET compression_algorithm unset + ceph osd pool get $TEST_POOL_GETSET compression_algorithm | expect_false grep '.' + + ceph osd pool get $TEST_POOL_GETSET compression_required_ratio | expect_false grep '.' + expect_false ceph osd pool set $TEST_POOL_GETSET compression_required_ratio 1.1 + expect_false ceph osd pool set $TEST_POOL_GETSET compression_required_ratio -.2 + ceph osd pool set $TEST_POOL_GETSET compression_required_ratio .2 + ceph osd pool get $TEST_POOL_GETSET compression_required_ratio | grep '.2' + ceph osd pool set $TEST_POOL_GETSET compression_required_ratio 0 + ceph osd pool get $TEST_POOL_GETSET compression_required_ratio | expect_false grep '.' + + ceph osd pool get $TEST_POOL_GETSET csum_type | expect_false grep '.' + ceph osd pool set $TEST_POOL_GETSET csum_type crc32c + ceph osd pool get $TEST_POOL_GETSET csum_type | grep 'crc32c' + ceph osd pool set $TEST_POOL_GETSET csum_type unset + ceph osd pool get $TEST_POOL_GETSET csum_type | expect_false grep '.' + + for size in compression_max_blob_size compression_min_blob_size csum_max_block csum_min_block; do + ceph osd pool get $TEST_POOL_GETSET $size | expect_false grep '.' + ceph osd pool set $TEST_POOL_GETSET $size 100 + ceph osd pool get $TEST_POOL_GETSET $size | grep '100' + ceph osd pool set $TEST_POOL_GETSET $size 0 + ceph osd pool get $TEST_POOL_GETSET $size | expect_false grep '.' + done } function test_mon_osd_tiered_pool_set() @@ -2194,64 +2255,6 @@ function test_mon_tell() ceph_watch_wait 'mon.b \[DBG\] from.*cmd=\[{"prefix": "version"}\]: dispatch' } -function test_mon_crushmap_validation() -{ - local map=$TEMP_DIR/map - ceph osd getcrushmap -o $map - - local crushtool_path="${TEMP_DIR}/crushtool" - touch "${crushtool_path}" - chmod +x "${crushtool_path}" - local crushtool_path_old=`ceph-conf --show-config-value crushtool` - ceph tell mon.\* injectargs --crushtool "${crushtool_path}" - - printf "%s\n" \ - "#!/bin/sh - cat > /dev/null - exit 0" > "${crushtool_path}" - - ceph osd setcrushmap -i $map - - printf "%s\n" \ - "#!/bin/sh - cat > /dev/null - exit 1" > "${crushtool_path}" - - expect_false ceph osd setcrushmap -i $map - - printf "%s\n" \ - "#!/bin/sh - cat > /dev/null - echo 'TEST FAIL' >&2 - exit 1" > "${crushtool_path}" - - expect_false ceph osd setcrushmap -i $map 2> $TMPFILE - check_response "Error EINVAL: Failed crushmap test: TEST FAIL" - - local mon_lease=`ceph-conf --show-config-value mon_lease` - - test "${mon_lease}" -gt 0 - - printf "%s\n" \ - "#!/bin/sh - cat > /dev/null - sleep $((mon_lease - 1))" > "${crushtool_path}" - - ceph osd setcrushmap -i $map - - printf "%s\n" \ - "#!/bin/sh - cat > /dev/null - sleep $((mon_lease + 1))" > "${crushtool_path}" - - expect_false ceph osd setcrushmap -i $map 2> $TMPFILE - check_response "Error EINVAL: Failed crushmap test: ${crushtool_path}: timed out (${mon_lease} sec)" - - ceph tell mon.\* injectargs --crushtool "${crushtool_path_old}" - - rm -f "${crushtool_path}" -} - function test_mon_ping() { ceph ping mon.a @@ -2329,6 +2332,12 @@ function test_osd_tell_help_command() expect_false ceph tell osd.100 help } +function test_osd_compact() +{ + ceph tell osd.1 compact + ceph daemon osd.1 compact +} + function test_mds_tell_help_command() { local FS_NAME=cephfs @@ -2352,9 +2361,11 @@ function test_mds_tell_help_command() ceph osd pool delete fs_metadata fs_metadata --yes-i-really-really-mean-it } -function test_mgr_tell_help_command() +function test_mgr_tell() { ceph tell mgr help + ceph tell mgr fs status + ceph tell mgr osd status } # @@ -2395,7 +2406,6 @@ MON_TESTS+=" mon_osd_erasure_code" MON_TESTS+=" mon_osd_misc" MON_TESTS+=" mon_heap_profiler" MON_TESTS+=" mon_tell" -MON_TESTS+=" mon_crushmap_validation" MON_TESTS+=" mon_ping" MON_TESTS+=" mon_deprecated_commands" MON_TESTS+=" mon_caps" @@ -2407,13 +2417,14 @@ OSD_TESTS+=" osd_negative_filestore_merge_threshold" OSD_TESTS+=" tiering_agent" OSD_TESTS+=" admin_heap_profiler" OSD_TESTS+=" osd_tell_help_command" +OSD_TESTS+=" osd_compact" MDS_TESTS+=" mds_tell" MDS_TESTS+=" mon_mds" MDS_TESTS+=" mon_mds_metadata" MDS_TESTS+=" mds_tell_help_command" -MGR_TESTS+=" mgr_tell_help_command" +MGR_TESTS+=" mgr_tell" TESTS+=$MON_TESTS TESTS+=$OSD_TESTS @@ -2488,6 +2499,8 @@ if [[ $do_list -eq 1 ]]; then exit 0 fi +ceph osd pool create rbd 10 + if test -z "$tests_to_run" ; then tests_to_run="$TESTS" fi diff --git a/ceph/qa/workunits/mon/auth_caps.sh b/ceph/qa/workunits/mon/auth_caps.sh index 74b22778c..6c282c4b7 100755 --- a/ceph/qa/workunits/mon/auth_caps.sh +++ b/ceph/qa/workunits/mon/auth_caps.sh @@ -13,8 +13,6 @@ for i in ${combinations}; do done # add special caps -# force blank cap with '--force' -keymap["blank"]=`ceph auth get-or-create-key client.blank mon 'allow' --force` || exit 1 keymap["all"]=`ceph auth get-or-create-key client.all mon 'allow *'` || exit 1 tmp=`mktemp` @@ -80,7 +78,6 @@ write_ops() { local caps=$1 local has_read=1 has_write=1 has_exec=1 local ret - local err local args ( echo $caps | grep 'r' ) || has_read=0 @@ -103,17 +100,10 @@ write_ops() { expect $ret ceph auth add client.foo $args expect $ret "ceph auth caps client.foo mon 'allow *' $args" expect $ret ceph auth get-or-create client.admin $args - echo "wtf -- before: err=$err ret=$ret" - err=$ret - [[ $ret -eq 0 ]] && err=22 # EINVAL - expect $err "ceph auth get-or-create client.bar mon 'allow' $args" - echo "wtf -- after: err=$err ret=$ret" - expect $ret "ceph auth get-or-create client.bar mon 'allow' --force $args" expect $ret ceph auth get-or-create-key client.admin $args expect $ret ceph auth get-or-create-key client.baz $args - expect $ret ceph auth del client.bar $args - expect $ret ceph auth del client.baz $args expect $ret ceph auth del client.foo $args + expect $ret ceph auth del client.baz $args expect $ret ceph auth import -i $tmp $args } @@ -133,7 +123,7 @@ for i in ${!keymap[@]}; do done # cleanup -for i in ${combinations} blank all; do +for i in ${combinations} all; do ceph auth del client.$i || exit 1 done diff --git a/ceph/qa/workunits/mon/crush_ops.sh b/ceph/qa/workunits/mon/crush_ops.sh index 11891480a..f28b48d9e 100755 --- a/ceph/qa/workunits/mon/crush_ops.sh +++ b/ceph/qa/workunits/mon/crush_ops.sh @@ -19,6 +19,19 @@ ceph osd crush rule create-simple foo default host ceph osd crush rule create-simple foo default host ceph osd crush rule create-simple bar default host +# make sure we're at luminous+ before using crush device classes +ceph osd require-osd-release luminous +ceph osd crush class create ssd +ceph osd crush class create hdd +ceph osd crush set-device-class ssd osd.0 +ceph osd crush set-device-class hdd osd.1 +ceph osd crush rule create-replicated foo-ssd default host ssd +ceph osd crush rule create-replicated foo-hdd default host hdd + +ceph osd erasure-code-profile set ec-foo-ssd crush-device-class=ssd m=2 k=2 +ceph osd pool create ec-foo 2 erasure ec-foo-ssd +ceph osd pool rm ec-foo ec-foo --yes-i-really-really-mean-it + ceph osd crush rule ls | grep foo ceph osd crush rule rm foo @@ -91,6 +104,7 @@ o3=`ceph osd create` ceph osd crush add $o3 123 root=default ceph osd tree | grep osd.$o3 | grep 123 ceph osd crush reweight osd.$o3 113 +expect_false ceph osd crush reweight osd.$o3 123456 ceph osd tree | grep osd.$o3 | grep 113 ceph osd crush rm osd.$o3 ceph osd rm osd.$o3 @@ -103,6 +117,7 @@ ceph osd crush add $o5 123 root=default host=foobaz ceph osd tree | grep osd.$o4 | grep 123 ceph osd tree | grep osd.$o5 | grep 123 ceph osd crush reweight-subtree foobaz 155 +expect_false ceph osd crush reweight-subtree foobaz 123456 ceph osd tree | grep osd.$o4 | grep 155 ceph osd tree | grep osd.$o5 | grep 155 ceph osd crush rm osd.$o4 diff --git a/ceph/qa/workunits/rados/load-gen-big.sh b/ceph/qa/workunits/rados/load-gen-big.sh index 1e9a2ca0e..6715658ec 100755 --- a/ceph/qa/workunits/rados/load-gen-big.sh +++ b/ceph/qa/workunits/rados/load-gen-big.sh @@ -6,5 +6,5 @@ rados -p rbd load-gen \ --max-object-size 25600000 \ --max-ops 1024 \ --max-backlog 1024 \ - --percent 50 \ + --read-percent 50 \ --run-length 1200 diff --git a/ceph/qa/workunits/rados/load-gen-mix-small-long.sh b/ceph/qa/workunits/rados/load-gen-mix-small-long.sh index 62364ef9b..593bad51d 100755 --- a/ceph/qa/workunits/rados/load-gen-mix-small-long.sh +++ b/ceph/qa/workunits/rados/load-gen-mix-small-long.sh @@ -6,5 +6,5 @@ rados -p rbd load-gen \ --max-object-size 1048576 \ --max-ops 128 \ --max-backlog 128 \ - --percent 50 \ + --read-percent 50 \ --run-length 1800 diff --git a/ceph/qa/workunits/rados/load-gen-mix-small.sh b/ceph/qa/workunits/rados/load-gen-mix-small.sh index 5fc15b14a..02db77bd0 100755 --- a/ceph/qa/workunits/rados/load-gen-mix-small.sh +++ b/ceph/qa/workunits/rados/load-gen-mix-small.sh @@ -6,5 +6,5 @@ rados -p rbd load-gen \ --max-object-size 1048576 \ --max-ops 128 \ --max-backlog 128 \ - --percent 50 \ + --read-percent 50 \ --run-length 600 diff --git a/ceph/qa/workunits/rados/load-gen-mix.sh b/ceph/qa/workunits/rados/load-gen-mix.sh index 2efb21069..ad3b4be84 100755 --- a/ceph/qa/workunits/rados/load-gen-mix.sh +++ b/ceph/qa/workunits/rados/load-gen-mix.sh @@ -6,5 +6,5 @@ rados -p rbd load-gen \ --max-object-size 1048576 \ --max-ops 128 \ --max-backlog 128 \ - --percent 50 \ + --read-percent 50 \ --run-length 600 diff --git a/ceph/qa/workunits/rados/load-gen-mostlyread.sh b/ceph/qa/workunits/rados/load-gen-mostlyread.sh index 1a7cb9546..236f82dd4 100755 --- a/ceph/qa/workunits/rados/load-gen-mostlyread.sh +++ b/ceph/qa/workunits/rados/load-gen-mostlyread.sh @@ -6,5 +6,5 @@ rados -p rbd load-gen \ --max-object-size 1048576 \ --max-ops 128 \ --max-backlog 128 \ - --percent 90 \ + --read-percent 90 \ --run-length 600 diff --git a/ceph/qa/workunits/rados/test.sh b/ceph/qa/workunits/rados/test.sh index 33bdd8ed0..cbf398fe6 100755 --- a/ceph/qa/workunits/rados/test.sh +++ b/ceph/qa/workunits/rados/test.sh @@ -16,6 +16,7 @@ declare -A pids for f in \ api_aio api_io api_list api_lock api_misc \ api_tier api_pool api_snapshots api_stat api_watch_notify api_cmd \ + api_service \ api_c_write_operations \ api_c_read_operations \ list_parallel \ diff --git a/ceph/qa/workunits/rados/test_alloc_hint.sh b/ceph/qa/workunits/rados/test_alloc_hint.sh index b3e185ade..85be5d75c 100755 --- a/ceph/qa/workunits/rados/test_alloc_hint.sh +++ b/ceph/qa/workunits/rados/test_alloc_hint.sh @@ -153,7 +153,7 @@ ceph osd pool delete "${POOL}" "${POOL}" --yes-i-really-really-mean-it PROFILE="alloc_hint-ecprofile" POOL="alloc_hint-ec" -ceph osd erasure-code-profile set "${PROFILE}" k=2 m=1 ruleset-failure-domain=osd +ceph osd erasure-code-profile set "${PROFILE}" k=2 m=1 crush-failure-domain=osd ceph osd erasure-code-profile get "${PROFILE}" # just so it's logged ceph osd pool create "${POOL}" "${NUM_PG}" "${NUM_PGP}" erasure "${PROFILE}" diff --git a/ceph/qa/workunits/rados/test_envlibrados_for_rocksdb.sh b/ceph/qa/workunits/rados/test_envlibrados_for_rocksdb.sh index 189478e46..94580c234 100755 --- a/ceph/qa/workunits/rados/test_envlibrados_for_rocksdb.sh +++ b/ceph/qa/workunits/rados/test_envlibrados_for_rocksdb.sh @@ -67,7 +67,7 @@ echo "Compile rocksdb" if [ -e rocksdb ]; then rm -fr rocksdb fi -git clone https://github.com/facebook/rocksdb.git +git clone https://github.com/facebook/rocksdb.git --depth 1 # compile code cd rocksdb diff --git a/ceph/qa/workunits/rados/test_health_warnings.sh b/ceph/qa/workunits/rados/test_health_warnings.sh index 252fa3443..8bf60065f 100755 --- a/ceph/qa/workunits/rados/test_health_warnings.sh +++ b/ceph/qa/workunits/rados/test_health_warnings.sh @@ -53,8 +53,25 @@ test_mark_all_but_last_osds_down() { wait_for_healthy } +test_mark_two_osds_same_host_down_with_classes() { + ceph osd set noup + ceph osd crush class create ssd + ceph osd crush class create hdd + ceph osd crush set-device-class ssd osd.0 osd.2 osd.4 osd.6 osd.8 + ceph osd crush set-device-class hdd osd.1 osd.3 osd.5 osd.7 osd.9 + ceph osd down osd.0 osd.1 + ceph health detail + ceph health | grep "1 host" + ceph health | grep "2 osds" + ceph health detail | grep "osd.0" + ceph health detail | grep "osd.1" + ceph osd unset noup + wait_for_healthy +} + test_mark_two_osds_same_host_down test_mark_two_osds_same_rack_down test_mark_all_but_last_osds_down +test_mark_two_osds_same_host_down_with_classes exit 0 diff --git a/ceph/qa/workunits/rados/test_rados_tool.sh b/ceph/qa/workunits/rados/test_rados_tool.sh index a792835d0..6a3ebe0b2 100755 --- a/ceph/qa/workunits/rados/test_rados_tool.sh +++ b/ceph/qa/workunits/rados/test_rados_tool.sh @@ -87,7 +87,7 @@ run_expect_nosignal "$RADOS_TOOL" --object_locator "asdf" ls run_expect_nosignal "$RADOS_TOOL" --namespace "asdf" ls run_expect_succ "$RADOS_TOOL" mkpool "$POOL" -run_expect_succ "$CEPH_TOOL" osd erasure-code-profile set myprofile k=2 m=1 stripe_unit=2K ruleset-failure-domain=osd --force +run_expect_succ "$CEPH_TOOL" osd erasure-code-profile set myprofile k=2 m=1 stripe_unit=2K crush-failure-domain=osd --force run_expect_succ "$CEPH_TOOL" osd pool create "$POOL_EC" 100 100 erasure myprofile diff --git a/ceph/qa/workunits/rbd/import_export.sh b/ceph/qa/workunits/rbd/import_export.sh index 35509642a..41585f284 100755 --- a/ceph/qa/workunits/rbd/import_export.sh +++ b/ceph/qa/workunits/rbd/import_export.sh @@ -74,70 +74,72 @@ cmp ${TMPDIR}/img ${TMPDIR}/img3 rm ${TMPDIR}/img ${TMPDIR}/img2 ${TMPDIR}/img3 -# try with --export-format for snapshots -dd if=/bin/dd of=${TMPDIR}/img bs=1k count=10 seek=100 -rbd import $RBD_CREATE_ARGS ${TMPDIR}/img testimg -rbd snap create testimg@snap -rbd export --export-format 2 testimg ${TMPDIR}/img_v2 -rbd import --export-format 2 ${TMPDIR}/img_v2 testimg_import -rbd info testimg_import -rbd info testimg_import@snap - -# compare the contents between testimg and testimg_import -rbd export testimg_import ${TMPDIR}/img_import -compare_files_and_ondisk_sizes ${TMPDIR}/img ${TMPDIR}/img_import - -rbd export testimg@snap ${TMPDIR}/img_snap -rbd export testimg_import@snap ${TMPDIR}/img_snap_import -compare_files_and_ondisk_sizes ${TMPDIR}/img_snap ${TMPDIR}/img_snap_import - -rm ${TMPDIR}/img_v2 -rm ${TMPDIR}/img_import -rm ${TMPDIR}/img_snap -rm ${TMPDIR}/img_snap_import - -rbd snap rm testimg_import@snap -rbd remove testimg_import -rbd snap rm testimg@snap -rbd rm testimg - -# order -rbd import --order 20 ${TMPDIR}/img testimg -rbd export --export-format 2 testimg ${TMPDIR}/img_v2 -rbd import --export-format 2 ${TMPDIR}/img_v2 testimg_import -rbd info testimg_import|grep order|awk '{print $2}'|grep 20 - -rm ${TMPDIR}/img_v2 - -rbd remove testimg_import -rbd remove testimg - -# features -rbd import --image-feature layering ${TMPDIR}/img testimg -FEATURES_BEFORE=`rbd info testimg|grep features` -rbd export --export-format 2 testimg ${TMPDIR}/img_v2 -rbd import --export-format 2 ${TMPDIR}/img_v2 testimg_import -FEATURES_AFTER=`rbd info testimg_import|grep features` -if [ "$FEATURES_BEFORE" != "$FEATURES_AFTER" ]; then - false -fi +if rbd help export | grep -q export-format; then + # try with --export-format for snapshots + dd if=/bin/dd of=${TMPDIR}/img bs=1k count=10 seek=100 + rbd import $RBD_CREATE_ARGS ${TMPDIR}/img testimg + rbd snap create testimg@snap + rbd export --export-format 2 testimg ${TMPDIR}/img_v2 + rbd import --export-format 2 ${TMPDIR}/img_v2 testimg_import + rbd info testimg_import + rbd info testimg_import@snap + + # compare the contents between testimg and testimg_import + rbd export testimg_import ${TMPDIR}/img_import + compare_files_and_ondisk_sizes ${TMPDIR}/img ${TMPDIR}/img_import + + rbd export testimg@snap ${TMPDIR}/img_snap + rbd export testimg_import@snap ${TMPDIR}/img_snap_import + compare_files_and_ondisk_sizes ${TMPDIR}/img_snap ${TMPDIR}/img_snap_import + + rm ${TMPDIR}/img_v2 + rm ${TMPDIR}/img_import + rm ${TMPDIR}/img_snap + rm ${TMPDIR}/img_snap_import + + rbd snap rm testimg_import@snap + rbd remove testimg_import + rbd snap rm testimg@snap + rbd rm testimg + + # order + rbd import --order 20 ${TMPDIR}/img testimg + rbd export --export-format 2 testimg ${TMPDIR}/img_v2 + rbd import --export-format 2 ${TMPDIR}/img_v2 testimg_import + rbd info testimg_import|grep order|awk '{print $2}'|grep 20 + + rm ${TMPDIR}/img_v2 + + rbd remove testimg_import + rbd remove testimg + + # features + rbd import --image-feature layering ${TMPDIR}/img testimg + FEATURES_BEFORE=`rbd info testimg|grep features` + rbd export --export-format 2 testimg ${TMPDIR}/img_v2 + rbd import --export-format 2 ${TMPDIR}/img_v2 testimg_import + FEATURES_AFTER=`rbd info testimg_import|grep features` + if [ "$FEATURES_BEFORE" != "$FEATURES_AFTER" ]; then + false + fi -rm ${TMPDIR}/img_v2 + rm ${TMPDIR}/img_v2 -rbd remove testimg_import -rbd remove testimg + rbd remove testimg_import + rbd remove testimg -# stripe -rbd import --stripe-count 1000 --stripe-unit 4096 ${TMPDIR}/img testimg -rbd export --export-format 2 testimg ${TMPDIR}/img_v2 -rbd import --export-format 2 ${TMPDIR}/img_v2 testimg_import -rbd info testimg_import|grep "stripe unit"|awk '{print $3}'|grep 4096 -rbd info testimg_import|grep "stripe count"|awk '{print $3}'|grep 1000 + # stripe + rbd import --stripe-count 1000 --stripe-unit 4096 ${TMPDIR}/img testimg + rbd export --export-format 2 testimg ${TMPDIR}/img_v2 + rbd import --export-format 2 ${TMPDIR}/img_v2 testimg_import + rbd info testimg_import|grep "stripe unit"|awk '{print $3}'|grep 4096 + rbd info testimg_import|grep "stripe count"|awk '{print $3}'|grep 1000 -rm ${TMPDIR}/img_v2 + rm ${TMPDIR}/img_v2 -rbd remove testimg_import -rbd remove testimg + rbd remove testimg_import + rbd remove testimg +fi tiered=0 if ceph osd dump | grep ^pool | grep "'rbd'" | grep tier; then diff --git a/ceph/qa/workunits/rbd/krbd_data_pool.sh b/ceph/qa/workunits/rbd/krbd_data_pool.sh index c3f48e381..9c37ff2f8 100755 --- a/ceph/qa/workunits/rbd/krbd_data_pool.sh +++ b/ceph/qa/workunits/rbd/krbd_data_pool.sh @@ -99,7 +99,7 @@ function get_num_clones() { } ceph osd pool create repdata 24 24 -ceph osd erasure-code-profile set teuthologyprofile ruleset-failure-domain=osd m=1 k=2 +ceph osd erasure-code-profile set teuthologyprofile crush-failure-domain=osd m=1 k=2 ceph osd pool create ecdata 24 24 erasure teuthologyprofile ceph osd pool set ecdata allow_ec_overwrites true ceph osd pool create rbdnonzero 24 24 diff --git a/ceph/qa/workunits/rbd/run_devstack_tempest.sh b/ceph/qa/workunits/rbd/run_devstack_tempest.sh index 0e2c96874..5cf898b6c 100755 --- a/ceph/qa/workunits/rbd/run_devstack_tempest.sh +++ b/ceph/qa/workunits/rbd/run_devstack_tempest.sh @@ -16,6 +16,11 @@ cleanup() { # ensure teuthology can clean up the logs [ -d ${STACK_LOG_PATH} ] && chmod -R a+rwx ${STACK_LOG_PATH} + mkdir ${STACK_LOG_PATH}/etc + cp -dpr /etc/cinder ${STACK_LOG_PATH}/etc || true + cp -dpr /etc/glance ${STACK_LOG_PATH}/etc || true + cp -dpr /etc/nova ${STACK_LOG_PATH}/etc || true + # kill all OpenStack services if [ -d ${STACK_OPT_PATH}/devstack ]; then cd ${STACK_OPT_PATH}/devstack @@ -44,6 +49,7 @@ SERVICE_PASSWORD=secretservice SERVICE_TOKEN=111222333444 SWIFT_HASH=1234123412341234 ROOTSLEEP=0 +NOVNC_FROM_PACKAGE=True ENABLED_SERVICES=c-api,c-bak,c-sch,c-vol,ceilometer-acentral,ceilometer-acompute,ceilometer-alarm-evaluator,ceilometer-alarm-notifier,ceilometer-anotification,ceilometer-api,ceilometer-collector,cinder,dstat,g-api,g-reg,horizon,key,mysql,n-api,n-cauth,n-cond,n-cpu,n-novnc,n-obj,n-sch,peakmem_tracker,placement-api,q-agt,q-dhcp,q-l3,q-meta,q-metering,q-svc,rabbit,s-account,s-container,s-object,s-proxy,tempest SKIP_EXERCISES=boot_from_volume,bundle,client-env,euca SYSLOG=False diff --git a/ceph/qa/workunits/rest/test-restful.sh b/ceph/qa/workunits/rest/test-restful.sh index 7beec9fc6..34fb18905 100755 --- a/ceph/qa/workunits/rest/test-restful.sh +++ b/ceph/qa/workunits/rest/test-restful.sh @@ -7,8 +7,8 @@ active=`ceph mgr dump | jq -r .active_name` echo "active $active admin secret $secret" prefix="mgr/restful/$active" -addr=`ceph config-key get $prefix/server_addr` -port=`ceph config-key get $prefix/server_port` +addr=`ceph config-key get $prefix/server_addr || echo 127.0.0.1` +port=`ceph config-key get $prefix/server_port || echo 8003` url="https://$addr:$port" echo "prefix $prefix url $url" $mydir/test_mgr_rest_api.py $url $secret diff --git a/ceph/qa/workunits/rest/test.py b/ceph/qa/workunits/rest/test.py index 565873e51..8b55378cf 100755 --- a/ceph/qa/workunits/rest/test.py +++ b/ceph/qa/workunits/rest/test.py @@ -330,7 +330,7 @@ if __name__ == '__main__': expect('pg/debug?debugop=unfound_objects_exist', 'GET', 200, '') expect('pg/debug?debugop=degraded_pgs_exist', 'GET', 200, '') - expect('pg/deep-scrub?pgid=0.0', 'PUT', 200, '') + expect('pg/deep-scrub?pgid=1.0', 'PUT', 200, '') r = expect('pg/dump', 'GET', 200, 'json', JSONHDR) assert('pg_stats_sum' in r.myjson['output']) r = expect('pg/dump', 'GET', 200, 'xml', XMLHDR) @@ -345,15 +345,15 @@ if __name__ == '__main__': r = expect('pg/getmap', 'GET', 200, '') assert(len(r.text) != 0) - r = expect('pg/map?pgid=0.0', 'GET', 200, 'json', JSONHDR) + r = expect('pg/map?pgid=1.0', 'GET', 200, 'json', JSONHDR) assert('acting' in r.myjson['output']) - assert(r.myjson['output']['pgid'] == '0.0') - r = expect('pg/map?pgid=0.0', 'GET', 200, 'xml', XMLHDR) + assert(r.myjson['output']['pgid'] == '1.0') + r = expect('pg/map?pgid=1.0', 'GET', 200, 'xml', XMLHDR) assert(r.tree.find('output/pg_map/acting') is not None) - assert(r.tree.find('output/pg_map/pgid').text == '0.0') + assert(r.tree.find('output/pg_map/pgid').text == '1.0') - expect('pg/repair?pgid=0.0', 'PUT', 200, '') - expect('pg/scrub?pgid=0.0', 'PUT', 200, '') + expect('pg/repair?pgid=1.0', 'PUT', 200, '') + expect('pg/scrub?pgid=1.0', 'PUT', 200, '') expect('osd/set-full-ratio?ratio=0.90', 'PUT', 200, '') r = expect('osd/dump', 'GET', 200, 'json', JSONHDR) @@ -373,7 +373,7 @@ if __name__ == '__main__': r = expect('pg/stat', 'GET', 200, 'xml', XMLHDR) assert(r.tree.find('output/pg_summary/num_pgs') is not None) - expect('tell/0.0/query', 'GET', 200, 'json', JSONHDR) + expect('tell/1.0/query', 'GET', 200, 'json', JSONHDR) expect('quorum?quorumcmd=enter', 'PUT', 200, 'json', JSONHDR) expect('quorum?quorumcmd=enter', 'PUT', 200, 'xml', XMLHDR) expect('quorum_status', 'GET', 200, 'json', JSONHDR) diff --git a/ceph/qa/workunits/rest/test_mgr_rest_api.py b/ceph/qa/workunits/rest/test_mgr_rest_api.py index 913438f4c..7c4335c7b 100755 --- a/ceph/qa/workunits/rest/test_mgr_rest_api.py +++ b/ceph/qa/workunits/rest/test_mgr_rest_api.py @@ -56,7 +56,7 @@ screenplay = [ ('get', '/osd', {}), ('get', '/osd/0', {}), ('get', '/osd/0/command', {}), - ('get', '/pool/0', {}), + ('get', '/pool/1', {}), ('get', '/server', {}), ('get', '/server/' + aserver, {}), ('post', '/osd/0/command', {'command': 'scrub'}), diff --git a/ceph/qa/workunits/suites/cephfs_journal_tool_smoke.sh b/ceph/qa/workunits/suites/cephfs_journal_tool_smoke.sh index fe9b60ab5..60e914965 100755 --- a/ceph/qa/workunits/suites/cephfs_journal_tool_smoke.sh +++ b/ceph/qa/workunits/suites/cephfs_journal_tool_smoke.sh @@ -55,7 +55,16 @@ $BIN journal reset $BIN journal inspect $BIN header get -# Can we import what we exported? +echo "Rolling back journal to original state..." +$BIN journal import $JOURNAL_FILE + +echo "Testing 'header' commands..." +$BIN header get +$BIN header set write_pos 123 +$BIN header set expire_pos 123 +$BIN header set trimmed_pos 123 + +echo "Rolling back journal to original state..." $BIN journal import $JOURNAL_FILE echo "Testing 'event' commands..." @@ -71,19 +80,13 @@ if [ ! -s $BINARY_OUTPUT ] ; then echo "Export to $BINARY_OUTPUT failed" exit -1 fi -$BIN event apply summary +$BIN event recover_dentries summary $BIN event splice summary -echo "Rolling back journal to original state..." -$BIN journal import $JOURNAL_FILE - -echo "Testing 'header' commands..." - -$BIN header get -$BIN header set write_pos 123 -$BIN header set expire_pos 123 -$BIN header set trimmed_pos 123 - -echo "Rolling back journal to original state..." -$BIN journal import $JOURNAL_FILE +# Tests finish. +# Metadata objects have been modified by the 'event recover_dentries' command. +# Journal is no long consistent with respect to metadata objects (especially inotable). +# To ensure mds successfully replays its journal, we need to do journal reset. +$BIN journal reset +cephfs-table-tool all reset session diff --git a/ceph/src/.git_version b/ceph/src/.git_version index 17e73fff5..d2a1b43b9 100644 --- a/ceph/src/.git_version +++ b/ceph/src/.git_version @@ -1,2 +1,2 @@ -262617c9f16c55e863693258061c5b25dea5b086 -v12.1.0 +f3e663a190bf2ed12c7e3cda288b9a159572c800 +v12.1.1 diff --git a/ceph/src/CMakeLists.txt b/ceph/src/CMakeLists.txt index aa08de7ce..a764c490e 100644 --- a/ceph/src/CMakeLists.txt +++ b/ceph/src/CMakeLists.txt @@ -464,6 +464,7 @@ set(libcommon_files msg/DispatchQueue.cc msg/Message.cc mon/PGMap.cc + mgr/ServiceMap.cc osd/ECMsgTypes.cc osd/HitSet.cc common/RefCountedObj.cc diff --git a/ceph/src/auth/RotatingKeyRing.cc b/ceph/src/auth/RotatingKeyRing.cc index ad0c0918d..e48127aa6 100644 --- a/ceph/src/auth/RotatingKeyRing.cc +++ b/ceph/src/auth/RotatingKeyRing.cc @@ -21,10 +21,10 @@ bool RotatingKeyRing::need_new_secrets(utime_t now) const return secrets.need_new_secrets(now); } -void RotatingKeyRing::set_secrets(RotatingSecrets& s) +void RotatingKeyRing::set_secrets(RotatingSecrets&& s) { Mutex::Locker l(lock); - secrets = s; + secrets = std::move(s); dump_rotating(); } diff --git a/ceph/src/auth/RotatingKeyRing.h b/ceph/src/auth/RotatingKeyRing.h index 4a5e2375f..729f5c520 100644 --- a/ceph/src/auth/RotatingKeyRing.h +++ b/ceph/src/auth/RotatingKeyRing.h @@ -41,7 +41,7 @@ public: bool need_new_secrets() const; bool need_new_secrets(utime_t now) const; - void set_secrets(RotatingSecrets& s); + void set_secrets(RotatingSecrets&& s); void dump_rotating() const; bool get_secret(const EntityName& name, CryptoKey& secret) const override; bool get_service_secret(uint32_t service_id, uint64_t secret_id, diff --git a/ceph/src/auth/cephx/CephxClientHandler.cc b/ceph/src/auth/cephx/CephxClientHandler.cc index 816b6526a..89d429037 100644 --- a/ceph/src/auth/cephx/CephxClientHandler.cc +++ b/ceph/src/auth/cephx/CephxClientHandler.cc @@ -186,7 +186,7 @@ int CephxClientHandler::handle_response(int ret, bufferlist::iterator& indata) << error << dendl; return -EINVAL; } else { - rotating_secrets->set_secrets(secrets); + rotating_secrets->set_secrets(std::move(secrets)); } } } diff --git a/ceph/src/ceph-create-keys b/ceph/src/ceph-create-keys index dda58e62e..75005f587 100755 --- a/ceph/src/ceph-create-keys +++ b/ceph/src/ceph-create-keys @@ -29,8 +29,8 @@ def get_ceph_gid(): gid = -1 return gid -def wait_for_quorum(cluster, mon_id): - wait_count = 600 # 10 minutes +def wait_for_quorum(cluster, mon_id, wait_count=600): + # wait 10 minutes by default while wait_count > 0: p = subprocess.Popen( args=[ @@ -74,10 +74,10 @@ def wait_for_quorum(cluster, mon_id): break if wait_count == 0: - raise SystemExit("ceph-mon was not able to join quorum within 10 minutes") + raise SystemExit("ceph-mon was not able to join quorum within %d seconds" % wait_count) -def get_key(cluster, mon_id): +def get_key(cluster, mon_id, wait_count=600): path = '/etc/ceph/{cluster}.client.admin.keyring'.format( cluster=cluster, ) @@ -93,7 +93,6 @@ def get_key(cluster, mon_id): os.makedirs(pathdir) os.chmod(pathdir, 0770) os.chown(pathdir, get_ceph_uid(), get_ceph_gid()) - wait_count = 600 # 10 minutes while wait_count > 0: try: with file(tmp, 'w') as f: @@ -172,10 +171,10 @@ def get_key(cluster, mon_id): raise if wait_count == 0: - raise SystemExit("Could not get or create the admin key after 10 minutes") + raise SystemExit("Could not get or create the admin key after %d seconds" % wait_count) -def bootstrap_key(cluster, type_): +def bootstrap_key(cluster, type_, wait_count=600): path = '/var/lib/ceph/bootstrap-{type}/{cluster}.keyring'.format( type=type_, cluster=cluster, @@ -205,7 +204,6 @@ def bootstrap_key(cluster, type_): os.chmod(pathdir, 0770) os.chown(pathdir, get_ceph_uid(), get_ceph_gid()) - wait_count = 600 # 10 minutes while wait_count > 0: try: with file(tmp, 'w') as f: @@ -237,7 +235,7 @@ def bootstrap_key(cluster, type_): else: raise if wait_count == 0: - raise SystemExit("Could not get or create %s bootstrap key after 10 minutes" % type_) + raise SystemExit("Could not get or create %s bootstrap key after %d seconds" % (type_, wait_count)) def parse_args(): @@ -260,8 +258,15 @@ def parse_args(): help='id of a ceph-mon that is coming up', required=True, ) + parser.add_argument( + '--timeout', '-t', + metavar='TIMEOUT', + type=int, + help='timeout in seconds to wait', + ) parser.set_defaults( cluster='ceph', + timeout=600, ) parser.set_defaults( # we want to hold on to this, for later @@ -282,20 +287,23 @@ def main(): level=loglevel, ) - wait_for_quorum(cluster=args.cluster, mon_id=args.id) - get_key(cluster=args.cluster, mon_id=args.id) + wait_for_quorum(cluster=args.cluster, mon_id=args.id, wait_count=args.timeout) + get_key(cluster=args.cluster, mon_id=args.id, wait_count=args.timeout) bootstrap_key( cluster=args.cluster, type_='osd', + wait_count=args.timeout, ) bootstrap_key( cluster=args.cluster, type_='rgw', + wait_count=args.timeout, ) bootstrap_key( cluster=args.cluster, type_='mds', + wait_count=args.timeout, ) diff --git a/ceph/src/ceph-disk/ceph_disk/main.py b/ceph/src/ceph-disk/ceph_disk/main.py index 414a63301..ddc6bcfa2 100755 --- a/ceph/src/ceph-disk/ceph_disk/main.py +++ b/ceph/src/ceph-disk/ceph_disk/main.py @@ -665,6 +665,30 @@ def get_dev_size(dev, size='megabytes'): os.close(fd) +def stmode_is_diskdevice(dmode): + if stat.S_ISBLK(dmode): + return True + else: + # FreeBSD does not have block devices + # All disks are character devices + return FREEBSD and stat.S_ISCHR(dmode) + + +def dev_is_diskdevice(dev): + dmode = os.stat(dev).st_mode + return stmode_is_diskdevice(dmode) + + +def ldev_is_diskdevice(dev): + dmode = os.lstat(dev).st_mode + return stmode_is_diskdevice(dmode) + + +def path_is_diskdevice(path): + dev = os.path.realpath(path) + return dev_is_diskdevice(dev) + + def get_partition_mpath(dev, pnum): part_re = "part{pnum}-mpath-".format(pnum=pnum) partitions = list_partitions_mpath(dev, part_re) @@ -777,7 +801,7 @@ def get_partition_base(dev): Get the base device for a partition """ dev = os.path.realpath(dev) - if not stat.S_ISBLK(os.lstat(dev).st_mode): + if not ldev_is_diskdevice(dev): raise Error('not a block device', dev) name = get_dev_name(dev) @@ -819,7 +843,7 @@ def is_partition(dev): dev = os.path.realpath(dev) st = os.lstat(dev) - if not stat.S_ISBLK(st.st_mode): + if not stmode_is_diskdevice(st.st_mode): raise Error('not a block device', dev) name = get_dev_name(dev) @@ -1532,14 +1556,7 @@ def update_partition(dev, description): command_check_call(['udevadm', 'settle', '--timeout=600']) -def zap(dev): - """ - Destroy the partition table and content of a given disk. - """ - dev = os.path.realpath(dev) - dmode = os.stat(dev).st_mode - if not stat.S_ISBLK(dmode) or is_partition(dev): - raise Error('not full block device; cannot zap', dev) +def zap_linux(dev): try: # Thoroughly wipe all partitions of any traces of # Filesystems or OSD Journals @@ -1598,13 +1615,42 @@ def zap(dev): dev, ], ) - update_partition(dev, 'zapped') except subprocess.CalledProcessError as e: raise Error(e) +def zap_freebsd(dev): + try: + # For FreeBSD we just need to zap the partition. + command_check_call( + [ + 'gpart', + 'destroy', + '-F', + dev, + ], + ) + + except subprocess.CalledProcessError as e: + raise Error(e) + + +def zap(dev): + """ + Destroy the partition table and content of a given disk. + """ + dev = os.path.realpath(dev) + dmode = os.stat(dev).st_mode + if not stat.S_ISBLK(dmode) or is_partition(dev): + raise Error('not full block device; cannot zap', dev) + if FREEBSD: + zap_freebsd(dev) + else: + zap_linux(dev) + + def adjust_symlink(target, path): create = True if os.path.lexists(path): @@ -2097,9 +2143,8 @@ class PrepareSpace(object): def set_type(self): name = self.name args = self.args - dmode = os.stat(args.data).st_mode if (self.wants_space() and - stat.S_ISBLK(dmode) and + dev_is_diskdevice(args.data) and not is_partition(args.data) and getattr(args, name) is None and getattr(args, name + '_file') is None): @@ -2122,7 +2167,7 @@ class PrepareSpace(object): return mode = os.stat(getattr(args, name)).st_mode - if stat.S_ISBLK(mode): + if stmode_is_diskdevice(mode): if getattr(args, name + '_file'): raise Error('%s is not a regular file' % name.capitalize, getattr(args, name)) @@ -2739,7 +2784,7 @@ class PrepareData(object): if stat.S_ISDIR(dmode): self.type = self.FILE - elif stat.S_ISBLK(dmode): + elif stmode_is_diskdevice(dmode): self.type = self.DEVICE else: raise Error('not a dir or block device', self.args.data) @@ -3694,7 +3739,7 @@ def main_activate(args): with activate_lock: mode = os.stat(args.path).st_mode - if stat.S_ISBLK(mode): + if stmode_is_diskdevice(mode): if (is_partition(args.path) and (get_partition_type(args.path) == PTYPE['mpath']['osd']['ready']) and @@ -4066,8 +4111,7 @@ def get_space_osd_uuid(name, path): if not os.path.exists(path): raise Error('%s does not exist' % path) - mode = os.stat(path).st_mode - if not stat.S_ISBLK(mode): + if path_is_diskdevice(path): raise Error('%s is not a block device' % path) if (is_partition(path) and @@ -4656,7 +4700,7 @@ def is_suppressed(path): disk = os.path.realpath(path) try: if (not disk.startswith('/dev/') or - not stat.S_ISBLK(os.lstat(disk).st_mode)): + not ldev_is_diskdevice(disk)): return False base = get_dev_name(disk) while len(base): @@ -4671,7 +4715,7 @@ def set_suppress(path): disk = os.path.realpath(path) if not os.path.exists(disk): raise Error('does not exist', path) - if not stat.S_ISBLK(os.lstat(path).st_mode): + if ldev_is_diskdevice(path): raise Error('not a block device', path) base = get_dev_name(disk) @@ -4684,7 +4728,7 @@ def unset_suppress(path): disk = os.path.realpath(path) if not os.path.exists(disk): raise Error('does not exist', path) - if not stat.S_ISBLK(os.lstat(path).st_mode): + if not ldev_is_diskdevice(path): raise Error('not a block device', path) assert disk.startswith('/dev/') base = get_dev_name(disk) diff --git a/ceph/src/ceph-rest-api b/ceph/src/ceph-rest-api index 1405ab5bb..d185a8041 100755 --- a/ceph/src/ceph-rest-api +++ b/ceph/src/ceph-rest-api @@ -14,10 +14,11 @@ DEVMODEMSG = '*** DEVELOPER MODE: setting PYTHONPATH and LD_LIBRARY_PATH' def parse_args(): parser = argparse.ArgumentParser(description="Ceph REST API webapp") - parser.add_argument('-c', '--conf', help='Ceph configuration file') + parser.add_argument('-c', '--conf', help='Ceph configuration file', + default='/etc/ceph/ceph.conf') parser.add_argument('--cluster', help='Ceph cluster name') parser.add_argument('-n', '--name', help='Ceph client name') - parser.add_argument('-i', '--id', help='Ceph client id') + parser.add_argument('-i', '--id', help='Ceph client id', default='admin') return parser.parse_known_args() @@ -48,4 +49,7 @@ if 'pdb.py' in files: app.run(host=app.ceph_addr, port=app.ceph_port, debug=True, use_reloader=False, use_debugger=False) else: - app.run(host=app.ceph_addr, port=app.ceph_port) + if __name__ == '__main__': + app.run(host=app.ceph_addr, port=app.ceph_port) + else: + application = app diff --git a/ceph/src/ceph.in b/ceph/src/ceph.in index 756cab644..04c9ed223 100755 --- a/ceph/src/ceph.in +++ b/ceph/src/ceph.in @@ -51,12 +51,16 @@ PRIO_DEBUGONLY = 0 PRIO_DEFAULT = PRIO_USEFUL # Make life easier on developers: -# If in src/, and .libs and pybind exist here, assume we're running -# from a Ceph source dir and tweak PYTHONPATH and LD_LIBRARY_PATH -# to use local files +# If our parent dir contains CMakeCache.txt and bin/init-ceph, +# assume we're running from a build dir (i.e. src/build/bin/ceph) +# and tweak sys.path and LD_LIBRARY_PATH to use built files. +# Since this involves re-execing, if CEPH_DBG is set in the environment +# re-exec with -mpdb. Also, if CEPH_DEV is in the env, suppress +# the warning message about the DEVELOPER MODE. MYPATH = os.path.abspath(__file__) MYDIR = os.path.dirname(MYPATH) +MYPDIR = os.path.dirname(MYDIR) DEVMODEMSG = '*** DEVELOPER MODE: setting PATH, PYTHONPATH and LD_LIBRARY_PATH ***' @@ -91,10 +95,10 @@ def get_pythonlib_dir(): """Returns the name of a distutils build directory""" return "lib.{version[0]}".format(version=sys.version_info) -if os.path.exists(os.path.join(os.getcwd(), "CMakeCache.txt")) \ - and os.path.exists(os.path.join(os.getcwd(), "bin/init-ceph")): +if os.path.exists(os.path.join(MYPDIR, "CMakeCache.txt")) \ + and os.path.exists(os.path.join(MYPDIR, "bin/init-ceph")): src_path = None - for l in open("./CMakeCache.txt"): + for l in open(os.path.join(MYPDIR, "CMakeCache.txt")): if l.startswith("ceph_SOURCE_DIR:STATIC="): src_path = l.split("=")[1].strip() @@ -103,8 +107,8 @@ if os.path.exists(os.path.join(os.getcwd(), "CMakeCache.txt")) \ pass else: # Developer mode, but in a cmake build dir instead of the src dir - lib_path = os.path.join(os.getcwd(), "lib") - bin_path = os.path.join(os.getcwd(), "bin") + lib_path = os.path.join(MYPDIR, "lib") + bin_path = os.path.join(MYPDIR, "bin") pybind_path = os.path.join(src_path, "src", "pybind") pythonlib_path = os.path.join(lib_path, "cython_modules", @@ -291,6 +295,11 @@ def parse_cmdargs(args=None, target=''): parser.add_argument('--watch-error', action='store_true', help='watch error events') + parser.add_argument('--watch-channel', dest="watch_channel", + help="which log channel to follow " \ + "when using -w/--watch. One of ['cluster', 'audit', '*'", + default='cluster') + parser.add_argument('--version', '-v', action="store_true", help="display version") parser.add_argument('--verbose', action="store_true", help="make verbose") parser.add_argument('--concise', dest='verbose', action="store_false", @@ -882,10 +891,7 @@ def main(): if not timeout: timeout = 5 - hdr('Monitor commands:') - print('[Contacting monitor, timeout after %d seconds]' % timeout) - - if childargs and childargs[0] == 'ping': + if childargs and childargs[0] == 'ping' and not parsed_args.help: if len(childargs) < 2: print('"ping" requires a monitor name as argument: "ping mon."', file=sys.stderr) return 1 @@ -893,9 +899,12 @@ def main(): # for completion let timeout be really small timeout = 3 try: - if childargs and childargs[0] == 'ping': + if childargs and childargs[0] == 'ping' and not parsed_args.help: return ping_monitor(cluster_handle, childargs[1], timeout) - run_in_thread(cluster_handle.connect, timeout=timeout) + result = run_in_thread(cluster_handle.connect, timeout=timeout) + if type(result) is tuple and result[0] == -errno.EINTR: + print('Cluster connection interrupted or timed out', file=sys.stderr) + return 1 except KeyboardInterrupt: print('Cluster connection aborted', file=sys.stderr) return 1 @@ -905,7 +914,12 @@ def main(): except Exception as e: print(str(e), file=sys.stderr) return 1 + if parsed_args.help: + hdr('Monitor commands:') + if verbose: + print('[Contacting monitor, timeout after %d seconds]' % timeout) + return do_extended_help(parser, childargs, ('mon', ''), ' '.join(childargs)) # implement "tell service.id help" @@ -924,14 +938,16 @@ def main(): if k.startswith('watch') and v: if k == 'watch': level = 'info' - else: + elif k != "watch_channel": level = k.replace('watch_', '') if level: - # an awfully simple callback - def watch_cb(arg, line, who, stamp_sec, stamp_nsec, seq, level, msg): - print(line) - sys.stdout.flush() + def watch_cb(arg, line, channel, name, who, stamp_sec, stamp_nsec, seq, level, msg): + # Filter on channel + if (channel == parsed_args.watch_channel or \ + parsed_args.watch_channel == "*"): + print(line) + sys.stdout.flush() # first do a ceph status ret, outbuf, outs = json_command(cluster_handle, prefix='status') @@ -942,7 +958,7 @@ def main(): # this instance keeps the watch connection alive, but is # otherwise unused - run_in_thread(cluster_handle.monitor_log, level, watch_cb, 0) + run_in_thread(cluster_handle.monitor_log2, level, watch_cb, 0) # loop forever letting watch_cb print lines try: diff --git a/ceph/src/ceph_mon.cc b/ceph/src/ceph_mon.cc index 0b5d4edfd..400c89895 100644 --- a/ceph/src/ceph_mon.cc +++ b/ceph/src/ceph_mon.cc @@ -368,8 +368,8 @@ int main(int argc, const char **argv) string name; monmap.get_addr_name(a, name); monmap.rename(name, g_conf->name.get_id()); - cout << argv[0] << ": renaming mon." << name << " " << a - << " to mon." << g_conf->name.get_id() << std::endl; + dout(0) << argv[0] << ": renaming mon." << name << " " << a + << " to mon." << g_conf->name.get_id() << dendl; } } else { // is a local address listed without a name? if so, name myself. @@ -382,12 +382,12 @@ int main(int argc, const char **argv) monmap.get_addr_name(local, name); if (name.compare(0, 7, "noname-") == 0) { - cout << argv[0] << ": mon." << name << " " << local - << " is local, renaming to mon." << g_conf->name.get_id() << std::endl; + dout(0) << argv[0] << ": mon." << name << " " << local + << " is local, renaming to mon." << g_conf->name.get_id() << dendl; monmap.rename(name, g_conf->name.get_id()); } else { - cout << argv[0] << ": mon." << name << " " << local - << " is local, but not 'noname-' + something; not assuming it's me" << std::endl; + dout(0) << argv[0] << ": mon." << name << " " << local + << " is local, but not 'noname-' + something; not assuming it's me" << dendl; } } } @@ -395,7 +395,7 @@ int main(int argc, const char **argv) if (!g_conf->fsid.is_zero()) { monmap.fsid = g_conf->fsid; - cout << argv[0] << ": set fsid to " << g_conf->fsid << std::endl; + dout(0) << argv[0] << ": set fsid to " << g_conf->fsid << dendl; } if (monmap.fsid.is_zero()) { @@ -435,8 +435,8 @@ int main(int argc, const char **argv) exit(1); } store.close(); - cout << argv[0] << ": created monfs at " << g_conf->mon_data - << " for " << g_conf->name << std::endl; + dout(0) << argv[0] << ": created monfs at " << g_conf->mon_data + << " for " << g_conf->name << dendl; return 0; } @@ -500,6 +500,7 @@ int main(int argc, const char **argv) derr << err_msg << dendl; prefork.exit(err); } + setsid(); global_init_postfork_start(g_ceph_context); } common_init_finish(g_ceph_context); @@ -706,18 +707,38 @@ int main(int argc, const char **argv) msgr->set_policy_throttlers(entity_name_t::TYPE_MDS, daemon_throttler, NULL); + entity_addr_t bind_addr = ipaddr; + entity_addr_t public_addr = ipaddr; + + // check if the public_bind_addr option is set + if (!g_conf->public_bind_addr.is_blank_ip()) { + bind_addr = g_conf->public_bind_addr; + + // set the default port if not already set + if (bind_addr.get_port() == 0) { + bind_addr.set_port(CEPH_MON_PORT); + } + } + dout(0) << "starting " << g_conf->name << " rank " << rank - << " at " << ipaddr + << " at public addr " << public_addr + << " at bind addr " << bind_addr << " mon_data " << g_conf->mon_data << " fsid " << monmap.get_fsid() << dendl; - err = msgr->bind(ipaddr); + err = msgr->bind(bind_addr); if (err < 0) { - derr << "unable to bind monitor to " << ipaddr << dendl; + derr << "unable to bind monitor to " << bind_addr << dendl; prefork.exit(1); } + // if the public and bind addr are different set the msgr addr + // to the public one, now that the bind is complete. + if (public_addr != bind_addr) { + msgr->set_addr(public_addr); + } + Messenger *mgr_msgr = Messenger::create(g_ceph_context, public_msgr_type, entity_name_t::MON(rank), "mon-mgrc", getpid(), 0); @@ -726,11 +747,11 @@ int main(int argc, const char **argv) prefork.exit(1); } - cout << "starting " << g_conf->name << " rank " << rank + dout(0) << "starting " << g_conf->name << " rank " << rank << " at " << ipaddr << " mon_data " << g_conf->mon_data << " fsid " << monmap.get_fsid() - << std::endl; + << dendl; // start monitor mon = new Monitor(g_ceph_context, g_conf->name.get_id(), store, @@ -802,4 +823,3 @@ int main(int argc, const char **argv) prefork.signal_exit(0); return 0; } - diff --git a/ceph/src/ceph_osd.cc b/ceph/src/ceph_osd.cc index a27ffb854..f3d585b47 100644 --- a/ceph/src/ceph_osd.cc +++ b/ceph/src/ceph_osd.cc @@ -598,6 +598,8 @@ flushjournal_out: return -1; #endif + srand(time(NULL) + getpid()); + osd = new OSD(g_ceph_context, store, whoami, diff --git a/ceph/src/ceph_release b/ceph/src/ceph_release index cfcf789ec..5fbeda91d 100644 --- a/ceph/src/ceph_release +++ b/ceph/src/ceph_release @@ -1,3 +1,3 @@ 12 luminous -dev +rc diff --git a/ceph/src/cls/lock/cls_lock.cc b/ceph/src/cls/lock/cls_lock.cc index 551ca901b..6e2ae4bbd 100644 --- a/ceph/src/cls/lock/cls_lock.cc +++ b/ceph/src/cls/lock/cls_lock.cc @@ -34,34 +34,6 @@ CLS_NAME(lock) #define LOCK_PREFIX "lock." -typedef struct lock_info_s { - map lockers; // map of lockers - ClsLockType lock_type; // lock type (exclusive / shared) - string tag; // tag: operations on lock can only succeed with this tag - // as long as set of non expired lockers - // is bigger than 0. - - void encode(bufferlist &bl, uint64_t features) const { - ENCODE_START(1, 1, bl); - ::encode(lockers, bl, features); - uint8_t t = (uint8_t)lock_type; - ::encode(t, bl); - ::encode(tag, bl); - ENCODE_FINISH(bl); - } - void decode(bufferlist::iterator &bl) { - DECODE_START_LEGACY_COMPAT_LEN(1, 1, 1, bl); - ::decode(lockers, bl); - uint8_t t; - ::decode(t, bl); - lock_type = (ClsLockType)t; - ::decode(tag, bl); - DECODE_FINISH(bl); - } - lock_info_s() : lock_type(LOCK_NONE) {} -} lock_info_t; -WRITE_CLASS_ENCODER_FEATURES(lock_info_t) - static int read_lock(cls_method_context_t hctx, const string& name, lock_info_t *lock) { bufferlist bl; diff --git a/ceph/src/cls/lock/cls_lock_types.cc b/ceph/src/cls/lock/cls_lock_types.cc index 1c67bdea5..38a0d93df 100644 --- a/ceph/src/cls/lock/cls_lock_types.cc +++ b/ceph/src/cls/lock/cls_lock_types.cc @@ -67,3 +67,32 @@ void locker_info_t::generate_test_instances(list& o) o.push_back(new locker_info_t); } +void lock_info_t::dump(Formatter *f) const +{ + f->dump_int("lock_type", lock_type); + f->dump_string("tag", tag); + f->open_array_section("lockers"); + for (auto &i : lockers) { + f->open_object_section("locker"); + f->dump_object("id", i.first); + f->dump_object("info", i.second); + f->close_section(); + } + f->close_section(); +} + +void lock_info_t::generate_test_instances(list& o) +{ + lock_info_t *i = new lock_info_t; + locker_id_t id; + locker_info_t info; + generate_lock_id(id, 1, "cookie"); + info.expiration = utime_t(5, 0); + generate_test_addr(info.addr, 1, 2); + info.description = "description"; + i->lockers[id] = info; + i->lock_type = LOCK_EXCLUSIVE; + i->tag = "tag"; + o.push_back(i); + o.push_back(new lock_info_t); +} diff --git a/ceph/src/cls/lock/cls_lock_types.h b/ceph/src/cls/lock/cls_lock_types.h index 03e6e11f6..36d39c890 100644 --- a/ceph/src/cls/lock/cls_lock_types.h +++ b/ceph/src/cls/lock/cls_lock_types.h @@ -96,10 +96,41 @@ namespace rados { static void generate_test_instances(list& o); }; WRITE_CLASS_ENCODER_FEATURES(rados::cls::lock::locker_info_t) + + struct lock_info_t { + map lockers; // map of lockers + ClsLockType lock_type; // lock type (exclusive / shared) + string tag; // tag: operations on lock can only succeed with this tag + // as long as set of non expired lockers + // is bigger than 0. + + void encode(bufferlist &bl, uint64_t features) const { + ENCODE_START(1, 1, bl); + ::encode(lockers, bl, features); + uint8_t t = (uint8_t)lock_type; + ::encode(t, bl); + ::encode(tag, bl); + ENCODE_FINISH(bl); + } + void decode(bufferlist::iterator &bl) { + DECODE_START_LEGACY_COMPAT_LEN(1, 1, 1, bl); + ::decode(lockers, bl); + uint8_t t; + ::decode(t, bl); + lock_type = (ClsLockType)t; + ::decode(tag, bl); + DECODE_FINISH(bl); + } + lock_info_t() : lock_type(LOCK_NONE) {} + void dump(Formatter *f) const; + static void generate_test_instances(list& o); + }; + WRITE_CLASS_ENCODER_FEATURES(rados::cls::lock::lock_info_t) } } } WRITE_CLASS_ENCODER_FEATURES(rados::cls::lock::locker_info_t) WRITE_CLASS_ENCODER(rados::cls::lock::locker_id_t) +WRITE_CLASS_ENCODER_FEATURES(rados::cls::lock::lock_info_t) #endif diff --git a/ceph/src/cls/log/cls_log_client.cc b/ceph/src/cls/log/cls_log_client.cc index 881be1636..0aa6e16d4 100644 --- a/ceph/src/cls/log/cls_log_client.cc +++ b/ceph/src/cls/log/cls_log_client.cc @@ -94,11 +94,11 @@ public: bufferlist::iterator iter = outbl.begin(); ::decode(ret, iter); if (entries) - *entries = ret.entries; + *entries = std::move(ret.entries); if (truncated) *truncated = ret.truncated; if (marker) - *marker = ret.marker; + *marker = std::move(ret.marker); } catch (buffer::error& err) { // nothing we can do about it atm } diff --git a/ceph/src/cls/rgw/cls_rgw.cc b/ceph/src/cls/rgw/cls_rgw.cc index 05cbb8ce9..9af96fe6a 100644 --- a/ceph/src/cls/rgw/cls_rgw.cc +++ b/ceph/src/cls/rgw/cls_rgw.cc @@ -1875,7 +1875,9 @@ int rgw_dir_suggest_changes(cls_method_context_t hctx, bufferlist *in, bufferlis return rc; } - timespan tag_timeout(header.tag_timeout ? header.tag_timeout : CEPH_RGW_TAG_TIMEOUT); + timespan tag_timeout( + std::chrono::seconds( + header.tag_timeout ? header.tag_timeout : CEPH_RGW_TAG_TIMEOUT)); bufferlist::iterator in_iter = in->begin(); diff --git a/ceph/src/common/BackTrace.h b/ceph/src/common/BackTrace.h index fe0ad0e7e..372788e6b 100644 --- a/ceph/src/common/BackTrace.h +++ b/ceph/src/common/BackTrace.h @@ -14,7 +14,7 @@ struct BackTrace { const static int max = 100; int skip; - void *array[max]; + void *array[max]{}; size_t size; char **strings; diff --git a/ceph/src/common/LogEntry.cc b/ceph/src/common/LogEntry.cc index 40bdbea2b..d9100fc46 100644 --- a/ceph/src/common/LogEntry.cc +++ b/ceph/src/common/LogEntry.cc @@ -1,3 +1,6 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +// #include #include @@ -36,6 +39,27 @@ void LogEntryKey::generate_test_instances(list& o) o.push_back(new LogEntryKey(entity_inst_t(), utime_t(1,2), 34)); } +clog_type LogEntry::str_to_level(std::string const &str) +{ + std::string level_str = str; + std::transform(level_str.begin(), level_str.end(), level_str.begin(), + [](char c) {return std::tolower(c);}); + + if (level_str == "debug") { + return CLOG_DEBUG; + } else if (level_str == "info") { + return CLOG_INFO; + } else if (level_str == "sec") { + return CLOG_SEC; + } else if (level_str == "warn" || level_str == "warning") { + return CLOG_WARN; + } else if (level_str == "error" || level_str == "err") { + return CLOG_ERROR; + } else { + return CLOG_UNKNOWN; + } +} + // ---- int clog_type_to_syslog_level(clog_type t) @@ -274,3 +298,4 @@ void LogSummary::generate_test_instances(list& o) o.push_back(new LogSummary); // more! } + diff --git a/ceph/src/common/LogEntry.h b/ceph/src/common/LogEntry.h index 4feea3d41..a25f9c381 100644 --- a/ceph/src/common/LogEntry.h +++ b/ceph/src/common/LogEntry.h @@ -115,6 +115,7 @@ struct LogEntry { void decode(bufferlist::iterator& bl); void dump(Formatter *f) const; static void generate_test_instances(list& o); + static clog_type str_to_level(std::string const &str); }; WRITE_CLASS_ENCODER_FEATURES(LogEntry) diff --git a/ceph/src/common/Mutex.cc b/ceph/src/common/Mutex.cc index 6ac022c8a..1bb588902 100644 --- a/ceph/src/common/Mutex.cc +++ b/ceph/src/common/Mutex.cc @@ -61,10 +61,11 @@ Mutex::Mutex(const std::string &n, bool r, bool ld, _register(); } else { - // If the mutex type is PTHREAD_MUTEX_NORMAL, deadlock detection - // shall not be provided. Attempting to relock the mutex causes - // deadlock. If a thread attempts to unlock a mutex that it has not - // locked or a mutex which is unlocked, undefined behavior results. + // If the mutex type is PTHREAD_MUTEX_DEFAULT, attempting to recursively + // lock the mutex results in undefined behavior. Attempting to unlock the + // mutex if it was not locked by the calling thread results in undefined + // behavior. Attempting to unlock the mutex if it is not locked results in + // undefined behavior. pthread_mutex_init(&_m, NULL); } } diff --git a/ceph/src/common/OpQueue.h b/ceph/src/common/OpQueue.h index 208d762b3..3902b329c 100644 --- a/ceph/src/common/OpQueue.h +++ b/ceph/src/common/OpQueue.h @@ -37,10 +37,11 @@ class OpQueue { public: // How many Ops are in the queue virtual unsigned length() const = 0; - // Ops will be removed f evaluates to true, f may have sideeffects - virtual void remove_by_filter( - std::function f) = 0; - // Ops of this priority should be deleted immediately + // Ops of this class should be deleted immediately. If out isn't + // nullptr then items should be added to the front in + // front-to-back order. The typical strategy is to visit items in + // the queue in *reverse* order and to use *push_front* to insert + // them into out. virtual void remove_by_class(K k, std::list *out) = 0; // Enqueue op in the back of the strict queue virtual void enqueue_strict(K cl, unsigned priority, T item) = 0; diff --git a/ceph/src/common/PrioritizedQueue.h b/ceph/src/common/PrioritizedQueue.h index 8d9cd95b2..816d80ac1 100644 --- a/ceph/src/common/PrioritizedQueue.h +++ b/ceph/src/common/PrioritizedQueue.h @@ -45,24 +45,6 @@ class PrioritizedQueue : public OpQueue { int64_t min_cost; typedef std::list > ListPairs; - static unsigned filter_list_pairs( - ListPairs *l, - std::function f) { - unsigned ret = 0; - for (typename ListPairs::iterator i = l->end(); - i != l->begin(); - ) { - auto next = i; - --next; - if (f(next->second)) { - ++ret; - l->erase(next); - } else { - i = next; - } - } - return ret; - } struct SubQueue { private: @@ -142,24 +124,6 @@ class PrioritizedQueue : public OpQueue { bool empty() const { return q.empty(); } - void remove_by_filter( - std::function f) { - for (typename Classes::iterator i = q.begin(); - i != q.end(); - ) { - size -= filter_list_pairs(&(i->second), f); - if (i->second.empty()) { - if (cur == i) { - ++cur; - } - q.erase(i++); - } else { - ++i; - } - } - if (cur == q.end()) - cur = q.begin(); - } void remove_by_class(K k, std::list *out) { typename Classes::iterator i = q.find(k); if (i == q.end()) { @@ -251,33 +215,6 @@ public: return total; } - void remove_by_filter( - std::function f) final { - for (typename SubQueues::iterator i = queue.begin(); - i != queue.end(); - ) { - unsigned priority = i->first; - - i->second.remove_by_filter(f); - if (i->second.empty()) { - ++i; - remove_queue(priority); - } else { - ++i; - } - } - for (typename SubQueues::iterator i = high_queue.begin(); - i != high_queue.end(); - ) { - i->second.remove_by_filter(f); - if (i->second.empty()) { - high_queue.erase(i++); - } else { - ++i; - } - } - } - void remove_by_class(K k, std::list *out = 0) final { for (typename SubQueues::iterator i = queue.begin(); i != queue.end(); diff --git a/ceph/src/common/Timer.cc b/ceph/src/common/Timer.cc index ef76a9e41..f211a6f8f 100644 --- a/ceph/src/common/Timer.cc +++ b/ceph/src/common/Timer.cc @@ -114,20 +114,24 @@ void SafeTimer::timer_thread() lock.Unlock(); } -void SafeTimer::add_event_after(double seconds, Context *callback) +bool SafeTimer::add_event_after(double seconds, Context *callback) { assert(lock.is_locked()); utime_t when = ceph_clock_now(); when += seconds; - add_event_at(when, callback); + return add_event_at(when, callback); } -void SafeTimer::add_event_at(utime_t when, Context *callback) +bool SafeTimer::add_event_at(utime_t when, Context *callback) { assert(lock.is_locked()); - ldout(cct,10) << "add_event_at " << when << " -> " << callback << dendl; - + ldout(cct,10) << __func__ << " " << when << " -> " << callback << dendl; + if (stopping) { + ldout(cct,5) << __func__ << " already shutdown, event not added" << dendl; + delete callback; + return false; + } scheduled_map_t::value_type s_val(when, callback); scheduled_map_t::iterator i = schedule.insert(s_val); @@ -141,7 +145,7 @@ void SafeTimer::add_event_at(utime_t when, Context *callback) * adjust our timeout. */ if (i == schedule.begin()) cond.Signal(); - + return true; } bool SafeTimer::cancel_event(Context *callback) diff --git a/ceph/src/common/Timer.h b/ceph/src/common/Timer.h index 078a172b2..861b239ca 100644 --- a/ceph/src/common/Timer.h +++ b/ceph/src/common/Timer.h @@ -70,8 +70,8 @@ public: /* Schedule an event in the future * Call with the event_lock LOCKED */ - void add_event_after(double seconds, Context *callback); - void add_event_at(utime_t when, Context *callback); + bool add_event_after(double seconds, Context *callback); + bool add_event_at(utime_t when, Context *callback); /* Cancel an event. * Call with the event_lock LOCKED diff --git a/ceph/src/common/WeightedPriorityQueue.h b/ceph/src/common/WeightedPriorityQueue.h index 10d6f0d45..64ac120bf 100644 --- a/ceph/src/common/WeightedPriorityQueue.h +++ b/ceph/src/common/WeightedPriorityQueue.h @@ -99,22 +99,6 @@ class WeightedPriorityQueue : public OpQueue unsigned get_size() const { return lp.size(); } - unsigned filter_list_pairs(std::function& f) { - 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 (Lit i = --lp.end();; --i) { - if (f(i->item)) { - i = lp.erase_and_dispose(i, DelItem()); - ++count; - } - if (i == lp.begin()) { - break; - } - } - return count; - } unsigned filter_class(std::list* out) { unsigned count = 0; for (Lit i = --lp.end();; --i) { @@ -180,25 +164,6 @@ class WeightedPriorityQueue : public OpQueue check_end(); return ret; } - unsigned filter_list_pairs(std::function& f) { - 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 (Kit i = klasses.begin(); i != klasses.end();) { - count += i->filter_list_pairs(f); - if (i->empty()) { - if (next == i) { - ++next; - } - i = klasses.erase_and_dispose(i, DelItem()); - } else { - ++i; - } - } - check_end(); - return count; - } unsigned filter_class(K& cl, std::list* out) { unsigned count = 0; Kit i = klasses.find(cl, MapKey()); @@ -291,17 +256,6 @@ class WeightedPriorityQueue : public OpQueue } return ret; } - void filter_list_pairs(std::function& f) { - for (Sit i = queues.begin(); i != queues.end();) { - size -= i->filter_list_pairs(f); - if (i->empty()) { - total_prio -= i->key; - i = queues.erase_and_dispose(i, DelItem()); - } else { - ++i; - } - } - } void filter_class(K& cl, std::list* out) { for (Sit i = queues.begin(); i != queues.end();) { size -= i->filter_class(cl, out); @@ -338,10 +292,6 @@ class WeightedPriorityQueue : public OpQueue unsigned length() const final { return strict.size + normal.size; } - void remove_by_filter(std::function f) final { - strict.filter_list_pairs(f); - normal.filter_list_pairs(f); - } void remove_by_class(K cl, std::list* removed = 0) final { strict.filter_class(cl, removed); normal.filter_class(cl, removed); diff --git a/ceph/src/common/WorkQueue.h b/ceph/src/common/WorkQueue.h index c817e74ec..d3eff47bd 100644 --- a/ceph/src/common/WorkQueue.h +++ b/ceph/src/common/WorkQueue.h @@ -373,6 +373,9 @@ public: PointerWQ(string n, time_t ti, time_t sti, ThreadPool* p) : WorkQueue_(std::move(n), ti, sti), m_pool(p), m_processing(0) { } + void register_work_queue() { + m_pool->add_work_queue(this); + } void _clear() override { assert(m_pool->_lock.is_locked()); m_items.clear(); @@ -576,7 +579,7 @@ public: ContextWQ(const string &name, time_t ti, ThreadPool *tp) : ThreadPool::PointerWQ(name, ti, 0, tp), m_lock("ContextWQ::m_lock") { - tp->add_work_queue(this); + this->register_work_queue(); } void queue(Context *ctx, int result = 0) { diff --git a/ceph/src/common/ceph_crypto.cc b/ceph/src/common/ceph_crypto.cc index 849d5fe70..a0aa8767e 100644 --- a/ceph/src/common/ceph_crypto.cc +++ b/ceph/src/common/ceph_crypto.cc @@ -60,7 +60,7 @@ void ceph::crypto::init(CephContext *cct) memset(&init_params, 0, sizeof(init_params)); init_params.length = sizeof(init_params); - uint32_t flags = NSS_INIT_READONLY; + uint32_t flags = (NSS_INIT_READONLY | NSS_INIT_PK11RELOAD); if (cct->_conf->nss_db_path.empty()) { flags |= (NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB); } diff --git a/ceph/src/common/cohort_lru.h b/ceph/src/common/cohort_lru.h index 13c760f76..dd786cfe9 100644 --- a/ceph/src/common/cohort_lru.h +++ b/ceph/src/common/cohort_lru.h @@ -14,6 +14,7 @@ #define COHORT_LRU_H #include +#include #include "common/likely.h" @@ -38,7 +39,7 @@ namespace cohort { LRU }; - typedef bi::link_mode link_mode; // for debugging + typedef bi::link_mode link_mode; class Object { @@ -54,6 +55,14 @@ namespace cohort { &Object::lru_hook >, bi::constant_time_size> Queue; + bi::slist_member_hook< link_mode > q2_hook; + + typedef bi::slist, + &Object::q2_hook >, + bi::constant_time_size> Queue2; + public: Object() : lru_flags(FLAG_NONE), lru_refcnt(0), lru_adj(0) {} @@ -67,6 +76,10 @@ namespace cohort { private: template friend class LRU; + + template + friend class TreeX; }; /* allocator & recycler interface (create or re-use LRU objects) */ @@ -125,12 +138,6 @@ namespace cohort { Lane& lane = qlane[lane_ix]; /* if object at LRU has refcnt==1, it may be reclaimable */ Object* o = &(lane.q.back()); -#if 0 /* XXX save for refactor */ - std::cout << __func__ - << " " << o - << " refcnt: " << o->lru_refcnt - << std::endl; -#endif if (can_reclaim(o)) { ++(o->lru_refcnt); o->lru_flags |= FLAG_EVICTING; @@ -190,6 +197,7 @@ namespace cohort { void unref(Object* o, uint32_t flags) { uint32_t refcnt = --(o->lru_refcnt); + Object* tdo = nullptr; if (unlikely(refcnt == 0)) { Lane& lane = lane_of(o); lane.lock.lock(); @@ -198,7 +206,7 @@ namespace cohort { Object::Queue::iterator it = Object::Queue::s_iterator_to(*o); lane.q.erase(it); - delete o; + tdo = o; } lane.lock.unlock(); } else if (unlikely(refcnt == SENTINEL_REFCNT)) { @@ -212,13 +220,16 @@ namespace cohort { lane.q.erase(it); /* hiwat check */ if (lane.q.size() > lane_hiwat) { - delete o; + tdo = o; } else { lane.q.push_back(*o); } } lane.lock.unlock(); } + /* unref out-of-line && !LOCKED */ + if (tdo) + delete tdo; } /* unref */ Object* insert(ObjectFactory* fac, Edge edge, uint32_t flags) { @@ -448,6 +459,7 @@ namespace cohort { /* clear a table, call supplied function on * each element found (e.g., retuns sentinel * references) */ + Object::Queue2 drain_q; for (int t_ix = 0; t_ix < n_part; ++t_ix) { Partition& p = part[t_ix]; if (flags & FLAG_LOCK) /* LOCKED */ @@ -455,13 +467,19 @@ namespace cohort { 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); + p.tr.erase(it); + drain_q.push_front(*v); } if (flags & FLAG_LOCK) /* we locked it, !LOCKED */ p.lock.unlock(); } /* each partition */ + /* unref out-of-line && !LOCKED */ + while (drain_q.size() > 0) { + Object::Queue2::iterator it = drain_q.begin(); + T* v = static_cast(&(*it)); + drain_q.erase(it); /* must precede uref(v) in safe_link mode */ + uref(v); + } } /* drain */ private: diff --git a/ceph/src/common/config.cc b/ceph/src/common/config.cc index 8c026f89a..5cbbd85e9 100644 --- a/ceph/src/common/config.cc +++ b/ceph/src/common/config.cc @@ -603,6 +603,7 @@ int md_config_t::parse_option(std::vector& args, } if (ret != 0 || !error_message.empty()) { + assert(option_name); if (oss) { *oss << "Parse error setting " << option_name << " to '" << val << "' using injectargs"; @@ -710,11 +711,11 @@ void md_config_t::call_all_observers() expand_all_meta(); - for (obs_map_t::iterator r = observers.begin(); r != observers.end(); ++r) { + for (auto r = observers.begin(); r != observers.end(); ++r) { obs[r->second].insert(r->first); } } - for (std::map >::iterator p = obs.begin(); + for (auto p = obs.begin(); p != obs.end(); ++p) { p->first->handle_conf_change(this, p->second); @@ -905,6 +906,10 @@ int md_config_t::_get_val(const char *key, std::string *value) const { ostringstream oss; if (bool *flag = boost::get(&config_value)) { oss << (*flag ? "true" : "false"); + } else if (float *fp = boost::get(&config_value)) { + oss << std::fixed << *fp ; + } else if (double *dp = boost::get(&config_value)) { + oss << std::fixed << *dp ; } else { oss << config_value; } @@ -921,29 +926,21 @@ int md_config_t::_get_val(const char *key, char **buf, int len) const if (!key) return -EINVAL; - string k(ConfFile::normalize_key_name(key)); - - config_value_t cval = _get_val(k.c_str()); - if (!boost::get(&cval)) { - ostringstream oss; - if (bool *flagp = boost::get(&cval)) { - oss << (*flagp ? "true" : "false"); - } else { - oss << cval; - } - string str(oss.str()); - int l = strlen(str.c_str()) + 1; + string val ; + if (!_get_val(key, &val)) { + int l = val.length() + 1; if (len == -1) { *buf = (char*)malloc(l); if (!*buf) return -ENOMEM; - strcpy(*buf, str.c_str()); + strncpy(*buf, val.c_str(), l); return 0; } - snprintf(*buf, len, "%s", str.c_str()); + snprintf(*buf, len, "%s", val.c_str()); return (l > len) ? -ENAMETOOLONG : 0; } + string k(ConfFile::normalize_key_name(key)); // subsys? for (int o = 0; o < subsys.get_num(); o++) { std::string as_option = "debug_" + subsys.get_name(o); diff --git a/ceph/src/common/config_opts.h b/ceph/src/common/config_opts.h index 443ef8c1a..b7348a02f 100644 --- a/ceph/src/common/config_opts.h +++ b/ceph/src/common/config_opts.h @@ -16,6 +16,7 @@ OPTION(host, OPT_STR, "") // "" means that ceph will use short hostname OPTION(fsid, OPT_UUID, uuid_d()) OPTION(public_addr, OPT_ADDR, entity_addr_t()) +OPTION(public_bind_addr, OPT_ADDR, entity_addr_t()) OPTION(cluster_addr, OPT_ADDR, entity_addr_t()) OPTION(public_network, OPT_STR, "") OPTION(cluster_network, OPT_STR, "") @@ -28,7 +29,6 @@ OPTION(lockdep_force_backtrace, OPT_BOOL, false) // always gather current backtr OPTION(run_dir, OPT_STR, "/var/run/ceph") // the "/var/run/ceph" dir, created on daemon startup OPTION(admin_socket, OPT_STR, "$run_dir/$cluster-$name.asok") // default changed by common_preinit() OPTION(admin_socket_mode, OPT_STR, "") // permission bits to set for admin socket file, e.g., "0775", "0755" -OPTION(crushtool, OPT_STR, "crushtool") // crushtool utility path OPTION(daemonize, OPT_BOOL, false) // default changed by common_preinit() OPTION(setuser, OPT_STR, "") // uid or user name @@ -212,6 +212,7 @@ OPTION(ms_bind_retry_count, OPT_INT, 6) // If binding fails, how many times do w OPTION(ms_bind_retry_delay, OPT_INT, 6) // Delay between attemps to bind #endif OPTION(ms_bind_before_connect, OPT_BOOL, false) +OPTION(ms_tcp_listen_backlog, OPT_INT, 512) OPTION(ms_rwthread_stack_bytes, OPT_U64, 1024 << 10) OPTION(ms_tcp_read_timeout, OPT_U64, 900) OPTION(ms_pq_max_tokens_per_priority, OPT_U64, 16777216) @@ -308,8 +309,7 @@ OPTION(mon_clock_drift_allowed, OPT_FLOAT, .050) // allowed clock drift between 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_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_health_max_detail, OPT_INT, 50) // max detailed pgs to report in health detail +OPTION(mon_pg_stuck_threshold, OPT_INT, 60) // number of seconds after which pgs can be considered stuck inactive, unclean, etc (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. OPTION(mon_pg_warn_min_per_osd, OPT_INT, 30) // min # pgs per (in) osd before we warn the admin OPTION(mon_pg_warn_max_per_osd, OPT_INT, 300) // max # pgs per (in) osd before we warn the admin @@ -352,6 +352,8 @@ 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) OPTION(mon_health_to_clog_tick_interval, OPT_DOUBLE, 60.0) +OPTION(mon_health_preluminous_compat, OPT_BOOL, false) +OPTION(mon_health_max_detail, OPT_INT, 50) // max detailed pgs to report in health detail OPTION(mon_data_avail_crit, OPT_INT, 5) OPTION(mon_data_avail_warn, OPT_INT, 30) OPTION(mon_data_size_warn, OPT_U64, 15*1024*1024*1024) // issue a warning when the monitor's data store goes over 15GB (in bytes) @@ -393,6 +395,8 @@ OPTION(mon_keyvaluedb, OPT_STR, "rocksdb") // type of keyvaluedb backend // UNSAFE -- TESTING ONLY! Allows addition of a cache tier with preexisting snaps OPTION(mon_debug_unsafe_allow_tier_with_nonempty_snaps, OPT_BOOL, false) +OPTION(mon_osd_blacklist_default_expire, OPT_DOUBLE, 60*60) // default one hour +OPTION(mon_osd_crush_smoke_test, OPT_BOOL, true) OPTION(paxos_stash_full_interval, OPT_INT, 25) // how often (in commits) to stash a full copy of the PaxosService state OPTION(paxos_max_join_drift, OPT_INT, 10) // max paxos iterations before we must first sync the monitor stores @@ -688,6 +692,7 @@ OPTION(osd_crush_update_weight_set, OPT_BOOL, true) // update weight set while u OPTION(osd_crush_chooseleaf_type, OPT_INT, 1) // 1 = host 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_crush_update_on_start, OPT_BOOL, true) +OPTION(osd_class_update_on_start, OPT_BOOL, true) // automatically set device class on start OPTION(osd_crush_initial_weight, OPT_DOUBLE, -1) // if >=0, the initial weight is for newly added osds. OPTION(osd_pool_default_crush_rule, OPT_INT, -1) OPTION(osd_pool_erasure_code_stripe_unit, OPT_U32, 4096) // in bytes @@ -695,6 +700,7 @@ OPTION(osd_pool_default_size, OPT_INT, 3) OPTION(osd_pool_default_min_size, OPT_INT, 0) // 0 means no specific default; ceph will use size-size/2 OPTION(osd_pool_default_pg_num, OPT_INT, 8) // number of PGs for new pools. Configure in global or mon section of ceph.conf OPTION(osd_pool_default_pgp_num, OPT_INT, 8) // number of PGs for placement purposes. Should be equal to pg_num +OPTION(osd_pool_default_type, OPT_STR, "replicated") OPTION(osd_pool_default_erasure_code_profile, OPT_STR, "plugin=jerasure " @@ -767,9 +773,35 @@ OPTION(osd_op_num_threads_per_shard_ssd, OPT_INT, 2) OPTION(osd_op_num_shards, OPT_INT, 0) OPTION(osd_op_num_shards_hdd, OPT_INT, 5) OPTION(osd_op_num_shards_ssd, OPT_INT, 8) -OPTION(osd_op_queue, OPT_STR, "wpq") // PrioritzedQueue (prio), Weighted Priority Queue (wpq), or debug_random + +// PrioritzedQueue (prio), Weighted Priority Queue (wpq ; default), +// mclock_opclass, mclock_client, or debug_random. "mclock_opclass" +// and "mclock_client" are based on the mClock/dmClock algorithm +// (Gulati, et al. 2010). "mclock_opclass" prioritizes based on the +// class the operation belongs to. "mclock_client" does the same but +// also works to ienforce fairness between clients. "debug_random" +// chooses among all four with equal probability. +OPTION(osd_op_queue, OPT_STR, "wpq") + OPTION(osd_op_queue_cut_off, OPT_STR, "low") // Min priority to go to strict queue. (low, high, debug_random) +// mClock priority queue parameters for five types of ops +OPTION(osd_op_queue_mclock_client_op_res, OPT_DOUBLE, 1000.0) +OPTION(osd_op_queue_mclock_client_op_wgt, OPT_DOUBLE, 500.0) +OPTION(osd_op_queue_mclock_client_op_lim, OPT_DOUBLE, 0.0) +OPTION(osd_op_queue_mclock_osd_subop_res, OPT_DOUBLE, 1000.0) +OPTION(osd_op_queue_mclock_osd_subop_wgt, OPT_DOUBLE, 500.0) +OPTION(osd_op_queue_mclock_osd_subop_lim, OPT_DOUBLE, 0.0) +OPTION(osd_op_queue_mclock_snap_res, OPT_DOUBLE, 0.0) +OPTION(osd_op_queue_mclock_snap_wgt, OPT_DOUBLE, 1.0) +OPTION(osd_op_queue_mclock_snap_lim, OPT_DOUBLE, 0.001) +OPTION(osd_op_queue_mclock_recov_res, OPT_DOUBLE, 0.0) +OPTION(osd_op_queue_mclock_recov_wgt, OPT_DOUBLE, 1.0) +OPTION(osd_op_queue_mclock_recov_lim, OPT_DOUBLE, 0.001) +OPTION(osd_op_queue_mclock_scrub_res, OPT_DOUBLE, 0.0) +OPTION(osd_op_queue_mclock_scrub_wgt, OPT_DOUBLE, 1.0) +OPTION(osd_op_queue_mclock_scrub_lim, OPT_DOUBLE, 0.001) + OPTION(osd_ignore_stale_divergent_priors, OPT_BOOL, false) // do not assert on divergent_prior entries which aren't in the log and whose on-disk objects are newer // Set to true for testing. Users should NOT set this. @@ -823,7 +855,6 @@ OPTION(osd_mon_ack_timeout, OPT_DOUBLE, 30.0) // time out a mon if it doesn't ac OPTION(osd_stats_ack_timeout_factor, OPT_DOUBLE, 2.0) // multiples of mon_ack_timeout OPTION(osd_stats_ack_timeout_decay, OPT_DOUBLE, .9) OPTION(osd_default_data_pool_replay_window, OPT_INT, 45) -OPTION(osd_preserve_trimmed_log, OPT_BOOL, false) OPTION(osd_auto_mark_unfound_lost, OPT_BOOL, false) OPTION(osd_recovery_delay_start, OPT_FLOAT, 0) OPTION(osd_recovery_max_active, OPT_U64, 3) @@ -853,7 +884,6 @@ OPTION(osd_deep_scrub_interval, OPT_FLOAT, 60*60*24*7) // once a week OPTION(osd_deep_scrub_randomize_ratio, OPT_FLOAT, 0.15) // scrubs will randomly become deep scrubs at this rate (0.15 -> 15% of scrubs are deep) OPTION(osd_deep_scrub_stride, OPT_INT, 524288) OPTION(osd_deep_scrub_update_digest_min_age, OPT_INT, 2*60*60) // objects must be this old (seconds) before we update the whole-object digest on scrub -OPTION(osd_scan_list_ping_tp_interval, OPT_U64, 100) OPTION(osd_class_dir, OPT_STR, CEPH_LIBDIR "/rados-classes") // where rados plugins are stored OPTION(osd_open_classes_on_start, OPT_BOOL, true) OPTION(osd_class_load_list, OPT_STR, "cephfs hello journal lock log numops " @@ -897,6 +927,7 @@ OPTION(osd_debug_reject_backfill_probability, OPT_DOUBLE, 0) OPTION(osd_debug_inject_copyfrom_error, OPT_BOOL, false) // inject failure during copyfrom completion OPTION(osd_debug_misdirected_ops, OPT_BOOL, false) OPTION(osd_debug_skip_full_check_in_recovery, OPT_BOOL, false) +OPTION(osd_debug_random_push_read_error, OPT_DOUBLE, 0) OPTION(osd_debug_verify_cached_snaps, OPT_BOOL, false) OPTION(osd_enable_op_tracker, OPT_BOOL, true) // enable/disable OSD op tracking OPTION(osd_num_op_tracker_shard, OPT_U32, 32) // The number of shards for holding the ops @@ -943,8 +974,8 @@ OPTION(kinetic_use_ssl, OPT_BOOL, false) // whether to secure kinetic traffic wi OPTION(rocksdb_separate_wal_dir, OPT_BOOL, false) // use $path.wal for wal SAFE_OPTION(rocksdb_db_paths, OPT_STR, "") // path,size( path,size)* OPTION(rocksdb_log_to_ceph_log, OPT_BOOL, true) // log to ceph log -OPTION(rocksdb_cache_size, OPT_U64, 128*1024*1024) // default rocksdb cache size -OPTION(rocksdb_cache_row_ratio, OPT_FLOAT, .2) // ratio of cache for row (vs block) +OPTION(rocksdb_cache_size, OPT_U64, 128*1024*1024) // rocksdb cache size (unless set by bluestore/etc) +OPTION(rocksdb_cache_row_ratio, OPT_FLOAT, 0) // ratio of cache for row (vs block) OPTION(rocksdb_cache_shard_bits, OPT_INT, 4) // rocksdb block cache shard bits, 4 bit -> 16 shards OPTION(rocksdb_cache_type, OPT_STR, "lru") // 'lru' or 'clock' OPTION(rocksdb_block_size, OPT_INT, 4*1024) // default rocksdb block size @@ -1027,6 +1058,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, 1024) +OPTION(bdev_aio_reap_max, OPT_INT, 16) OPTION(bdev_block_size, OPT_INT, 4096) OPTION(bdev_debug_aio, OPT_BOOL, false) OPTION(bdev_debug_aio_suicide_timeout, OPT_FLOAT, 60.0) @@ -1135,9 +1167,12 @@ OPTION(bluestore_cache_trim_max_skip_pinned, OPT_U32, 64) // skip this many onod OPTION(bluestore_cache_type, OPT_STR, "2q") // lru, 2q OPTION(bluestore_2q_cache_kin_ratio, OPT_DOUBLE, .5) // kin page slot size / max page slot size OPTION(bluestore_2q_cache_kout_ratio, OPT_DOUBLE, .5) // number of kout page slot / total number of page slot -OPTION(bluestore_cache_size, OPT_U64, 1024*1024*1024) -OPTION(bluestore_cache_meta_ratio, OPT_DOUBLE, .7) -OPTION(bluestore_cache_kv_ratio, OPT_DOUBLE, .2) +OPTION(bluestore_cache_size, OPT_U64, 0) +OPTION(bluestore_cache_size_hdd, OPT_U64, 1*1024*1024*1024) +OPTION(bluestore_cache_size_ssd, OPT_U64, 3*1024*1024*1024) +OPTION(bluestore_cache_meta_ratio, OPT_DOUBLE, .01) +OPTION(bluestore_cache_kv_ratio, OPT_DOUBLE, .99) +OPTION(bluestore_cache_kv_max, OPT_U64, 512*1024*1024) // limit the maximum amount of cache for the kv store OPTION(bluestore_kvbackend, OPT_STR, "rocksdb") OPTION(bluestore_allocator, OPT_STR, "bitmap") // stupid | bitmap OPTION(bluestore_freelist_blocks_per_key, OPT_INT, 128) @@ -1178,6 +1213,7 @@ OPTION(bluestore_debug_fsck_abort, OPT_BOOL, false) OPTION(bluestore_debug_omit_kv_commit, OPT_BOOL, false) OPTION(bluestore_debug_permit_any_bdev_label, OPT_BOOL, false) OPTION(bluestore_shard_finishers, OPT_BOOL, false) +OPTION(bluestore_debug_random_read_err, OPT_DOUBLE, 0) OPTION(kstore_max_ops, OPT_U64, 512) OPTION(kstore_max_bytes, OPT_U64, 64*1024*1024) @@ -1190,7 +1226,6 @@ OPTION(kstore_nid_prealloc, OPT_U64, 1024) OPTION(kstore_sync_transaction, OPT_BOOL, false) OPTION(kstore_sync_submit_transaction, OPT_BOOL, false) OPTION(kstore_onode_map_size, OPT_U64, 1024) -OPTION(kstore_cache_tails, OPT_BOOL, true) OPTION(kstore_default_stripe_size, OPT_INT, 65536) OPTION(filestore_omap_backend, OPT_STR, "rocksdb") @@ -1221,6 +1256,7 @@ OPTION(filestore_index_retry_probability, OPT_DOUBLE, 0) // Allow object read error injection OPTION(filestore_debug_inject_read_err, OPT_BOOL, false) +OPTION(filestore_debug_random_read_err, OPT_DOUBLE, 0) OPTION(filestore_debug_omap_check, OPT_BOOL, false) // Expensive debugging check on sync OPTION(filestore_omap_header_cache_size, OPT_INT, 1024) @@ -1307,6 +1343,7 @@ OPTION(filestore_commit_timeout, OPT_FLOAT, 600) OPTION(filestore_fiemap_threshold, OPT_INT, 4096) OPTION(filestore_merge_threshold, OPT_INT, 10) OPTION(filestore_split_multiple, OPT_INT, 2) +OPTION(filestore_split_rand_factor, OPT_U32, 20) // randomize the split threshold by adding 16 * [0, rand_factor) OPTION(filestore_update_to, OPT_INT, 1000) OPTION(filestore_blackhole, OPT_BOOL, false) // drop any new transactions on the floor OPTION(filestore_fd_cache_size, OPT_INT, 128) // FD lru size @@ -1702,7 +1739,7 @@ OPTION(rgw_shard_warning_threshold, OPT_DOUBLE, 90) // pct of safe max OPTION(rgw_swift_versioning_enabled, OPT_BOOL, false) // whether swift object versioning feature is enabled OPTION(mgr_module_path, OPT_STR, CEPH_PKGLIBDIR "/mgr") // where to load python modules from -OPTION(mgr_modules, OPT_STR, "restful") // Which modules to load +OPTION(mgr_initial_modules, OPT_STR, "restful status") // Which modules to load OPTION(mgr_data, OPT_STR, "/var/lib/ceph/mgr/$cluster-$id") // where to find keyring etc OPTION(mgr_tick_period, OPT_INT, 2) // How frequently to tick OPTION(mgr_stats_period, OPT_INT, 5) // How frequently clients send stats @@ -1716,10 +1753,12 @@ OPTION(mgr_mon_bytes, OPT_U64, 128*1048576) // bytes from mons OPTION(mgr_mon_messages, OPT_U64, 128) // messages from mons OPTION(mgr_connect_retry_interval, OPT_DOUBLE, 1.0) +OPTION(mgr_service_beacon_grace, OPT_DOUBLE, 60.0) OPTION(mon_mgr_digest_period, OPT_INT, 5) // How frequently to send digests OPTION(mon_mgr_beacon_grace, OPT_INT, 30) // How long to wait to failover OPTION(mon_mgr_inactive_grace, OPT_INT, 60) // How long before health WARN -> ERR +OPTION(mon_mgr_mkfs_grace, OPT_INT, 60) // How long before we complain about MGR_DOWN OPTION(rgw_crypt_require_ssl, OPT_BOOL, true) // requests including encryption key headers must be sent over ssl OPTION(rgw_crypt_default_encryption_key, OPT_STR, "") // base64 encoded key for encryption of rgw objects OPTION(rgw_crypt_s3_kms_encryption_keys, OPT_STR, "") // extra keys that may be used for aws:kms @@ -1751,6 +1790,8 @@ OPTION(debug_deliberately_leak_memory, OPT_BOOL, false) OPTION(rgw_swift_custom_header, OPT_STR, "") // option to enable swift custom headers +OPTION(rgw_swift_need_stats, OPT_BOOL, true) // option to enable stats on bucket listing for swift + /* resharding tunables */ OPTION(rgw_reshard_num_logs, OPT_INT, 16) OPTION(rgw_reshard_bucket_lock_duration, OPT_INT, 120) // duration of lock on bucket obj during resharding diff --git a/ceph/src/common/dns_resolve.cc b/ceph/src/common/dns_resolve.cc index 3227c88e2..13f06548e 100644 --- a/ceph/src/common/dns_resolve.cc +++ b/ceph/src/common/dns_resolve.cc @@ -14,6 +14,7 @@ #include +#include "include/scope_guard.h" #include "dns_resolve.h" #include "common/debug.h" @@ -102,10 +103,11 @@ int DNSResolver::resolve_cname(CephContext *cct, const string& hostname, if (r < 0) { return r; } + auto put_state = make_scope_guard([res, this] { + this->put_state(res); + }); #endif - int ret; - #define LARGE_ENOUGH_DNS_BUFSIZE 1024 unsigned char buf[LARGE_ENOUGH_DNS_BUFSIZE]; @@ -128,8 +130,7 @@ int DNSResolver::resolve_cname(CephContext *cct, const string& hostname, #endif if (len < 0) { lderr(cct) << "res_query() failed" << dendl; - ret = 0; - goto done; + return 0; } answer = buf; @@ -139,15 +140,13 @@ int DNSResolver::resolve_cname(CephContext *cct, const string& hostname, /* read query */ if ((len = dn_expand(answer, answend, pt, host, sizeof(host))) < 0) { lderr(cct) << "ERROR: dn_expand() failed" << dendl; - ret = -EINVAL; - goto done; + return -EINVAL; } pt += len; if (pt + 4 > answend) { lderr(cct) << "ERROR: bad reply" << dendl; - ret = -EIO; - goto done; + return -EIO; } int type; @@ -156,24 +155,21 @@ int DNSResolver::resolve_cname(CephContext *cct, const string& hostname, if (type != ns_t_cname) { lderr(cct) << "ERROR: failed response type: type=" << type << " (was expecting " << ns_t_cname << ")" << dendl; - ret = -EIO; - goto done; + return -EIO; } pt += NS_INT16SZ; /* class */ /* read answer */ if ((len = dn_expand(answer, answend, pt, host, sizeof(host))) < 0) { - ret = 0; - goto done; + return 0; } pt += len; ldout(cct, 20) << "name=" << host << dendl; if (pt + 10 > answend) { lderr(cct) << "ERROR: bad reply" << dendl; - ret = -EIO; - goto done; + return -EIO; } NS_GET16(type, pt); @@ -182,19 +178,13 @@ int DNSResolver::resolve_cname(CephContext *cct, const string& hostname, pt += NS_INT16SZ; /* size */ if ((len = dn_expand(answer, answend, pt, host, sizeof(host))) < 0) { - ret = 0; - goto done; + return 0; } ldout(cct, 20) << "cname host=" << host << dendl; *cname = host; *found = true; - ret = 0; -done: -#ifdef HAVE_RES_NQUERY - put_state(res); -#endif - return ret; + return 0; } @@ -268,13 +258,14 @@ int DNSResolver::resolve_ip_addr(CephContext *cct, res_state *res, const string& } int DNSResolver::resolve_srv_hosts(CephContext *cct, const string& service_name, - const SRV_Protocol trans_protocol, map *srv_hosts) { + const SRV_Protocol trans_protocol, + map *srv_hosts) { return this->resolve_srv_hosts(cct, service_name, trans_protocol, "", srv_hosts); } int DNSResolver::resolve_srv_hosts(CephContext *cct, const string& service_name, const SRV_Protocol trans_protocol, const string& domain, - map *srv_hosts) { + map *srv_hosts) { #ifdef HAVE_RES_NQUERY res_state res; @@ -282,9 +273,11 @@ int DNSResolver::resolve_srv_hosts(CephContext *cct, const string& service_name, if (r < 0) { return r; } + auto put_state = make_scope_guard([res, this] { + this->put_state(res); + }); #endif - int ret; u_char nsbuf[NS_PACKETSZ]; int num_hosts; @@ -306,14 +299,12 @@ int DNSResolver::resolve_srv_hosts(CephContext *cct, const string& service_name, } #endif if (len < 0) { - lderr(cct) << "res_search() failed" << dendl; - ret = len; - goto done; + lderr(cct) << "failed for service " << query_str << dendl; + return len; } else if (len == 0) { ldout(cct, 20) << "No hosts found for service " << query_str << dendl; - ret = 0; - goto done; + return 0; } ns_msg handle; @@ -323,8 +314,7 @@ int DNSResolver::resolve_srv_hosts(CephContext *cct, const string& service_name, num_hosts = ns_msg_count (handle, ns_s_an); if (num_hosts == 0) { ldout(cct, 20) << "No hosts found for service " << query_str << dendl; - ret = 0; - goto done; + return 0; } ns_rr rr; @@ -334,8 +324,7 @@ int DNSResolver::resolve_srv_hosts(CephContext *cct, const string& service_name, int r; if ((r = ns_parserr(&handle, ns_s_an, i, &rr)) < 0) { lderr(cct) << "Error while parsing DNS record" << dendl; - ret = r; - goto done; + return r; } string full_srv_name = ns_rr_name(rr); @@ -343,11 +332,13 @@ int DNSResolver::resolve_srv_hosts(CephContext *cct, const string& service_name, string srv_domain = full_srv_name.substr(full_srv_name.find(protocol) + protocol.length()); - int port = ns_get16(ns_rr_rdata(rr) + (NS_INT16SZ * 2)); /* port = rdata + priority + weight */ + auto rdata = ns_rr_rdata(rr); + uint16_t priority = ns_get16(rdata); rdata += NS_INT16SZ; + rdata += NS_INT16SZ; // weight + uint16_t port = ns_get16(rdata); rdata += NS_INT16SZ; memset(full_target, 0, sizeof(full_target)); ns_name_uncompress(ns_msg_base(handle), ns_msg_end(handle), - ns_rr_rdata(rr) + (NS_INT16SZ * 3), /* comp_dn = rdata + priority + weight + port */ - full_target, sizeof(full_target)); + rdata, full_target, sizeof(full_target)); entity_addr_t addr; #ifdef HAVE_RES_NQUERY @@ -359,20 +350,17 @@ int DNSResolver::resolve_srv_hosts(CephContext *cct, const string& service_name, if (r == 0) { addr.set_port(port); string target = full_target; - assert(target.find(srv_domain) != target.npos); - target = target.substr(0, target.find(srv_domain)); - (*srv_hosts)[target] = addr; + auto end = target.find(srv_domain); + if (end == target.npos) { + lderr(cct) << "resolved target not in search domain: " + << target << " / " << srv_domain << dendl; + return -EINVAL; + } + target = target.substr(0, end); + (*srv_hosts)[target] = {priority, addr}; } - } - - ret = 0; -done: -#ifdef HAVE_RES_NQUERY - put_state(res); -#endif - return ret; + return 0; } } - diff --git a/ceph/src/common/dns_resolve.h b/ceph/src/common/dns_resolve.h index 3e8f7e463..e587224d8 100644 --- a/ceph/src/common/dns_resolve.h +++ b/ceph/src/common/dns_resolve.h @@ -18,8 +18,7 @@ #include #include "common/Mutex.h" - -struct entity_addr_t; +#include "msg/msg_types.h" // for entity_addr_t namespace ceph { @@ -78,6 +77,11 @@ class DNSResolver { }; + struct Record { + uint16_t priority; + entity_addr_t addr; + }; + int resolve_cname(CephContext *cct, const std::string& hostname, std::string *cname, bool *found); @@ -103,7 +107,7 @@ class DNSResolver { * @returns 0 on success, negative error code on failure */ int resolve_srv_hosts(CephContext *cct, const std::string& service_name, - const SRV_Protocol trans_protocol, std::map *srv_hosts); + const SRV_Protocol trans_protocol, std::map *srv_hosts); /** * Returns the list of hostnames and addresses that provide a given @@ -119,7 +123,7 @@ class DNSResolver { */ int resolve_srv_hosts(CephContext *cct, const std::string& service_name, const SRV_Protocol trans_protocol, const std::string& domain, - std::map *srv_hosts); + std::map *srv_hosts); private: DNSResolver() : lock("DNSResolver") { resolv_h = new ResolvHWrapper(); } diff --git a/ceph/src/common/fork_function.h b/ceph/src/common/fork_function.h new file mode 100644 index 000000000..fa214f788 --- /dev/null +++ b/ceph/src/common/fork_function.h @@ -0,0 +1,161 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +// Run a function in a forked child, with a timeout. + +#pragma once + +#include +#include +#include +#include +#include +#include +#include "common/errno.h" + +static void _fork_function_dummy_sighandler(int sig) {} + +// Run a function post-fork, with a timeout. Function can return +// int8_t only due to unix exit code limitations. Returns -ETIMEDOUT +// if timeout is reached. + +static inline int fork_function( + int timeout, + std::ostream& errstr, + std::function f) +{ + // first fork the forker. + pid_t forker_pid = fork(); + if (forker_pid) { + // just wait + int status; + while (waitpid(forker_pid, &status, 0) == -1) { + assert(errno == EINTR); + } + if (WIFSIGNALED(status)) { + errstr << ": got signal: " << WTERMSIG(status) << "\n"; + return 128 + WTERMSIG(status); + } + if (WIFEXITED(status)) { + int8_t r = WEXITSTATUS(status); + errstr << ": exit status: " << (int)r << "\n"; + return r; + } + errstr << ": waitpid: unknown status returned\n"; + return -1; + } + + // we are forker (first child) + + // close all fds + int maxfd = sysconf(_SC_OPEN_MAX); + if (maxfd == -1) + maxfd = 16384; + for (int fd = 0; fd <= maxfd; fd++) { + if (fd == STDIN_FILENO) + continue; + if (fd == STDOUT_FILENO) + continue; + if (fd == STDERR_FILENO) + continue; + ::close(fd); + } + + sigset_t mask, oldmask; + int pid; + + // Restore default action for SIGTERM in case the parent process decided + // to ignore it. + if (signal(SIGTERM, SIG_DFL) == SIG_ERR) { + std::cerr << ": signal failed: " << cpp_strerror(errno) << "\n"; + goto fail_exit; + } + // Because SIGCHLD is ignored by default, setup dummy handler for it, + // so we can mask it. + if (signal(SIGCHLD, _fork_function_dummy_sighandler) == SIG_ERR) { + std::cerr << ": signal failed: " << cpp_strerror(errno) << "\n"; + goto fail_exit; + } + // Setup timeout handler. + if (signal(SIGALRM, timeout_sighandler) == SIG_ERR) { + std::cerr << ": signal failed: " << cpp_strerror(errno) << "\n"; + goto fail_exit; + } + // Block interesting signals. + sigemptyset(&mask); + sigaddset(&mask, SIGINT); + sigaddset(&mask, SIGTERM); + sigaddset(&mask, SIGCHLD); + sigaddset(&mask, SIGALRM); + if (sigprocmask(SIG_SETMASK, &mask, &oldmask) == -1) { + std::cerr << ": sigprocmask failed: " + << cpp_strerror(errno) << "\n"; + goto fail_exit; + } + + pid = fork(); + + if (pid == -1) { + std::cerr << ": fork failed: " << cpp_strerror(errno) << "\n"; + goto fail_exit; + } + + if (pid == 0) { // we are second child + // Restore old sigmask. + if (sigprocmask(SIG_SETMASK, &oldmask, NULL) == -1) { + std::cerr << ": sigprocmask failed: " + << cpp_strerror(errno) << "\n"; + goto fail_exit; + } + (void)setpgid(0, 0); // Become process group leader. + int8_t r = f(); + _exit((uint8_t)r); + } + + // Parent + (void)alarm(timeout); + + for (;;) { + int signo; + if (sigwait(&mask, &signo) == -1) { + std::cerr << ": sigwait failed: " << cpp_strerror(errno) << "\n"; + goto fail_exit; + } + switch (signo) { + case SIGCHLD: + int status; + if (waitpid(pid, &status, WNOHANG) == -1) { + std::cerr << ": waitpid failed: " << cpp_strerror(errno) << "\n"; + goto fail_exit; + } + if (WIFEXITED(status)) + _exit(WEXITSTATUS(status)); + if (WIFSIGNALED(status)) + _exit(128 + WTERMSIG(status)); + std::cerr << ": unknown status returned\n"; + goto fail_exit; + case SIGINT: + case SIGTERM: + // Pass SIGINT and SIGTERM, which are usually used to terminate + // a process, to the child. + if (::kill(pid, signo) == -1) { + std::cerr << ": kill failed: " << cpp_strerror(errno) << "\n"; + goto fail_exit; + } + continue; + case SIGALRM: + std::cerr << ": timed out (" << timeout << " sec)\n"; + if (::killpg(pid, SIGKILL) == -1) { + std::cerr << ": kill failed: " << cpp_strerror(errno) << "\n"; + goto fail_exit; + } + _exit(-ETIMEDOUT); + default: + std::cerr << ": sigwait: invalid signal: " << signo << "\n"; + goto fail_exit; + } + } + return 0; +fail_exit: + _exit(EXIT_FAILURE); +} diff --git a/ceph/src/common/freebsd_errno.cc b/ceph/src/common/freebsd_errno.cc index 77f6df91e..259ce7be7 100644 --- a/ceph/src/common/freebsd_errno.cc +++ b/ceph/src/common/freebsd_errno.cc @@ -201,7 +201,7 @@ __s32 ceph_to_hostos_errno(__s32 r) { int sign = (r < 0 ? -1 : 1); int err = std::abs(r); - if (err < 256 && hostos_to_ceph_conv[err] !=0 ) { + if (err < 256 && ceph_to_hostos_conv[err] !=0 ) { err = ceph_to_hostos_conv[err]; } return err * sign; diff --git a/ceph/src/common/mClockPriorityQueue.h b/ceph/src/common/mClockPriorityQueue.h new file mode 100644 index 000000000..b651cf08f --- /dev/null +++ b/ceph/src/common/mClockPriorityQueue.h @@ -0,0 +1,361 @@ +// -*- 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. + * + */ + +#pragma once + + +#include +#include +#include +#include + +#include "common/Formatter.h" +#include "common/OpQueue.h" + +#include "dmclock/src/dmclock_server.h" + +// the following is done to unclobber _ASSERT_H so it returns to the +// way ceph likes it +#include "include/assert.h" + + +namespace ceph { + + namespace dmc = crimson::dmclock; + + template + class mClockQueue : public OpQueue { + + using priority_t = unsigned; + using cost_t = unsigned; + + typedef std::list > ListPairs; + + static unsigned filter_list_pairs(ListPairs *l, + std::function f, + std::list* out = nullptr) { + unsigned ret = 0; + for (typename ListPairs::iterator i = l->end(); + i != l->begin(); + /* no inc */ + ) { + auto next = i; + --next; + if (f(next->second)) { + ++ret; + if (out) out->push_back(next->second); + l->erase(next); + } else { + i = next; + } + } + return ret; + } + + struct SubQueue { + private: + typedef std::map Classes; + // client-class to ordered queue + Classes q; + + unsigned tokens, max_tokens; + int64_t size; + + typename Classes::iterator cur; + + public: + + SubQueue(const SubQueue &other) + : q(other.q), + tokens(other.tokens), + max_tokens(other.max_tokens), + size(other.size), + cur(q.begin()) {} + + SubQueue() + : tokens(0), + max_tokens(0), + size(0), cur(q.begin()) {} + + void set_max_tokens(unsigned mt) { + max_tokens = mt; + } + + unsigned get_max_tokens() const { + return max_tokens; + } + + unsigned num_tokens() const { + return tokens; + } + + void put_tokens(unsigned t) { + tokens += t; + if (tokens > max_tokens) { + tokens = max_tokens; + } + } + + void take_tokens(unsigned t) { + if (tokens > t) { + tokens -= t; + } else { + tokens = 0; + } + } + + void enqueue(K cl, cost_t cost, T item) { + q[cl].push_back(std::make_pair(cost, item)); + if (cur == q.end()) + cur = q.begin(); + size++; + } + + void enqueue_front(K cl, cost_t cost, T item) { + q[cl].push_front(std::make_pair(cost, item)); + if (cur == q.end()) + cur = q.begin(); + size++; + } + + std::pair front() const { + assert(!(q.empty())); + assert(cur != q.end()); + return cur->second.front(); + } + + void pop_front() { + assert(!(q.empty())); + assert(cur != q.end()); + cur->second.pop_front(); + if (cur->second.empty()) { + auto i = cur; + ++cur; + q.erase(i); + } else { + ++cur; + } + if (cur == q.end()) { + cur = q.begin(); + } + size--; + } + + unsigned length() const { + assert(size >= 0); + return (unsigned)size; + } + + bool empty() const { + return q.empty(); + } + + void remove_by_filter(std::function f) { + for (typename Classes::iterator i = q.begin(); + i != q.end(); + /* no-inc */) { + size -= filter_list_pairs(&(i->second), f); + if (i->second.empty()) { + if (cur == i) { + ++cur; + } + i = q.erase(i); + } else { + ++i; + } + } + if (cur == q.end()) cur = q.begin(); + } + + void remove_by_class(K k, std::list *out) { + typename Classes::iterator i = q.find(k); + if (i == q.end()) { + return; + } + size -= i->second.size(); + if (i == cur) { + ++cur; + } + if (out) { + for (auto j = i->second.rbegin(); j != i->second.rend(); ++j) { + out->push_front(j->second); + } + } + q.erase(i); + if (cur == q.end()) cur = q.begin(); + } + + void dump(ceph::Formatter *f) const { + f->dump_int("size", size); + f->dump_int("num_keys", q.size()); + } + }; + + using SubQueues = std::map; + + SubQueues high_queue; + + dmc::PullPriorityQueue queue; + + // when enqueue_front is called, rather than try to re-calc tags + // to put in mClock priority queue, we'll just keep a separate + // list from which we dequeue items first, and only when it's + // empty do we use queue. + std::list> queue_front; + + public: + + mClockQueue( + const typename dmc::PullPriorityQueue::ClientInfoFunc& info_func) : + queue(info_func, true) + { + // empty + } + + unsigned length() const override final { + unsigned total = 0; + total += queue_front.size(); + total += queue.request_count(); + for (auto i = high_queue.cbegin(); i != high_queue.cend(); ++i) { + assert(i->second.length()); + total += i->second.length(); + } + return total; + } + + // be sure to do things in reverse priority order and push_front + // to the list so items end up on list in front-to-back priority + // order + void remove_by_filter(std::function filter_accum) { + queue.remove_by_req_filter(filter_accum, true); + + for (auto i = queue_front.rbegin(); i != queue_front.rend(); /* no-inc */) { + if (filter_accum(i->second)) { + i = decltype(i){ queue_front.erase(std::next(i).base()) }; + } else { + ++i; + } + } + + for (typename SubQueues::iterator i = high_queue.begin(); + i != high_queue.end(); + /* no-inc */ ) { + i->second.remove_by_filter(filter_accum); + if (i->second.empty()) { + i = high_queue.erase(i); + } else { + ++i; + } + } + } + + void remove_by_class(K k, std::list *out = nullptr) override final { + if (out) { + queue.remove_by_client(k, + true, + [&out] (const T& t) { out->push_front(t); }); + } else { + queue.remove_by_client(k, true); + } + + for (auto i = queue_front.rbegin(); i != queue_front.rend(); /* no-inc */) { + if (k == i->first) { + if (nullptr != out) out->push_front(i->second); + i = decltype(i){ queue_front.erase(std::next(i).base()) }; + } else { + ++i; + } + } + + for (auto i = high_queue.begin(); i != high_queue.end(); /* no-inc */) { + i->second.remove_by_class(k, out); + if (i->second.empty()) { + i = high_queue.erase(i); + } else { + ++i; + } + } + } + + void enqueue_strict(K cl, unsigned priority, T item) override final { + high_queue[priority].enqueue(cl, 0, item); + } + + void enqueue_strict_front(K cl, unsigned priority, T item) override final { + high_queue[priority].enqueue_front(cl, 0, item); + } + + void enqueue(K cl, unsigned priority, unsigned cost, T item) override final { + // priority is ignored + queue.add_request(item, cl, cost); + } + + void enqueue_front(K cl, + unsigned priority, + unsigned cost, + T item) override final { + queue_front.emplace_front(std::pair(cl, item)); + } + + bool empty() const override final { + return queue.empty() && high_queue.empty() && queue_front.empty(); + } + + 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); + } + return ret; + } + + if (!queue_front.empty()) { + T ret = queue_front.front().second; + queue_front.pop_front(); + return ret; + } + + auto pr = queue.pull_request(); + assert(pr.is_retn()); + auto& retn = pr.get_retn(); + return *(retn.request); + } + + void dump(ceph::Formatter *f) const override final { + 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); + f->close_section(); + } + f->close_section(); + + f->open_object_section("queue_front"); + f->dump_int("size", queue_front.size()); + f->close_section(); + + f->open_object_section("queue"); + f->dump_int("size", queue.request_count()); + f->close_section(); + } // dump + }; + +} // namespace ceph diff --git a/ceph/src/compressor/zlib/CMakeLists.txt b/ceph/src/compressor/zlib/CMakeLists.txt index 635c730b5..1b3bc259a 100644 --- a/ceph/src/compressor/zlib/CMakeLists.txt +++ b/ceph/src/compressor/zlib/CMakeLists.txt @@ -4,21 +4,31 @@ if(HAVE_INTEL_SSE4_1 AND HAVE_BETTER_YASM_ELF64) set(zlib_sources CompressionPluginZlib.cc ZlibCompressor.cc - ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip.c + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/crc32_gzip.asm + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/crc32_gzip_base.c + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/detect_repeated_char.asm + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/encode_df.c + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/encode_df_04.asm + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/flatten_ll.c + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/huff_codes.c ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/hufftables_c.c - ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/crc_utils_01.asm - ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/crc_utils_04.asm + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip.c + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip.c + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_base.c ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_body_01.asm + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_body_02.asm ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_body_04.asm ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_finish.asm - ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_stateless_01.asm - ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_stateless_04.asm - ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/crc_data.asm - ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/crc32_gzip.asm - ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/detect_repeated_char.asm + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_icf_base.c + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_icf_body_01.asm + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_icf_body_02.asm + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_icf_body_04.asm + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_icf_finish.asm ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_multibinary.asm - ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_stateless_base.c - ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_base.c + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_update_histogram_01.asm + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_update_histogram_04.asm + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/proc_heap.asm + ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/rfc1951_lookup.asm ) else(HAVE_INTEL_SSE4_1 AND HAVE_BETTER_YASM_ELF64) set(zlib_sources diff --git a/ceph/src/compressor/zlib/CompressionPluginZlib.h b/ceph/src/compressor/zlib/CompressionPluginZlib.h index 0aa641f8b..4515f2bba 100644 --- a/ceph/src/compressor/zlib/CompressionPluginZlib.h +++ b/ceph/src/compressor/zlib/CompressionPluginZlib.h @@ -44,7 +44,7 @@ public: } #endif if (compressor == 0 || has_isal != isal) { - compressor = std::make_shared(isal); + compressor = std::make_shared(cct, isal); has_isal = isal; } *cs = compressor; diff --git a/ceph/src/compressor/zlib/ZlibCompressor.cc b/ceph/src/compressor/zlib/ZlibCompressor.cc index beb2f195d..492e6328d 100644 --- a/ceph/src/compressor/zlib/ZlibCompressor.cc +++ b/ceph/src/compressor/zlib/ZlibCompressor.cc @@ -22,7 +22,7 @@ #include // ----------------------------------------------------------------------------- -#define dout_context g_ceph_context +#define dout_context cct #define dout_subsys ceph_subsys_compressor #undef dout_prefix #define dout_prefix _prefix(_dout) @@ -59,7 +59,7 @@ int ZlibCompressor::zlib_compress(const bufferlist &in, bufferlist &out) strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; - ret = deflateInit2(&strm, g_conf->compressor_zlib_level, Z_DEFLATED, ZLIB_DEFAULT_WIN_SIZE, ZLIB_MEMORY_LEVEL, Z_DEFAULT_STRATEGY); + ret = deflateInit2(&strm, cct->_conf->compressor_zlib_level, Z_DEFLATED, ZLIB_DEFAULT_WIN_SIZE, ZLIB_MEMORY_LEVEL, Z_DEFAULT_STRATEGY); if (ret != Z_OK) { dout(1) << "Compression init error: init return " << ret << " instead of Z_OK" << dendl; diff --git a/ceph/src/compressor/zlib/ZlibCompressor.h b/ceph/src/compressor/zlib/ZlibCompressor.h index 35f9df3ef..198450dc0 100644 --- a/ceph/src/compressor/zlib/ZlibCompressor.h +++ b/ceph/src/compressor/zlib/ZlibCompressor.h @@ -21,8 +21,10 @@ class ZlibCompressor : public Compressor { bool isal_enabled; + CephContext *const cct; public: - ZlibCompressor(bool isal) : Compressor(COMP_ALG_ZLIB, "zlib"), isal_enabled(isal) {} + ZlibCompressor(CephContext *cct, bool isal) + : Compressor(COMP_ALG_ZLIB, "zlib"), isal_enabled(isal), cct(cct) {} int compress(const bufferlist &in, bufferlist &out) override; int decompress(const bufferlist &in, bufferlist &out) override; diff --git a/ceph/src/crush/CrushCompiler.cc b/ceph/src/crush/CrushCompiler.cc index a6b624566..e01d089ac 100644 --- a/ceph/src/crush/CrushCompiler.cc +++ b/ceph/src/crush/CrushCompiler.cc @@ -232,7 +232,7 @@ int CrushCompiler::decompile_weight_set(crush_weight_set *weight_set, return 0; } -int CrushCompiler::decompile_ids(int *ids, +int CrushCompiler::decompile_ids(__s32 *ids, __u32 size, ostream &out) { @@ -972,7 +972,7 @@ int CrushCompiler::parse_choose_arg_ids(iter_t const& i, int bucket_id, crush_ch return -1; } arg->ids_size = size; - arg->ids = (int *)calloc(arg->ids_size, sizeof(int)); + arg->ids = (__s32 *)calloc(arg->ids_size, sizeof(__s32)); __u32 pos = 0; for (iter_t p = i->children.begin() + 2; pos < size; p++, pos++) arg->ids[pos] = int_node(*p); diff --git a/ceph/src/crush/CrushLocation.h b/ceph/src/crush/CrushLocation.h index b3241eff3..bba737eca 100644 --- a/ceph/src/crush/CrushLocation.h +++ b/ceph/src/crush/CrushLocation.h @@ -19,7 +19,7 @@ class CrushLocation { public: CrushLocation(CephContext *c) : cct(c) { - update_from_conf(); + init_on_startup(); } int update_from_conf(); ///< refresh from config diff --git a/ceph/src/crush/CrushTester.cc b/ceph/src/crush/CrushTester.cc index ef83e7311..ac58c882f 100644 --- a/ceph/src/crush/CrushTester.cc +++ b/ceph/src/crush/CrushTester.cc @@ -19,6 +19,7 @@ #include #include #include "common/SubProcess.h" +#include "common/fork_function.h" void CrushTester::set_device_weight(int dev, float f) { @@ -359,47 +360,16 @@ void CrushTester::write_integer_indexed_scalar_data_string(vector &dst, dst.push_back( data_buffer.str() ); } -int CrushTester::test_with_crushtool(const char *crushtool_cmd, - int max_id, int timeout, - int ruleset) +int CrushTester::test_with_fork(int timeout) { - SubProcessTimed crushtool(crushtool_cmd, SubProcess::PIPE, SubProcess::CLOSE, SubProcess::PIPE, timeout); - string opt_max_id = boost::lexical_cast(max_id); - crushtool.add_cmd_args( - "-i", "-", - "--test", "--check", opt_max_id.c_str(), - "--min-x", "1", - "--max-x", "50", - NULL); - if (ruleset >= 0) { - crushtool.add_cmd_args( - "--ruleset", - stringify(ruleset).c_str(), - NULL); + ostringstream sink; + int r = fork_function(timeout, sink, [&]() { + return test(); + }); + if (r == -ETIMEDOUT) { + err << "timed out during smoke test (" << timeout << " seconds)"; } - int ret = crushtool.spawn(); - if (ret != 0) { - err << "failed run crushtool: " << crushtool.err(); - return ret; - } - - bufferlist bl; - ::encode(crush, bl, CEPH_FEATURES_SUPPORTED_DEFAULT); - bl.write_fd(crushtool.get_stdin()); - crushtool.close_stdin(); - bl.clear(); - ret = bl.read_fd(crushtool.get_stderr(), 100 * 1024); - if (ret < 0) { - err << "failed read from crushtool: " << cpp_strerror(-ret); - return ret; - } - bl.write_stream(err); - if (crushtool.join() != 0) { - err << crushtool.err(); - return -EINVAL; - } - - return 0; + return r; } namespace { diff --git a/ceph/src/crush/CrushTester.h b/ceph/src/crush/CrushTester.h index b3c3b70c3..e58c24875 100644 --- a/ceph/src/crush/CrushTester.h +++ b/ceph/src/crush/CrushTester.h @@ -358,10 +358,7 @@ public: */ void check_overlapped_rules() const; int test(); - int test_with_crushtool(const char *crushtool_cmd = "crushtool", - int max_id = -1, - int timeout = 0, - int ruleset = -1); + int test_with_fork(int timeout); }; #endif diff --git a/ceph/src/crush/CrushTreeDumper.h b/ceph/src/crush/CrushTreeDumper.h index 40691c697..ca5a93fce 100644 --- a/ceph/src/crush/CrushTreeDumper.h +++ b/ceph/src/crush/CrushTreeDumper.h @@ -64,7 +64,7 @@ namespace CrushTreeDumper { class Dumper : public list { public: explicit Dumper(const CrushWrapper *crush_) : crush(crush_) { - crush->find_roots(roots); + crush->find_nonshadow_roots(roots); root = roots.begin(); } @@ -150,6 +150,10 @@ namespace CrushTreeDumper { inline void dump_item_fields(const CrushWrapper *crush, const Item &qi, Formatter *f) { f->dump_int("id", qi.id); + const char *c = crush->get_item_class(qi.id); + if (!c) + c = ""; + f->dump_string("device_class", c); if (qi.is_bucket()) { int type = crush->get_bucket_type(qi.id); f->dump_string("name", crush->get_item_name(qi.id)); diff --git a/ceph/src/crush/CrushWrapper.cc b/ceph/src/crush/CrushWrapper.cc index 3a669e959..e6f221944 100644 --- a/ceph/src/crush/CrushWrapper.cc +++ b/ceph/src/crush/CrushWrapper.cc @@ -300,6 +300,21 @@ void CrushWrapper::find_roots(set& roots) const } } +void CrushWrapper::find_nonshadow_roots(set& roots) const +{ + for (int i = 0; i < crush->max_buckets; i++) { + if (!crush->buckets[i]) + continue; + crush_bucket *b = crush->buckets[i]; + if (_search_item_exists(b->id)) + continue; + const char *name = get_item_name(b->id); + if (name && !is_valid_crush_name(name)) + continue; + roots.insert(b->id); + } +} + bool CrushWrapper::subtree_contains(int root, int item) const { if (root == item) @@ -335,11 +350,13 @@ bool CrushWrapper::_maybe_remove_last_instance(CephContext *cct, int item, bool crush_remove_bucket(crush, t); if (class_bucket.count(item) != 0) class_bucket.erase(item); + class_remove_item(item); } if ((item >= 0 || !unlink_only) && name_map.count(item)) { ldout(cct, 5) << "_maybe_remove_last_instance removing name for item " << item << dendl; name_map.erase(item); have_rmaps = false; + class_remove_item(item); } return true; } @@ -807,6 +824,11 @@ int CrushWrapper::insert_item(CephContext *cct, int item, float weight, string n if (!is_valid_crush_loc(cct, loc)) return -EINVAL; + int r = validate_weightf(weight); + if (r < 0) { + return r; + } + if (name_exists(name)) { if (get_item_id(name) != item) { ldout(cct, 10) << "device name '" << name << "' already exists as id " @@ -1021,6 +1043,11 @@ int CrushWrapper::update_item(CephContext *cct, int item, float weight, string n if (!is_valid_crush_loc(cct, loc)) return -EINVAL; + ret = validate_weightf(weight); + if (ret < 0) { + return ret; + } + // compare quantized (fixed-point integer) weights! int iweight = (int)(weight * (float)0x10000); int old_iweight; @@ -1184,6 +1211,9 @@ pair CrushWrapper::get_immediate_parent(int id, int *_ret) crush_bucket *b = crush->buckets[bidx]; if (b == 0) continue; + const char *n = get_item_name(b->id); + if (n && !is_valid_crush_name(n)) + continue; for (unsigned i = 0; i < b->size; i++) if (b->items[i] == id) { string parent_id = name_map[b->id]; @@ -1206,6 +1236,9 @@ int CrushWrapper::get_immediate_parent_id(int id, int *parent) const crush_bucket *b = crush->buckets[bidx]; if (b == 0) continue; + const char *n = get_item_name(b->id); + if (n && !is_valid_crush_name(n)) + continue; for (unsigned i = 0; i < b->size; i++) { if (b->items[i] == id) { *parent = b->id; @@ -1283,6 +1316,32 @@ int CrushWrapper::trim_roots_with_class(bool unused) return 0; } +int32_t CrushWrapper::_alloc_class_id() const { + if (class_name.empty()) { + return 0; + } + int32_t class_id = class_name.rbegin()->first + 1; + if (class_id >= 0) { + return class_id; + } + // wrapped, pick a random start and do exhaustive search + uint32_t upperlimit = numeric_limits::max(); + upperlimit++; + class_id = rand() % upperlimit; + const auto start = class_id; + do { + if (!class_name.count(class_id)) { + return class_id; + } else { + class_id++; + if (class_id < 0) { + class_id = 0; + } + } + } while (class_id != start); + assert(0 == "no available class id"); +} + void CrushWrapper::reweight(CephContext *cct) { set roots; @@ -1300,8 +1359,10 @@ void CrushWrapper::reweight(CephContext *cct) int CrushWrapper::add_simple_rule_at( string name, string root_name, string failure_domain_name, + string device_class, string mode, int rule_type, - int rno, ostream *err) + int rno, + ostream *err) { if (rule_exists(name)) { if (err) @@ -1340,6 +1401,22 @@ int CrushWrapper::add_simple_rule_at( return -EINVAL; } } + if (device_class.size()) { + if (!class_exists(device_class)) { + if (err) + *err << "device class " << device_class << " does not exist"; + return -EINVAL; + } + int c = get_class_id(device_class); + if (class_bucket.count(root) == 0 || + class_bucket[root].count(c) == 0) { + if (err) + *err << "root " << root_name << " has no devices with class " + << device_class; + return -EINVAL; + } + root = class_bucket[root][c]; + } if (mode != "firstn" && mode != "indep") { if (err) *err << "unknown mode " << mode; @@ -1387,10 +1464,12 @@ int CrushWrapper::add_simple_rule_at( int CrushWrapper::add_simple_rule( string name, string root_name, string failure_domain_name, + string device_class, string mode, int rule_type, ostream *err) { - return add_simple_rule_at(name, root_name, failure_domain_name, mode, + return add_simple_rule_at(name, root_name, failure_domain_name, device_class, + mode, rule_type, -1, err); } @@ -1498,7 +1577,7 @@ int CrushWrapper::bucket_add_item(crush_bucket *bucket, int item, int weight) weight_set->size = new_size; } if (arg->ids_size) { - arg->ids = (int*)realloc(arg->ids, new_size * sizeof(int)); + arg->ids = (__s32 *)realloc(arg->ids, new_size * sizeof(__s32)); assert(arg->ids_size + 1 == new_size); arg->ids[arg->ids_size] = item; arg->ids_size = new_size; @@ -1530,28 +1609,27 @@ int CrushWrapper::bucket_remove_item(crush_bucket *bucket, int item) assert(arg->ids_size - 1 == new_size); for (__u32 k = position; k < new_size; k++) arg->ids[k] = arg->ids[k+1]; - arg->ids = (int*)realloc(arg->ids, new_size * sizeof(int)); + arg->ids = (__s32 *)realloc(arg->ids, new_size * sizeof(__s32)); arg->ids_size = new_size; } } return crush_bucket_remove_item(crush, bucket, item); } -int CrushWrapper::update_device_class(CephContext *cct, int id, const string& class_name, const string& name) +int CrushWrapper::update_device_class(int id, + const string& class_name, + const string& name, + ostream *ss) { - int class_id = get_class_id(class_name); - if (class_id < 0) { - ldout(cct, 0) << "update_device_class class " << class_name << " does not exist " << dendl; - return -ENOENT; - } + int class_id = get_or_create_class_id(class_name); if (id < 0) { - ldout(cct, 0) << "update_device_class " << name << " id " << id << " is negative " << dendl; + *ss << name << " id " << id << " is negative"; return -EINVAL; } assert(item_exists(id)); if (class_map.count(id) != 0 && class_map[id] == class_id) { - ldout(cct, 5) << "update_device_class " << name << " already set to class " << class_name << dendl; + *ss << name << " already set to class " << class_name; return 0; } @@ -1577,7 +1655,7 @@ int CrushWrapper::device_class_clone(int original_id, int device_class, int *clo return 0; } crush_bucket *original = get_bucket(original_id); - if (original == NULL) + if (IS_ERR(original)) return -ENOENT; crush_bucket *copy = crush_make_bucket(crush, original->alg, @@ -1753,11 +1831,12 @@ void CrushWrapper::encode(bufferlist& bl, uint64_t features) const ::encode(class_name, bl); ::encode(class_bucket, bl); - ::encode(choose_args.size(), bl); + __u32 size = (__u32)choose_args.size(); + ::encode(size, bl); for (auto c : choose_args) { ::encode(c.first, bl); crush_choose_arg_map arg_map = c.second; - __u32 size = 0; + size = 0; for (__u32 i = 0; i < arg_map.size; i++) { crush_choose_arg *arg = &arg_map.args[i]; if (arg->weight_set_size == 0 && @@ -1886,9 +1965,9 @@ void CrushWrapper::decode(bufferlist::iterator& blp) cleanup_classes(); } if (!blp.end()) { - size_t choose_args_size; + __u32 choose_args_size; ::decode(choose_args_size, blp); - for (size_t i = 0; i < choose_args_size; i++) { + for (__u32 i = 0; i < choose_args_size; i++) { uint64_t choose_args_index; ::decode(choose_args_index, blp); crush_choose_arg_map arg_map; @@ -1911,7 +1990,7 @@ void CrushWrapper::decode(bufferlist::iterator& blp) ::decode(weight_set->weights[l], blp); } ::decode(arg->ids_size, blp); - arg->ids = (int*)calloc(arg->ids_size, sizeof(int)); + arg->ids = (__s32 *)calloc(arg->ids_size, sizeof(__s32)); for (__u32 k = 0; k < arg->ids_size; k++) ::decode(arg->ids[k], blp); } diff --git a/ceph/src/crush/CrushWrapper.h b/ceph/src/crush/CrushWrapper.h index fce35ce79..5fd35a88a 100644 --- a/ceph/src/crush/CrushWrapper.h +++ b/ceph/src/crush/CrushWrapper.h @@ -442,34 +442,52 @@ public: return class_rname.count(name); } const char *get_class_name(int i) const { - std::map::const_iterator p = class_name.find(i); + auto p = class_name.find(i); if (p != class_name.end()) return p->second.c_str(); return 0; } int get_class_id(const string& name) const { - std::map::const_iterator p = class_rname.find(name); + auto p = class_rname.find(name); if (p != class_rname.end()) return p->second; else return -EINVAL; } int remove_class_name(const string& name) { - std::map::const_iterator p = class_rname.find(name); + auto p = class_rname.find(name); if (p == class_rname.end()) return -ENOENT; int class_id = p->second; - std::map::const_iterator q = class_name.find(class_id); + auto q = class_name.find(class_id); if (q == class_name.end()) return -ENOENT; class_rname.erase(name); class_name.erase(class_id); return 0; } + + int rename_class(const string& srcname, const string& dstname) { + auto p = class_rname.find(srcname); + if (p == class_rname.end()) + return -ENOENT; + int class_id = p->second; + auto q = class_name.find(class_id); + if (q == class_name.end()) + return -ENOENT; + class_rname.erase(srcname); + class_name.erase(class_id); + class_rname[dstname] = class_id; + class_name[class_id] = dstname; + return 0; + } + + int32_t _alloc_class_id() const; + int get_or_create_class_id(const string& name) { int c = get_class_id(name); if (c < 0) { - int i = class_name.size(); + int i = _alloc_class_id(); class_name[i] = name; class_rname[name] = i; return i; @@ -494,7 +512,26 @@ public: class_map[i] = c; return c; } - + void get_devices_by_class(const string &name, set *devices) const { + assert(devices); + devices->clear(); + if (!class_exists(name)) { + return; + } + auto cid = get_class_id(name); + for (auto& p : class_map) { + if (p.first >= 0 && p.second == cid) { + devices->insert(p.first); + } + } + } + void class_remove_item(int i) { + auto it = class_map.find(i); + if (it == class_map.end()) { + return; + } + class_map.erase(it); + } int can_rename_item(const string& srcname, const string& dstname, ostream *ss) const; @@ -546,6 +583,14 @@ public: */ void find_roots(set& roots) const; + /** + * find tree roots that are not shadow (device class) items + * + * These are parentless nodes in the map that are not shadow + * items for device classes. + */ + void find_nonshadow_roots(set& roots) const; + /** * see if an item is contained within a subtree * @@ -833,18 +878,37 @@ public: return (float)get_item_weight_in_loc(id, loc) / (float)0x10000; } + int validate_weightf(float weight) { + uint64_t iweight = weight * 0x10000; + if (iweight > std::numeric_limits::max()) { + return -EOVERFLOW; + } + return 0; + } int adjust_item_weight(CephContext *cct, int id, int weight); int adjust_item_weightf(CephContext *cct, int id, float weight) { + int r = validate_weightf(weight); + if (r < 0) { + return r; + } return adjust_item_weight(cct, id, (int)(weight * (float)0x10000)); } int adjust_item_weight_in_loc(CephContext *cct, int id, int weight, const map& loc); int adjust_item_weightf_in_loc(CephContext *cct, int id, float weight, const map& loc) { + int r = validate_weightf(weight); + if (r < 0) { + return r; + } return adjust_item_weight_in_loc(cct, id, (int)(weight * (float)0x10000), loc); } void reweight(CephContext *cct); int adjust_subtree_weight(CephContext *cct, int id, int weight); int adjust_subtree_weightf(CephContext *cct, int id, float weight) { + int r = validate_weightf(weight); + if (r < 0) { + return r; + } return adjust_subtree_weight(cct, id, (int)(weight * (float)0x10000)); } @@ -999,6 +1063,7 @@ public: int add_simple_rule( string name, string root_name, string failure_domain_type, + string device_class, string mode, int rule_type, ostream *err = 0); /** @@ -1006,7 +1071,7 @@ public: */ int add_simple_rule_at( string name, string root_name, - string failure_domain_type, string mode, + string failure_domain_type, string device_class, string mode, int rule_type, int rno, ostream *err = 0); int remove_rule(int ruleno); @@ -1175,7 +1240,7 @@ public: have_uniform_rules = !has_legacy_rulesets(); } - int update_device_class(CephContext *cct, int id, const string& class_name, const string& name); + int update_device_class(int id, const string& class_name, const string& name, ostream *ss); int device_class_clone(int original, int device_class, int *clone); bool class_is_in_use(int class_id); int populate_classes(); diff --git a/ceph/src/crush/builder.c b/ceph/src/crush/builder.c index dc342d28a..3b4ba25b2 100644 --- a/ceph/src/crush/builder.c +++ b/ceph/src/crush/builder.c @@ -1413,13 +1413,13 @@ struct crush_choose_arg *crush_make_choose_args(struct crush_map *map, int num_p int size = (sizeof(struct crush_choose_arg) * map->max_buckets + sizeof(struct crush_weight_set) * bucket_count * num_positions + sizeof(__u32) * sum_bucket_size * num_positions + // weights - sizeof(__u32) * sum_bucket_size); // ids + sizeof(__s32) * sum_bucket_size); // ids char *space = malloc(size); struct crush_choose_arg *arg = (struct crush_choose_arg *)space; struct crush_weight_set *weight_set = (struct crush_weight_set *)(arg + map->max_buckets); __u32 *weights = (__u32 *)(weight_set + bucket_count * num_positions); char *weight_set_ends = (char*)weights; - int *ids = (int *)(weights + sum_bucket_size * num_positions); + __s32 *ids = (__s32 *)(weights + sum_bucket_size * num_positions); char *weights_end = (char *)ids; char *ids_end = (char *)(ids + sum_bucket_size); BUG_ON(space + size != ids_end); @@ -1442,7 +1442,7 @@ struct crush_choose_arg *crush_make_choose_args(struct crush_map *map, int num_p arg[b].weight_set_size = num_positions; weight_set += position; - memcpy(ids, bucket->h.items, sizeof(int) * bucket->h.size); + memcpy(ids, bucket->h.items, sizeof(__s32) * bucket->h.size); arg[b].ids = ids; arg[b].ids_size = bucket->h.size; ids += bucket->h.size; diff --git a/ceph/src/crush/crush.h b/ceph/src/crush/crush.h index 31fb94def..e5bdba2d7 100644 --- a/ceph/src/crush/crush.h +++ b/ceph/src/crush/crush.h @@ -143,7 +143,7 @@ enum crush_algorithm { * can contain items with arbitrary weights. To place a * replica, CRUSH begins at the head of the list with the most * recently added item and compares its weight to the sum of - * all remaining items’ weights. Depending on the value of + * all remaining items' weights. Depending on the value of * hash( x , r , item), either the current item is chosen with * the appropriate probability, or the process continues * recursively down the list. This is a natural and intuitive @@ -174,13 +174,13 @@ enum crush_algorithm { * change due an addition, removal, or re-weighting of an * item. * - * The straw2 bucket type allows all items to fairly “compete” + * The straw2 bucket type allows all items to fairly "compete" * against each other for replica placement through a process * analogous to a draw of straws. To place a replica, a straw * of random length is drawn for each item in the bucket. The * item with the longest straw wins. The length of each straw * is initially a value in a fixed range. Each straw length - * is scaled by a factor based on the item’s weight so that + * is scaled by a factor based on the item's weight so that * heavily weighted items are more likely to win the draw. * Although this process is almost twice as slow (on average) * than a list bucket and even slower than a tree bucket @@ -271,7 +271,7 @@ struct crush_weight_set { * */ struct crush_choose_arg { - int *ids; /*!< values to use instead of items */ + __s32 *ids; /*!< values to use instead of items */ __u32 ids_size; /*!< size of the __ids__ array */ struct crush_weight_set *weight_set; /*!< weight replacements for a given position */ __u32 weight_set_size; /*!< size of the __weight_set__ array */ diff --git a/ceph/src/crush/mapper.c b/ceph/src/crush/mapper.c index 321e7a7d5..8ea91897d 100644 --- a/ceph/src/crush/mapper.c +++ b/ceph/src/crush/mapper.c @@ -312,8 +312,8 @@ static inline __u32 *get_choose_arg_weights(const struct crush_bucket_straw2 *bu return arg->weight_set[position].weights; } -static inline int *get_choose_arg_ids(const struct crush_bucket_straw2 *bucket, - const struct crush_choose_arg *arg) +static inline __s32 *get_choose_arg_ids(const struct crush_bucket_straw2 *bucket, + const struct crush_choose_arg *arg) { if ((arg == NULL) || (arg->ids == NULL)) return bucket->h.items; @@ -328,7 +328,7 @@ static int bucket_straw2_choose(const struct crush_bucket_straw2 *bucket, unsigned int u; __s64 ln, draw, high_draw = 0; __u32 *weights = get_choose_arg_weights(bucket, arg, position); - int *ids = get_choose_arg_ids(bucket, arg); + __s32 *ids = get_choose_arg_ids(bucket, arg); for (i = 0; i < bucket->h.size; i++) { dprintk("weight 0x%x item %d\n", weights[i], ids[i]); if (weights[i]) { diff --git a/ceph/src/erasure-code/ErasureCode.cc b/ceph/src/erasure-code/ErasureCode.cc index 353ab4f0d..c37adedb6 100644 --- a/ceph/src/erasure-code/ErasureCode.cc +++ b/ceph/src/erasure-code/ErasureCode.cc @@ -22,11 +22,57 @@ #include "common/strtol.h" #include "include/buffer.h" +#include "crush/CrushWrapper.h" +#include "osd/osd_types.h" using namespace std; const unsigned ErasureCode::SIMD_ALIGN = 32; +#define DEFAULT_RULE_ROOT "default" +#define DEFAULT_RULE_FAILURE_DOMAIN "host" + +int ErasureCode::init( + ErasureCodeProfile &profile, + std::ostream *ss) +{ + int err = 0; + err |= to_string("crush-root", profile, + &rule_root, + DEFAULT_RULE_ROOT, ss); + err |= to_string("crush-failure-domain", profile, + &rule_failure_domain, + DEFAULT_RULE_FAILURE_DOMAIN, ss); + err |= to_string("crush-device-class", profile, + &rule_device_class, + "", ss); + if (err) + return err; + _profile = profile; + return 0; +} + +int ErasureCode::create_rule( + const std::string &name, + CrushWrapper &crush, + std::ostream *ss) const +{ + int ruleid = crush.add_simple_rule( + name, + rule_root, + rule_failure_domain, + rule_device_class, + "indep", + pg_pool_t::TYPE_ERASURE, + ss); + + if (ruleid < 0) + return ruleid; + + crush.set_rule_mask_max_size(ruleid, get_chunk_count()); + return ruleid; +} + int ErasureCode::sanity_check_k(int k, ostream *ss) { if (k < 2) { diff --git a/ceph/src/erasure-code/ErasureCode.h b/ceph/src/erasure-code/ErasureCode.h index e544b022a..fc79cf03a 100644 --- a/ceph/src/erasure-code/ErasureCode.h +++ b/ceph/src/erasure-code/ErasureCode.h @@ -33,17 +33,23 @@ namespace ceph { std::vector chunk_mapping; ErasureCodeProfile _profile; + // for CRUSH rule + std::string rule_root; + std::string rule_failure_domain; + std::string rule_device_class; + ~ErasureCode() override {} - int init(ErasureCodeProfile &profile, std::ostream *ss) override { - _profile = profile; - return 0; - } + int init(ErasureCodeProfile &profile, std::ostream *ss) override; const ErasureCodeProfile &get_profile() const override { return _profile; } + int create_rule(const std::string &name, + CrushWrapper &crush, + std::ostream *ss) const; + int sanity_check_k(int k, std::ostream *ss); unsigned int get_coding_chunk_count() const override { diff --git a/ceph/src/erasure-code/ErasureCodeInterface.h b/ceph/src/erasure-code/ErasureCodeInterface.h index fbe9eea27..2159ae1ce 100644 --- a/ceph/src/erasure-code/ErasureCodeInterface.h +++ b/ceph/src/erasure-code/ErasureCodeInterface.h @@ -196,22 +196,22 @@ namespace ceph { virtual const ErasureCodeProfile &get_profile() const = 0; /** - * Create a new ruleset in **crush** under the name **name**, + * Create a new rule in **crush** under the name **name**, * unless it already exists. * - * Return the ruleset number that was created on success. If a - * ruleset **name** already exists, return -EEXISTS, otherwise + * Return the rule number that was created on success. If a + * rule **name** already exists, return -EEXISTS, otherwise * return a negative value indicating an error with a semantic * defined by the implementation. * - * @param [in] name of the ruleset to create - * @param [in] crush crushmap in which the ruleset is created + * @param [in] name of the rule to create + * @param [in] crush crushmap in which the rule is created * @param [out] ss contains informative messages when an error occurs - * @return a ruleset on success or a negative errno on error. + * @return a rule on success or a negative errno on error. */ - virtual int create_ruleset(const std::string &name, - CrushWrapper &crush, - std::ostream *ss) const = 0; + virtual int create_rule(const std::string &name, + CrushWrapper &crush, + std::ostream *ss) const = 0; /** * Return the number of chunks created by a call to the **encode** diff --git a/ceph/src/erasure-code/isa/CMakeLists.txt b/ceph/src/erasure-code/isa/CMakeLists.txt index c205e367c..e0a511e0a 100644 --- a/ceph/src/erasure-code/isa/CMakeLists.txt +++ b/ceph/src/erasure-code/isa/CMakeLists.txt @@ -64,8 +64,6 @@ add_library(ec_isa SHARED add_dependencies(ec_isa ${CMAKE_SOURCE_DIR}/src/ceph_ver.h) target_link_libraries(ec_isa ${EXTRALIBS}) set_target_properties(ec_isa PROPERTIES - VERSION 2.16.0 - SOVERSION 2 INSTALL_RPATH "") install(TARGETS ec_isa DESTINATION ${erasure_plugin_dir}) diff --git a/ceph/src/erasure-code/isa/ErasureCodeIsa.cc b/ceph/src/erasure-code/isa/ErasureCodeIsa.cc index 4a6841abd..46c8e8301 100644 --- a/ceph/src/erasure-code/isa/ErasureCodeIsa.cc +++ b/ceph/src/erasure-code/isa/ErasureCodeIsa.cc @@ -19,8 +19,7 @@ #include "common/debug.h" #include "ErasureCodeIsa.h" #include "xor_op.h" -#include "crush/CrushWrapper.h" -#include "osd/osd_types.h" +#include "include/assert.h" using namespace std; // ----------------------------------------------------------------------------- @@ -46,26 +45,6 @@ _prefix(std::ostream* _dout) const std::string ErasureCodeIsaDefault::DEFAULT_K("7"); const std::string ErasureCodeIsaDefault::DEFAULT_M("3"); -int -ErasureCodeIsa::create_ruleset(const string &name, - CrushWrapper &crush, - ostream *ss) const -{ - int ruleid = crush.add_simple_rule( - name, - ruleset_root, - ruleset_failure_domain, - "indep", - pg_pool_t::TYPE_ERASURE, - ss); - - if (ruleid < 0) - return ruleid; - else { - crush.set_rule_mask_max_size(ruleid, get_chunk_count()); - return crush.get_rule_mask_ruleset(ruleid); - } -} // ----------------------------------------------------------------------------- @@ -73,18 +52,11 @@ int ErasureCodeIsa::init(ErasureCodeProfile &profile, ostream *ss) { int err = 0; - err |= to_string("ruleset-root", profile, - &ruleset_root, - DEFAULT_RULESET_ROOT, ss); - err |= to_string("ruleset-failure-domain", profile, - &ruleset_failure_domain, - DEFAULT_RULESET_FAILURE_DOMAIN, ss); err |= parse(profile, ss); if (err) return err; prepare(); - ErasureCode::init(profile, ss); - return err; + return ErasureCode::init(profile, ss); } // ----------------------------------------------------------------------------- diff --git a/ceph/src/erasure-code/isa/ErasureCodeIsa.h b/ceph/src/erasure-code/isa/ErasureCodeIsa.h index ccf8d8437..d67b918f7 100644 --- a/ceph/src/erasure-code/isa/ErasureCodeIsa.h +++ b/ceph/src/erasure-code/isa/ErasureCodeIsa.h @@ -30,9 +30,6 @@ #include "ErasureCodeIsaTableCache.h" // ----------------------------------------------------------------------------- -#define DEFAULT_RULESET_ROOT "default" -#define DEFAULT_RULESET_FAILURE_DOMAIN "host" - class ErasureCodeIsa : public ErasureCode { public: @@ -46,8 +43,6 @@ public: ErasureCodeIsaTableCache &tcache; const char *technique; - std::string ruleset_root; - std::string ruleset_failure_domain; ErasureCodeIsa(const char *_technique, ErasureCodeIsaTableCache &_tcache) : @@ -55,9 +50,7 @@ public: m(0), w(0), tcache(_tcache), - technique(_technique), - ruleset_root(DEFAULT_RULESET_ROOT), - ruleset_failure_domain(DEFAULT_RULESET_FAILURE_DOMAIN) + technique(_technique) { } @@ -66,10 +59,6 @@ public: { } - int create_ruleset(const std::string &name, - CrushWrapper &crush, - std::ostream *ss) const override; - unsigned int get_chunk_count() const override { diff --git a/ceph/src/erasure-code/jerasure/ErasureCodeJerasure.cc b/ceph/src/erasure-code/jerasure/ErasureCodeJerasure.cc index ca1b09649..599073eb3 100644 --- a/ceph/src/erasure-code/jerasure/ErasureCodeJerasure.cc +++ b/ceph/src/erasure-code/jerasure/ErasureCodeJerasure.cc @@ -17,8 +17,6 @@ #include "common/debug.h" #include "ErasureCodeJerasure.h" -#include "crush/CrushWrapper.h" -#include "osd/osd_types.h" using namespace std; @@ -42,38 +40,17 @@ static ostream& _prefix(std::ostream* _dout) return *_dout << "ErasureCodeJerasure: "; } -int ErasureCodeJerasure::create_ruleset(const string &name, - CrushWrapper &crush, - ostream *ss) const -{ - int ruleid = crush.add_simple_rule( - name, ruleset_root, ruleset_failure_domain, - "indep", pg_pool_t::TYPE_ERASURE, ss); - if (ruleid < 0) - return ruleid; - else { - crush.set_rule_mask_max_size(ruleid, get_chunk_count()); - return crush.get_rule_mask_ruleset(ruleid); - } -} int ErasureCodeJerasure::init(ErasureCodeProfile& profile, ostream *ss) { int err = 0; dout(10) << "technique=" << technique << dendl; profile["technique"] = technique; - err |= to_string("ruleset-root", profile, - &ruleset_root, - DEFAULT_RULESET_ROOT, ss); - err |= to_string("ruleset-failure-domain", profile, - &ruleset_failure_domain, - DEFAULT_RULESET_FAILURE_DOMAIN, ss); err |= parse(profile, ss); if (err) return err; prepare(); - ErasureCode::init(profile, ss); - return err; + return ErasureCode::init(profile, ss); } int ErasureCodeJerasure::parse(ErasureCodeProfile &profile, diff --git a/ceph/src/erasure-code/jerasure/ErasureCodeJerasure.h b/ceph/src/erasure-code/jerasure/ErasureCodeJerasure.h index 5696c6e90..be9abc561 100644 --- a/ceph/src/erasure-code/jerasure/ErasureCodeJerasure.h +++ b/ceph/src/erasure-code/jerasure/ErasureCodeJerasure.h @@ -20,9 +20,6 @@ #include "erasure-code/ErasureCode.h" -#define DEFAULT_RULESET_ROOT "default" -#define DEFAULT_RULESET_FAILURE_DOMAIN "host" - class ErasureCodeJerasure : public ErasureCode { public: int k; @@ -32,8 +29,8 @@ public: int w; std::string DEFAULT_W; const char *technique; - std::string ruleset_root; - std::string ruleset_failure_domain; + std::string rule_root; + std::string rule_failure_domain; bool per_chunk_alignment; explicit ErasureCodeJerasure(const char *_technique) : @@ -44,17 +41,11 @@ public: w(0), DEFAULT_W("8"), technique(_technique), - ruleset_root(DEFAULT_RULESET_ROOT), - ruleset_failure_domain(DEFAULT_RULESET_FAILURE_DOMAIN), per_chunk_alignment(false) {} ~ErasureCodeJerasure() override {} - int create_ruleset(const std::string &name, - CrushWrapper &crush, - std::ostream *ss) const override; - unsigned int get_chunk_count() const override { return k + m; } diff --git a/ceph/src/erasure-code/lrc/ErasureCodeLrc.cc b/ceph/src/erasure-code/lrc/ErasureCodeLrc.cc index 52dc2d879..05cd6ed75 100644 --- a/ceph/src/erasure-code/lrc/ErasureCodeLrc.cc +++ b/ceph/src/erasure-code/lrc/ErasureCodeLrc.cc @@ -43,7 +43,7 @@ static ostream& _prefix(std::ostream* _dout) return *_dout << "ErasureCodeLrc: "; } -int ErasureCodeLrc::create_ruleset(const string &name, +int ErasureCodeLrc::create_rule(const string &name, CrushWrapper &crush, ostream *ss) const { @@ -51,25 +51,39 @@ int ErasureCodeLrc::create_ruleset(const string &name, *ss << "rule " << name << " exists"; return -EEXIST; } - if (!crush.name_exists(ruleset_root)) { - *ss << "root item " << ruleset_root << " does not exist"; + if (!crush.name_exists(rule_root)) { + *ss << "root item " << rule_root << " does not exist"; return -ENOENT; } - int root = crush.get_item_id(ruleset_root); + int root = crush.get_item_id(rule_root); + if (rule_device_class.size()) { + if (!crush.class_exists(rule_device_class)) { + *ss << "device class " << rule_device_class << " does not exist"; + return -ENOENT; + } + int c = crush.get_class_id(rule_device_class); + if (crush.class_bucket.count(root) == 0 || + crush.class_bucket[root].count(c) == 0) { + *ss << "root item " << rule_root << " has no devices with class " + << rule_device_class; + return -EINVAL; + } + root = crush.class_bucket[root][c]; + } - int ruleset = 0; + int rule = 0; int rno = 0; for (rno = 0; rno < crush.get_max_rules(); rno++) { if (!crush.rule_exists(rno) && !crush.ruleset_exists(rno)) break; } - ruleset = rno; + rule = rno; - int steps = 4 + ruleset_steps.size(); + int steps = 4 + rule_steps.size(); int min_rep = 3; int max_rep = get_chunk_count(); int ret; - ret = crush.add_rule(steps, ruleset, pg_pool_t::TYPE_ERASURE, + ret = crush.add_rule(steps, rule, pg_pool_t::TYPE_ERASURE, min_rep, max_rep, rno); assert(ret == rno); int step = 0; @@ -82,8 +96,8 @@ int ErasureCodeLrc::create_ruleset(const string &name, assert(ret == 0); // [ [ "choose", "rack", 2 ], // [ "chooseleaf", "host", 5 ] ] - for (vector::const_iterator i = ruleset_steps.begin(); - i != ruleset_steps.end(); + for (vector::const_iterator i = rule_steps.begin(); + i != rule_steps.end(); ++i) { int op = i->op == "chooseleaf" ? CRUSH_RULE_CHOOSELEAF_INDEP : CRUSH_RULE_CHOOSE_INDEP; @@ -98,7 +112,7 @@ int ErasureCodeLrc::create_ruleset(const string &name, ret = crush.set_rule_step(rno, step++, CRUSH_RULE_EMIT, 0, 0); assert(ret == 0); crush.set_rule_name(rno, name); - return ruleset; + return rule; } int ErasureCodeLrc::layers_description(const ErasureCodeProfile &profile, @@ -275,7 +289,7 @@ int ErasureCodeLrc::parse(ErasureCodeProfile &profile, if (r) return r; - return parse_ruleset(profile, ss); + return parse_rule(profile, ss); } const string ErasureCodeLrc::DEFAULT_KML("-1"); @@ -302,7 +316,7 @@ int ErasureCodeLrc::parse_kml(ErasureCodeProfile &profile, const char *generated[] = { "mapping", "layers", - "ruleset-steps" }; + "crush-steps" }; for (int i = 0; i < 3; i++) { if (profile.count(generated[i])) { @@ -363,54 +377,57 @@ int ErasureCodeLrc::parse_kml(ErasureCodeProfile &profile, profile["layers"] = layers + "]"; ErasureCodeProfile::const_iterator parameter; - string ruleset_locality; - parameter = profile.find("ruleset-locality"); + string rule_locality; + parameter = profile.find("crush-locality"); if (parameter != profile.end()) - ruleset_locality = parameter->second; - string ruleset_failure_domain = "host"; - parameter = profile.find("ruleset-failure-domain"); + rule_locality = parameter->second; + string rule_failure_domain = "host"; + parameter = profile.find("crush-failure-domain"); if (parameter != profile.end()) - ruleset_failure_domain = parameter->second; + rule_failure_domain = parameter->second; - if (ruleset_locality != "") { - ruleset_steps.clear(); - ruleset_steps.push_back(Step("choose", ruleset_locality, + if (rule_locality != "") { + rule_steps.clear(); + rule_steps.push_back(Step("choose", rule_locality, local_group_count)); - ruleset_steps.push_back(Step("chooseleaf", ruleset_failure_domain, + rule_steps.push_back(Step("chooseleaf", rule_failure_domain, l + 1)); - } else if (ruleset_failure_domain != "") { - ruleset_steps.clear(); - ruleset_steps.push_back(Step("chooseleaf", ruleset_failure_domain, 0)); + } else if (rule_failure_domain != "") { + rule_steps.clear(); + rule_steps.push_back(Step("chooseleaf", rule_failure_domain, 0)); } return err; } -int ErasureCodeLrc::parse_ruleset(ErasureCodeProfile &profile, +int ErasureCodeLrc::parse_rule(ErasureCodeProfile &profile, ostream *ss) { int err = 0; - err |= to_string("ruleset-root", profile, - &ruleset_root, + err |= to_string("crush-root", profile, + &rule_root, "default", ss); + err |= to_string("crush-device-class", profile, + &rule_device_class, + "", ss); - if (profile.count("ruleset-steps") != 0) { - ruleset_steps.clear(); - string str = profile.find("ruleset-steps")->second; + if (profile.count("crush-steps") != 0) { + rule_steps.clear(); + string str = profile.find("crush-steps")->second; json_spirit::mArray description; try { json_spirit::mValue json; json_spirit::read_or_throw(str, json); if (json.type() != json_spirit::array_type) { - *ss << "ruleset-steps='" << str + *ss << "crush-steps='" << str << "' must be a JSON array but is of type " << json.type() << " instead" << std::endl; return ERROR_LRC_ARRAY; } description = json.get_array(); } catch (json_spirit::Error_position &e) { - *ss << "failed to parse ruleset-steps='" << str << "'" + *ss << "failed to parse crush-steps='" << str << "'" << " at line " << e.line_ << ", column " << e.column_ << " : " << e.reason_ << std::endl; return ERROR_LRC_PARSE_JSON; @@ -429,7 +446,7 @@ int ErasureCodeLrc::parse_ruleset(ErasureCodeProfile &profile, << " is of type " << i->type() << " instead" << std::endl; return ERROR_LRC_ARRAY; } - int r = parse_ruleset_step(str, i->get_array(), ss); + int r = parse_rule_step(str, i->get_array(), ss); if (r) return r; } @@ -437,7 +454,7 @@ int ErasureCodeLrc::parse_ruleset(ErasureCodeProfile &profile, return 0; } -int ErasureCodeLrc::parse_ruleset_step(string description_string, +int ErasureCodeLrc::parse_rule_step(string description_string, json_spirit::mArray description, ostream *ss) { @@ -456,14 +473,14 @@ int ErasureCodeLrc::parse_ruleset_step(string description_string, << json_string.str() << " found in " << description_string << " must be a JSON string but is of type " << i->type() << " instead" << std::endl; - return position == 0 ? ERROR_LRC_RULESET_OP : ERROR_LRC_RULESET_TYPE; + return position == 0 ? ERROR_LRC_RULE_OP : ERROR_LRC_RULE_TYPE; } if (position == 2 && i->type() != json_spirit::int_type) { *ss << "element " << position << " of the array " << json_string.str() << " found in " << description_string << " must be a JSON int but is of type " << i->type() << " instead" << std::endl; - return ERROR_LRC_RULESET_N; + return ERROR_LRC_RULE_N; } if (position == 0) @@ -473,7 +490,7 @@ int ErasureCodeLrc::parse_ruleset_step(string description_string, if (position == 2) n = i->get_int(); } - ruleset_steps.push_back(Step(op, type, n)); + rule_steps.push_back(Step(op, type, n)); return 0; } diff --git a/ceph/src/erasure-code/lrc/ErasureCodeLrc.h b/ceph/src/erasure-code/lrc/ErasureCodeLrc.h index fac4d54a5..3cd6c849e 100644 --- a/ceph/src/erasure-code/lrc/ErasureCodeLrc.h +++ b/ceph/src/erasure-code/lrc/ErasureCodeLrc.h @@ -35,9 +35,9 @@ #define ERROR_LRC_COUNT_CONSTRAINT -(MAX_ERRNO + 11) #define ERROR_LRC_CONFIG_OPTIONS -(MAX_ERRNO + 12) #define ERROR_LRC_LAYERS_COUNT -(MAX_ERRNO + 13) -#define ERROR_LRC_RULESET_OP -(MAX_ERRNO + 14) -#define ERROR_LRC_RULESET_TYPE -(MAX_ERRNO + 15) -#define ERROR_LRC_RULESET_N -(MAX_ERRNO + 16) +#define ERROR_LRC_RULE_OP -(MAX_ERRNO + 14) +#define ERROR_LRC_RULE_TYPE -(MAX_ERRNO + 15) +#define ERROR_LRC_RULE_N -(MAX_ERRNO + 16) #define ERROR_LRC_ALL_OR_NOTHING -(MAX_ERRNO + 17) #define ERROR_LRC_GENERATED -(MAX_ERRNO + 18) #define ERROR_LRC_K_M_MODULO -(MAX_ERRNO + 19) @@ -62,7 +62,8 @@ public: std::string directory; unsigned int chunk_count; unsigned int data_chunk_count; - std::string ruleset_root; + std::string rule_root; + std::string rule_device_class; struct Step { Step(std::string _op, std::string _type, int _n) : op(_op), @@ -72,13 +73,13 @@ public: std::string type; int n; }; - std::vector ruleset_steps; + std::vector rule_steps; explicit ErasureCodeLrc(const std::string &dir) : directory(dir), - chunk_count(0), data_chunk_count(0), ruleset_root("default") + chunk_count(0), data_chunk_count(0), rule_root("default") { - ruleset_steps.push_back(Step("chooseleaf", "host", 0)); + rule_steps.push_back(Step("chooseleaf", "host", 0)); } ~ErasureCodeLrc() override {} @@ -90,7 +91,7 @@ public: const std::set &available, std::set *minimum) override; - int create_ruleset(const std::string &name, + int create_rule(const std::string &name, CrushWrapper &crush, std::ostream *ss) const override; @@ -117,11 +118,11 @@ public: int parse_kml(ErasureCodeProfile &profile, std::ostream *ss); - int parse_ruleset(ErasureCodeProfile &profile, std::ostream *ss); + int parse_rule(ErasureCodeProfile &profile, std::ostream *ss); - int parse_ruleset_step(std::string description_string, - json_spirit::mArray description, - std::ostream *ss); + int parse_rule_step(std::string description_string, + json_spirit::mArray description, + std::ostream *ss); int layers_description(const ErasureCodeProfile &profile, json_spirit::mArray *description, diff --git a/ceph/src/erasure-code/shec/ErasureCodeShec.cc b/ceph/src/erasure-code/shec/ErasureCodeShec.cc index c25732c47..17b380d5e 100644 --- a/ceph/src/erasure-code/shec/ErasureCodeShec.cc +++ b/ceph/src/erasure-code/shec/ErasureCodeShec.cc @@ -27,8 +27,6 @@ using namespace std; #include "common/debug.h" #include "ErasureCodeShec.h" -#include "crush/CrushWrapper.h" -#include "osd/osd_types.h" extern "C" { #include "jerasure/include/jerasure.h" #include "jerasure/include/galois.h" @@ -47,37 +45,15 @@ static ostream& _prefix(std::ostream* _dout) return *_dout << "ErasureCodeShec: "; } -int ErasureCodeShec::create_ruleset(const string &name, - CrushWrapper &crush, - ostream *ss) const -{ - int ruleid = crush.add_simple_rule( - name, ruleset_root, ruleset_failure_domain, - "indep", pg_pool_t::TYPE_ERASURE, ss); - if (ruleid < 0) { - return ruleid; - } else { - crush.set_rule_mask_max_size(ruleid, get_chunk_count()); - return crush.get_rule_mask_ruleset(ruleid); - } -} - int ErasureCodeShec::init(ErasureCodeProfile &profile, ostream *ss) { int err = 0; - err |= ErasureCode::to_string("ruleset-root", profile, - &ruleset_root, - DEFAULT_RULESET_ROOT, ss); - err |= ErasureCode::to_string("ruleset-failure-domain", profile, - &ruleset_failure_domain, - DEFAULT_RULESET_FAILURE_DOMAIN, ss); err |= parse(profile); if (err) return err; prepare(); - ErasureCode::init(profile, ss); - return err; + return ErasureCode::init(profile, ss); } unsigned int ErasureCodeShec::get_chunk_size(unsigned int object_size) const diff --git a/ceph/src/erasure-code/shec/ErasureCodeShec.h b/ceph/src/erasure-code/shec/ErasureCodeShec.h index 2974bce9d..073644e7a 100644 --- a/ceph/src/erasure-code/shec/ErasureCodeShec.h +++ b/ceph/src/erasure-code/shec/ErasureCodeShec.h @@ -24,9 +24,6 @@ #include "erasure-code/ErasureCode.h" #include "ErasureCodeShecTableCache.h" -#define DEFAULT_RULESET_ROOT "default" -#define DEFAULT_RULESET_FAILURE_DOMAIN "host" - class ErasureCodeShec : public ErasureCode { public: @@ -45,8 +42,6 @@ public: int w; int DEFAULT_W; int technique; - string ruleset_root; - string ruleset_failure_domain; int *matrix; ErasureCodeShec(const int _technique, @@ -61,17 +56,11 @@ public: w(0), DEFAULT_W(8), technique(_technique), - ruleset_root(DEFAULT_RULESET_ROOT), - ruleset_failure_domain(DEFAULT_RULESET_FAILURE_DOMAIN), matrix(0) {} ~ErasureCodeShec() override {} - int create_ruleset(const string &name, - CrushWrapper &crush, - ostream *ss) const override; - unsigned int get_chunk_count() const override { return k + m; } diff --git a/ceph/src/global/global_init.cc b/ceph/src/global/global_init.cc index a8833c5eb..e5e19e079 100644 --- a/ceph/src/global/global_init.cc +++ b/ceph/src/global/global_init.cc @@ -114,7 +114,7 @@ void global_pre_init(std::vector < const char * > *alt_def_args, dout_emergency(oss.str()); _exit(1); } else { - derr <<"did not load config file, using default settings." << dendl; + derr << "did not load config file, using default settings." << dendl; } } } diff --git a/ceph/src/include/Context.h b/ceph/src/include/Context.h index bf992d0a2..e30c3f68c 100644 --- a/ceph/src/include/Context.h +++ b/ceph/src/include/Context.h @@ -217,7 +217,11 @@ public: : cct(cct_) { } - + ~C_ContextsBase() override { + for (auto c : contexts) { + delete c; + } + } void add(ContextType* c) { contexts.push_back(c); } diff --git a/ceph/src/include/ceph_fs.h b/ceph/src/include/ceph_fs.h index 4188bff8b..4ddfda5be 100644 --- a/ceph/src/include/ceph_fs.h +++ b/ceph/src/include/ceph_fs.h @@ -239,7 +239,7 @@ struct ceph_mon_subscribe_ack { #define CEPH_MDSMAP_ALLOW_CLASSICS (CEPH_MDSMAP_ALLOW_SNAPS | CEPH_MDSMAP_ALLOW_MULTIMDS | \ CEPH_MDSMAP_ALLOW_DIRFRAGS) -#define CEPH_MDSMAP_DEFAULTS CEPH_MDSMAP_ALLOW_DIRFRAGS +#define CEPH_MDSMAP_DEFAULTS CEPH_MDSMAP_ALLOW_DIRFRAGS | CEPH_MDSMAP_ALLOW_MULTIMDS /* * mds states diff --git a/ceph/src/include/health.h b/ceph/src/include/health.h new file mode 100644 index 000000000..b23a4d4e2 --- /dev/null +++ b/ceph/src/include/health.h @@ -0,0 +1,68 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#pragma once + +#include +#include + +#include "include/encoding.h" + +// health_status_t +enum health_status_t { + HEALTH_ERR = 0, + HEALTH_WARN = 1, + HEALTH_OK = 2, +}; + +static inline void encode(health_status_t hs, bufferlist& bl) { + uint8_t v = hs; + ::encode(v, bl); +} +static inline void decode(health_status_t& hs, bufferlist::iterator& p) { + uint8_t v; + ::decode(v, p); + hs = health_status_t(v); +} +template<> +struct denc_traits { + static constexpr bool supported = true; + static constexpr bool featured = false; + static constexpr bool bounded = true; + static constexpr bool need_contiguous = false; + static void bound_encode(const bufferptr& v, size_t& p, uint64_t f=0) { + p++; + } + static void encode(const health_status_t& v, + buffer::list::contiguous_appender& p, + uint64_t f=0) { + ::denc((uint8_t)v, p); + } + static void decode(health_status_t& v, buffer::ptr::iterator& p, + uint64_t f=0) { + uint8_t tmp; + ::denc(tmp, p); + v = health_status_t(tmp); + } + static void decode(health_status_t& v, buffer::list::iterator& p, + uint64_t f=0) { + uint8_t tmp; + ::denc(tmp, p); + v = health_status_t(tmp); + } +}; + +inline std::ostream& operator<<(std::ostream &oss, const health_status_t status) { + switch (status) { + case HEALTH_ERR: + oss << "HEALTH_ERR"; + break; + case HEALTH_WARN: + oss << "HEALTH_WARN"; + break; + case HEALTH_OK: + oss << "HEALTH_OK"; + break; + } + return oss; +} diff --git a/ceph/src/include/rados/librados.h b/ceph/src/include/rados/librados.h index 8fa4b69f5..544c2dbca 100644 --- a/ceph/src/include/rados/librados.h +++ b/ceph/src/include/rados/librados.h @@ -3677,6 +3677,7 @@ typedef void (*rados_log_callback_t)(void *arg, */ typedef void (*rados_log_callback2_t)(void *arg, const char *line, + const char *channel, const char *who, const char *name, uint64_t sec, uint64_t nsec, @@ -3688,6 +3689,47 @@ CEPH_RADOS_API int rados_monitor_log(rados_t cluster, const char *level, CEPH_RADOS_API int rados_monitor_log2(rados_t cluster, const char *level, rados_log_callback2_t cb, void *arg); + +/** + * register daemon instance for a service + * + * Register us as a daemon providing a particular service. We identify + * the service (e.g., 'rgw') and our instance name (e.g., 'rgw.$hostname'). + * The metadata is a map of keys and values with arbitrary static metdata + * for this instance. The encoding is a series of NULL-terminated strings, + * alternating key names and values, terminating with an empty key name. + * For example, "foo\0bar\0this\0that\0\0" is the dict {foo=bar,this=that}. + * + * For the lifetime of the librados instance, regular beacons will be sent + * to the cluster to maintain our registration in the service map. + * + * @param cluster handle + * @param service service name + * @param daemon deamon instance name + * @param metadata_dict static daemon metadata dict + */ +CEPH_RADOS_API int rados_service_register( + rados_t cluster, + const char *service, + const char *daemon, + const char *metadata_dict); + +/** + * update daemon status + * + * Update our mutable status information in the service map. + * + * The status dict is encoded the same way the daemon metadata is encoded + * for rados_service_register. For example, "foo\0bar\0this\0that\0\0" is + * {foo=bar,this=that}. + * + * @param cluster rados cluster handle + * @param status_dict status dict + */ +CEPH_RADOS_API int rados_service_update_status( + rados_t cluster, + const char *status_dict); + /** @} Mon/OSD/PG commands */ /* diff --git a/ceph/src/include/rados/librados.hpp b/ceph/src/include/rados/librados.hpp index e4eb2d250..0fc93a733 100644 --- a/ceph/src/include/rados/librados.hpp +++ b/ceph/src/include/rados/librados.hpp @@ -1298,6 +1298,13 @@ namespace librados int conf_set(const char *option, const char *value); int conf_get(const char *option, std::string &val); + int service_daemon_register( + const std::string& service, ///< service name (e.g., 'rgw') + const std::string& name, ///< daemon name (e.g., 'gwfoo') + const std::map& metadata); ///< static metadata about daemon + int service_daemon_update_status( + const std::map& status); + int pool_create(const char *name); int pool_create(const char *name, uint64_t auid); int pool_create(const char *name, uint64_t auid, uint8_t crush_rule); diff --git a/ceph/src/include/scope_guard.h b/ceph/src/include/scope_guard.h index 0d06ce936..ebffc5dfe 100644 --- a/ceph/src/include/scope_guard.h +++ b/ceph/src/include/scope_guard.h @@ -15,6 +15,8 @@ #ifndef SCOPE_GUARD #define SCOPE_GUARD +#include + template struct scope_guard { F f; diff --git a/ceph/src/include/stringify.h b/ceph/src/include/stringify.h index d7b90ed2c..1b2a130c9 100644 --- a/ceph/src/include/stringify.h +++ b/ceph/src/include/stringify.h @@ -4,6 +4,8 @@ #include #include +#include "include/types.h" + template inline std::string stringify(const T& a) { #if defined(__GNUC__) && !(defined(__clang__) || defined(__INTEL_COMPILER)) diff --git a/ceph/src/include/types.h b/ceph/src/include/types.h index deb794cbd..e904a151d 100644 --- a/ceph/src/include/types.h +++ b/ceph/src/include/types.h @@ -411,29 +411,6 @@ inline ostream& operator<<(ostream& out, const ceph_mon_subscribe_item& i) << ((i.flags & CEPH_SUBSCRIBE_ONETIME) ? "" : "+"); } -enum health_status_t { - HEALTH_ERR = 0, - HEALTH_WARN = 1, - HEALTH_OK = 2, -}; - -#ifdef __cplusplus -inline ostream& operator<<(ostream &oss, const health_status_t status) { - switch (status) { - case HEALTH_ERR: - oss << "HEALTH_ERR"; - break; - case HEALTH_WARN: - oss << "HEALTH_WARN"; - break; - case HEALTH_OK: - oss << "HEALTH_OK"; - break; - } - return oss; -} -#endif - struct weightf_t { float v; // cppcheck-suppress noExplicitConstructor @@ -489,10 +466,13 @@ struct errorcode32_t { // cppcheck-suppress noExplicitConstructor errorcode32_t(int32_t i) : code(i) {} - operator int() const { return code; } - int operator==(int i) { - return code==i; - } + operator int() const { return code; } + int* operator&() { return &code; } + int operator==(int i) { return code == i; } + int operator>(int i) { return code > i; } + int operator>=(int i) { return code >= i; } + int operator<(int i) { return code < i; } + int operator<=(int i) { return code <= i; } void encode(bufferlist &bl) const { __s32 newcode = hostos_to_ceph_errno(code); diff --git a/ceph/src/isa-l/CONTRIBUTING.md b/ceph/src/isa-l/CONTRIBUTING.md new file mode 100644 index 000000000..593a46765 --- /dev/null +++ b/ceph/src/isa-l/CONTRIBUTING.md @@ -0,0 +1,35 @@ +# Contributing to ISA-L + +Everyone is welcome to contribute. Patches may be submitted using GitHub pull +requests (PRs). All commits must be signed off by the developer (--signoff) +which indicates that you agree to the Developer Certificate of Origin. Patch +discussion will happen directly on the GitHub PR. Design pre-work and general +discussion occurs on the [mailing list]. Anyone can provide feedback in either +location and all discussion is welcome. Decisions on whether to merge patches +will be handled by the maintainer. + +## License + +ISA-L is licensed using a BSD 3-clause [license]. All code submitted to +the project is required to carry that license. + +## Certificate of Origin + +In order to get a clear contribution chain of trust we use the +[signed-off-by language] used by the Linux kernel project. + +## Mailing List + +Contributors and users are welcome to submit new request on our roadmap, submit +patches, file issues, and ask questions on our [mailing list]. + +## Coding Style + +The coding style for ISA-L C code roughly follows linux kernel guidelines. Use +the included indent script to format C code. + + ./tools/iindent your_files.c + +[mailing list]:https://lists.01.org/mailman/listinfo/isal +[license]:LICENSE +[signed-off-by language]:https://01.org/community/signed-process diff --git a/ceph/src/isa-l/Doxyfile b/ceph/src/isa-l/Doxyfile new file mode 100644 index 000000000..1678ca7bf --- /dev/null +++ b/ceph/src/isa-l/Doxyfile @@ -0,0 +1,27 @@ +PROJECT_NAME = "Intel Intelligent Storage Acceleration Library" +PROJECT_BRIEF = "ISA-L API reference doc" + +OUTPUT_DIRECTORY = generated_doc +FULL_PATH_NAMES = NO +TAB_SIZE = 8 +ALIASES = "requires=\xrefitem requires \"Requires\" \"Instruction Set Requirements for arch-specific functions (non-multibinary)\"" +OPTIMIZE_OUTPUT_FOR_C = YES +HIDE_UNDOC_MEMBERS = YES + +INPUT = isa-l.h \ + include \ + README.md \ + Release_notes.txt + +EXCLUDE = include/test.h +EXAMPLE_PATH = . crc raid erasure_code igzip +PAPER_TYPE = letter +LATEX_SOURCE_CODE = YES +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = YES +PREDEFINED = "DECLARE_ALIGNED(n, a)=ALIGN n" \ + __declspec(x)='x' \ + align(x)='ALIGN \ + x' +EXPAND_AS_DEFINED = DECLARE_ALIGNED +EXTENSION_MAPPING = "txt=md" diff --git a/ceph/src/isa-l/Makefile.am b/ceph/src/isa-l/Makefile.am index 995259ed0..e0edfa3f6 100644 --- a/ceph/src/isa-l/Makefile.am +++ b/ceph/src/isa-l/Makefile.am @@ -1,4 +1,4 @@ -EXTRA_DIST = autogen.sh Makefile.unx make.inc Makefile.nmake isa-l.def LICENSE README.md +EXTRA_DIST = autogen.sh Makefile.unx make.inc Makefile.nmake isa-l.def LICENSE README.md Doxyfile CONTRIBUTING.md CLEANFILES = LDADD = AM_MAKEFLAGS = --no-print-directory @@ -6,9 +6,9 @@ noinst_HEADERS = pkginclude_HEADERS = include/test.h noinst_LTLIBRARIES = INCLUDE = -I $(srcdir)/include/ -AM_CFLAGS = ${my_CFLAGS} ${INCLUDE} ${D} lsrc= +src_include= extern_hdrs= other_src= check_tests= @@ -18,6 +18,9 @@ unit_tests_extra= perf_tests_extra= examples= other_tests= +lsrc_x86_64= +lsrc_x86_32= +lsrc_base_aliases= lsrc32= unit_tests32= perf_tests32= @@ -31,12 +34,25 @@ include igzip/Makefile.am # LIB version info not necessarily the same as package version LIBISAL_CURRENT=2 -LIBISAL_REVISION=16 +LIBISAL_REVISION=18 LIBISAL_AGE=0 lib_LTLIBRARIES = libisal.la pkginclude_HEADERS += $(sort ${extern_hdrs}) libisal_la_SOURCES = ${lsrc} + +if CPU_X86_64 +libisal_la_SOURCES += ${lsrc_x86_64} +endif + +if CPU_X86_32 +libisal_la_SOURCES += ${lsrc_x86_32} +endif + +if CPU_UNDEFINED +libisal_la_SOURCES += ${lsrc_base_aliases} +endif + nobase_include_HEADERS = isa-l.h libisal_la_LDFLAGS = $(AM_LDFLAGS) \ -version-info $(LIBISAL_CURRENT):$(LIBISAL_REVISION):$(LIBISAL_AGE) @@ -59,6 +75,7 @@ CLEANFILES += ${EXTRA_PROGRAMS} perfs: ${perf_tests} tests: ${unit_tests} +checks: ${check_tests} other: ${other_tests} perf: $(addsuffix .run,$(perf_tests)) ex: ${examples} @@ -75,12 +92,13 @@ if USE_YASM endif if USE_NASM as_filter = ${srcdir}/tools/nasm-filter.sh - as_include = $(addprefix -I ${srcdir}/,$(sort $(dir $(lsrc)))) endif CCAS = $(as_filter) EXTRA_DIST += tools/yasm-filter.sh tools/nasm-filter.sh -AM_CCASFLAGS = ${yasm_args} ${INCLUDE} ${as_include} ${DEFS} ${D} + +AM_CFLAGS = ${my_CFLAGS} ${INCLUDE} $(src_include) ${D} +AM_CCASFLAGS = ${yasm_args} ${INCLUDE} ${src_include} ${DEFS} ${D} .asm.s: @echo " MKTMP " $@; @@ -104,9 +122,7 @@ isa-l.h: @for unit in $(sort $(extern_hdrs)); do echo "#include " | sed -e 's;include/;;' >> $@; done @echo '#endif //_ISAL_H_' >> $@ - -license = bsd -licc = $(srcdir)/doc/license_$(license)_c.txt -lica = $(srcdir)/doc/license_$(license)_asm.txt -licm = $(srcdir)/doc/license_$(license)_make.txt - +doc: isa-l.h + (cat Doxyfile; echo 'PROJECT_NUMBER=${VERSION}') | doxygen - + $(MAKE) -C generated_doc/latex &> generated_doc/latex_build_api.log + cp generated_doc/latex/refman.pdf isa-l_api_${VERSION}.pdf diff --git a/ceph/src/isa-l/Makefile.nmake b/ceph/src/isa-l/Makefile.nmake index b520246b2..e3f604e62 100644 --- a/ceph/src/isa-l/Makefile.nmake +++ b/ceph/src/isa-l/Makefile.nmake @@ -80,11 +80,13 @@ objs = \ bin\pq_check_sse.obj \ bin\pq_gen_avx.obj \ bin\pq_gen_avx2.obj \ + bin\pq_gen_avx512.obj \ bin\pq_gen_sse.obj \ bin\raid_base.obj \ bin\raid_multibinary.obj \ bin\xor_check_sse.obj \ bin\xor_gen_avx.obj \ + bin\xor_gen_avx512.obj \ bin\xor_gen_sse.obj \ bin\crc16_t10dif_01.obj \ bin\crc16_t10dif_by4.obj \ @@ -93,22 +95,42 @@ objs = \ bin\crc32_ieee_by4.obj \ bin\crc32_iscsi_00.obj \ bin\crc32_iscsi_01.obj \ + bin\crc64_base.obj \ + bin\crc64_ecma_norm_by8.obj \ + bin\crc64_ecma_refl_by8.obj \ + bin\crc64_iso_norm_by8.obj \ + bin\crc64_iso_refl_by8.obj \ + bin\crc64_jones_norm_by8.obj \ + bin\crc64_jones_refl_by8.obj \ + bin\crc64_multibinary.obj \ bin\crc_base.obj \ - bin\crc_data.obj \ + bin\crc32_gzip_base.obj \ bin\crc_multibinary.obj \ bin\huff_codes.obj \ bin\hufftables_c.obj \ bin\igzip.obj \ bin\igzip_base.obj \ bin\igzip_body_01.obj \ + bin\igzip_body_02.obj \ bin\igzip_body_04.obj \ + bin\igzip_decode_block_stateless_01.obj \ + bin\igzip_decode_block_stateless_04.obj \ bin\igzip_finish.obj \ + bin\flatten_ll.obj \ + bin\encode_df.obj \ + bin\encode_df_04.obj \ + bin\proc_heap.obj \ + bin\igzip_icf_body_01.obj \ + bin\igzip_icf_body_02.obj \ + bin\igzip_icf_body_04.obj \ + bin\igzip_icf_finish.obj \ + bin\igzip_icf_base.obj \ + bin\igzip_inflate.obj \ + bin\igzip_inflate_multibinary.obj \ bin\igzip_multibinary.obj \ - bin\igzip_stateless_01.obj \ - bin\igzip_stateless_04.obj \ - bin\igzip_stateless_base.obj \ - bin\crc_utils_01.obj \ - bin\crc_utils_04.obj \ + bin\igzip_update_histogram_01.obj \ + bin\igzip_update_histogram_04.obj \ + bin\rfc1951_lookup.obj \ bin\detect_repeated_char.obj INCLUDES = -I./ -Ierasure_code/ -Iraid/ -Icrc/ -Iigzip/ -Iinclude/ @@ -173,7 +195,8 @@ checks = \ crc16_t10dif_test.exe \ crc32_ieee_test.exe \ crc32_iscsi_test.exe \ - igzip_check.exe + crc64_funcs_test.exe \ + igzip_rand_test.exe checks: lib $(checks) $(checks): $(@B).obj @@ -182,22 +205,11 @@ check: $(checks) # Unit tests tests = \ - gf_vect_mul_sse_test.exe \ - gf_vect_mul_avx_test.exe \ gf_vect_mul_base_test.exe \ - gf_vect_dot_prod_sse_test.exe \ - gf_vect_dot_prod_avx_test.exe \ - gf_2vect_dot_prod_sse_test.exe \ - gf_3vect_dot_prod_sse_test.exe \ - gf_4vect_dot_prod_sse_test.exe \ - gf_5vect_dot_prod_sse_test.exe \ - gf_6vect_dot_prod_sse_test.exe \ gf_vect_dot_prod_base_test.exe \ gf_vect_dot_prod_test.exe \ gf_vect_mad_test.exe \ - erasure_code_base_test.exe \ - erasure_code_sse_test.exe \ - igzip_rand_test.exe + erasure_code_base_test.exe tests: lib $(tests) $(tests): $(@B).obj @@ -241,9 +253,5 @@ clean: -if exist isa-l.dll del isa-l.dll zlib.lib: -igzip_rand_test.exe: igzip_inflate_ref.obj -igzip_inflate_perf.exe: igzip_inflate_ref.obj igzip_inflate_perf.exe: zlib.lib -igzip_inflate_test.exe: igzip_inflate_ref.obj igzip_inflate_test.exe: zlib.lib -igzip_check.exe: igzip_inflate_ref.obj diff --git a/ceph/src/isa-l/README.md b/ceph/src/isa-l/README.md index b084891ed..48127384f 100644 --- a/ceph/src/isa-l/README.md +++ b/ceph/src/isa-l/README.md @@ -1,37 +1,59 @@ -================================================= Intel(R) Intelligent Storage Acceleration Library ================================================= [![Build Status](https://travis-ci.org/01org/isa-l.svg?branch=master)](https://travis-ci.org/01org/isa-l) -Build Prerequisites -=================== - -ISA-L requires yasm version 1.2.0 or later or nasm v2.11.01 or later. Building -with autotools requires autoconf/automake packages. +ISA-L is a collection of optimized low-level functions targeting storage +applications. ISA-L includes: +* Erasure codes - Fast block Reed-Solomon type erasure codes for any + encode/decode matrix in GF(2^8). +* CRC - Fast implementations of cyclic redundancy check. Six different + polynomials supported. + - iscsi32, ieee32, t10dif, ecma64, iso64, jones64. +* Raid - calculate and operate on XOR and P+Q parity found in common RAID + implementations. +* Compression - Fast deflate-compatible data compression. +* De-compression - Fast inflate-compatible data compression. + +Also see: +* [ISA-L for updates](https://github.com/01org/isa-l). +* For crypto functions see [isa-l_crypto on github](https://github.com/01org/isa-l_crypto). +* The [github wiki](https://github.com/01org/isa-l/wiki). +* ISA-L [mailing list](https://lists.01.org/mailman/listinfo/isal). +* [Contributing](CONTRIBUTING.md). Building ISA-L -============== +-------------- + +### Prerequisites -Autotools ---------- +* yasm version 1.2.0 or later or nasm v2.11.01 or later. +* gcc, clang, icc or VC compiler. +* GNU 'make' or 'nmake' (Windows). +* Building with autotools requires autoconf/automake packages. -To build and install the library with autotools it is usually sufficient to run -the following: +### Autotools +To build and install the library with autotools it is usually sufficient to run: ./autogen.sh ./configure make sudo make install -Other targets include: make check, make tests, make perfs, make ex (examples) -and make other. +### Makefile +To use a standard makefile run: -Windows -------- + make -f Makefile.unx +### Windows On Windows use nmake to build dll and static lib: nmake -f Makefile.nmake -Other targes include: nmake check. +### Other make targets +Other targets include: +* `make check` : create and run tests +* `make tests` : create additional unit tests +* `make perfs` : create included performance tests +* `make ex` : build examples +* `make other` : build other utilities such as compression file tests diff --git a/ceph/src/isa-l/Release_notes.txt b/ceph/src/isa-l/Release_notes.txt index 43aa22c8c..d6bd4fe6a 100644 --- a/ceph/src/isa-l/Release_notes.txt +++ b/ceph/src/isa-l/Release_notes.txt @@ -1,28 +1,35 @@ -============================================================================= -v2.16 Intel Intelligent Storage Acceleration Library Release Notes - Open Source Version -============================================================================= +v2.18 Intel Intelligent Storage Acceleration Library Release Notes +================================================================== -============================================================================= RELEASE NOTE CONTENTS -============================================================================= 1. KNOWN ISSUES 2. FIXED ISSUES 3. CHANGE LOG & FEATURES ADDED -============================================================================= -1. KNOWN ISSUES -============================================================================= - -* Only erasure code unit included in open source version at this time. +1. KNOWN ISSUES +---------------- * Perf tests do not run in Windows environment. * 32-bit lib is not supported in Windows. -============================================================================= 2. FIXED ISSUES -============================================================================= +--------------- + +v2.18 + +* Mac OS X/darwin systems no longer require the --target=darwin config option. + The autoconf canonical build should detect. + +v2.17 + +* Fix igzip using 32K window and a shared object + +* Fix igzip undefined instruction error on Nehalem. + +* Fixed issue in crc performance tests where OS optimizations turned cold cache + tests into warm tests. + v2.15 * Fix for windows register save in gf_6vect_mad_avx2.asm. Only affects windows @@ -40,9 +47,35 @@ v2.10 affects windows versions of erasure code. GP register saves/restore were pushed to same stack area as XMM. -============================================================================= 3. CHANGE LOG & FEATURES ADDED -============================================================================= +------------------------------ + +v2.18 + +* New 2-pass fully-dynamic deflate compression (level -1). ISA-L fast deflate + now has two levels. Level 0 (default) is the same as previous generations. + Setting to level 1 will switch to the fully-dynamic compression that will + typically reach higher compression ratios. + +* RAID AVX512 functions. + +v2.17 + +* New fast decompression (inflate) + +* Compression improvements (deflate) + - Speed and compression ratio improvements. + - Fast custom Huffman code generation. + - New features: + * Run-time option of gzip crc calculation and headers/trailer. + * Choice of static header (BTYPE 01) blocks. + * LARGE_WINDOW, 32K history, now default. + * Stateless full flush mode. + +* CRC64 + - Six new 64-bit polynomials supported. Normal and reflected versions of ECMA, + ISO and Jones polynomials. + v2.16 * Units added: crc, raid, igzip (deflate compression). diff --git a/ceph/src/isa-l/configure.ac b/ceph/src/isa-l/configure.ac index b2923ea79..b4cb0fe94 100644 --- a/ceph/src/isa-l/configure.ac +++ b/ceph/src/isa-l/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ(2.69) AC_INIT([libisal], - [2.16.0], + [2.18.0], [sg.support.isal@intel.com], [isa-l], [http://01.org/storage-acceleration-library]) @@ -22,6 +22,17 @@ AM_INIT_AUTOMAKE([ ]) AM_PROG_AS +AC_CANONICAL_HOST +CPU="" +AS_CASE([$host_cpu], + [x86_64], [CPU="x86_64"], + [amd64], [CPU="x86_64"], + [i?86], [CPU="x86_32"], +) +AM_CONDITIONAL([CPU_X86_64], [test "$CPU" = "x86_64"]) +AM_CONDITIONAL([CPU_X86_32], [test "$CPU" = "x86_32"]) +AM_CONDITIONAL([CPU_UNDEFINED], [test "x$CPU" = "x"]) + # Check for programs AC_PROG_CC_STDC AC_USE_SYSTEM_EXTENSIONS @@ -88,7 +99,7 @@ else fi # Pick an assembler yasm or nasm -if test x"$AS" == x""; then +if test x"$AS" = x""; then if test x"$yasm_knows_avx512" = x"yes"; then AS=yasm elif test x"$nasm_knows_avx512" = x"yes"; then @@ -114,7 +125,7 @@ AM_CONDITIONAL(USE_NASM, test x"$AS" = x"nasm") AM_CONDITIONAL(WITH_AVX512, test x"$have_as_knows_avx512" = x"yes") -case $target in +case $host_os in *linux*) arch=linux yasm_args="-f elf64";; *darwin*) arch=darwin yasm_args="-f macho64 --prefix=_ ";; *netbsd*) arch=netbsd yasm_args="-f elf64";; diff --git a/ceph/src/isa-l/crc/Makefile.am b/ceph/src/isa-l/crc/Makefile.am index d1fb32075..74b964743 100644 --- a/ceph/src/isa-l/crc/Makefile.am +++ b/ceph/src/isa-l/crc/Makefile.am @@ -1,5 +1,5 @@ ######################################################################## -# Copyright(c) 2011-2015 Intel Corporation All rights reserved. +# Copyright(c) 2011-2017 Intel Corporation All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -28,6 +28,13 @@ ######################################################################## lsrc += \ + crc/crc_base.c \ + crc/crc64_base.c + +lsrc_base_aliases += crc/crc_base_aliases.c +lsrc_x86_32 += crc/crc_base_aliases.c + +lsrc_x86_64 += \ crc/crc16_t10dif_01.asm \ crc/crc16_t10dif_by4.asm \ crc/crc32_ieee_01.asm \ @@ -35,14 +42,23 @@ lsrc += \ crc/crc32_iscsi_01.asm \ crc/crc32_iscsi_00.asm \ crc/crc_multibinary.asm \ - crc/crc_base.c + crc/crc64_multibinary.asm \ + crc/crc64_ecma_refl_by8.asm \ + crc/crc64_ecma_norm_by8.asm \ + crc/crc64_iso_refl_by8.asm \ + crc/crc64_iso_norm_by8.asm \ + crc/crc64_jones_refl_by8.asm \ + crc/crc64_jones_norm_by8.asm -extern_hdrs += include/crc.h +src_include += -I $(srcdir)/crc +extern_hdrs += include/crc.h include/crc64.h other_src += include/reg_sizes.asm include/types.h include/test.h -check_tests += crc/crc16_t10dif_test crc/crc32_ieee_test crc/crc32_iscsi_test +check_tests += crc/crc16_t10dif_test crc/crc32_ieee_test crc/crc32_iscsi_test \ + crc/crc64_funcs_test -perf_tests += crc/crc16_t10dif_perf crc/crc32_ieee_perf crc/crc32_iscsi_perf +perf_tests += crc/crc16_t10dif_perf crc/crc32_ieee_perf crc/crc32_iscsi_perf \ + crc/crc64_funcs_perf -examples += crc/crc_simple_test +examples += crc/crc_simple_test crc/crc64_example diff --git a/ceph/src/isa-l/crc/crc16_t10dif_01.asm b/ceph/src/isa-l/crc/crc16_t10dif_01.asm index 129a9eb9f..fb9c73c8b 100644 --- a/ceph/src/isa-l/crc/crc16_t10dif_01.asm +++ b/ceph/src/isa-l/crc/crc16_t10dif_01.asm @@ -44,6 +44,8 @@ %include "reg_sizes.asm" +%define fetch_dist 1024 + [bits 64] default rel @@ -145,6 +147,7 @@ _fold_128_B_loop: ; update the buffer pointer add arg2, 128 ; buf += 128; + prefetchnta [arg2+fetch_dist+0] movdqu xmm9, [arg2+16*0] movdqu xmm12, [arg2+16*1] pshufb xmm9, xmm11 @@ -160,6 +163,7 @@ _fold_128_B_loop: pxor xmm1, xmm12 xorps xmm1, xmm13 + prefetchnta [arg2+fetch_dist+32] movdqu xmm9, [arg2+16*2] movdqu xmm12, [arg2+16*3] pshufb xmm9, xmm11 @@ -175,6 +179,7 @@ _fold_128_B_loop: pxor xmm3, xmm12 xorps xmm3, xmm13 + prefetchnta [arg2+fetch_dist+64] movdqu xmm9, [arg2+16*4] movdqu xmm12, [arg2+16*5] pshufb xmm9, xmm11 @@ -190,6 +195,7 @@ _fold_128_B_loop: pxor xmm5, xmm12 xorps xmm5, xmm13 + prefetchnta [arg2+fetch_dist+96] movdqu xmm9, [arg2+16*6] movdqu xmm12, [arg2+16*7] pshufb xmm9, xmm11 diff --git a/ceph/src/isa-l/crc/crc16_t10dif_by4.asm b/ceph/src/isa-l/crc/crc16_t10dif_by4.asm index 16129fd04..f79f4f6dc 100644 --- a/ceph/src/isa-l/crc/crc16_t10dif_by4.asm +++ b/ceph/src/isa-l/crc/crc16_t10dif_by4.asm @@ -45,6 +45,8 @@ %include "reg_sizes.asm" +%define fetch_dist 1024 + [bits 64] default rel @@ -129,6 +131,7 @@ _fold_64_B_loop: ; update the buffer pointer add arg2, 64 ; buf += 64; + prefetchnta [arg2+fetch_dist+0] movdqu xmm4, xmm0 movdqu xmm5, xmm1 @@ -141,6 +144,7 @@ _fold_64_B_loop: pxor xmm0, xmm4 pxor xmm1, xmm5 + prefetchnta [arg2+fetch_dist+32] movdqu xmm4, xmm2 movdqu xmm5, xmm3 diff --git a/ceph/src/isa-l/crc/crc16_t10dif_perf.c b/ceph/src/isa-l/crc/crc16_t10dif_perf.c index 5576e6d62..34f1ddbdf 100644 --- a/ceph/src/isa-l/crc/crc16_t10dif_perf.c +++ b/ceph/src/isa-l/crc/crc16_t10dif_perf.c @@ -72,6 +72,7 @@ int main(int argc, char *argv[]) printf("Start timed tests\n"); fflush(0); + memset(buf, 0, TEST_LEN); crc = crc16_t10dif(TEST_SEED, buf, TEST_LEN); perf_start(&start); for (i = 0; i < TEST_LOOPS; i++) { diff --git a/ceph/src/isa-l/crc/crc32_ieee_01.asm b/ceph/src/isa-l/crc/crc32_ieee_01.asm index fcc4c6bba..3c463dada 100644 --- a/ceph/src/isa-l/crc/crc32_ieee_01.asm +++ b/ceph/src/isa-l/crc/crc32_ieee_01.asm @@ -44,6 +44,7 @@ %include "reg_sizes.asm" +%define fetch_dist 1024 [bits 64] default rel @@ -143,6 +144,7 @@ _fold_128_B_loop: ; update the buffer pointer add arg2, 128 ; buf += 128; + prefetchnta [arg2+fetch_dist+0] movdqu xmm9, [arg2+16*0] movdqu xmm12, [arg2+16*1] pshufb xmm9, xmm11 @@ -158,6 +160,7 @@ _fold_128_B_loop: pxor xmm1, xmm12 xorps xmm1, xmm13 + prefetchnta [arg2+fetch_dist+32] movdqu xmm9, [arg2+16*2] movdqu xmm12, [arg2+16*3] pshufb xmm9, xmm11 @@ -173,6 +176,7 @@ _fold_128_B_loop: pxor xmm3, xmm12 xorps xmm3, xmm13 + prefetchnta [arg2+fetch_dist+64] movdqu xmm9, [arg2+16*4] movdqu xmm12, [arg2+16*5] pshufb xmm9, xmm11 @@ -188,6 +192,7 @@ _fold_128_B_loop: pxor xmm5, xmm12 xorps xmm5, xmm13 + prefetchnta [arg2+fetch_dist+96] movdqu xmm9, [arg2+16*6] movdqu xmm12, [arg2+16*7] pshufb xmm9, xmm11 diff --git a/ceph/src/isa-l/crc/crc32_ieee_by4.asm b/ceph/src/isa-l/crc/crc32_ieee_by4.asm index 4837497c0..97f686809 100644 --- a/ceph/src/isa-l/crc/crc32_ieee_by4.asm +++ b/ceph/src/isa-l/crc/crc32_ieee_by4.asm @@ -45,6 +45,8 @@ %include "reg_sizes.asm" +%define fetch_dist 1024 + [bits 64] default rel @@ -133,6 +135,7 @@ _fold_64_B_loop: ;update the buffer pointer add arg2, 64 + prefetchnta [arg2+fetch_dist+0] movdqa xmm4, xmm0 movdqa xmm5, xmm1 @@ -145,6 +148,7 @@ _fold_64_B_loop: pxor xmm0, xmm4 pxor xmm1, xmm5 + prefetchnta [arg2+fetch_dist+32] movdqa xmm4, xmm2 movdqa xmm5, xmm3 diff --git a/ceph/src/isa-l/crc/crc32_ieee_perf.c b/ceph/src/isa-l/crc/crc32_ieee_perf.c index 0a7559cd2..c6c74950e 100644 --- a/ceph/src/isa-l/crc/crc32_ieee_perf.c +++ b/ceph/src/isa-l/crc/crc32_ieee_perf.c @@ -72,6 +72,7 @@ int main(int argc, char *argv[]) printf("Start timed tests\n"); fflush(0); + memset(buf, 0, TEST_LEN); crc = crc32_ieee(TEST_SEED, buf, TEST_LEN); perf_start(&start); for (i = 0; i < TEST_LOOPS; i++) { diff --git a/ceph/src/isa-l/crc/crc32_iscsi_00.asm b/ceph/src/isa-l/crc/crc32_iscsi_00.asm index 0503e8f09..2833a8d0d 100644 --- a/ceph/src/isa-l/crc/crc32_iscsi_00.asm +++ b/ceph/src/isa-l/crc/crc32_iscsi_00.asm @@ -57,6 +57,9 @@ default rel %assign i 0 %rep %%bSize/8 - 1 + %if i < %%bSize*3/4 + prefetchnta [bufptmp+ %%bSize*3 +i*4] + %endif crc32 rax, qword [bufptmp+i + 0*%%bSize] ;; update crc0 crc32 rbx, qword [bufptmp+i + 1*%%bSize] ;; update crc1 crc32 r10, qword [bufptmp+i + 2*%%bSize] ;; update crc2 diff --git a/ceph/src/isa-l/crc/crc32_iscsi_01.asm b/ceph/src/isa-l/crc/crc32_iscsi_01.asm index f323a23bd..5b730f639 100644 --- a/ceph/src/isa-l/crc/crc32_iscsi_01.asm +++ b/ceph/src/isa-l/crc/crc32_iscsi_01.asm @@ -196,6 +196,10 @@ CONCAT(crc_,i,:) crc32 crc_init, qword [block_0 - i*8] crc32 crc1, qword [block_1 - i*8] crc32 crc2, qword [block_2 - i*8] + + %if i > 128*8 / 32 ; prefetch next 3KB data + prefetchnta [block_2 + 128*32 - i*32] + %endif %assign i (i-1) %endrep diff --git a/ceph/src/isa-l/crc/crc32_iscsi_perf.c b/ceph/src/isa-l/crc/crc32_iscsi_perf.c index ddcb2b2ee..2770099ae 100644 --- a/ceph/src/isa-l/crc/crc32_iscsi_perf.c +++ b/ceph/src/isa-l/crc/crc32_iscsi_perf.c @@ -72,6 +72,7 @@ int main(int argc, char *argv[]) printf("Start timed tests\n"); fflush(0); + memset(buf, 0, TEST_LEN); crc = crc32_iscsi(buf, TEST_LEN, TEST_SEED); perf_start(&start); for (i = 0; i < TEST_LOOPS; i++) { diff --git a/ceph/src/isa-l/crc/crc64_base.c b/ceph/src/isa-l/crc/crc64_base.c new file mode 100644 index 000000000..29166f901 --- /dev/null +++ b/ceph/src/isa-l/crc/crc64_base.c @@ -0,0 +1,159 @@ +/********************************************************************** + Copyright(c) 2011-2016 Intel Corporation All rights reserved. + + 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 Intel Corporation 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 + 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. +**********************************************************************/ + +#include +#include "crc64.h" + +#define MAX_ITER 8 + +// crc64_ecma baseline function +// Slow crc64 from the definition. Can be sped up with a lookup table. +uint64_t crc64_ecma_refl_base(uint64_t seed, const uint8_t * buf, uint64_t len) +{ + uint64_t rem = ~seed; + unsigned int i, j; + + uint64_t poly = 0xC96C5795D7870F42ULL; // ECMA-182 standard reflected + + for (i = 0; i < len; i++) { + rem = rem ^ (uint64_t) buf[i]; + for (j = 0; j < MAX_ITER; j++) { + rem = (rem & 0x1ULL ? poly : 0) ^ (rem >> 1); + } + } + return ~rem; +} + +uint64_t crc64_ecma_norm_base(uint64_t seed, const uint8_t * buf, uint64_t len) +{ + uint64_t rem = ~seed; + unsigned int i, j; + + uint64_t poly = 0x42F0E1EBA9EA3693ULL; // ECMA-182 standard + + for (i = 0; i < len; i++) { + rem = rem ^ ((uint64_t) buf[i] << 56); + for (j = 0; j < MAX_ITER; j++) { + rem = (rem & 0x8000000000000000ULL ? poly : 0) ^ (rem << 1); + } + } + return ~rem; +} + +// crc64_iso baseline function +// Slow crc64 from the definition. Can be sped up with a lookup table. +uint64_t crc64_iso_refl_base(uint64_t seed, const uint8_t * buf, uint64_t len) +{ + uint64_t rem = ~seed; + unsigned int i, j; + + uint64_t poly = 0xD800000000000000ULL; // ISO standard reflected + + for (i = 0; i < len; i++) { + rem = rem ^ (uint64_t) buf[i]; + for (j = 0; j < MAX_ITER; j++) { + rem = (rem & 0x1ULL ? poly : 0) ^ (rem >> 1); + } + } + return ~rem; +} + +uint64_t crc64_iso_norm_base(uint64_t seed, const uint8_t * buf, uint64_t len) +{ + uint64_t rem = ~seed; + unsigned int i, j; + + uint64_t poly = 0x000000000000001BULL; // ISO standard + + for (i = 0; i < len; i++) { + rem = rem ^ ((uint64_t) buf[i] << 56); + for (j = 0; j < MAX_ITER; j++) { + rem = (rem & 0x8000000000000000ULL ? poly : 0) ^ (rem << 1); + } + } + return ~rem; +} + +// crc64_jones baseline function +// Slow crc64 from the definition. Can be sped up with a lookup table. +uint64_t crc64_jones_refl_base(uint64_t seed, const uint8_t * buf, uint64_t len) +{ + uint64_t rem = ~seed; + unsigned int i, j; + + uint64_t poly = 0x95ac9329ac4bc9b5ULL; // Jones coefficients reflected + + for (i = 0; i < len; i++) { + rem = rem ^ (uint64_t) buf[i]; + for (j = 0; j < MAX_ITER; j++) { + rem = (rem & 0x1ULL ? poly : 0) ^ (rem >> 1); + } + } + return ~rem; +} + +uint64_t crc64_jones_norm_base(uint64_t seed, const uint8_t * buf, uint64_t len) +{ + uint64_t rem = ~seed; + unsigned int i, j; + + uint64_t poly = 0xad93d23594c935a9ULL; // Jones coefficients + + for (i = 0; i < len; i++) { + rem = rem ^ ((uint64_t) buf[i] << 56); + for (j = 0; j < MAX_ITER; j++) { + rem = (rem & 0x8000000000000000ULL ? poly : 0) ^ (rem << 1); + } + } + return ~rem; +} + +struct slver { + unsigned short snum; + unsigned char ver; + unsigned char core; +}; + +struct slver crc64_ecma_refl_base_slver_0000001c; +struct slver crc64_ecma_refl_base_slver = { 0x001c, 0x00, 0x00 }; + +struct slver crc64_ecma_norm_base_slver_00000019; +struct slver crc64_ecma_norm_base_slver = { 0x0019, 0x00, 0x00 }; + +struct slver crc64_iso_refl_base_slver_00000022; +struct slver crc64_iso_refl_base_slver = { 0x0022, 0x00, 0x00 }; + +struct slver crc64_iso_norm_base_slver_0000001f; +struct slver crc64_iso_norm_base_slver = { 0x001f, 0x00, 0x00 }; + +struct slver crc64_jones_refl_base_slver_00000028; +struct slver crc64_jones_refl_base_slver = { 0x0028, 0x00, 0x00 }; + +struct slver crc64_jones_norm_base_slver_00000025; +struct slver crc64_jones_norm_base_slver = { 0x0025, 0x00, 0x00 }; diff --git a/ceph/src/isa-l/crc/crc64_ecma_norm_by8.asm b/ceph/src/isa-l/crc/crc64_ecma_norm_by8.asm new file mode 100644 index 000000000..cff01e1c8 --- /dev/null +++ b/ceph/src/isa-l/crc/crc64_ecma_norm_by8.asm @@ -0,0 +1,583 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2016 Intel Corporation All rights reserved. +; +; 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 Intel Corporation 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 +; 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. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Function API: +; uint64_t crc64_ecma_norm_by8( +; uint64_t init_crc, //initial CRC value, 64 bits +; const unsigned char *buf, //buffer pointer to calculate CRC on +; uint64_t len //buffer length in bytes (64-bit data) +; ); +; +; yasm -f x64 -f elf64 -X gnu -g dwarf2 crc64_ecma_norm_by8 +%include "reg_sizes.asm" + +%define fetch_dist 1024 + +[bits 64] +default rel + +section .text + +%ifidn __OUTPUT_FORMAT__, win64 + %xdefine arg1 rcx + %xdefine arg2 rdx + %xdefine arg3 r8 +%else + %xdefine arg1 rdi + %xdefine arg2 rsi + %xdefine arg3 rdx +%endif + +%define TMP 16*0 +%ifidn __OUTPUT_FORMAT__, win64 + %define XMM_SAVE 16*2 + %define VARIABLE_OFFSET 16*10+8 +%else + %define VARIABLE_OFFSET 16*2+8 +%endif +align 16 +global crc64_ecma_norm_by8:function +crc64_ecma_norm_by8: + + not arg1 ;~init_crc + + sub rsp,VARIABLE_OFFSET + +%ifidn __OUTPUT_FORMAT__, win64 + ; push the xmm registers into the stack to maintain + movdqa [rsp + XMM_SAVE + 16*0], xmm6 + movdqa [rsp + XMM_SAVE + 16*1], xmm7 + movdqa [rsp + XMM_SAVE + 16*2], xmm8 + movdqa [rsp + XMM_SAVE + 16*3], xmm9 + movdqa [rsp + XMM_SAVE + 16*4], xmm10 + movdqa [rsp + XMM_SAVE + 16*5], xmm11 + movdqa [rsp + XMM_SAVE + 16*6], xmm12 + movdqa [rsp + XMM_SAVE + 16*7], xmm13 +%endif + + + ; check if smaller than 256 + cmp arg3, 256 + + ; for sizes less than 256, we can't fold 128B at a time... + jl _less_than_256 + + + ; load the initial crc value + movq xmm10, arg1 ; initial crc + + ; crc value does not need to be byte-reflected, but it needs to be moved to the high part of the register. + ; because data will be byte-reflected and will align with initial crc at correct place. + pslldq xmm10, 8 + + movdqa xmm11, [SHUF_MASK] + ; receive the initial 128B data, xor the initial crc value + movdqu xmm0, [arg2+16*0] + movdqu xmm1, [arg2+16*1] + movdqu xmm2, [arg2+16*2] + movdqu xmm3, [arg2+16*3] + movdqu xmm4, [arg2+16*4] + movdqu xmm5, [arg2+16*5] + movdqu xmm6, [arg2+16*6] + movdqu xmm7, [arg2+16*7] + + pshufb xmm0, xmm11 + ; XOR the initial_crc value + pxor xmm0, xmm10 + pshufb xmm1, xmm11 + pshufb xmm2, xmm11 + pshufb xmm3, xmm11 + pshufb xmm4, xmm11 + pshufb xmm5, xmm11 + pshufb xmm6, xmm11 + pshufb xmm7, xmm11 + + movdqa xmm10, [rk3] ;xmm10 has rk3 and rk4 + ;imm value of pclmulqdq instruction will determine which constant to use + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ; we subtract 256 instead of 128 to save one instruction from the loop + sub arg3, 256 + + ; at this section of the code, there is 128*x+y (0<=y<128) bytes of buffer. The _fold_128_B_loop + ; loop will fold 128B at a time until we have 128+y Bytes of buffer + + + ; fold 128B at a time. This section of the code folds 8 xmm registers in parallel +_fold_128_B_loop: + + ; update the buffer pointer + add arg2, 128 ; buf += 128; + + prefetchnta [arg2+fetch_dist+0] + movdqu xmm9, [arg2+16*0] + movdqu xmm12, [arg2+16*1] + pshufb xmm9, xmm11 + pshufb xmm12, xmm11 + movdqa xmm8, xmm0 + movdqa xmm13, xmm1 + pclmulqdq xmm0, xmm10, 0x0 + pclmulqdq xmm8, xmm10 , 0x11 + pclmulqdq xmm1, xmm10, 0x0 + pclmulqdq xmm13, xmm10 , 0x11 + pxor xmm0, xmm9 + xorps xmm0, xmm8 + pxor xmm1, xmm12 + xorps xmm1, xmm13 + + prefetchnta [arg2+fetch_dist+32] + movdqu xmm9, [arg2+16*2] + movdqu xmm12, [arg2+16*3] + pshufb xmm9, xmm11 + pshufb xmm12, xmm11 + movdqa xmm8, xmm2 + movdqa xmm13, xmm3 + pclmulqdq xmm2, xmm10, 0x0 + pclmulqdq xmm8, xmm10 , 0x11 + pclmulqdq xmm3, xmm10, 0x0 + pclmulqdq xmm13, xmm10 , 0x11 + pxor xmm2, xmm9 + xorps xmm2, xmm8 + pxor xmm3, xmm12 + xorps xmm3, xmm13 + + prefetchnta [arg2+fetch_dist+64] + movdqu xmm9, [arg2+16*4] + movdqu xmm12, [arg2+16*5] + pshufb xmm9, xmm11 + pshufb xmm12, xmm11 + movdqa xmm8, xmm4 + movdqa xmm13, xmm5 + pclmulqdq xmm4, xmm10, 0x0 + pclmulqdq xmm8, xmm10 , 0x11 + pclmulqdq xmm5, xmm10, 0x0 + pclmulqdq xmm13, xmm10 , 0x11 + pxor xmm4, xmm9 + xorps xmm4, xmm8 + pxor xmm5, xmm12 + xorps xmm5, xmm13 + + prefetchnta [arg2+fetch_dist+96] + movdqu xmm9, [arg2+16*6] + movdqu xmm12, [arg2+16*7] + pshufb xmm9, xmm11 + pshufb xmm12, xmm11 + movdqa xmm8, xmm6 + movdqa xmm13, xmm7 + pclmulqdq xmm6, xmm10, 0x0 + pclmulqdq xmm8, xmm10 , 0x11 + pclmulqdq xmm7, xmm10, 0x0 + pclmulqdq xmm13, xmm10 , 0x11 + pxor xmm6, xmm9 + xorps xmm6, xmm8 + pxor xmm7, xmm12 + xorps xmm7, xmm13 + + sub arg3, 128 + + ; check if there is another 128B in the buffer to be able to fold + jge _fold_128_B_loop + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + add arg2, 128 + ; at this point, the buffer pointer is pointing at the last y Bytes of the buffer, where 0 <= y < 128 + ; the 128B of folded data is in 8 of the xmm registers: xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7 + + + ; fold the 8 xmm registers to 1 xmm register with different constants + + movdqa xmm10, [rk9] + movdqa xmm8, xmm0 + pclmulqdq xmm0, xmm10, 0x11 + pclmulqdq xmm8, xmm10, 0x0 + pxor xmm7, xmm8 + xorps xmm7, xmm0 + + movdqa xmm10, [rk11] + movdqa xmm8, xmm1 + pclmulqdq xmm1, xmm10, 0x11 + pclmulqdq xmm8, xmm10, 0x0 + pxor xmm7, xmm8 + xorps xmm7, xmm1 + + movdqa xmm10, [rk13] + movdqa xmm8, xmm2 + pclmulqdq xmm2, xmm10, 0x11 + pclmulqdq xmm8, xmm10, 0x0 + pxor xmm7, xmm8 + pxor xmm7, xmm2 + + movdqa xmm10, [rk15] + movdqa xmm8, xmm3 + pclmulqdq xmm3, xmm10, 0x11 + pclmulqdq xmm8, xmm10, 0x0 + pxor xmm7, xmm8 + xorps xmm7, xmm3 + + movdqa xmm10, [rk17] + movdqa xmm8, xmm4 + pclmulqdq xmm4, xmm10, 0x11 + pclmulqdq xmm8, xmm10, 0x0 + pxor xmm7, xmm8 + pxor xmm7, xmm4 + + movdqa xmm10, [rk19] + movdqa xmm8, xmm5 + pclmulqdq xmm5, xmm10, 0x11 + pclmulqdq xmm8, xmm10, 0x0 + pxor xmm7, xmm8 + xorps xmm7, xmm5 + + movdqa xmm10, [rk1] ;xmm10 has rk1 and rk2 + + movdqa xmm8, xmm6 + pclmulqdq xmm6, xmm10, 0x11 + pclmulqdq xmm8, xmm10, 0x0 + pxor xmm7, xmm8 + pxor xmm7, xmm6 + + + ; instead of 128, we add 112 to the loop counter to save 1 instruction from the loop + ; instead of a cmp instruction, we use the negative flag with the jl instruction + add arg3, 128-16 + jl _final_reduction_for_128 + + ; now we have 16+y bytes left to reduce. 16 Bytes is in register xmm7 and the rest is in memory + ; we can fold 16 bytes at a time if y>=16 + ; continue folding 16B at a time + +_16B_reduction_loop: + movdqa xmm8, xmm7 + pclmulqdq xmm7, xmm10, 0x11 + pclmulqdq xmm8, xmm10, 0x0 + pxor xmm7, xmm8 + movdqu xmm0, [arg2] + pshufb xmm0, xmm11 + pxor xmm7, xmm0 + add arg2, 16 + sub arg3, 16 + ; instead of a cmp instruction, we utilize the flags with the jge instruction + ; equivalent of: cmp arg3, 16-16 + ; check if there is any more 16B in the buffer to be able to fold + jge _16B_reduction_loop + + ;now we have 16+z bytes left to reduce, where 0<= z < 16. + ;first, we reduce the data in the xmm7 register + + +_final_reduction_for_128: + ; check if any more data to fold. If not, compute the CRC of the final 128 bits + add arg3, 16 + je _128_done + + ; here we are getting data that is less than 16 bytes. + ; since we know that there was data before the pointer, we can offset the input pointer before the actual point, to receive exactly 16 bytes. + ; after that the registers need to be adjusted. +_get_last_two_xmms: + movdqa xmm2, xmm7 + + movdqu xmm1, [arg2 - 16 + arg3] + pshufb xmm1, xmm11 + + ; get rid of the extra data that was loaded before + ; load the shift constant + lea rax, [pshufb_shf_table + 16] + sub rax, arg3 + movdqu xmm0, [rax] + + ; shift xmm2 to the left by arg3 bytes + pshufb xmm2, xmm0 + + ; shift xmm7 to the right by 16-arg3 bytes + pxor xmm0, [mask1] + pshufb xmm7, xmm0 + pblendvb xmm1, xmm2 ;xmm0 is implicit + + ; fold 16 Bytes + movdqa xmm2, xmm1 + movdqa xmm8, xmm7 + pclmulqdq xmm7, xmm10, 0x11 + pclmulqdq xmm8, xmm10, 0x0 + pxor xmm7, xmm8 + pxor xmm7, xmm2 + +_128_done: + ; compute crc of a 128-bit value + movdqa xmm10, [rk5] ; rk5 and rk6 in xmm10 + movdqa xmm0, xmm7 + + ;64b fold + pclmulqdq xmm7, xmm10, 0x01 ; H*L + pslldq xmm0, 8 + pxor xmm7, xmm0 + + ;barrett reduction +_barrett: + movdqa xmm10, [rk7] ; rk7 and rk8 in xmm10 + movdqa xmm0, xmm7 + + movdqa xmm1, xmm7 + pand xmm1, [mask3] + pclmulqdq xmm7, xmm10, 0x01 + pxor xmm7, xmm1 + + pclmulqdq xmm7, xmm10, 0x11 + pxor xmm7, xmm0 + pextrq rax, xmm7, 0 + +_cleanup: + not rax +%ifidn __OUTPUT_FORMAT__, win64 + movdqa xmm6, [rsp + XMM_SAVE + 16*0] + movdqa xmm7, [rsp + XMM_SAVE + 16*1] + movdqa xmm8, [rsp + XMM_SAVE + 16*2] + movdqa xmm9, [rsp + XMM_SAVE + 16*3] + movdqa xmm10, [rsp + XMM_SAVE + 16*4] + movdqa xmm11, [rsp + XMM_SAVE + 16*5] + movdqa xmm12, [rsp + XMM_SAVE + 16*6] + movdqa xmm13, [rsp + XMM_SAVE + 16*7] +%endif + add rsp, VARIABLE_OFFSET + ret + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align 16 +_less_than_256: + + ; check if there is enough buffer to be able to fold 16B at a time + cmp arg3, 32 + jl _less_than_32 + movdqa xmm11, [SHUF_MASK] + + ; if there is, load the constants + movdqa xmm10, [rk1] ; rk1 and rk2 in xmm10 + + movq xmm0, arg1 ; get the initial crc value + pslldq xmm0, 8 ; align it to its correct place + movdqu xmm7, [arg2] ; load the plaintext + pshufb xmm7, xmm11 ; byte-reflect the plaintext + pxor xmm7, xmm0 + + + ; update the buffer pointer + add arg2, 16 + + ; update the counter. subtract 32 instead of 16 to save one instruction from the loop + sub arg3, 32 + + jmp _16B_reduction_loop +align 16 +_less_than_32: + ; mov initial crc to the return value. this is necessary for zero-length buffers. + mov rax, arg1 + test arg3, arg3 + je _cleanup + + movdqa xmm11, [SHUF_MASK] + + movq xmm0, arg1 ; get the initial crc value + pslldq xmm0, 8 ; align it to its correct place + + cmp arg3, 16 + je _exact_16_left + jl _less_than_16_left + + movdqu xmm7, [arg2] ; load the plaintext + pshufb xmm7, xmm11 ; byte-reflect the plaintext + pxor xmm7, xmm0 ; xor the initial crc value + add arg2, 16 + sub arg3, 16 + movdqa xmm10, [rk1] ; rk1 and rk2 in xmm10 + jmp _get_last_two_xmms +align 16 +_less_than_16_left: + ; use stack space to load data less than 16 bytes, zero-out the 16B in memory first. + pxor xmm1, xmm1 + mov r11, rsp + movdqa [r11], xmm1 + + ; backup the counter value + mov r9, arg3 + cmp arg3, 8 + jl _less_than_8_left + + ; load 8 Bytes + mov rax, [arg2] + mov [r11], rax + add r11, 8 + sub arg3, 8 + add arg2, 8 +_less_than_8_left: + + cmp arg3, 4 + jl _less_than_4_left + + ; load 4 Bytes + mov eax, [arg2] + mov [r11], eax + add r11, 4 + sub arg3, 4 + add arg2, 4 +_less_than_4_left: + + cmp arg3, 2 + jl _less_than_2_left + + ; load 2 Bytes + mov ax, [arg2] + mov [r11], ax + add r11, 2 + sub arg3, 2 + add arg2, 2 +_less_than_2_left: + cmp arg3, 1 + jl _zero_left + + ; load 1 Byte + mov al, [arg2] + mov [r11], al +_zero_left: + movdqa xmm7, [rsp] + pshufb xmm7, xmm11 + pxor xmm7, xmm0 ; xor the initial crc value + + ; shl r9, 4 + lea rax, [pshufb_shf_table + 16] + sub rax, r9 + + cmp r9, 8 + jl _end_1to7 + +_end_8to15: + movdqu xmm0, [rax] + pxor xmm0, [mask1] + + pshufb xmm7, xmm0 + jmp _128_done + +_end_1to7: + ; Right shift (8-length) bytes in XMM + add rax, 8 + movdqu xmm0, [rax] + pshufb xmm7,xmm0 + + jmp _barrett +align 16 +_exact_16_left: + movdqu xmm7, [arg2] + pshufb xmm7, xmm11 + pxor xmm7, xmm0 ; xor the initial crc value + + jmp _128_done + +section .data + +; precomputed constants +align 16 + +rk1 : +DQ 0x5f5c3c7eb52fab6 +rk2 : +DQ 0x4eb938a7d257740e +rk3 : +DQ 0x5cf79dea9ac37d6 +rk4 : +DQ 0x001067e571d7d5c2 +rk5 : +DQ 0x5f5c3c7eb52fab6 +rk6 : +DQ 0x0000000000000000 +rk7 : +DQ 0x578d29d06cc4f872 +rk8 : +DQ 0x42f0e1eba9ea3693 +rk9 : +DQ 0xe464f4df5fb60ac1 +rk10 : +DQ 0xb649c5b35a759cf2 +rk11 : +DQ 0x9af04e1eff82d0dd +rk12 : +DQ 0x6e82e609297f8fe8 +rk13 : +DQ 0x97c516e98bd2e73 +rk14 : +DQ 0xb76477b31e22e7b +rk15 : +DQ 0x5f6843ca540df020 +rk16 : +DQ 0xddf4b6981205b83f +rk17 : +DQ 0x54819d8713758b2c +rk18 : +DQ 0x4a6b90073eb0af5a +rk19 : +DQ 0x571bee0a227ef92b +rk20 : +DQ 0x44bef2a201b5200c + + +mask1: +dq 0x8080808080808080, 0x8080808080808080 +mask2: +dq 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF +mask3: +dq 0x0000000000000000, 0xFFFFFFFFFFFFFFFF + +SHUF_MASK: +dq 0x08090A0B0C0D0E0F, 0x0001020304050607 + +pshufb_shf_table: +; use these values for shift constants for the pshufb instruction +; different alignments result in values as shown: +; dq 0x8887868584838281, 0x008f8e8d8c8b8a89 ; shl 15 (16-1) / shr1 +; dq 0x8988878685848382, 0x01008f8e8d8c8b8a ; shl 14 (16-3) / shr2 +; dq 0x8a89888786858483, 0x0201008f8e8d8c8b ; shl 13 (16-4) / shr3 +; dq 0x8b8a898887868584, 0x030201008f8e8d8c ; shl 12 (16-4) / shr4 +; dq 0x8c8b8a8988878685, 0x04030201008f8e8d ; shl 11 (16-5) / shr5 +; dq 0x8d8c8b8a89888786, 0x0504030201008f8e ; shl 10 (16-6) / shr6 +; dq 0x8e8d8c8b8a898887, 0x060504030201008f ; shl 9 (16-7) / shr7 +; dq 0x8f8e8d8c8b8a8988, 0x0706050403020100 ; shl 8 (16-8) / shr8 +; dq 0x008f8e8d8c8b8a89, 0x0807060504030201 ; shl 7 (16-9) / shr9 +; dq 0x01008f8e8d8c8b8a, 0x0908070605040302 ; shl 6 (16-10) / shr10 +; dq 0x0201008f8e8d8c8b, 0x0a09080706050403 ; shl 5 (16-11) / shr11 +; dq 0x030201008f8e8d8c, 0x0b0a090807060504 ; shl 4 (16-12) / shr12 +; dq 0x04030201008f8e8d, 0x0c0b0a0908070605 ; shl 3 (16-13) / shr13 +; dq 0x0504030201008f8e, 0x0d0c0b0a09080706 ; shl 2 (16-14) / shr14 +; dq 0x060504030201008f, 0x0e0d0c0b0a090807 ; shl 1 (16-15) / shr15 +dq 0x8786858483828100, 0x8f8e8d8c8b8a8988 +dq 0x0706050403020100, 0x0f0e0d0c0b0a0908 +dq 0x8080808080808080, 0x0f0e0d0c0b0a0908 +dq 0x8080808080808080, 0x8080808080808080 + +;;; func core, ver, snum +slversion crc64_ecma_norm_by8, 01, 00, 001a diff --git a/ceph/src/isa-l/crc/crc64_ecma_refl_by8.asm b/ceph/src/isa-l/crc/crc64_ecma_refl_by8.asm new file mode 100644 index 000000000..9d3847e96 --- /dev/null +++ b/ceph/src/isa-l/crc/crc64_ecma_refl_by8.asm @@ -0,0 +1,548 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2016 Intel Corporation All rights reserved. +; +; 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 Intel Corporation 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 +; 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. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Function API: +; uint64_t crc64_ecma_refl_by8( +; uint64_t init_crc, //initial CRC value, 64 bits +; const unsigned char *buf, //buffer pointer to calculate CRC on +; uint64_t len //buffer length in bytes (64-bit data) +; ); +; +; Reference paper titled "Fast CRC Computation for Generic Polynomials Using PCLMULQDQ Instruction" +; sample yasm command line: +; yasm -f x64 -f elf64 -X gnu -g dwarf2 crc64_ecma_refl_by8 +%include "reg_sizes.asm" + +%define fetch_dist 1024 + +[bits 64] +default rel + +section .text + + +%ifidn __OUTPUT_FORMAT__, win64 + %xdefine arg1 rcx + %xdefine arg2 rdx + %xdefine arg3 r8 +%else + %xdefine arg1 rdi + %xdefine arg2 rsi + %xdefine arg3 rdx +%endif + +%define TMP 16*0 +%ifidn __OUTPUT_FORMAT__, win64 + %define XMM_SAVE 16*2 + %define VARIABLE_OFFSET 16*10+8 +%else + %define VARIABLE_OFFSET 16*2+8 +%endif + + +align 16 +global crc64_ecma_refl_by8:function +crc64_ecma_refl_by8: + ; uint64_t c = crc ^ 0xffffffff,ffffffffL; + not arg1 + sub rsp, VARIABLE_OFFSET + +%ifidn __OUTPUT_FORMAT__, win64 + ; push the xmm registers into the stack to maintain + movdqa [rsp + XMM_SAVE + 16*0], xmm6 + movdqa [rsp + XMM_SAVE + 16*1], xmm7 + movdqa [rsp + XMM_SAVE + 16*2], xmm8 + movdqa [rsp + XMM_SAVE + 16*3], xmm9 + movdqa [rsp + XMM_SAVE + 16*4], xmm10 + movdqa [rsp + XMM_SAVE + 16*5], xmm11 + movdqa [rsp + XMM_SAVE + 16*6], xmm12 + movdqa [rsp + XMM_SAVE + 16*7], xmm13 +%endif + + ; check if smaller than 256B + cmp arg3, 256 + + ; for sizes less than 256, we can't fold 128B at a time... + jl _less_than_256 + + + ; load the initial crc value + movq xmm10, arg1 ; initial crc + ; receive the initial 128B data, xor the initial crc value + movdqu xmm0, [arg2+16*0] + movdqu xmm1, [arg2+16*1] + movdqu xmm2, [arg2+16*2] + movdqu xmm3, [arg2+16*3] + movdqu xmm4, [arg2+16*4] + movdqu xmm5, [arg2+16*5] + movdqu xmm6, [arg2+16*6] + movdqu xmm7, [arg2+16*7] + + ; XOR the initial_crc value + pxor xmm0, xmm10 + movdqa xmm10, [rk3] ;xmm10 has rk3 and rk4 + ;imm value of pclmulqdq instruction will determine which constant to use + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ; we subtract 256 instead of 128 to save one instruction from the loop + sub arg3, 256 + + ; at this section of the code, there is 128*x+y (0<=y<128) bytes of buffer. The _fold_128_B_loop + ; loop will fold 128B at a time until we have 128+y Bytes of buffer + + + ; fold 128B at a time. This section of the code folds 8 xmm registers in parallel +_fold_128_B_loop: + + ; update the buffer pointer + add arg2, 128 + + prefetchnta [arg2+fetch_dist+0] + movdqu xmm9, [arg2+16*0] + movdqu xmm12, [arg2+16*1] + movdqa xmm8, xmm0 + movdqa xmm13, xmm1 + pclmulqdq xmm0, xmm10, 0x10 + pclmulqdq xmm8, xmm10 , 0x1 + pclmulqdq xmm1, xmm10, 0x10 + pclmulqdq xmm13, xmm10 , 0x1 + pxor xmm0, xmm9 + xorps xmm0, xmm8 + pxor xmm1, xmm12 + xorps xmm1, xmm13 + + prefetchnta [arg2+fetch_dist+32] + movdqu xmm9, [arg2+16*2] + movdqu xmm12, [arg2+16*3] + movdqa xmm8, xmm2 + movdqa xmm13, xmm3 + pclmulqdq xmm2, xmm10, 0x10 + pclmulqdq xmm8, xmm10 , 0x1 + pclmulqdq xmm3, xmm10, 0x10 + pclmulqdq xmm13, xmm10 , 0x1 + pxor xmm2, xmm9 + xorps xmm2, xmm8 + pxor xmm3, xmm12 + xorps xmm3, xmm13 + + prefetchnta [arg2+fetch_dist+64] + movdqu xmm9, [arg2+16*4] + movdqu xmm12, [arg2+16*5] + movdqa xmm8, xmm4 + movdqa xmm13, xmm5 + pclmulqdq xmm4, xmm10, 0x10 + pclmulqdq xmm8, xmm10 , 0x1 + pclmulqdq xmm5, xmm10, 0x10 + pclmulqdq xmm13, xmm10 , 0x1 + pxor xmm4, xmm9 + xorps xmm4, xmm8 + pxor xmm5, xmm12 + xorps xmm5, xmm13 + + prefetchnta [arg2+fetch_dist+96] + movdqu xmm9, [arg2+16*6] + movdqu xmm12, [arg2+16*7] + movdqa xmm8, xmm6 + movdqa xmm13, xmm7 + pclmulqdq xmm6, xmm10, 0x10 + pclmulqdq xmm8, xmm10 , 0x1 + pclmulqdq xmm7, xmm10, 0x10 + pclmulqdq xmm13, xmm10 , 0x1 + pxor xmm6, xmm9 + xorps xmm6, xmm8 + pxor xmm7, xmm12 + xorps xmm7, xmm13 + + sub arg3, 128 + + ; check if there is another 128B in the buffer to be able to fold + jge _fold_128_B_loop + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + add arg2, 128 + ; at this point, the buffer pointer is pointing at the last y Bytes of the buffer, where 0 <= y < 128 + ; the 128B of folded data is in 8 of the xmm registers: xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7 + + + ; fold the 8 xmm registers to 1 xmm register with different constants + ; xmm0 to xmm7 + movdqa xmm10, [rk9] + movdqa xmm8, xmm0 + pclmulqdq xmm0, xmm10, 0x1 + pclmulqdq xmm8, xmm10, 0x10 + pxor xmm7, xmm8 + xorps xmm7, xmm0 + ;xmm1 to xmm7 + movdqa xmm10, [rk11] + movdqa xmm8, xmm1 + pclmulqdq xmm1, xmm10, 0x1 + pclmulqdq xmm8, xmm10, 0x10 + pxor xmm7, xmm8 + xorps xmm7, xmm1 + + movdqa xmm10, [rk13] + movdqa xmm8, xmm2 + pclmulqdq xmm2, xmm10, 0x1 + pclmulqdq xmm8, xmm10, 0x10 + pxor xmm7, xmm8 + pxor xmm7, xmm2 + + movdqa xmm10, [rk15] + movdqa xmm8, xmm3 + pclmulqdq xmm3, xmm10, 0x1 + pclmulqdq xmm8, xmm10, 0x10 + pxor xmm7, xmm8 + xorps xmm7, xmm3 + + movdqa xmm10, [rk17] + movdqa xmm8, xmm4 + pclmulqdq xmm4, xmm10, 0x1 + pclmulqdq xmm8, xmm10, 0x10 + pxor xmm7, xmm8 + pxor xmm7, xmm4 + + movdqa xmm10, [rk19] + movdqa xmm8, xmm5 + pclmulqdq xmm5, xmm10, 0x1 + pclmulqdq xmm8, xmm10, 0x10 + pxor xmm7, xmm8 + xorps xmm7, xmm5 + ; xmm6 to xmm7 + movdqa xmm10, [rk1] + movdqa xmm8, xmm6 + pclmulqdq xmm6, xmm10, 0x1 + pclmulqdq xmm8, xmm10, 0x10 + pxor xmm7, xmm8 + pxor xmm7, xmm6 + + + ; instead of 128, we add 128-16 to the loop counter to save 1 instruction from the loop + ; instead of a cmp instruction, we use the negative flag with the jl instruction + add arg3, 128-16 + jl _final_reduction_for_128 + + ; now we have 16+y bytes left to reduce. 16 Bytes is in register xmm7 and the rest is in memory + ; we can fold 16 bytes at a time if y>=16 + ; continue folding 16B at a time + +_16B_reduction_loop: + movdqa xmm8, xmm7 + pclmulqdq xmm7, xmm10, 0x1 + pclmulqdq xmm8, xmm10, 0x10 + pxor xmm7, xmm8 + movdqu xmm0, [arg2] + pxor xmm7, xmm0 + add arg2, 16 + sub arg3, 16 + ; instead of a cmp instruction, we utilize the flags with the jge instruction + ; equivalent of: cmp arg3, 16-16 + ; check if there is any more 16B in the buffer to be able to fold + jge _16B_reduction_loop + + ;now we have 16+z bytes left to reduce, where 0<= z < 16. + ;first, we reduce the data in the xmm7 register + + +_final_reduction_for_128: + add arg3, 16 + je _128_done + ; here we are getting data that is less than 16 bytes. + ; since we know that there was data before the pointer, we can offset the input pointer before the actual point, to receive exactly 16 bytes. + ; after that the registers need to be adjusted. +_get_last_two_xmms: + + + movdqa xmm2, xmm7 + movdqu xmm1, [arg2 - 16 + arg3] + + ; get rid of the extra data that was loaded before + ; load the shift constant + lea rax, [pshufb_shf_table] + add rax, arg3 + movdqu xmm0, [rax] + + + pshufb xmm7, xmm0 + pxor xmm0, [mask3] + pshufb xmm2, xmm0 + + pblendvb xmm2, xmm1 ;xmm0 is implicit + ;;;;;;;;;; + movdqa xmm8, xmm7 + pclmulqdq xmm7, xmm10, 0x1 + + pclmulqdq xmm8, xmm10, 0x10 + pxor xmm7, xmm8 + pxor xmm7, xmm2 + +_128_done: + ; compute crc of a 128-bit value + movdqa xmm10, [rk5] + movdqa xmm0, xmm7 + + ;64b fold + pclmulqdq xmm7, xmm10, 0 + psrldq xmm0, 8 + pxor xmm7, xmm0 + + ;barrett reduction +_barrett: + movdqa xmm1, xmm7 + movdqa xmm10, [rk7] + + pclmulqdq xmm7, xmm10, 0 + movdqa xmm2, xmm7 + pclmulqdq xmm7, xmm10, 0x10 + pslldq xmm2, 8 + pxor xmm7, xmm2 + pxor xmm7, xmm1 + pextrq rax, xmm7, 1 + +_cleanup: + ; return c ^ 0xffffffff, ffffffffL; + not rax + + +%ifidn __OUTPUT_FORMAT__, win64 + movdqa xmm6, [rsp + XMM_SAVE + 16*0] + movdqa xmm7, [rsp + XMM_SAVE + 16*1] + movdqa xmm8, [rsp + XMM_SAVE + 16*2] + movdqa xmm9, [rsp + XMM_SAVE + 16*3] + movdqa xmm10, [rsp + XMM_SAVE + 16*4] + movdqa xmm11, [rsp + XMM_SAVE + 16*5] + movdqa xmm12, [rsp + XMM_SAVE + 16*6] + movdqa xmm13, [rsp + XMM_SAVE + 16*7] +%endif + add rsp, VARIABLE_OFFSET + ret + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align 16 +_less_than_256: + + ; check if there is enough buffer to be able to fold 16B at a time + cmp arg3, 32 + jl _less_than_32 + + ; if there is, load the constants + movdqa xmm10, [rk1] ; rk1 and rk2 in xmm10 + + movq xmm0, arg1 ; get the initial crc value + movdqu xmm7, [arg2] ; load the plaintext + pxor xmm7, xmm0 + + ; update the buffer pointer + add arg2, 16 + + ; update the counter. subtract 32 instead of 16 to save one instruction from the loop + sub arg3, 32 + + jmp _16B_reduction_loop + +align 16 +_less_than_32: + ; mov initial crc to the return value. this is necessary for zero-length buffers. + mov rax, arg1 + test arg3, arg3 + je _cleanup + + movq xmm0, arg1 ; get the initial crc value + + cmp arg3, 16 + je _exact_16_left + jl _less_than_16_left + + movdqu xmm7, [arg2] ; load the plaintext + pxor xmm7, xmm0 ; xor the initial crc value + add arg2, 16 + sub arg3, 16 + movdqa xmm10, [rk1] ; rk1 and rk2 in xmm10 + jmp _get_last_two_xmms + + +align 16 +_less_than_16_left: + ; use stack space to load data less than 16 bytes, zero-out the 16B in memory first. + + pxor xmm1, xmm1 + mov r11, rsp + movdqa [r11], xmm1 + + ; backup the counter value + mov r9, arg3 + cmp arg3, 8 + jl _less_than_8_left + + ; load 8 Bytes + mov rax, [arg2] + mov [r11], rax + add r11, 8 + sub arg3, 8 + add arg2, 8 +_less_than_8_left: + + cmp arg3, 4 + jl _less_than_4_left + + ; load 4 Bytes + mov eax, [arg2] + mov [r11], eax + add r11, 4 + sub arg3, 4 + add arg2, 4 +_less_than_4_left: + + cmp arg3, 2 + jl _less_than_2_left + + ; load 2 Bytes + mov ax, [arg2] + mov [r11], ax + add r11, 2 + sub arg3, 2 + add arg2, 2 +_less_than_2_left: + cmp arg3, 1 + jl _zero_left + + ; load 1 Byte + mov al, [arg2] + mov [r11], al + +_zero_left: + movdqa xmm7, [rsp] + pxor xmm7, xmm0 ; xor the initial crc value + + lea rax,[pshufb_shf_table] + + cmp r9, 8 + jl _end_1to7 + +_end_8to15: + movdqu xmm0, [rax + r9] + pshufb xmm7,xmm0 + jmp _128_done + +_end_1to7: + ; Left shift (8-length) bytes in XMM + movdqu xmm0, [rax + r9 + 8] + pshufb xmm7,xmm0 + + jmp _barrett + +align 16 +_exact_16_left: + movdqu xmm7, [arg2] + pxor xmm7, xmm0 ; xor the initial crc value + + jmp _128_done + +section .data + +; precomputed constants +align 16 +; rk7 = floor(2^128/Q) +; rk8 = Q +rk1 : +DQ 0xdabe95afc7875f40 +rk2 : +DQ 0xe05dd497ca393ae4 +rk3 : +DQ 0xd7d86b2af73de740 +rk4 : +DQ 0x8757d71d4fcc1000 +rk5 : +DQ 0xdabe95afc7875f40 +rk6 : +DQ 0x0000000000000000 +rk7 : +DQ 0x9c3e466c172963d5 +rk8 : +DQ 0x92d8af2baf0e1e84 +rk9 : +DQ 0x947874de595052cb +rk10 : +DQ 0x9e735cb59b4724da +rk11 : +DQ 0xe4ce2cd55fea0037 +rk12 : +DQ 0x2fe3fd2920ce82ec +rk13 : +DQ 0xe31d519421a63a5 +rk14 : +DQ 0x2e30203212cac325 +rk15 : +DQ 0x81f6054a7842df4 +rk16 : +DQ 0x6ae3efbb9dd441f3 +rk17 : +DQ 0x69a35d91c3730254 +rk18 : +DQ 0xb5ea1af9c013aca4 +rk19 : +DQ 0x3be653a30fe1af51 +rk20 : +DQ 0x60095b008a9efa44 + + +pshufb_shf_table: +; use these values for shift constants for the pshufb instruction +; different alignments result in values as shown: +; dq 0x8887868584838281, 0x008f8e8d8c8b8a89 ; shl 15 (16-1) / shr1 +; dq 0x8988878685848382, 0x01008f8e8d8c8b8a ; shl 14 (16-3) / shr2 +; dq 0x8a89888786858483, 0x0201008f8e8d8c8b ; shl 13 (16-4) / shr3 +; dq 0x8b8a898887868584, 0x030201008f8e8d8c ; shl 12 (16-4) / shr4 +; dq 0x8c8b8a8988878685, 0x04030201008f8e8d ; shl 11 (16-5) / shr5 +; dq 0x8d8c8b8a89888786, 0x0504030201008f8e ; shl 10 (16-6) / shr6 +; dq 0x8e8d8c8b8a898887, 0x060504030201008f ; shl 9 (16-7) / shr7 +; dq 0x8f8e8d8c8b8a8988, 0x0706050403020100 ; shl 8 (16-8) / shr8 +; dq 0x008f8e8d8c8b8a89, 0x0807060504030201 ; shl 7 (16-9) / shr9 +; dq 0x01008f8e8d8c8b8a, 0x0908070605040302 ; shl 6 (16-10) / shr10 +; dq 0x0201008f8e8d8c8b, 0x0a09080706050403 ; shl 5 (16-11) / shr11 +; dq 0x030201008f8e8d8c, 0x0b0a090807060504 ; shl 4 (16-12) / shr12 +; dq 0x04030201008f8e8d, 0x0c0b0a0908070605 ; shl 3 (16-13) / shr13 +; dq 0x0504030201008f8e, 0x0d0c0b0a09080706 ; shl 2 (16-14) / shr14 +; dq 0x060504030201008f, 0x0e0d0c0b0a090807 ; shl 1 (16-15) / shr15 +dq 0x8786858483828100, 0x8f8e8d8c8b8a8988 +dq 0x0706050403020100, 0x000e0d0c0b0a0908 + + +mask: +dq 0xFFFFFFFFFFFFFFFF, 0x0000000000000000 +mask2: +dq 0xFFFFFFFF00000000, 0xFFFFFFFFFFFFFFFF +mask3: +dq 0x8080808080808080, 0x8080808080808080 + +;;; func core, ver, snum +slversion crc64_ecma_refl_by8, 01, 00, 001d diff --git a/ceph/src/isa-l/crc/crc64_example.c b/ceph/src/isa-l/crc/crc64_example.c new file mode 100644 index 000000000..64763a1b0 --- /dev/null +++ b/ceph/src/isa-l/crc/crc64_example.c @@ -0,0 +1,68 @@ +/********************************************************************** + Copyright(c) 2011-2016 Intel Corporation All rights reserved. + + 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 Intel Corporation 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 + 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. +**********************************************************************/ +#include +#include +#include +#include "crc64.h" + +#define BUF_SIZE 8192 +#define INIT_SEED 0x12345678 + +int main(int argc, char *argv[]) +{ + uint8_t inbuf[BUF_SIZE]; + uint64_t avail_in, total_in = 0; + uint64_t crc64_checksum; + FILE *in; + + if (argc != 2) { + fprintf(stderr, "Usage: crc64_example infile\n"); + exit(0); + } + in = fopen(argv[1], "rb"); + if (!in) { + fprintf(stderr, "Can't open %s for reading\n", argv[1]); + exit(0); + } + + printf("crc64_example -- crc64_ecma_refl:\n"); + fflush(0); + + crc64_checksum = INIT_SEED; + while ((avail_in = fread(inbuf, 1, BUF_SIZE, in))) { + // crc update mode + crc64_checksum = crc64_ecma_refl(crc64_checksum, inbuf, avail_in); + total_in += avail_in; + } + + fclose(in); + printf("total length is %ld, checksum is 0x%lx\n", total_in, crc64_checksum); + + return 0; +} diff --git a/ceph/src/isa-l/crc/crc64_funcs_perf.c b/ceph/src/isa-l/crc/crc64_funcs_perf.c new file mode 100644 index 000000000..04135bff8 --- /dev/null +++ b/ceph/src/isa-l/crc/crc64_funcs_perf.c @@ -0,0 +1,109 @@ +/********************************************************************** + Copyright(c) 2011-2016 Intel Corporation All rights reserved. + + 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 Intel Corporation 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 + 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. +**********************************************************************/ + +#include +#include +#include +#include +#include +#include "crc64.h" +#include "test.h" + +//#define CACHED_TEST +#ifdef CACHED_TEST +// Cached test, loop many times over small dataset +# define TEST_LEN 8*1024 +# define TEST_LOOPS 400000 +# define TEST_TYPE_STR "_warm" +#else +// Uncached test. Pull from large mem base. +# define GT_L3_CACHE 32*1024*1024 /* some number > last level cache */ +# define TEST_LEN (2 * GT_L3_CACHE) +# define TEST_LOOPS 100 +# define TEST_TYPE_STR "_cold" +#endif + +#ifndef TEST_SEED +# define TEST_SEED 0x1234 +#endif + +#define TEST_MEM TEST_LEN + +typedef uint64_t(*crc64_func_t) (uint64_t, const uint8_t *, uint64_t); + +typedef struct func_case { + char *note; + crc64_func_t crc64_func_call; + crc64_func_t crc64_ref_call; +} func_case_t; + +func_case_t test_funcs[] = { + {"crc64_ecma_norm", crc64_ecma_norm, crc64_ecma_norm_base}, + {"crc64_ecma_refl", crc64_ecma_refl, crc64_ecma_refl_base}, + {"crc64_iso_norm", crc64_iso_norm, crc64_iso_norm_base}, + {"crc64_iso_refl", crc64_iso_refl, crc64_iso_refl_base}, + {"crc64_jones_norm", crc64_jones_norm, crc64_jones_norm_base}, + {"crc64_jones_refl", crc64_jones_refl, crc64_jones_refl_base} +}; + +int main(int argc, char *argv[]) +{ + int i, j; + void *buf; + uint64_t crc; + struct perf start, stop; + func_case_t *test_func; + + if (posix_memalign(&buf, 1024, TEST_LEN)) { + printf("alloc error: Fail"); + return -1; + } + memset(buf, (char)TEST_SEED, TEST_LEN); + + for (j = 0; j < sizeof(test_funcs) / sizeof(test_funcs[0]); j++) { + test_func = &test_funcs[j]; + printf("%s_perf:\n", test_func->note); + + printf("Start timed tests\n"); + fflush(0); + + crc = test_func->crc64_func_call(TEST_SEED, buf, TEST_LEN); + perf_start(&start); + for (i = 0; i < TEST_LOOPS; i++) { + crc = test_func->crc64_func_call(TEST_SEED, buf, TEST_LEN); + } + perf_stop(&stop); + printf("%s" TEST_TYPE_STR ": ", test_func->note); + perf_print(stop, start, (long long)TEST_LEN * i); + + printf("finish 0x%lx\n", crc); + } + + return 0; +} diff --git a/ceph/src/isa-l/crc/crc64_funcs_test.c b/ceph/src/isa-l/crc/crc64_funcs_test.c new file mode 100644 index 000000000..f638f0f94 --- /dev/null +++ b/ceph/src/isa-l/crc/crc64_funcs_test.c @@ -0,0 +1,290 @@ +/********************************************************************** + Copyright(c) 2011-2016 Intel Corporation All rights reserved. + + 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 Intel Corporation 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 + 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. +**********************************************************************/ + +#include +#include +#include +#include +#include "crc64.h" +#include "types.h" + +#ifndef TEST_SEED +# define TEST_SEED 0x1234 +#endif + +#define MAX_BUF 512 +#define TEST_SIZE 20 + +typedef uint64_t u64; +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; + +typedef uint64_t(*crc64_func_t) (uint64_t, const uint8_t *, uint64_t); + +typedef struct func_case { + char *note; + crc64_func_t crc64_func_call; + crc64_func_t crc64_ref_call; +} func_case_t; + +func_case_t test_funcs[] = { + {"crc64_ecma_norm", crc64_ecma_norm, crc64_ecma_norm_base}, + {"crc64_ecma_refl", crc64_ecma_refl, crc64_ecma_refl_base}, + {"crc64_iso_norm", crc64_iso_norm, crc64_iso_norm_base}, + {"crc64_iso_refl", crc64_iso_refl, crc64_iso_refl_base}, + {"crc64_jones_norm", crc64_jones_norm, crc64_jones_norm_base}, + {"crc64_jones_refl", crc64_jones_refl, crc64_jones_refl_base} +}; + +// Generates pseudo-random data + +void rand_buffer(unsigned char *buf, long buffer_size) +{ + long i; + for (i = 0; i < buffer_size; i++) + buf[i] = rand(); +} + +// Test cases +int zeros_test(func_case_t * test_func); + +int simple_pattern_test(func_case_t * test_func); + +int seeds_sizes_test(func_case_t * test_func); + +int eob_test(func_case_t * test_func); + +int update_test(func_case_t * test_func); + +int verbose = 0; +void *buf_alloc = NULL; + +int main(int argc, char *argv[]) +{ + int fail = 0, fail_case; + int i, ret; + func_case_t *test_func; + + verbose = argc - 1; + + // Align to MAX_BUF boundary + ret = posix_memalign(&buf_alloc, MAX_BUF, MAX_BUF * TEST_SIZE); + if (ret) { + printf("alloc error: Fail"); + return -1; + } + srand(TEST_SEED); + printf("CRC64 Tests\n"); + + for (i = 0; i < sizeof(test_funcs) / sizeof(test_funcs[0]); i++) { + fail_case = 0; + test_func = &test_funcs[i]; + + printf("Test %s ", test_func->note); + fail_case += zeros_test(test_func); + fail_case += simple_pattern_test(test_func); + fail_case += seeds_sizes_test(test_func); + fail_case += eob_test(test_func); + fail_case += update_test(test_func); + printf("Test %s done: %s\n", test_func->note, fail_case ? "Fail" : "Pass"); + + if (fail_case) { + printf("\n%s Failed %d tests\n", test_func->note, fail_case); + fail++; + } + } + + printf("CRC64 Tests all done: %s\n", fail ? "Fail" : "Pass"); + + return fail; +} + +// Test of all zeros +int zeros_test(func_case_t * test_func) +{ + uint64_t crc, crc_ref; + int fail = 0; + unsigned char *buf = NULL; + + buf = (unsigned char *)buf_alloc; + memset(buf, 0, MAX_BUF * 10); + crc = test_func->crc64_func_call(TEST_SEED, buf, MAX_BUF * 10); + crc_ref = test_func->crc64_ref_call(TEST_SEED, buf, MAX_BUF * 10); + + if (crc != crc_ref) { + fail++; + printf("\n opt ref\n"); + printf(" ------ ------\n"); + printf("crc zero = 0x%16lx 0x%16lx \n", crc, crc_ref); + } else + printf("."); + + return fail; +} + +// Another simple test pattern +int simple_pattern_test(func_case_t * test_func) +{ + uint64_t crc, crc_ref; + int fail = 0; + unsigned char *buf = NULL; + + buf = (unsigned char *)buf_alloc; + memset(buf, 0x8a, MAX_BUF); + crc = test_func->crc64_func_call(TEST_SEED, buf, MAX_BUF); + crc_ref = test_func->crc64_ref_call(TEST_SEED, buf, MAX_BUF); + if (crc != crc_ref) + fail++; + if (verbose) + printf("crc all 8a = 0x%16lx 0x%16lx\n", crc, crc_ref); + else + printf("."); + + return fail; +} + +int seeds_sizes_test(func_case_t * test_func) +{ + uint64_t crc, crc_ref; + int fail = 0; + int i; + uint64_t r, s; + unsigned char *buf = NULL; + + // Do a few random tests + buf = (unsigned char *)buf_alloc; //reset buf + r = rand(); + rand_buffer(buf, MAX_BUF * TEST_SIZE); + + for (i = 0; i < TEST_SIZE; i++) { + crc = test_func->crc64_func_call(r, buf, MAX_BUF); + crc_ref = test_func->crc64_ref_call(r, buf, MAX_BUF); + if (crc != crc_ref) + fail++; + if (verbose) + printf("crc rand%3d = 0x%16lx 0x%16lx\n", i, crc, crc_ref); + else + printf("."); + buf += MAX_BUF; + } + + // Do a few random sizes + buf = (unsigned char *)buf_alloc; //reset buf + r = rand(); + + for (i = MAX_BUF; i >= 0; i--) { + crc = test_func->crc64_func_call(r, buf, i); + crc_ref = test_func->crc64_ref_call(r, buf, i); + if (crc != crc_ref) { + fail++; + printf("fail random size%i 0x%16lx 0x%16lx\n", i, crc, crc_ref); + } else + printf("."); + } + + // Try different seeds + for (s = 0; s < 20; s++) { + buf = (unsigned char *)buf_alloc; //reset buf + + r = rand(); // just to get a new seed + rand_buffer(buf, MAX_BUF * TEST_SIZE); // new pseudo-rand data + + if (verbose) + printf("seed = 0x%lx\n", r); + + for (i = 0; i < TEST_SIZE; i++) { + crc = test_func->crc64_func_call(r, buf, MAX_BUF); + crc_ref = test_func->crc64_ref_call(r, buf, MAX_BUF); + if (crc != crc_ref) + fail++; + if (verbose) + printf("crc rand%3d = 0x%16lx 0x%16lx\n", i, crc, crc_ref); + else + printf("."); + buf += MAX_BUF; + } + } + + return fail; +} + +// Run tests at end of buffer +int eob_test(func_case_t * test_func) +{ + uint64_t crc, crc_ref; + int fail = 0; + int i; + unsigned char *buf = NULL; + + buf = (unsigned char *)buf_alloc; //reset buf + buf = buf + ((MAX_BUF - 1) * TEST_SIZE); //Line up TEST_SIZE from end + for (i = 0; i < TEST_SIZE; i++) { + crc = test_func->crc64_func_call(TEST_SEED, buf + i, TEST_SIZE - i); + crc_ref = test_func->crc64_ref_call(TEST_SEED, buf + i, TEST_SIZE - i); + if (crc != crc_ref) + fail++; + if (verbose) + printf("crc eob rand%3d = 0x%16lx 0x%16lx\n", i, crc, crc_ref); + else + printf("."); + } + + return fail; +} + +int update_test(func_case_t * test_func) +{ + uint64_t crc, crc_ref; + int fail = 0; + int i; + uint64_t r; + unsigned char *buf = NULL; + + buf = (unsigned char *)buf_alloc; //reset buf + r = rand(); + // Process the whole buf with reference func single call. + crc_ref = test_func->crc64_ref_call(r, buf, MAX_BUF * TEST_SIZE); + // Process buf with update method. + for (i = 0; i < TEST_SIZE; i++) { + crc = test_func->crc64_func_call(r, buf, MAX_BUF); + // Update crc seeds and buf pointer. + r = crc; + buf += MAX_BUF; + } + + if (crc != crc_ref) + fail++; + if (verbose) + printf("crc rand%3d = 0x%16lx 0x%16lx\n", i, crc, crc_ref); + else + printf("."); + + return fail; +} diff --git a/ceph/src/isa-l/crc/crc64_iso_norm_by8.asm b/ceph/src/isa-l/crc/crc64_iso_norm_by8.asm new file mode 100644 index 000000000..1a4195d6a --- /dev/null +++ b/ceph/src/isa-l/crc/crc64_iso_norm_by8.asm @@ -0,0 +1,581 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2016 Intel Corporation All rights reserved. +; +; 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 Intel Corporation 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 +; 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. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Function API: +; uint64_t crc64_iso_norm_by8( +; uint64_t init_crc, //initial CRC value, 64 bits +; const unsigned char *buf, //buffer pointer to calculate CRC on +; uint64_t len //buffer length in bytes (64-bit data) +; ); +; +%include "reg_sizes.asm" + +%define fetch_dist 1024 + +[bits 64] +default rel + +section .text + +%ifidn __OUTPUT_FORMAT__, win64 + %xdefine arg1 rcx + %xdefine arg2 rdx + %xdefine arg3 r8 +%else + %xdefine arg1 rdi + %xdefine arg2 rsi + %xdefine arg3 rdx +%endif + +%define TMP 16*0 +%ifidn __OUTPUT_FORMAT__, win64 + %define XMM_SAVE 16*2 + %define VARIABLE_OFFSET 16*10+8 +%else + %define VARIABLE_OFFSET 16*2+8 +%endif +align 16 +global crc64_iso_norm_by8:function +crc64_iso_norm_by8: + + not arg1 ;~init_crc + + sub rsp,VARIABLE_OFFSET + +%ifidn __OUTPUT_FORMAT__, win64 + ; push the xmm registers into the stack to maintain + movdqa [rsp + XMM_SAVE + 16*0], xmm6 + movdqa [rsp + XMM_SAVE + 16*1], xmm7 + movdqa [rsp + XMM_SAVE + 16*2], xmm8 + movdqa [rsp + XMM_SAVE + 16*3], xmm9 + movdqa [rsp + XMM_SAVE + 16*4], xmm10 + movdqa [rsp + XMM_SAVE + 16*5], xmm11 + movdqa [rsp + XMM_SAVE + 16*6], xmm12 + movdqa [rsp + XMM_SAVE + 16*7], xmm13 +%endif + + + ; check if smaller than 256 + cmp arg3, 256 + + ; for sizes less than 256, we can't fold 128B at a time... + jl _less_than_256 + + + ; load the initial crc value + movq xmm10, arg1 ; initial crc + + ; crc value does not need to be byte-reflected, but it needs to be moved to the high part of the register. + ; because data will be byte-reflected and will align with initial crc at correct place. + pslldq xmm10, 8 + + movdqa xmm11, [SHUF_MASK] + ; receive the initial 128B data, xor the initial crc value + movdqu xmm0, [arg2+16*0] + movdqu xmm1, [arg2+16*1] + movdqu xmm2, [arg2+16*2] + movdqu xmm3, [arg2+16*3] + movdqu xmm4, [arg2+16*4] + movdqu xmm5, [arg2+16*5] + movdqu xmm6, [arg2+16*6] + movdqu xmm7, [arg2+16*7] + + pshufb xmm0, xmm11 + ; XOR the initial_crc value + pxor xmm0, xmm10 + pshufb xmm1, xmm11 + pshufb xmm2, xmm11 + pshufb xmm3, xmm11 + pshufb xmm4, xmm11 + pshufb xmm5, xmm11 + pshufb xmm6, xmm11 + pshufb xmm7, xmm11 + + movdqa xmm10, [rk3] ;xmm10 has rk3 and rk4 + ;imm value of pclmulqdq instruction will determine which constant to use + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ; we subtract 256 instead of 128 to save one instruction from the loop + sub arg3, 256 + + ; at this section of the code, there is 128*x+y (0<=y<128) bytes of buffer. The _fold_128_B_loop + ; loop will fold 128B at a time until we have 128+y Bytes of buffer + + + ; fold 128B at a time. This section of the code folds 8 xmm registers in parallel +_fold_128_B_loop: + + ; update the buffer pointer + add arg2, 128 ; buf += 128; + + prefetchnta [arg2+fetch_dist+0] + movdqu xmm9, [arg2+16*0] + movdqu xmm12, [arg2+16*1] + pshufb xmm9, xmm11 + pshufb xmm12, xmm11 + movdqa xmm8, xmm0 + movdqa xmm13, xmm1 + pclmulqdq xmm0, xmm10, 0x0 + pclmulqdq xmm8, xmm10 , 0x11 + pclmulqdq xmm1, xmm10, 0x0 + pclmulqdq xmm13, xmm10 , 0x11 + pxor xmm0, xmm9 + xorps xmm0, xmm8 + pxor xmm1, xmm12 + xorps xmm1, xmm13 + + prefetchnta [arg2+fetch_dist+32] + movdqu xmm9, [arg2+16*2] + movdqu xmm12, [arg2+16*3] + pshufb xmm9, xmm11 + pshufb xmm12, xmm11 + movdqa xmm8, xmm2 + movdqa xmm13, xmm3 + pclmulqdq xmm2, xmm10, 0x0 + pclmulqdq xmm8, xmm10 , 0x11 + pclmulqdq xmm3, xmm10, 0x0 + pclmulqdq xmm13, xmm10 , 0x11 + pxor xmm2, xmm9 + xorps xmm2, xmm8 + pxor xmm3, xmm12 + xorps xmm3, xmm13 + + prefetchnta [arg2+fetch_dist+64] + movdqu xmm9, [arg2+16*4] + movdqu xmm12, [arg2+16*5] + pshufb xmm9, xmm11 + pshufb xmm12, xmm11 + movdqa xmm8, xmm4 + movdqa xmm13, xmm5 + pclmulqdq xmm4, xmm10, 0x0 + pclmulqdq xmm8, xmm10 , 0x11 + pclmulqdq xmm5, xmm10, 0x0 + pclmulqdq xmm13, xmm10 , 0x11 + pxor xmm4, xmm9 + xorps xmm4, xmm8 + pxor xmm5, xmm12 + xorps xmm5, xmm13 + + prefetchnta [arg2+fetch_dist+96] + movdqu xmm9, [arg2+16*6] + movdqu xmm12, [arg2+16*7] + pshufb xmm9, xmm11 + pshufb xmm12, xmm11 + movdqa xmm8, xmm6 + movdqa xmm13, xmm7 + pclmulqdq xmm6, xmm10, 0x0 + pclmulqdq xmm8, xmm10 , 0x11 + pclmulqdq xmm7, xmm10, 0x0 + pclmulqdq xmm13, xmm10 , 0x11 + pxor xmm6, xmm9 + xorps xmm6, xmm8 + pxor xmm7, xmm12 + xorps xmm7, xmm13 + + sub arg3, 128 + + ; check if there is another 128B in the buffer to be able to fold + jge _fold_128_B_loop + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + add arg2, 128 + ; at this point, the buffer pointer is pointing at the last y Bytes of the buffer, where 0 <= y < 128 + ; the 128B of folded data is in 8 of the xmm registers: xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7 + + + ; fold the 8 xmm registers to 1 xmm register with different constants + + movdqa xmm10, [rk9] + movdqa xmm8, xmm0 + pclmulqdq xmm0, xmm10, 0x11 + pclmulqdq xmm8, xmm10, 0x0 + pxor xmm7, xmm8 + xorps xmm7, xmm0 + + movdqa xmm10, [rk11] + movdqa xmm8, xmm1 + pclmulqdq xmm1, xmm10, 0x11 + pclmulqdq xmm8, xmm10, 0x0 + pxor xmm7, xmm8 + xorps xmm7, xmm1 + + movdqa xmm10, [rk13] + movdqa xmm8, xmm2 + pclmulqdq xmm2, xmm10, 0x11 + pclmulqdq xmm8, xmm10, 0x0 + pxor xmm7, xmm8 + pxor xmm7, xmm2 + + movdqa xmm10, [rk15] + movdqa xmm8, xmm3 + pclmulqdq xmm3, xmm10, 0x11 + pclmulqdq xmm8, xmm10, 0x0 + pxor xmm7, xmm8 + xorps xmm7, xmm3 + + movdqa xmm10, [rk17] + movdqa xmm8, xmm4 + pclmulqdq xmm4, xmm10, 0x11 + pclmulqdq xmm8, xmm10, 0x0 + pxor xmm7, xmm8 + pxor xmm7, xmm4 + + movdqa xmm10, [rk19] + movdqa xmm8, xmm5 + pclmulqdq xmm5, xmm10, 0x11 + pclmulqdq xmm8, xmm10, 0x0 + pxor xmm7, xmm8 + xorps xmm7, xmm5 + + movdqa xmm10, [rk1] ;xmm10 has rk1 and rk2 + + movdqa xmm8, xmm6 + pclmulqdq xmm6, xmm10, 0x11 + pclmulqdq xmm8, xmm10, 0x0 + pxor xmm7, xmm8 + pxor xmm7, xmm6 + + + ; instead of 128, we add 112 to the loop counter to save 1 instruction from the loop + ; instead of a cmp instruction, we use the negative flag with the jl instruction + add arg3, 128-16 + jl _final_reduction_for_128 + + ; now we have 16+y bytes left to reduce. 16 Bytes is in register xmm7 and the rest is in memory + ; we can fold 16 bytes at a time if y>=16 + ; continue folding 16B at a time + +_16B_reduction_loop: + movdqa xmm8, xmm7 + pclmulqdq xmm7, xmm10, 0x11 + pclmulqdq xmm8, xmm10, 0x0 + pxor xmm7, xmm8 + movdqu xmm0, [arg2] + pshufb xmm0, xmm11 + pxor xmm7, xmm0 + add arg2, 16 + sub arg3, 16 + ; instead of a cmp instruction, we utilize the flags with the jge instruction + ; equivalent of: cmp arg3, 16-16 + ; check if there is any more 16B in the buffer to be able to fold + jge _16B_reduction_loop + + ;now we have 16+z bytes left to reduce, where 0<= z < 16. + ;first, we reduce the data in the xmm7 register + + +_final_reduction_for_128: + ; check if any more data to fold. If not, compute the CRC of the final 128 bits + add arg3, 16 + je _128_done + + ; here we are getting data that is less than 16 bytes. + ; since we know that there was data before the pointer, we can offset the input pointer before the actual point, to receive exactly 16 bytes. + ; after that the registers need to be adjusted. +_get_last_two_xmms: + movdqa xmm2, xmm7 + + movdqu xmm1, [arg2 - 16 + arg3] + pshufb xmm1, xmm11 + + ; get rid of the extra data that was loaded before + ; load the shift constant + lea rax, [pshufb_shf_table + 16] + sub rax, arg3 + movdqu xmm0, [rax] + + ; shift xmm2 to the left by arg3 bytes + pshufb xmm2, xmm0 + + ; shift xmm7 to the right by 16-arg3 bytes + pxor xmm0, [mask1] + pshufb xmm7, xmm0 + pblendvb xmm1, xmm2 ;xmm0 is implicit + + ; fold 16 Bytes + movdqa xmm2, xmm1 + movdqa xmm8, xmm7 + pclmulqdq xmm7, xmm10, 0x11 + pclmulqdq xmm8, xmm10, 0x0 + pxor xmm7, xmm8 + pxor xmm7, xmm2 + +_128_done: + ; compute crc of a 128-bit value + movdqa xmm10, [rk5] ; rk5 and rk6 in xmm10 + movdqa xmm0, xmm7 + + ;64b fold + pclmulqdq xmm7, xmm10, 0x01 ; H*L + pslldq xmm0, 8 + pxor xmm7, xmm0 + + ;barrett reduction +_barrett: + movdqa xmm10, [rk7] ; rk7 and rk8 in xmm10 + movdqa xmm0, xmm7 + + movdqa xmm1, xmm7 + pand xmm1, [mask3] + pclmulqdq xmm7, xmm10, 0x01 + pxor xmm7, xmm1 + + pclmulqdq xmm7, xmm10, 0x11 + pxor xmm7, xmm0 + pextrq rax, xmm7, 0 + +_cleanup: + not rax +%ifidn __OUTPUT_FORMAT__, win64 + movdqa xmm6, [rsp + XMM_SAVE + 16*0] + movdqa xmm7, [rsp + XMM_SAVE + 16*1] + movdqa xmm8, [rsp + XMM_SAVE + 16*2] + movdqa xmm9, [rsp + XMM_SAVE + 16*3] + movdqa xmm10, [rsp + XMM_SAVE + 16*4] + movdqa xmm11, [rsp + XMM_SAVE + 16*5] + movdqa xmm12, [rsp + XMM_SAVE + 16*6] + movdqa xmm13, [rsp + XMM_SAVE + 16*7] +%endif + add rsp, VARIABLE_OFFSET + ret + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align 16 +_less_than_256: + + ; check if there is enough buffer to be able to fold 16B at a time + cmp arg3, 32 + jl _less_than_32 + movdqa xmm11, [SHUF_MASK] + + ; if there is, load the constants + movdqa xmm10, [rk1] ; rk1 and rk2 in xmm10 + + movq xmm0, arg1 ; get the initial crc value + pslldq xmm0, 8 ; align it to its correct place + movdqu xmm7, [arg2] ; load the plaintext + pshufb xmm7, xmm11 ; byte-reflect the plaintext + pxor xmm7, xmm0 + + + ; update the buffer pointer + add arg2, 16 + + ; update the counter. subtract 32 instead of 16 to save one instruction from the loop + sub arg3, 32 + + jmp _16B_reduction_loop +align 16 +_less_than_32: + ; mov initial crc to the return value. this is necessary for zero-length buffers. + mov rax, arg1 + test arg3, arg3 + je _cleanup + + movdqa xmm11, [SHUF_MASK] + + movq xmm0, arg1 ; get the initial crc value + pslldq xmm0, 8 ; align it to its correct place + + cmp arg3, 16 + je _exact_16_left + jl _less_than_16_left + + movdqu xmm7, [arg2] ; load the plaintext + pshufb xmm7, xmm11 ; byte-reflect the plaintext + pxor xmm7, xmm0 ; xor the initial crc value + add arg2, 16 + sub arg3, 16 + movdqa xmm10, [rk1] ; rk1 and rk2 in xmm10 + jmp _get_last_two_xmms +align 16 +_less_than_16_left: + ; use stack space to load data less than 16 bytes, zero-out the 16B in memory first. + pxor xmm1, xmm1 + mov r11, rsp + movdqa [r11], xmm1 + + ; backup the counter value + mov r9, arg3 + cmp arg3, 8 + jl _less_than_8_left + + ; load 8 Bytes + mov rax, [arg2] + mov [r11], rax + add r11, 8 + sub arg3, 8 + add arg2, 8 +_less_than_8_left: + + cmp arg3, 4 + jl _less_than_4_left + + ; load 4 Bytes + mov eax, [arg2] + mov [r11], eax + add r11, 4 + sub arg3, 4 + add arg2, 4 +_less_than_4_left: + + cmp arg3, 2 + jl _less_than_2_left + + ; load 2 Bytes + mov ax, [arg2] + mov [r11], ax + add r11, 2 + sub arg3, 2 + add arg2, 2 +_less_than_2_left: + cmp arg3, 1 + jl _zero_left + + ; load 1 Byte + mov al, [arg2] + mov [r11], al +_zero_left: + movdqa xmm7, [rsp] + pshufb xmm7, xmm11 + pxor xmm7, xmm0 ; xor the initial crc value + + ; shl r9, 4 + lea rax, [pshufb_shf_table + 16] + sub rax, r9 + + cmp r9, 8 + jl _end_1to7 + +_end_8to15: + movdqu xmm0, [rax] + pxor xmm0, [mask1] + + pshufb xmm7, xmm0 + jmp _128_done + +_end_1to7: + ; Right shift (8-length) bytes in XMM + add rax, 8 + movdqu xmm0, [rax] + pshufb xmm7,xmm0 + + jmp _barrett +align 16 +_exact_16_left: + movdqu xmm7, [arg2] + pshufb xmm7, xmm11 + pxor xmm7, xmm0 ; xor the initial crc value + + jmp _128_done + +section .data + +; precomputed constants +align 16 + +rk1: +DQ 0x0000000000000145 +rk2: +DQ 0x0000000000001db7 +rk3: +DQ 0x000100000001001a +rk4: +DQ 0x001b0000001b015e +rk5: +DQ 0x0000000000000145 +rk6: +DQ 0x0000000000000000 +rk7: +DQ 0x000000000000001b +rk8: +DQ 0x000000000000001b +rk9: +DQ 0x0150145145145015 +rk10: +DQ 0x1c71db6db6db71c7 +rk11: +DQ 0x0001110110110111 +rk12: +DQ 0x001aab1ab1ab1aab +rk13: +DQ 0x0000014445014445 +rk14: +DQ 0x00001daab71daab7 +rk15: +DQ 0x0000000101000101 +rk16: +DQ 0x0000001b1b001b1b +rk17: +DQ 0x0000000001514515 +rk18: +DQ 0x000000001c6db6c7 +rk19: +DQ 0x0000000000011011 +rk20: +DQ 0x00000000001ab1ab + +mask1: +dq 0x8080808080808080, 0x8080808080808080 +mask2: +dq 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF +mask3: +dq 0x0000000000000000, 0xFFFFFFFFFFFFFFFF + +SHUF_MASK: +dq 0x08090A0B0C0D0E0F, 0x0001020304050607 + +pshufb_shf_table: +; use these values for shift constants for the pshufb instruction +; different alignments result in values as shown: +; dq 0x8887868584838281, 0x008f8e8d8c8b8a89 ; shl 15 (16-1) / shr1 +; dq 0x8988878685848382, 0x01008f8e8d8c8b8a ; shl 14 (16-3) / shr2 +; dq 0x8a89888786858483, 0x0201008f8e8d8c8b ; shl 13 (16-4) / shr3 +; dq 0x8b8a898887868584, 0x030201008f8e8d8c ; shl 12 (16-4) / shr4 +; dq 0x8c8b8a8988878685, 0x04030201008f8e8d ; shl 11 (16-5) / shr5 +; dq 0x8d8c8b8a89888786, 0x0504030201008f8e ; shl 10 (16-6) / shr6 +; dq 0x8e8d8c8b8a898887, 0x060504030201008f ; shl 9 (16-7) / shr7 +; dq 0x8f8e8d8c8b8a8988, 0x0706050403020100 ; shl 8 (16-8) / shr8 +; dq 0x008f8e8d8c8b8a89, 0x0807060504030201 ; shl 7 (16-9) / shr9 +; dq 0x01008f8e8d8c8b8a, 0x0908070605040302 ; shl 6 (16-10) / shr10 +; dq 0x0201008f8e8d8c8b, 0x0a09080706050403 ; shl 5 (16-11) / shr11 +; dq 0x030201008f8e8d8c, 0x0b0a090807060504 ; shl 4 (16-12) / shr12 +; dq 0x04030201008f8e8d, 0x0c0b0a0908070605 ; shl 3 (16-13) / shr13 +; dq 0x0504030201008f8e, 0x0d0c0b0a09080706 ; shl 2 (16-14) / shr14 +; dq 0x060504030201008f, 0x0e0d0c0b0a090807 ; shl 1 (16-15) / shr15 +dq 0x8786858483828100, 0x8f8e8d8c8b8a8988 +dq 0x0706050403020100, 0x0f0e0d0c0b0a0908 +dq 0x8080808080808080, 0x0f0e0d0c0b0a0908 +dq 0x8080808080808080, 0x8080808080808080 + +;;; func core, ver, snum +slversion crc64_iso_norm_by8, 01, 00, 0020 diff --git a/ceph/src/isa-l/crc/crc64_iso_refl_by8.asm b/ceph/src/isa-l/crc/crc64_iso_refl_by8.asm new file mode 100644 index 000000000..d7ed8ae34 --- /dev/null +++ b/ceph/src/isa-l/crc/crc64_iso_refl_by8.asm @@ -0,0 +1,544 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2016 Intel Corporation All rights reserved. +; +; 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 Intel Corporation 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 +; 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. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Function API: +; uint64_t crc64_iso_refl_by8( +; uint64_t init_crc, //initial CRC value, 64 bits +; const unsigned char *buf, //buffer pointer to calculate CRC on +; uint64_t len //buffer length in bytes (64-bit data) +; ); +; +%include "reg_sizes.asm" + +%define fetch_dist 1024 + +[bits 64] +default rel + +section .text + + +%ifidn __OUTPUT_FORMAT__, win64 + %xdefine arg1 rcx + %xdefine arg2 rdx + %xdefine arg3 r8 +%else + %xdefine arg1 rdi + %xdefine arg2 rsi + %xdefine arg3 rdx +%endif + +%define TMP 16*0 +%ifidn __OUTPUT_FORMAT__, win64 + %define XMM_SAVE 16*2 + %define VARIABLE_OFFSET 16*10+8 +%else + %define VARIABLE_OFFSET 16*2+8 +%endif + + +align 16 +global crc64_iso_refl_by8:function +crc64_iso_refl_by8: + ; uint64_t c = crc ^ 0xffffffff,ffffffffL; + not arg1 + sub rsp, VARIABLE_OFFSET + +%ifidn __OUTPUT_FORMAT__, win64 + ; push the xmm registers into the stack to maintain + movdqa [rsp + XMM_SAVE + 16*0], xmm6 + movdqa [rsp + XMM_SAVE + 16*1], xmm7 + movdqa [rsp + XMM_SAVE + 16*2], xmm8 + movdqa [rsp + XMM_SAVE + 16*3], xmm9 + movdqa [rsp + XMM_SAVE + 16*4], xmm10 + movdqa [rsp + XMM_SAVE + 16*5], xmm11 + movdqa [rsp + XMM_SAVE + 16*6], xmm12 + movdqa [rsp + XMM_SAVE + 16*7], xmm13 +%endif + + ; check if smaller than 256B + cmp arg3, 256 + + ; for sizes less than 256, we can't fold 128B at a time... + jl _less_than_256 + + + ; load the initial crc value + movq xmm10, arg1 ; initial crc + ; receive the initial 128B data, xor the initial crc value + movdqu xmm0, [arg2+16*0] + movdqu xmm1, [arg2+16*1] + movdqu xmm2, [arg2+16*2] + movdqu xmm3, [arg2+16*3] + movdqu xmm4, [arg2+16*4] + movdqu xmm5, [arg2+16*5] + movdqu xmm6, [arg2+16*6] + movdqu xmm7, [arg2+16*7] + + ; XOR the initial_crc value + pxor xmm0, xmm10 + movdqa xmm10, [rk3] ;xmm10 has rk3 and rk4 + ;imm value of pclmulqdq instruction will determine which constant to use + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ; we subtract 256 instead of 128 to save one instruction from the loop + sub arg3, 256 + + ; at this section of the code, there is 128*x+y (0<=y<128) bytes of buffer. The _fold_128_B_loop + ; loop will fold 128B at a time until we have 128+y Bytes of buffer + + + ; fold 128B at a time. This section of the code folds 8 xmm registers in parallel +_fold_128_B_loop: + + ; update the buffer pointer + add arg2, 128 + + prefetchnta [arg2+fetch_dist+0] + movdqu xmm9, [arg2+16*0] + movdqu xmm12, [arg2+16*1] + movdqa xmm8, xmm0 + movdqa xmm13, xmm1 + pclmulqdq xmm0, xmm10, 0x10 + pclmulqdq xmm8, xmm10 , 0x1 + pclmulqdq xmm1, xmm10, 0x10 + pclmulqdq xmm13, xmm10 , 0x1 + pxor xmm0, xmm9 + xorps xmm0, xmm8 + pxor xmm1, xmm12 + xorps xmm1, xmm13 + + prefetchnta [arg2+fetch_dist+32] + movdqu xmm9, [arg2+16*2] + movdqu xmm12, [arg2+16*3] + movdqa xmm8, xmm2 + movdqa xmm13, xmm3 + pclmulqdq xmm2, xmm10, 0x10 + pclmulqdq xmm8, xmm10 , 0x1 + pclmulqdq xmm3, xmm10, 0x10 + pclmulqdq xmm13, xmm10 , 0x1 + pxor xmm2, xmm9 + xorps xmm2, xmm8 + pxor xmm3, xmm12 + xorps xmm3, xmm13 + + prefetchnta [arg2+fetch_dist+64] + movdqu xmm9, [arg2+16*4] + movdqu xmm12, [arg2+16*5] + movdqa xmm8, xmm4 + movdqa xmm13, xmm5 + pclmulqdq xmm4, xmm10, 0x10 + pclmulqdq xmm8, xmm10 , 0x1 + pclmulqdq xmm5, xmm10, 0x10 + pclmulqdq xmm13, xmm10 , 0x1 + pxor xmm4, xmm9 + xorps xmm4, xmm8 + pxor xmm5, xmm12 + xorps xmm5, xmm13 + + prefetchnta [arg2+fetch_dist+96] + movdqu xmm9, [arg2+16*6] + movdqu xmm12, [arg2+16*7] + movdqa xmm8, xmm6 + movdqa xmm13, xmm7 + pclmulqdq xmm6, xmm10, 0x10 + pclmulqdq xmm8, xmm10 , 0x1 + pclmulqdq xmm7, xmm10, 0x10 + pclmulqdq xmm13, xmm10 , 0x1 + pxor xmm6, xmm9 + xorps xmm6, xmm8 + pxor xmm7, xmm12 + xorps xmm7, xmm13 + + sub arg3, 128 + + ; check if there is another 128B in the buffer to be able to fold + jge _fold_128_B_loop + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + add arg2, 128 + ; at this point, the buffer pointer is pointing at the last y Bytes of the buffer, where 0 <= y < 128 + ; the 128B of folded data is in 8 of the xmm registers: xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7 + + + ; fold the 8 xmm registers to 1 xmm register with different constants + ; xmm0 to xmm7 + movdqa xmm10, [rk9] + movdqa xmm8, xmm0 + pclmulqdq xmm0, xmm10, 0x1 + pclmulqdq xmm8, xmm10, 0x10 + pxor xmm7, xmm8 + xorps xmm7, xmm0 + ;xmm1 to xmm7 + movdqa xmm10, [rk11] + movdqa xmm8, xmm1 + pclmulqdq xmm1, xmm10, 0x1 + pclmulqdq xmm8, xmm10, 0x10 + pxor xmm7, xmm8 + xorps xmm7, xmm1 + + movdqa xmm10, [rk13] + movdqa xmm8, xmm2 + pclmulqdq xmm2, xmm10, 0x1 + pclmulqdq xmm8, xmm10, 0x10 + pxor xmm7, xmm8 + pxor xmm7, xmm2 + + movdqa xmm10, [rk15] + movdqa xmm8, xmm3 + pclmulqdq xmm3, xmm10, 0x1 + pclmulqdq xmm8, xmm10, 0x10 + pxor xmm7, xmm8 + xorps xmm7, xmm3 + + movdqa xmm10, [rk17] + movdqa xmm8, xmm4 + pclmulqdq xmm4, xmm10, 0x1 + pclmulqdq xmm8, xmm10, 0x10 + pxor xmm7, xmm8 + pxor xmm7, xmm4 + + movdqa xmm10, [rk19] + movdqa xmm8, xmm5 + pclmulqdq xmm5, xmm10, 0x1 + pclmulqdq xmm8, xmm10, 0x10 + pxor xmm7, xmm8 + xorps xmm7, xmm5 + ; xmm6 to xmm7 + movdqa xmm10, [rk1] + movdqa xmm8, xmm6 + pclmulqdq xmm6, xmm10, 0x1 + pclmulqdq xmm8, xmm10, 0x10 + pxor xmm7, xmm8 + pxor xmm7, xmm6 + + + ; instead of 128, we add 128-16 to the loop counter to save 1 instruction from the loop + ; instead of a cmp instruction, we use the negative flag with the jl instruction + add arg3, 128-16 + jl _final_reduction_for_128 + + ; now we have 16+y bytes left to reduce. 16 Bytes is in register xmm7 and the rest is in memory + ; we can fold 16 bytes at a time if y>=16 + ; continue folding 16B at a time + +_16B_reduction_loop: + movdqa xmm8, xmm7 + pclmulqdq xmm7, xmm10, 0x1 + pclmulqdq xmm8, xmm10, 0x10 + pxor xmm7, xmm8 + movdqu xmm0, [arg2] + pxor xmm7, xmm0 + add arg2, 16 + sub arg3, 16 + ; instead of a cmp instruction, we utilize the flags with the jge instruction + ; equivalent of: cmp arg3, 16-16 + ; check if there is any more 16B in the buffer to be able to fold + jge _16B_reduction_loop + + ;now we have 16+z bytes left to reduce, where 0<= z < 16. + ;first, we reduce the data in the xmm7 register + + +_final_reduction_for_128: + add arg3, 16 + je _128_done + ; here we are getting data that is less than 16 bytes. + ; since we know that there was data before the pointer, we can offset the input pointer before the actual point, to receive exactly 16 bytes. + ; after that the registers need to be adjusted. +_get_last_two_xmms: + + + movdqa xmm2, xmm7 + movdqu xmm1, [arg2 - 16 + arg3] + + ; get rid of the extra data that was loaded before + ; load the shift constant + lea rax, [pshufb_shf_table] + add rax, arg3 + movdqu xmm0, [rax] + + + pshufb xmm7, xmm0 + pxor xmm0, [mask3] + pshufb xmm2, xmm0 + + pblendvb xmm2, xmm1 ;xmm0 is implicit + ;;;;;;;;;; + movdqa xmm8, xmm7 + pclmulqdq xmm7, xmm10, 0x1 + + pclmulqdq xmm8, xmm10, 0x10 + pxor xmm7, xmm8 + pxor xmm7, xmm2 + +_128_done: + ; compute crc of a 128-bit value + movdqa xmm10, [rk5] + movdqa xmm0, xmm7 + + ;64b fold + pclmulqdq xmm7, xmm10, 0 + psrldq xmm0, 8 + pxor xmm7, xmm0 + + ;barrett reduction +_barrett: + movdqa xmm1, xmm7 + movdqa xmm10, [rk7] + + pclmulqdq xmm7, xmm10, 0 + movdqa xmm2, xmm7 + pclmulqdq xmm7, xmm10, 0x10 + pslldq xmm2, 8 + pxor xmm7, xmm2 + pxor xmm7, xmm1 + pextrq rax, xmm7, 1 + +_cleanup: + ; return c ^ 0xffffffff, ffffffffL; + not rax + + +%ifidn __OUTPUT_FORMAT__, win64 + movdqa xmm6, [rsp + XMM_SAVE + 16*0] + movdqa xmm7, [rsp + XMM_SAVE + 16*1] + movdqa xmm8, [rsp + XMM_SAVE + 16*2] + movdqa xmm9, [rsp + XMM_SAVE + 16*3] + movdqa xmm10, [rsp + XMM_SAVE + 16*4] + movdqa xmm11, [rsp + XMM_SAVE + 16*5] + movdqa xmm12, [rsp + XMM_SAVE + 16*6] + movdqa xmm13, [rsp + XMM_SAVE + 16*7] +%endif + add rsp, VARIABLE_OFFSET + ret + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align 16 +_less_than_256: + + ; check if there is enough buffer to be able to fold 16B at a time + cmp arg3, 32 + jl _less_than_32 + + ; if there is, load the constants + movdqa xmm10, [rk1] ; rk1 and rk2 in xmm10 + + movq xmm0, arg1 ; get the initial crc value + movdqu xmm7, [arg2] ; load the plaintext + pxor xmm7, xmm0 + + ; update the buffer pointer + add arg2, 16 + + ; update the counter. subtract 32 instead of 16 to save one instruction from the loop + sub arg3, 32 + + jmp _16B_reduction_loop + +align 16 +_less_than_32: + ; mov initial crc to the return value. this is necessary for zero-length buffers. + mov rax, arg1 + test arg3, arg3 + je _cleanup + + movq xmm0, arg1 ; get the initial crc value + + cmp arg3, 16 + je _exact_16_left + jl _less_than_16_left + + movdqu xmm7, [arg2] ; load the plaintext + pxor xmm7, xmm0 ; xor the initial crc value + add arg2, 16 + sub arg3, 16 + movdqa xmm10, [rk1] ; rk1 and rk2 in xmm10 + jmp _get_last_two_xmms + + +align 16 +_less_than_16_left: + ; use stack space to load data less than 16 bytes, zero-out the 16B in memory first. + + pxor xmm1, xmm1 + mov r11, rsp + movdqa [r11], xmm1 + + ; backup the counter value + mov r9, arg3 + cmp arg3, 8 + jl _less_than_8_left + + ; load 8 Bytes + mov rax, [arg2] + mov [r11], rax + add r11, 8 + sub arg3, 8 + add arg2, 8 +_less_than_8_left: + + cmp arg3, 4 + jl _less_than_4_left + + ; load 4 Bytes + mov eax, [arg2] + mov [r11], eax + add r11, 4 + sub arg3, 4 + add arg2, 4 +_less_than_4_left: + + cmp arg3, 2 + jl _less_than_2_left + + ; load 2 Bytes + mov ax, [arg2] + mov [r11], ax + add r11, 2 + sub arg3, 2 + add arg2, 2 +_less_than_2_left: + cmp arg3, 1 + jl _zero_left + + ; load 1 Byte + mov al, [arg2] + mov [r11], al + +_zero_left: + movdqa xmm7, [rsp] + pxor xmm7, xmm0 ; xor the initial crc value + + lea rax,[pshufb_shf_table] + + cmp r9, 8 + jl _end_1to7 + +_end_8to15: + movdqu xmm0, [rax + r9] + pshufb xmm7,xmm0 + jmp _128_done + +_end_1to7: + ; Left shift (8-length) bytes in XMM + movdqu xmm0, [rax + r9 + 8] + pshufb xmm7,xmm0 + + jmp _barrett + +align 16 +_exact_16_left: + movdqu xmm7, [arg2] + pxor xmm7, xmm0 ; xor the initial crc value + + jmp _128_done + +section .data + +; precomputed constants +align 16 +; rk7 = floor(2^128/Q) +; rk8 = Q +rk1: +DQ 0xf500000000000001 +rk2: +DQ 0x6b70000000000001 +rk3: +DQ 0xb001000000010000 +rk4: +DQ 0xf501b0000001b000 +rk5: +DQ 0xf500000000000001 +rk6: +DQ 0x0000000000000000 +rk7: +DQ 0xb000000000000001 +rk8: +DQ 0xb000000000000000 +rk9: +DQ 0xe014514514501501 +rk10: +DQ 0x771db6db6db71c71 +rk11: +DQ 0xa101101101110001 +rk12: +DQ 0x1ab1ab1ab1aab001 +rk13: +DQ 0xf445014445000001 +rk14: +DQ 0x6aab71daab700001 +rk15: +DQ 0xb100010100000001 +rk16: +DQ 0x01b001b1b0000001 +rk17: +DQ 0xe145150000000001 +rk18: +DQ 0x76db6c7000000001 +rk19: +DQ 0xa011000000000001 +rk20: +DQ 0x1b1ab00000000001 + +pshufb_shf_table: +; use these values for shift constants for the pshufb instruction +; different alignments result in values as shown: +; dq 0x8887868584838281, 0x008f8e8d8c8b8a89 ; shl 15 (16-1) / shr1 +; dq 0x8988878685848382, 0x01008f8e8d8c8b8a ; shl 14 (16-3) / shr2 +; dq 0x8a89888786858483, 0x0201008f8e8d8c8b ; shl 13 (16-4) / shr3 +; dq 0x8b8a898887868584, 0x030201008f8e8d8c ; shl 12 (16-4) / shr4 +; dq 0x8c8b8a8988878685, 0x04030201008f8e8d ; shl 11 (16-5) / shr5 +; dq 0x8d8c8b8a89888786, 0x0504030201008f8e ; shl 10 (16-6) / shr6 +; dq 0x8e8d8c8b8a898887, 0x060504030201008f ; shl 9 (16-7) / shr7 +; dq 0x8f8e8d8c8b8a8988, 0x0706050403020100 ; shl 8 (16-8) / shr8 +; dq 0x008f8e8d8c8b8a89, 0x0807060504030201 ; shl 7 (16-9) / shr9 +; dq 0x01008f8e8d8c8b8a, 0x0908070605040302 ; shl 6 (16-10) / shr10 +; dq 0x0201008f8e8d8c8b, 0x0a09080706050403 ; shl 5 (16-11) / shr11 +; dq 0x030201008f8e8d8c, 0x0b0a090807060504 ; shl 4 (16-12) / shr12 +; dq 0x04030201008f8e8d, 0x0c0b0a0908070605 ; shl 3 (16-13) / shr13 +; dq 0x0504030201008f8e, 0x0d0c0b0a09080706 ; shl 2 (16-14) / shr14 +; dq 0x060504030201008f, 0x0e0d0c0b0a090807 ; shl 1 (16-15) / shr15 +dq 0x8786858483828100, 0x8f8e8d8c8b8a8988 +dq 0x0706050403020100, 0x000e0d0c0b0a0908 + + +mask: +dq 0xFFFFFFFFFFFFFFFF, 0x0000000000000000 +mask2: +dq 0xFFFFFFFF00000000, 0xFFFFFFFFFFFFFFFF +mask3: +dq 0x8080808080808080, 0x8080808080808080 + +;;; func core, ver, snum +slversion crc64_iso_refl_by8, 01, 00, 0023 diff --git a/ceph/src/isa-l/crc/crc64_jones_norm_by8.asm b/ceph/src/isa-l/crc/crc64_jones_norm_by8.asm new file mode 100644 index 000000000..0e5e75a22 --- /dev/null +++ b/ceph/src/isa-l/crc/crc64_jones_norm_by8.asm @@ -0,0 +1,581 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2016 Intel Corporation All rights reserved. +; +; 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 Intel Corporation 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 +; 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. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Function API: +; uint64_t crc64_jones_norm_by8( +; uint64_t init_crc, //initial CRC value, 64 bits +; const unsigned char *buf, //buffer pointer to calculate CRC on +; uint64_t len //buffer length in bytes (64-bit data) +; ); +; +%include "reg_sizes.asm" + +%define fetch_dist 1024 + +[bits 64] +default rel + +section .text + +%ifidn __OUTPUT_FORMAT__, win64 + %xdefine arg1 rcx + %xdefine arg2 rdx + %xdefine arg3 r8 +%else + %xdefine arg1 rdi + %xdefine arg2 rsi + %xdefine arg3 rdx +%endif + +%define TMP 16*0 +%ifidn __OUTPUT_FORMAT__, win64 + %define XMM_SAVE 16*2 + %define VARIABLE_OFFSET 16*10+8 +%else + %define VARIABLE_OFFSET 16*2+8 +%endif +align 16 +global crc64_jones_norm_by8:function +crc64_jones_norm_by8: + + not arg1 ;~init_crc + + sub rsp,VARIABLE_OFFSET + +%ifidn __OUTPUT_FORMAT__, win64 + ; push the xmm registers into the stack to maintain + movdqa [rsp + XMM_SAVE + 16*0], xmm6 + movdqa [rsp + XMM_SAVE + 16*1], xmm7 + movdqa [rsp + XMM_SAVE + 16*2], xmm8 + movdqa [rsp + XMM_SAVE + 16*3], xmm9 + movdqa [rsp + XMM_SAVE + 16*4], xmm10 + movdqa [rsp + XMM_SAVE + 16*5], xmm11 + movdqa [rsp + XMM_SAVE + 16*6], xmm12 + movdqa [rsp + XMM_SAVE + 16*7], xmm13 +%endif + + + ; check if smaller than 256 + cmp arg3, 256 + + ; for sizes less than 256, we can't fold 128B at a time... + jl _less_than_256 + + + ; load the initial crc value + movq xmm10, arg1 ; initial crc + + ; crc value does not need to be byte-reflected, but it needs to be moved to the high part of the register. + ; because data will be byte-reflected and will align with initial crc at correct place. + pslldq xmm10, 8 + + movdqa xmm11, [SHUF_MASK] + ; receive the initial 128B data, xor the initial crc value + movdqu xmm0, [arg2+16*0] + movdqu xmm1, [arg2+16*1] + movdqu xmm2, [arg2+16*2] + movdqu xmm3, [arg2+16*3] + movdqu xmm4, [arg2+16*4] + movdqu xmm5, [arg2+16*5] + movdqu xmm6, [arg2+16*6] + movdqu xmm7, [arg2+16*7] + + pshufb xmm0, xmm11 + ; XOR the initial_crc value + pxor xmm0, xmm10 + pshufb xmm1, xmm11 + pshufb xmm2, xmm11 + pshufb xmm3, xmm11 + pshufb xmm4, xmm11 + pshufb xmm5, xmm11 + pshufb xmm6, xmm11 + pshufb xmm7, xmm11 + + movdqa xmm10, [rk3] ;xmm10 has rk3 and rk4 + ;imm value of pclmulqdq instruction will determine which constant to use + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ; we subtract 256 instead of 128 to save one instruction from the loop + sub arg3, 256 + + ; at this section of the code, there is 128*x+y (0<=y<128) bytes of buffer. The _fold_128_B_loop + ; loop will fold 128B at a time until we have 128+y Bytes of buffer + + + ; fold 128B at a time. This section of the code folds 8 xmm registers in parallel +_fold_128_B_loop: + + ; update the buffer pointer + add arg2, 128 ; buf += 128; + + prefetchnta [arg2+fetch_dist+0] + movdqu xmm9, [arg2+16*0] + movdqu xmm12, [arg2+16*1] + pshufb xmm9, xmm11 + pshufb xmm12, xmm11 + movdqa xmm8, xmm0 + movdqa xmm13, xmm1 + pclmulqdq xmm0, xmm10, 0x0 + pclmulqdq xmm8, xmm10 , 0x11 + pclmulqdq xmm1, xmm10, 0x0 + pclmulqdq xmm13, xmm10 , 0x11 + pxor xmm0, xmm9 + xorps xmm0, xmm8 + pxor xmm1, xmm12 + xorps xmm1, xmm13 + + prefetchnta [arg2+fetch_dist+32] + movdqu xmm9, [arg2+16*2] + movdqu xmm12, [arg2+16*3] + pshufb xmm9, xmm11 + pshufb xmm12, xmm11 + movdqa xmm8, xmm2 + movdqa xmm13, xmm3 + pclmulqdq xmm2, xmm10, 0x0 + pclmulqdq xmm8, xmm10 , 0x11 + pclmulqdq xmm3, xmm10, 0x0 + pclmulqdq xmm13, xmm10 , 0x11 + pxor xmm2, xmm9 + xorps xmm2, xmm8 + pxor xmm3, xmm12 + xorps xmm3, xmm13 + + prefetchnta [arg2+fetch_dist+64] + movdqu xmm9, [arg2+16*4] + movdqu xmm12, [arg2+16*5] + pshufb xmm9, xmm11 + pshufb xmm12, xmm11 + movdqa xmm8, xmm4 + movdqa xmm13, xmm5 + pclmulqdq xmm4, xmm10, 0x0 + pclmulqdq xmm8, xmm10 , 0x11 + pclmulqdq xmm5, xmm10, 0x0 + pclmulqdq xmm13, xmm10 , 0x11 + pxor xmm4, xmm9 + xorps xmm4, xmm8 + pxor xmm5, xmm12 + xorps xmm5, xmm13 + + prefetchnta [arg2+fetch_dist+96] + movdqu xmm9, [arg2+16*6] + movdqu xmm12, [arg2+16*7] + pshufb xmm9, xmm11 + pshufb xmm12, xmm11 + movdqa xmm8, xmm6 + movdqa xmm13, xmm7 + pclmulqdq xmm6, xmm10, 0x0 + pclmulqdq xmm8, xmm10 , 0x11 + pclmulqdq xmm7, xmm10, 0x0 + pclmulqdq xmm13, xmm10 , 0x11 + pxor xmm6, xmm9 + xorps xmm6, xmm8 + pxor xmm7, xmm12 + xorps xmm7, xmm13 + + sub arg3, 128 + + ; check if there is another 128B in the buffer to be able to fold + jge _fold_128_B_loop + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + add arg2, 128 + ; at this point, the buffer pointer is pointing at the last y Bytes of the buffer, where 0 <= y < 128 + ; the 128B of folded data is in 8 of the xmm registers: xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7 + + + ; fold the 8 xmm registers to 1 xmm register with different constants + + movdqa xmm10, [rk9] + movdqa xmm8, xmm0 + pclmulqdq xmm0, xmm10, 0x11 + pclmulqdq xmm8, xmm10, 0x0 + pxor xmm7, xmm8 + xorps xmm7, xmm0 + + movdqa xmm10, [rk11] + movdqa xmm8, xmm1 + pclmulqdq xmm1, xmm10, 0x11 + pclmulqdq xmm8, xmm10, 0x0 + pxor xmm7, xmm8 + xorps xmm7, xmm1 + + movdqa xmm10, [rk13] + movdqa xmm8, xmm2 + pclmulqdq xmm2, xmm10, 0x11 + pclmulqdq xmm8, xmm10, 0x0 + pxor xmm7, xmm8 + pxor xmm7, xmm2 + + movdqa xmm10, [rk15] + movdqa xmm8, xmm3 + pclmulqdq xmm3, xmm10, 0x11 + pclmulqdq xmm8, xmm10, 0x0 + pxor xmm7, xmm8 + xorps xmm7, xmm3 + + movdqa xmm10, [rk17] + movdqa xmm8, xmm4 + pclmulqdq xmm4, xmm10, 0x11 + pclmulqdq xmm8, xmm10, 0x0 + pxor xmm7, xmm8 + pxor xmm7, xmm4 + + movdqa xmm10, [rk19] + movdqa xmm8, xmm5 + pclmulqdq xmm5, xmm10, 0x11 + pclmulqdq xmm8, xmm10, 0x0 + pxor xmm7, xmm8 + xorps xmm7, xmm5 + + movdqa xmm10, [rk1] ;xmm10 has rk1 and rk2 + + movdqa xmm8, xmm6 + pclmulqdq xmm6, xmm10, 0x11 + pclmulqdq xmm8, xmm10, 0x0 + pxor xmm7, xmm8 + pxor xmm7, xmm6 + + + ; instead of 128, we add 112 to the loop counter to save 1 instruction from the loop + ; instead of a cmp instruction, we use the negative flag with the jl instruction + add arg3, 128-16 + jl _final_reduction_for_128 + + ; now we have 16+y bytes left to reduce. 16 Bytes is in register xmm7 and the rest is in memory + ; we can fold 16 bytes at a time if y>=16 + ; continue folding 16B at a time + +_16B_reduction_loop: + movdqa xmm8, xmm7 + pclmulqdq xmm7, xmm10, 0x11 + pclmulqdq xmm8, xmm10, 0x0 + pxor xmm7, xmm8 + movdqu xmm0, [arg2] + pshufb xmm0, xmm11 + pxor xmm7, xmm0 + add arg2, 16 + sub arg3, 16 + ; instead of a cmp instruction, we utilize the flags with the jge instruction + ; equivalent of: cmp arg3, 16-16 + ; check if there is any more 16B in the buffer to be able to fold + jge _16B_reduction_loop + + ;now we have 16+z bytes left to reduce, where 0<= z < 16. + ;first, we reduce the data in the xmm7 register + + +_final_reduction_for_128: + ; check if any more data to fold. If not, compute the CRC of the final 128 bits + add arg3, 16 + je _128_done + + ; here we are getting data that is less than 16 bytes. + ; since we know that there was data before the pointer, we can offset the input pointer before the actual point, to receive exactly 16 bytes. + ; after that the registers need to be adjusted. +_get_last_two_xmms: + movdqa xmm2, xmm7 + + movdqu xmm1, [arg2 - 16 + arg3] + pshufb xmm1, xmm11 + + ; get rid of the extra data that was loaded before + ; load the shift constant + lea rax, [pshufb_shf_table + 16] + sub rax, arg3 + movdqu xmm0, [rax] + + ; shift xmm2 to the left by arg3 bytes + pshufb xmm2, xmm0 + + ; shift xmm7 to the right by 16-arg3 bytes + pxor xmm0, [mask1] + pshufb xmm7, xmm0 + pblendvb xmm1, xmm2 ;xmm0 is implicit + + ; fold 16 Bytes + movdqa xmm2, xmm1 + movdqa xmm8, xmm7 + pclmulqdq xmm7, xmm10, 0x11 + pclmulqdq xmm8, xmm10, 0x0 + pxor xmm7, xmm8 + pxor xmm7, xmm2 + +_128_done: + ; compute crc of a 128-bit value + movdqa xmm10, [rk5] ; rk5 and rk6 in xmm10 + movdqa xmm0, xmm7 + + ;64b fold + pclmulqdq xmm7, xmm10, 0x01 ; H*L + pslldq xmm0, 8 + pxor xmm7, xmm0 + + ;barrett reduction +_barrett: + movdqa xmm10, [rk7] ; rk7 and rk8 in xmm10 + movdqa xmm0, xmm7 + + movdqa xmm1, xmm7 + pand xmm1, [mask3] + pclmulqdq xmm7, xmm10, 0x01 + pxor xmm7, xmm1 + + pclmulqdq xmm7, xmm10, 0x11 + pxor xmm7, xmm0 + pextrq rax, xmm7, 0 + +_cleanup: + not rax +%ifidn __OUTPUT_FORMAT__, win64 + movdqa xmm6, [rsp + XMM_SAVE + 16*0] + movdqa xmm7, [rsp + XMM_SAVE + 16*1] + movdqa xmm8, [rsp + XMM_SAVE + 16*2] + movdqa xmm9, [rsp + XMM_SAVE + 16*3] + movdqa xmm10, [rsp + XMM_SAVE + 16*4] + movdqa xmm11, [rsp + XMM_SAVE + 16*5] + movdqa xmm12, [rsp + XMM_SAVE + 16*6] + movdqa xmm13, [rsp + XMM_SAVE + 16*7] +%endif + add rsp, VARIABLE_OFFSET + ret + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align 16 +_less_than_256: + + ; check if there is enough buffer to be able to fold 16B at a time + cmp arg3, 32 + jl _less_than_32 + movdqa xmm11, [SHUF_MASK] + + ; if there is, load the constants + movdqa xmm10, [rk1] ; rk1 and rk2 in xmm10 + + movq xmm0, arg1 ; get the initial crc value + pslldq xmm0, 8 ; align it to its correct place + movdqu xmm7, [arg2] ; load the plaintext + pshufb xmm7, xmm11 ; byte-reflect the plaintext + pxor xmm7, xmm0 + + + ; update the buffer pointer + add arg2, 16 + + ; update the counter. subtract 32 instead of 16 to save one instruction from the loop + sub arg3, 32 + + jmp _16B_reduction_loop +align 16 +_less_than_32: + ; mov initial crc to the return value. this is necessary for zero-length buffers. + mov rax, arg1 + test arg3, arg3 + je _cleanup + + movdqa xmm11, [SHUF_MASK] + + movq xmm0, arg1 ; get the initial crc value + pslldq xmm0, 8 ; align it to its correct place + + cmp arg3, 16 + je _exact_16_left + jl _less_than_16_left + + movdqu xmm7, [arg2] ; load the plaintext + pshufb xmm7, xmm11 ; byte-reflect the plaintext + pxor xmm7, xmm0 ; xor the initial crc value + add arg2, 16 + sub arg3, 16 + movdqa xmm10, [rk1] ; rk1 and rk2 in xmm10 + jmp _get_last_two_xmms +align 16 +_less_than_16_left: + ; use stack space to load data less than 16 bytes, zero-out the 16B in memory first. + pxor xmm1, xmm1 + mov r11, rsp + movdqa [r11], xmm1 + + ; backup the counter value + mov r9, arg3 + cmp arg3, 8 + jl _less_than_8_left + + ; load 8 Bytes + mov rax, [arg2] + mov [r11], rax + add r11, 8 + sub arg3, 8 + add arg2, 8 +_less_than_8_left: + + cmp arg3, 4 + jl _less_than_4_left + + ; load 4 Bytes + mov eax, [arg2] + mov [r11], eax + add r11, 4 + sub arg3, 4 + add arg2, 4 +_less_than_4_left: + + cmp arg3, 2 + jl _less_than_2_left + + ; load 2 Bytes + mov ax, [arg2] + mov [r11], ax + add r11, 2 + sub arg3, 2 + add arg2, 2 +_less_than_2_left: + cmp arg3, 1 + jl _zero_left + + ; load 1 Byte + mov al, [arg2] + mov [r11], al +_zero_left: + movdqa xmm7, [rsp] + pshufb xmm7, xmm11 + pxor xmm7, xmm0 ; xor the initial crc value + + ; shl r9, 4 + lea rax, [pshufb_shf_table + 16] + sub rax, r9 + + cmp r9, 8 + jl _end_1to7 + +_end_8to15: + movdqu xmm0, [rax] + pxor xmm0, [mask1] + + pshufb xmm7, xmm0 + jmp _128_done + +_end_1to7: + ; Right shift (8-length) bytes in XMM + add rax, 8 + movdqu xmm0, [rax] + pshufb xmm7,xmm0 + + jmp _barrett +align 16 +_exact_16_left: + movdqu xmm7, [arg2] + pshufb xmm7, xmm11 + pxor xmm7, xmm0 ; xor the initial crc value + + jmp _128_done + +section .data + +; precomputed constants +align 16 + +rk1: +DQ 0x4445ed2750017038 +rk2: +DQ 0x698b74157cfbd736 +rk3: +DQ 0x0cfcfb5101c4b775 +rk4: +DQ 0x65403fd47cbec866 +rk5: +DQ 0x4445ed2750017038 +rk6: +DQ 0x0000000000000000 +rk7: +DQ 0xddf3eeb298be6cf8 +rk8: +DQ 0xad93d23594c935a9 +rk9: +DQ 0xd8dc208e2ba527b4 +rk10: +DQ 0xf032cfec76bb2bc5 +rk11: +DQ 0xb536044f357f4238 +rk12: +DQ 0xfdbf104d938ba67a +rk13: +DQ 0xeeddad9297a843e7 +rk14: +DQ 0x3550bce629466473 +rk15: +DQ 0x4e501e58ca43d25e +rk16: +DQ 0x13c961588f27f643 +rk17: +DQ 0x3b60d00dcb1099bc +rk18: +DQ 0x44bf1f468c53b9a3 +rk19: +DQ 0x96f2236e317179ee +rk20: +DQ 0xf00839aa0dd64bac + +mask1: +dq 0x8080808080808080, 0x8080808080808080 +mask2: +dq 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF +mask3: +dq 0x0000000000000000, 0xFFFFFFFFFFFFFFFF + +SHUF_MASK: +dq 0x08090A0B0C0D0E0F, 0x0001020304050607 + +pshufb_shf_table: +; use these values for shift constants for the pshufb instruction +; different alignments result in values as shown: +; dq 0x8887868584838281, 0x008f8e8d8c8b8a89 ; shl 15 (16-1) / shr1 +; dq 0x8988878685848382, 0x01008f8e8d8c8b8a ; shl 14 (16-3) / shr2 +; dq 0x8a89888786858483, 0x0201008f8e8d8c8b ; shl 13 (16-4) / shr3 +; dq 0x8b8a898887868584, 0x030201008f8e8d8c ; shl 12 (16-4) / shr4 +; dq 0x8c8b8a8988878685, 0x04030201008f8e8d ; shl 11 (16-5) / shr5 +; dq 0x8d8c8b8a89888786, 0x0504030201008f8e ; shl 10 (16-6) / shr6 +; dq 0x8e8d8c8b8a898887, 0x060504030201008f ; shl 9 (16-7) / shr7 +; dq 0x8f8e8d8c8b8a8988, 0x0706050403020100 ; shl 8 (16-8) / shr8 +; dq 0x008f8e8d8c8b8a89, 0x0807060504030201 ; shl 7 (16-9) / shr9 +; dq 0x01008f8e8d8c8b8a, 0x0908070605040302 ; shl 6 (16-10) / shr10 +; dq 0x0201008f8e8d8c8b, 0x0a09080706050403 ; shl 5 (16-11) / shr11 +; dq 0x030201008f8e8d8c, 0x0b0a090807060504 ; shl 4 (16-12) / shr12 +; dq 0x04030201008f8e8d, 0x0c0b0a0908070605 ; shl 3 (16-13) / shr13 +; dq 0x0504030201008f8e, 0x0d0c0b0a09080706 ; shl 2 (16-14) / shr14 +; dq 0x060504030201008f, 0x0e0d0c0b0a090807 ; shl 1 (16-15) / shr15 +dq 0x8786858483828100, 0x8f8e8d8c8b8a8988 +dq 0x0706050403020100, 0x0f0e0d0c0b0a0908 +dq 0x8080808080808080, 0x0f0e0d0c0b0a0908 +dq 0x8080808080808080, 0x8080808080808080 + +;;; func core, ver, snum +slversion crc64_jones_norm_by8, 01, 00, 0026 diff --git a/ceph/src/isa-l/crc/crc64_jones_refl_by8.asm b/ceph/src/isa-l/crc/crc64_jones_refl_by8.asm new file mode 100644 index 000000000..39da6b822 --- /dev/null +++ b/ceph/src/isa-l/crc/crc64_jones_refl_by8.asm @@ -0,0 +1,544 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2016 Intel Corporation All rights reserved. +; +; 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 Intel Corporation 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 +; 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. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Function API: +; uint64_t crc64_jones_refl_by8( +; uint64_t init_crc, //initial CRC value, 64 bits +; const unsigned char *buf, //buffer pointer to calculate CRC on +; uint64_t len //buffer length in bytes (64-bit data) +; ); +; +%include "reg_sizes.asm" + +%define fetch_dist 1024 + +[bits 64] +default rel + +section .text + + +%ifidn __OUTPUT_FORMAT__, win64 + %xdefine arg1 rcx + %xdefine arg2 rdx + %xdefine arg3 r8 +%else + %xdefine arg1 rdi + %xdefine arg2 rsi + %xdefine arg3 rdx +%endif + +%define TMP 16*0 +%ifidn __OUTPUT_FORMAT__, win64 + %define XMM_SAVE 16*2 + %define VARIABLE_OFFSET 16*10+8 +%else + %define VARIABLE_OFFSET 16*2+8 +%endif + + +align 16 +global crc64_jones_refl_by8:function +crc64_jones_refl_by8: + ; uint64_t c = crc ^ 0xffffffff,ffffffffL; + not arg1 + sub rsp, VARIABLE_OFFSET + +%ifidn __OUTPUT_FORMAT__, win64 + ; push the xmm registers into the stack to maintain + movdqa [rsp + XMM_SAVE + 16*0], xmm6 + movdqa [rsp + XMM_SAVE + 16*1], xmm7 + movdqa [rsp + XMM_SAVE + 16*2], xmm8 + movdqa [rsp + XMM_SAVE + 16*3], xmm9 + movdqa [rsp + XMM_SAVE + 16*4], xmm10 + movdqa [rsp + XMM_SAVE + 16*5], xmm11 + movdqa [rsp + XMM_SAVE + 16*6], xmm12 + movdqa [rsp + XMM_SAVE + 16*7], xmm13 +%endif + + ; check if smaller than 256B + cmp arg3, 256 + + ; for sizes less than 256, we can't fold 128B at a time... + jl _less_than_256 + + + ; load the initial crc value + movq xmm10, arg1 ; initial crc + ; receive the initial 128B data, xor the initial crc value + movdqu xmm0, [arg2+16*0] + movdqu xmm1, [arg2+16*1] + movdqu xmm2, [arg2+16*2] + movdqu xmm3, [arg2+16*3] + movdqu xmm4, [arg2+16*4] + movdqu xmm5, [arg2+16*5] + movdqu xmm6, [arg2+16*6] + movdqu xmm7, [arg2+16*7] + + ; XOR the initial_crc value + pxor xmm0, xmm10 + movdqa xmm10, [rk3] ;xmm10 has rk3 and rk4 + ;imm value of pclmulqdq instruction will determine which constant to use + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ; we subtract 256 instead of 128 to save one instruction from the loop + sub arg3, 256 + + ; at this section of the code, there is 128*x+y (0<=y<128) bytes of buffer. The _fold_128_B_loop + ; loop will fold 128B at a time until we have 128+y Bytes of buffer + + + ; fold 128B at a time. This section of the code folds 8 xmm registers in parallel +_fold_128_B_loop: + + ; update the buffer pointer + add arg2, 128 + + prefetchnta [arg2+fetch_dist+0] + movdqu xmm9, [arg2+16*0] + movdqu xmm12, [arg2+16*1] + movdqa xmm8, xmm0 + movdqa xmm13, xmm1 + pclmulqdq xmm0, xmm10, 0x10 + pclmulqdq xmm8, xmm10 , 0x1 + pclmulqdq xmm1, xmm10, 0x10 + pclmulqdq xmm13, xmm10 , 0x1 + pxor xmm0, xmm9 + xorps xmm0, xmm8 + pxor xmm1, xmm12 + xorps xmm1, xmm13 + + prefetchnta [arg2+fetch_dist+32] + movdqu xmm9, [arg2+16*2] + movdqu xmm12, [arg2+16*3] + movdqa xmm8, xmm2 + movdqa xmm13, xmm3 + pclmulqdq xmm2, xmm10, 0x10 + pclmulqdq xmm8, xmm10 , 0x1 + pclmulqdq xmm3, xmm10, 0x10 + pclmulqdq xmm13, xmm10 , 0x1 + pxor xmm2, xmm9 + xorps xmm2, xmm8 + pxor xmm3, xmm12 + xorps xmm3, xmm13 + + prefetchnta [arg2+fetch_dist+64] + movdqu xmm9, [arg2+16*4] + movdqu xmm12, [arg2+16*5] + movdqa xmm8, xmm4 + movdqa xmm13, xmm5 + pclmulqdq xmm4, xmm10, 0x10 + pclmulqdq xmm8, xmm10 , 0x1 + pclmulqdq xmm5, xmm10, 0x10 + pclmulqdq xmm13, xmm10 , 0x1 + pxor xmm4, xmm9 + xorps xmm4, xmm8 + pxor xmm5, xmm12 + xorps xmm5, xmm13 + + prefetchnta [arg2+fetch_dist+96] + movdqu xmm9, [arg2+16*6] + movdqu xmm12, [arg2+16*7] + movdqa xmm8, xmm6 + movdqa xmm13, xmm7 + pclmulqdq xmm6, xmm10, 0x10 + pclmulqdq xmm8, xmm10 , 0x1 + pclmulqdq xmm7, xmm10, 0x10 + pclmulqdq xmm13, xmm10 , 0x1 + pxor xmm6, xmm9 + xorps xmm6, xmm8 + pxor xmm7, xmm12 + xorps xmm7, xmm13 + + sub arg3, 128 + + ; check if there is another 128B in the buffer to be able to fold + jge _fold_128_B_loop + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + add arg2, 128 + ; at this point, the buffer pointer is pointing at the last y Bytes of the buffer, where 0 <= y < 128 + ; the 128B of folded data is in 8 of the xmm registers: xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7 + + + ; fold the 8 xmm registers to 1 xmm register with different constants + ; xmm0 to xmm7 + movdqa xmm10, [rk9] + movdqa xmm8, xmm0 + pclmulqdq xmm0, xmm10, 0x1 + pclmulqdq xmm8, xmm10, 0x10 + pxor xmm7, xmm8 + xorps xmm7, xmm0 + ;xmm1 to xmm7 + movdqa xmm10, [rk11] + movdqa xmm8, xmm1 + pclmulqdq xmm1, xmm10, 0x1 + pclmulqdq xmm8, xmm10, 0x10 + pxor xmm7, xmm8 + xorps xmm7, xmm1 + + movdqa xmm10, [rk13] + movdqa xmm8, xmm2 + pclmulqdq xmm2, xmm10, 0x1 + pclmulqdq xmm8, xmm10, 0x10 + pxor xmm7, xmm8 + pxor xmm7, xmm2 + + movdqa xmm10, [rk15] + movdqa xmm8, xmm3 + pclmulqdq xmm3, xmm10, 0x1 + pclmulqdq xmm8, xmm10, 0x10 + pxor xmm7, xmm8 + xorps xmm7, xmm3 + + movdqa xmm10, [rk17] + movdqa xmm8, xmm4 + pclmulqdq xmm4, xmm10, 0x1 + pclmulqdq xmm8, xmm10, 0x10 + pxor xmm7, xmm8 + pxor xmm7, xmm4 + + movdqa xmm10, [rk19] + movdqa xmm8, xmm5 + pclmulqdq xmm5, xmm10, 0x1 + pclmulqdq xmm8, xmm10, 0x10 + pxor xmm7, xmm8 + xorps xmm7, xmm5 + ; xmm6 to xmm7 + movdqa xmm10, [rk1] + movdqa xmm8, xmm6 + pclmulqdq xmm6, xmm10, 0x1 + pclmulqdq xmm8, xmm10, 0x10 + pxor xmm7, xmm8 + pxor xmm7, xmm6 + + + ; instead of 128, we add 128-16 to the loop counter to save 1 instruction from the loop + ; instead of a cmp instruction, we use the negative flag with the jl instruction + add arg3, 128-16 + jl _final_reduction_for_128 + + ; now we have 16+y bytes left to reduce. 16 Bytes is in register xmm7 and the rest is in memory + ; we can fold 16 bytes at a time if y>=16 + ; continue folding 16B at a time + +_16B_reduction_loop: + movdqa xmm8, xmm7 + pclmulqdq xmm7, xmm10, 0x1 + pclmulqdq xmm8, xmm10, 0x10 + pxor xmm7, xmm8 + movdqu xmm0, [arg2] + pxor xmm7, xmm0 + add arg2, 16 + sub arg3, 16 + ; instead of a cmp instruction, we utilize the flags with the jge instruction + ; equivalent of: cmp arg3, 16-16 + ; check if there is any more 16B in the buffer to be able to fold + jge _16B_reduction_loop + + ;now we have 16+z bytes left to reduce, where 0<= z < 16. + ;first, we reduce the data in the xmm7 register + + +_final_reduction_for_128: + add arg3, 16 + je _128_done + ; here we are getting data that is less than 16 bytes. + ; since we know that there was data before the pointer, we can offset the input pointer before the actual point, to receive exactly 16 bytes. + ; after that the registers need to be adjusted. +_get_last_two_xmms: + + + movdqa xmm2, xmm7 + movdqu xmm1, [arg2 - 16 + arg3] + + ; get rid of the extra data that was loaded before + ; load the shift constant + lea rax, [pshufb_shf_table] + add rax, arg3 + movdqu xmm0, [rax] + + + pshufb xmm7, xmm0 + pxor xmm0, [mask3] + pshufb xmm2, xmm0 + + pblendvb xmm2, xmm1 ;xmm0 is implicit + ;;;;;;;;;; + movdqa xmm8, xmm7 + pclmulqdq xmm7, xmm10, 0x1 + + pclmulqdq xmm8, xmm10, 0x10 + pxor xmm7, xmm8 + pxor xmm7, xmm2 + +_128_done: + ; compute crc of a 128-bit value + movdqa xmm10, [rk5] + movdqa xmm0, xmm7 + + ;64b fold + pclmulqdq xmm7, xmm10, 0 + psrldq xmm0, 8 + pxor xmm7, xmm0 + + ;barrett reduction +_barrett: + movdqa xmm1, xmm7 + movdqa xmm10, [rk7] + + pclmulqdq xmm7, xmm10, 0 + movdqa xmm2, xmm7 + pclmulqdq xmm7, xmm10, 0x10 + pslldq xmm2, 8 + pxor xmm7, xmm2 + pxor xmm7, xmm1 + pextrq rax, xmm7, 1 + +_cleanup: + ; return c ^ 0xffffffff, ffffffffL; + not rax + + +%ifidn __OUTPUT_FORMAT__, win64 + movdqa xmm6, [rsp + XMM_SAVE + 16*0] + movdqa xmm7, [rsp + XMM_SAVE + 16*1] + movdqa xmm8, [rsp + XMM_SAVE + 16*2] + movdqa xmm9, [rsp + XMM_SAVE + 16*3] + movdqa xmm10, [rsp + XMM_SAVE + 16*4] + movdqa xmm11, [rsp + XMM_SAVE + 16*5] + movdqa xmm12, [rsp + XMM_SAVE + 16*6] + movdqa xmm13, [rsp + XMM_SAVE + 16*7] +%endif + add rsp, VARIABLE_OFFSET + ret + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align 16 +_less_than_256: + + ; check if there is enough buffer to be able to fold 16B at a time + cmp arg3, 32 + jl _less_than_32 + + ; if there is, load the constants + movdqa xmm10, [rk1] ; rk1 and rk2 in xmm10 + + movq xmm0, arg1 ; get the initial crc value + movdqu xmm7, [arg2] ; load the plaintext + pxor xmm7, xmm0 + + ; update the buffer pointer + add arg2, 16 + + ; update the counter. subtract 32 instead of 16 to save one instruction from the loop + sub arg3, 32 + + jmp _16B_reduction_loop + +align 16 +_less_than_32: + ; mov initial crc to the return value. this is necessary for zero-length buffers. + mov rax, arg1 + test arg3, arg3 + je _cleanup + + movq xmm0, arg1 ; get the initial crc value + + cmp arg3, 16 + je _exact_16_left + jl _less_than_16_left + + movdqu xmm7, [arg2] ; load the plaintext + pxor xmm7, xmm0 ; xor the initial crc value + add arg2, 16 + sub arg3, 16 + movdqa xmm10, [rk1] ; rk1 and rk2 in xmm10 + jmp _get_last_two_xmms + + +align 16 +_less_than_16_left: + ; use stack space to load data less than 16 bytes, zero-out the 16B in memory first. + + pxor xmm1, xmm1 + mov r11, rsp + movdqa [r11], xmm1 + + ; backup the counter value + mov r9, arg3 + cmp arg3, 8 + jl _less_than_8_left + + ; load 8 Bytes + mov rax, [arg2] + mov [r11], rax + add r11, 8 + sub arg3, 8 + add arg2, 8 +_less_than_8_left: + + cmp arg3, 4 + jl _less_than_4_left + + ; load 4 Bytes + mov eax, [arg2] + mov [r11], eax + add r11, 4 + sub arg3, 4 + add arg2, 4 +_less_than_4_left: + + cmp arg3, 2 + jl _less_than_2_left + + ; load 2 Bytes + mov ax, [arg2] + mov [r11], ax + add r11, 2 + sub arg3, 2 + add arg2, 2 +_less_than_2_left: + cmp arg3, 1 + jl _zero_left + + ; load 1 Byte + mov al, [arg2] + mov [r11], al + +_zero_left: + movdqa xmm7, [rsp] + pxor xmm7, xmm0 ; xor the initial crc value + + lea rax,[pshufb_shf_table] + + cmp r9, 8 + jl _end_1to7 + +_end_8to15: + movdqu xmm0, [rax + r9] + pshufb xmm7,xmm0 + jmp _128_done + +_end_1to7: + ; Left shift (8-length) bytes in XMM + movdqu xmm0, [rax + r9 + 8] + pshufb xmm7,xmm0 + + jmp _barrett + +align 16 +_exact_16_left: + movdqu xmm7, [arg2] + pxor xmm7, xmm0 ; xor the initial crc value + + jmp _128_done + +section .data + +; precomputed constants +align 16 +; rk7 = floor(2^128/Q) +; rk8 = Q +rk1: +DQ 0x381d0015c96f4444 +rk2: +DQ 0xd9d7be7d505da32c +rk3: +DQ 0x768361524d29ed0b +rk4: +DQ 0xcc26fa7c57f8054c +rk5: +DQ 0x381d0015c96f4444 +rk6: +DQ 0x0000000000000000 +rk7: +DQ 0x3e6cfa329aef9f77 +rk8: +DQ 0x2b5926535897936a +rk9: +DQ 0x5bc94ba8e2087636 +rk10: +DQ 0x6cf09c8f37710b75 +rk11: +DQ 0x3885fd59e440d95a +rk12: +DQ 0xbccba3936411fb7e +rk13: +DQ 0xe4dd0d81cbfce585 +rk14: +DQ 0xb715e37b96ed8633 +rk15: +DQ 0xf49784a634f014e4 +rk16: +DQ 0xaf86efb16d9ab4fb +rk17: +DQ 0x7b3211a760160db8 +rk18: +DQ 0xa062b2319d66692f +rk19: +DQ 0xef3d1d18ed889ed2 +rk20: +DQ 0x6ba4d760ab38201e + +pshufb_shf_table: +; use these values for shift constants for the pshufb instruction +; different alignments result in values as shown: +; dq 0x8887868584838281, 0x008f8e8d8c8b8a89 ; shl 15 (16-1) / shr1 +; dq 0x8988878685848382, 0x01008f8e8d8c8b8a ; shl 14 (16-3) / shr2 +; dq 0x8a89888786858483, 0x0201008f8e8d8c8b ; shl 13 (16-4) / shr3 +; dq 0x8b8a898887868584, 0x030201008f8e8d8c ; shl 12 (16-4) / shr4 +; dq 0x8c8b8a8988878685, 0x04030201008f8e8d ; shl 11 (16-5) / shr5 +; dq 0x8d8c8b8a89888786, 0x0504030201008f8e ; shl 10 (16-6) / shr6 +; dq 0x8e8d8c8b8a898887, 0x060504030201008f ; shl 9 (16-7) / shr7 +; dq 0x8f8e8d8c8b8a8988, 0x0706050403020100 ; shl 8 (16-8) / shr8 +; dq 0x008f8e8d8c8b8a89, 0x0807060504030201 ; shl 7 (16-9) / shr9 +; dq 0x01008f8e8d8c8b8a, 0x0908070605040302 ; shl 6 (16-10) / shr10 +; dq 0x0201008f8e8d8c8b, 0x0a09080706050403 ; shl 5 (16-11) / shr11 +; dq 0x030201008f8e8d8c, 0x0b0a090807060504 ; shl 4 (16-12) / shr12 +; dq 0x04030201008f8e8d, 0x0c0b0a0908070605 ; shl 3 (16-13) / shr13 +; dq 0x0504030201008f8e, 0x0d0c0b0a09080706 ; shl 2 (16-14) / shr14 +; dq 0x060504030201008f, 0x0e0d0c0b0a090807 ; shl 1 (16-15) / shr15 +dq 0x8786858483828100, 0x8f8e8d8c8b8a8988 +dq 0x0706050403020100, 0x000e0d0c0b0a0908 + + +mask: +dq 0xFFFFFFFFFFFFFFFF, 0x0000000000000000 +mask2: +dq 0xFFFFFFFF00000000, 0xFFFFFFFFFFFFFFFF +mask3: +dq 0x8080808080808080, 0x8080808080808080 + +;;; func core, ver, snum +slversion crc64_jones_refl_by8, 01, 00, 0029 diff --git a/ceph/src/isa-l/crc/crc64_multibinary.asm b/ceph/src/isa-l/crc/crc64_multibinary.asm new file mode 100644 index 000000000..a20c8a796 --- /dev/null +++ b/ceph/src/isa-l/crc/crc64_multibinary.asm @@ -0,0 +1,89 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2016 Intel Corporation All rights reserved. +; +; 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 Intel Corporation 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 +; 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. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; +;;; uint64_t crc64_func(uint64_t init_crc, const unsigned char *buf, uint64_t len); +;;; + +default rel +[bits 64] + +%ifidn __OUTPUT_FORMAT__, elf64 +%define WRT_OPT wrt ..plt +%else +%define WRT_OPT +%endif + +%include "reg_sizes.asm" + +extern crc64_ecma_refl_by8 +extern crc64_ecma_refl_base + +extern crc64_ecma_norm_by8 +extern crc64_ecma_norm_base + +extern crc64_iso_refl_by8 +extern crc64_iso_refl_base + +extern crc64_iso_norm_by8 +extern crc64_iso_norm_base + +extern crc64_jones_refl_by8 +extern crc64_jones_refl_base + +extern crc64_jones_norm_by8 +extern crc64_jones_norm_base + +section .text + +%include "multibinary.asm" + +mbin_interface crc64_ecma_refl +mbin_dispatch_init_clmul crc64_ecma_refl, crc64_ecma_refl_base, crc64_ecma_refl_by8 +mbin_interface crc64_ecma_norm +mbin_dispatch_init_clmul crc64_ecma_norm, crc64_ecma_norm_base, crc64_ecma_norm_by8 + +mbin_interface crc64_iso_refl +mbin_dispatch_init_clmul crc64_iso_refl, crc64_iso_refl_base, crc64_iso_refl_by8 +mbin_interface crc64_iso_norm +mbin_dispatch_init_clmul crc64_iso_norm, crc64_iso_norm_base, crc64_iso_norm_by8 + +mbin_interface crc64_jones_refl +mbin_dispatch_init_clmul crc64_jones_refl, crc64_jones_refl_base, crc64_jones_refl_by8 +mbin_interface crc64_jones_norm +mbin_dispatch_init_clmul crc64_jones_norm, crc64_jones_norm_base, crc64_jones_norm_by8 + +;;; func core, ver, snum +slversion crc64_ecma_refl, 00, 00, 001b +slversion crc64_ecma_norm, 00, 00, 0018 +slversion crc64_iso_refl, 00, 00, 0021 +slversion crc64_iso_norm, 00, 00, 001e +slversion crc64_jones_refl, 00, 00, 0027 +slversion crc64_jones_norm, 00, 00, 0024 diff --git a/ceph/src/isa-l/crc/crc_base_aliases.c b/ceph/src/isa-l/crc/crc_base_aliases.c new file mode 100644 index 000000000..63dfb3063 --- /dev/null +++ b/ceph/src/isa-l/crc/crc_base_aliases.c @@ -0,0 +1,77 @@ +/********************************************************************** + Copyright(c) 2011-2017 Intel Corporation All rights reserved. + + 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 Intel Corporation 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 + 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. +**********************************************************************/ + +#include "crc.h" +#include "crc64.h" +#include + +unsigned int crc32_iscsi(unsigned char *buffer, int len, unsigned int crc_init) +{ + return crc32_iscsi_base(buffer, len, crc_init); +} + +uint16_t crc16_t10dif(uint16_t seed, const unsigned char *buf, uint64_t len) +{ + return crc16_t10dif_base(seed, (uint8_t *) buf, len); +} + +uint32_t crc32_ieee(uint32_t seed, const unsigned char *buf, uint64_t len) +{ + return crc32_ieee_base(seed, (uint8_t *) buf, len); +} + +uint64_t crc64_ecma_refl(uint64_t seed, const uint8_t * buf, uint64_t len) +{ + return crc64_ecma_refl_base(seed, buf, len); +} + +uint64_t crc64_ecma_norm(uint64_t seed, const uint8_t * buf, uint64_t len) +{ + return crc64_ecma_norm_base(seed, buf, len); +} + +uint64_t crc64_iso_refl(uint64_t seed, const uint8_t * buf, uint64_t len) +{ + return crc64_iso_refl_base(seed, buf, len); +} + +uint64_t crc64_iso_norm(uint64_t seed, const uint8_t * buf, uint64_t len) +{ + return crc64_iso_norm_base(seed, buf, len); +} + +uint64_t crc64_jones_refl(uint64_t seed, const uint8_t * buf, uint64_t len) +{ + return crc64_jones_refl_base(seed, buf, len); +} + +uint64_t crc64_jones_norm(uint64_t seed, const uint8_t * buf, uint64_t len) +{ + return crc64_jones_norm_base(seed, buf, len); +} diff --git a/ceph/src/isa-l/erasure_code/Makefile.am b/ceph/src/isa-l/erasure_code/Makefile.am index 846b06efa..054dd7353 100644 --- a/ceph/src/isa-l/erasure_code/Makefile.am +++ b/ceph/src/isa-l/erasure_code/Makefile.am @@ -1,5 +1,5 @@ ######################################################################## -# Copyright(c) 2011-2015 Intel Corporation All rights reserved. +# Copyright(c) 2011-2017 Intel Corporation All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -27,8 +27,12 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ######################################################################## -lsrc += erasure_code/ec_highlevel_func.c \ - erasure_code/ec_base.c \ +lsrc += erasure_code/ec_base.c + +lsrc_base_aliases += erasure_code/ec_base_aliases.c + +lsrc_x86_64 += \ + erasure_code/ec_highlevel_func.c \ erasure_code/gf_vect_mul_sse.asm \ erasure_code/gf_vect_mul_avx.asm \ erasure_code/gf_vect_dot_prod_sse.asm \ @@ -70,7 +74,8 @@ lsrc += erasure_code/ec_highlevel_func.c \ erasure_code/ec_multibinary.asm #if HAVE_AVX512 -lsrc += erasure_code/gf_vect_dot_prod_avx512.asm \ +lsrc_x86_64 += \ + erasure_code/gf_vect_dot_prod_avx512.asm \ erasure_code/gf_2vect_dot_prod_avx512.asm \ erasure_code/gf_3vect_dot_prod_avx512.asm \ erasure_code/gf_4vect_dot_prod_avx512.asm \ @@ -79,9 +84,9 @@ lsrc += erasure_code/gf_vect_dot_prod_avx512.asm \ erasure_code/gf_3vect_mad_avx512.asm \ erasure_code/gf_4vect_mad_avx512.asm -lsrc32 += erasure_code/ec_highlevel_func.c \ +lsrc_x86_32 += \ + erasure_code/ec_highlevel_func.c \ erasure_code/ec_multibinary.asm \ - erasure_code/ec_base.c \ erasure_code/gf_vect_dot_prod_avx.asm \ erasure_code/gf_2vect_dot_prod_avx.asm \ erasure_code/gf_3vect_dot_prod_avx.asm \ @@ -120,6 +125,7 @@ perf_tests32 += erasure_code/gf_vect_mul_perf \ erasure_code/gf_3vect_dot_prod_sse_perf \ erasure_code/gf_4vect_dot_prod_sse_perf +src_include += -I $(srcdir)/erasure_code extern_hdrs += include/erasure_code.h \ include/gf_vect_mul.h diff --git a/ceph/src/isa-l/erasure_code/ec_base.c b/ceph/src/isa-l/erasure_code/ec_base.c index e690b46ab..a34e3fdf7 100644 --- a/ceph/src/isa-l/erasure_code/ec_base.c +++ b/ceph/src/isa-l/erasure_code/ec_base.c @@ -33,6 +33,18 @@ #include "ec_base.h" // for GF tables #include "types.h" +void ec_init_tables(int k, int rows, unsigned char *a, unsigned char *g_tbls) +{ + int i, j; + + for (i = 0; i < rows; i++) { + for (j = 0; j < k; j++) { + gf_vect_mul_init(*a++, g_tbls); + g_tbls += 32; + } + } +} + unsigned char gf_mul(unsigned char a, unsigned char b) { #ifndef GF_LARGE_TABLES diff --git a/ceph/src/isa-l/erasure_code/ec_base_aliases.c b/ceph/src/isa-l/erasure_code/ec_base_aliases.c new file mode 100644 index 000000000..d046ff61a --- /dev/null +++ b/ceph/src/isa-l/erasure_code/ec_base_aliases.c @@ -0,0 +1,61 @@ +/********************************************************************** + Copyright(c) 2011-2017 Intel Corporation All rights reserved. + + 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 Intel Corporation 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 + 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. +**********************************************************************/ + +#include "erasure_code.h" + +void gf_vect_dot_prod(int len, int vlen, unsigned char *v, + unsigned char **src, unsigned char *dest) +{ + gf_vect_dot_prod_base(len, vlen, v, src, dest); +} + +void gf_vect_mad(int len, int vec, int vec_i, + unsigned char *v, unsigned char *src, unsigned char *dest) +{ + gf_vect_mad_base(len, vec, vec_i, v, src, dest); + +} + +void ec_encode_data(int len, int srcs, int dests, unsigned char *v, + unsigned char **src, unsigned char **dest) +{ + ec_encode_data_base(len, srcs, dests, v, src, dest); +} + +void ec_encode_data_update(int len, int k, int rows, int vec_i, unsigned char *v, + unsigned char *data, unsigned char **dest) +{ + ec_encode_data_update_base(len, k, rows, vec_i, v, data, dest); +} + +int gf_vect_mul(int len, unsigned char *a, void *src, void *dest) +{ + gf_vect_mul_base(len, a, (unsigned char *)src, (unsigned char *)dest); + return 0; +} diff --git a/ceph/src/isa-l/erasure_code/ec_highlevel_func.c b/ceph/src/isa-l/erasure_code/ec_highlevel_func.c index d77792173..baaf20d43 100644 --- a/ceph/src/isa-l/erasure_code/ec_highlevel_func.c +++ b/ceph/src/isa-l/erasure_code/ec_highlevel_func.c @@ -30,17 +30,6 @@ #include "erasure_code.h" #include "types.h" -void ec_init_tables(int k, int rows, unsigned char *a, unsigned char *g_tbls) -{ - int i, j; - - for (i = 0; i < rows; i++) { - for (j = 0; j < k; j++) { - gf_vect_mul_init(*a++, g_tbls); - g_tbls += 32; - } - } -} void ec_encode_data_sse(int len, int k, int rows, unsigned char *g_tbls, unsigned char **data, unsigned char **coding) diff --git a/ceph/src/isa-l/igzip/Makefile.am b/ceph/src/isa-l/igzip/Makefile.am index 5a94a9438..7b70ad61f 100644 --- a/ceph/src/isa-l/igzip/Makefile.am +++ b/ceph/src/isa-l/igzip/Makefile.am @@ -27,69 +27,98 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ######################################################################## -lsrc += igzip/igzip.c igzip/hufftables_c.c \ - igzip/crc_utils_01.asm \ - igzip/crc_utils_04.asm \ - igzip/igzip_body_01.asm igzip/igzip_body_04.asm igzip/igzip_finish.asm \ - igzip/igzip_stateless_01.asm igzip/igzip_stateless_04.asm \ - igzip/crc_data.asm \ +lsrc += igzip/igzip.c \ + igzip/hufftables_c.c \ + igzip/igzip_base.c \ + igzip/igzip_icf_base.c \ + igzip/crc32_gzip_base.c \ + igzip/flatten_ll.c \ + igzip/encode_df.c + +lsrc_base_aliases += igzip/igzip_base_aliases.c igzip/proc_heap_base.c +lsrc_x86_32 += igzip/igzip_base_aliases.c igzip/proc_heap_base.c + +lsrc_x86_64 += \ + igzip/igzip_body_01.asm \ + igzip/igzip_body_02.asm \ + igzip/igzip_body_04.asm \ + igzip/igzip_finish.asm \ + igzip/igzip_icf_body_01.asm \ + igzip/igzip_icf_body_02.asm \ + igzip/igzip_icf_body_04.asm \ + igzip/igzip_icf_finish.asm \ + igzip/rfc1951_lookup.asm \ igzip/crc32_gzip.asm igzip/detect_repeated_char.asm \ igzip/igzip_multibinary.asm \ - igzip/igzip_stateless_base.c \ - igzip/igzip_base.c + igzip/igzip_update_histogram_01.asm \ + igzip/igzip_update_histogram_04.asm \ + igzip/igzip_decode_block_stateless_01.asm \ + igzip/igzip_decode_block_stateless_04.asm \ + igzip/igzip_inflate_multibinary.asm \ + igzip/encode_df_04.asm \ + igzip/proc_heap.asm +src_include += -I $(srcdir)/igzip extern_hdrs += include/igzip_lib.h pkginclude_HEADERS += include/types.h -unit_tests += igzip/igzip_rand_test - -check_tests += igzip/igzip_check +check_tests += igzip/igzip_rand_test perf_tests += igzip/igzip_perf igzip/igzip_sync_flush_perf -other_tests += igzip/igzip_file_perf igzip/igzip_sync_flush_file_perf igzip/igzip_stateless_file_perf +other_tests += igzip/igzip_file_perf igzip/igzip_sync_flush_file_perf igzip/igzip_stateless_file_perf igzip/igzip_hist_perf +other_tests += igzip/igzip_semi_dyn_file_perf -other_src += igzip/bitbuf2.asm igzip/data_struct2.asm \ - igzip/igzip_buffer_utils_01.asm \ - igzip/igzip_buffer_utils_04.asm \ - igzip/igzip_body.asm igzip/igzip_finish.asm \ - igzip/lz0a_const.asm igzip/options.asm igzip/stdmac.asm igzip/igzip_compare_types.asm \ - igzip/bitbuf2.h igzip/repeated_char_result.h \ +other_src += igzip/bitbuf2.asm \ + igzip/data_struct2.asm \ + igzip/inflate_data_structs.asm \ igzip/igzip_body.asm \ - igzip/igzip_stateless.asm \ + igzip/igzip_icf_body.asm \ + igzip/igzip_finish.asm \ + igzip/lz0a_const.asm \ + igzip/options.asm \ + igzip/stdmac.asm \ + igzip/igzip_compare_types.asm \ + igzip/bitbuf2.h \ + igzip/repeated_char_result.h \ + igzip/igzip_update_histogram.asm \ igzip/huffman.asm \ include/reg_sizes.asm \ include/multibinary.asm \ include/test.h \ - igzip/huffman.h - + igzip/huffman.h \ + igzip/igzip_level_buf_structs.h \ + igzip/igzip_decode_block_stateless.asm \ + igzip/inflate_std_vects.h \ + igzip/flatten_ll.h \ + igzip/encode_df.h \ + igzip/encode_df_asm.asm \ + igzip/heap_macros.asm examples += igzip/igzip_example igzip/igzip_sync_flush_example -igzip_rand_test: igzip_inflate_ref.o -igzip_igzip_rand_test_LDADD = igzip/igzip_inflate_ref.lo libisal.la +igzip_igzip_rand_test_LDADD = libisal.la # Include tools to make custom Huffman tables based on sample data other_tests += igzip/generate_custom_hufftables -other_tests += igzip/generate_constant_block_header other_src += igzip/huff_codes.h lsrc += igzip/huff_codes.c # Include tools and tests using the reference inflate other_tests += igzip/igzip_inflate_perf other_tests += igzip/igzip_inflate_test -other_src += igzip/igzip_inflate_ref.h -other_src += igzip/igzip_inflate_ref.c +other_tests += igzip/igzip_fuzz_inflate +lsrc += igzip/igzip_inflate.c other_src += igzip/crc_inflate.h -igzip_inflate_perf: igzip_inflate_ref.o igzip_inflate_perf: LDLIBS += -lz -igzip_igzip_inflate_perf_LDADD = igzip/igzip_inflate_ref.lo libisal.la +igzip_igzip_inflate_perf_LDADD = libisal.la igzip_igzip_inflate_perf_LDFLAGS = -lz -igzip_inflate_test: igzip_inflate_ref.o igzip_inflate_test: LDLIBS += -lz -igzip_igzip_inflate_test_LDADD = igzip/igzip_inflate_ref.lo libisal.la +igzip_igzip_inflate_test_LDADD = libisal.la igzip_igzip_inflate_test_LDFLAGS = -lz -igzip_check: igzip_inflate_ref.o -igzip_igzip_check_LDADD = igzip/igzip_inflate_ref.lo libisal.la +igzip_igzip_hist_perf_LDADD = libisal.la +igzip_fuzz_inflate: LDLIBS += -lz +igzip_igzip_fuzz_inflate_LDADD = libisal.la +igzip_igzip_fuzz_inflate_LDFLAGS = -lz diff --git a/ceph/src/isa-l/igzip/bitbuf2.asm b/ceph/src/isa-l/igzip/bitbuf2.asm index 42821c3b9..531adf35a 100644 --- a/ceph/src/isa-l/igzip/bitbuf2.asm +++ b/ceph/src/isa-l/igzip/bitbuf2.asm @@ -203,3 +203,10 @@ ; code2 is clobbered, rcx is clobbered %endif %endm + +%macro write_dword 2 +%define %%data %1d +%define %%addr %2 + movnti [%%addr], %%data + add %%addr, 4 +%endm diff --git a/ceph/src/isa-l/igzip/bitbuf2.h b/ceph/src/isa-l/igzip/bitbuf2.h index 84d521df9..0f018b0b1 100644 --- a/ceph/src/isa-l/igzip/bitbuf2.h +++ b/ceph/src/isa-l/igzip/bitbuf2.h @@ -31,7 +31,15 @@ #include "igzip_lib.h" -#if defined (__unix__) || (__APPLE__) +/* bit buffer types + * BITBUF8: (e) Always write 8 bytes of data + * BITBUFB: (b) Always write data + */ +#if !(defined(USE_BITBUFB) || defined(USE_BITBUF8) || defined(USE_BITBUF_ELSE)) +# define USE_BITBUFB +#endif + +#if defined (__unix__) || (__APPLE__) || (__MINGW32__) #define _mm_stream_si64x(dst, src) *((uint64_t*)dst) = src #else #include @@ -94,19 +102,28 @@ static inline uint32_t buffer_used(struct BitBuf2 *me) return (uint32_t)(me->m_out_buf - me->m_out_start); } +static inline uint32_t buffer_bits_used(struct BitBuf2 *me) +{ + return (8 * (uint32_t)(me->m_out_buf - me->m_out_start) + me->m_bit_count); +} + +static inline void flush_bits(struct BitBuf2 *me) +{ + uint32_t bits; + _mm_stream_si64x((int64_t *) me->m_out_buf, me->m_bits); + bits = me->m_bit_count & ~7; + me->m_bit_count -= bits; + me->m_out_buf += bits/8; + me->m_bits >>= bits; + +} + static inline void check_space(struct BitBuf2 *me, uint32_t num_bits) { /* Checks if bitbuf has num_bits extra space and flushes the bytes in * the bitbuf if it doesn't. */ - uint32_t bytes; - if (63 - me->m_bit_count < num_bits) { - _mm_stream_si64x((int64_t *) me->m_out_buf, me->m_bits); - bytes = me->m_bit_count / 8; - me->m_out_buf += bytes; - bytes *= 8; - me->m_bit_count -= bytes; - me->m_bits >>= bytes; - } + if (63 - me->m_bit_count < num_bits) + flush_bits(me); } static inline void write_bits_unsafe(struct BitBuf2 *me, uint64_t code, uint32_t count) @@ -128,16 +145,10 @@ static inline void write_bits(struct BitBuf2 *me, uint64_t code, uint32_t count) } #elif defined(USE_BITBUFB) /* Write bits always */ /* Assumes there is space to fit code into m_bits. */ - uint32_t bits; me->m_bits |= code << me->m_bit_count; me->m_bit_count += count; - if (me->m_bit_count >= 8) { - _mm_stream_si64x((int64_t *) me->m_out_buf, me->m_bits); - bits = me->m_bit_count & ~7; - me->m_bit_count -= bits; - me->m_out_buf += bits/8; - me->m_bits >>= bits; - } + if (me->m_bit_count >= 8) + flush_bits(me); #else /* USE_BITBUF_ELSE */ check_space(me, count); write_bits_unsafe(me, code, count); diff --git a/ceph/src/isa-l/igzip/crc32_gzip.asm b/ceph/src/isa-l/igzip/crc32_gzip.asm index e0b0ba41c..e8a5414ef 100644 --- a/ceph/src/isa-l/igzip/crc32_gzip.asm +++ b/ceph/src/isa-l/igzip/crc32_gzip.asm @@ -84,8 +84,8 @@ section .text %endif align 16 -global crc32_gzip -crc32_gzip: +global crc32_gzip_01 +crc32_gzip_01: ; unsigned long c = crc ^ 0xffffffffL; not arg1_low32 ; diff --git a/ceph/src/isa-l/igzip/crc32_gzip_base.c b/ceph/src/isa-l/igzip/crc32_gzip_base.c new file mode 100644 index 000000000..bf187be92 --- /dev/null +++ b/ceph/src/isa-l/igzip/crc32_gzip_base.c @@ -0,0 +1,106 @@ +/********************************************************************** + Copyright(c) 2011-2017 Intel Corporation All rights reserved. + + 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 Intel Corporation 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 + 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. +**********************************************************************/ + +#include + +uint32_t crc32_table_gzip_base[256] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, +}; + +uint32_t crc32_gzip_base(uint32_t crc, uint8_t * start, uint32_t length) +{ + uint8_t *end = start + length; + crc = ~crc; + while (start < end) + crc = (crc >> 8) ^ crc32_table_gzip_base[(crc & 0xff) ^ *start++]; + return ~crc; +} diff --git a/ceph/src/isa-l/igzip/crc_data.asm b/ceph/src/isa-l/igzip/crc_data.asm deleted file mode 100644 index 04779f810..000000000 --- a/ceph/src/isa-l/igzip/crc_data.asm +++ /dev/null @@ -1,120 +0,0 @@ -%ifndef CRC_DATA - -%define CRC_DATA -; precomputed constants -section .data - -align 32 - -global pshufb_shf_table:data internal -pshufb_shf_table: -dq 0x8887868584838281, 0x008f8e8d8c8b8a89 ; shl 15 (16-1) / shr1 -dq 0x8988878685848382, 0x01008f8e8d8c8b8a ; shl 14 (16-3) / shr2 -dq 0x8a89888786858483, 0x0201008f8e8d8c8b ; shl 13 (16-4) / shr3 -dq 0x8b8a898887868584, 0x030201008f8e8d8c ; shl 12 (16-4) / shr4 -dq 0x8c8b8a8988878685, 0x04030201008f8e8d ; shl 11 (16-5) / shr5 -dq 0x8d8c8b8a89888786, 0x0504030201008f8e ; shl 10 (16-6) / shr6 -dq 0x8e8d8c8b8a898887, 0x060504030201008f ; shl 9 (16-7) / shr7 -dq 0x8f8e8d8c8b8a8988, 0x0706050403020100 ; shl 8 (16-8) / shr8 -dq 0x008f8e8d8c8b8a89, 0x0807060504030201 ; shl 7 (16-9) / shr9 -dq 0x01008f8e8d8c8b8a, 0x0908070605040302 ; shl 6 (16-10) / shr10 -dq 0x0201008f8e8d8c8b, 0x0a09080706050403 ; shl 5 (16-11) / shr11 -dq 0x030201008f8e8d8c, 0x0b0a090807060504 ; shl 4 (16-12) / shr12 -dq 0x04030201008f8e8d, 0x0c0b0a0908070605 ; shl 3 (16-13) / shr13 -dq 0x0504030201008f8e, 0x0d0c0b0a09080706 ; shl 2 (16-14) / shr14 -dq 0x060504030201008f, 0x0e0d0c0b0a090807 ; shl 1 (16-15) / shr15 - -;; ; MAGIC value, which when folded 4 times gives FFFFFF00000...0000 -;; global crc_init_4 -;; crc_init_4: -;; dq 0x9db42487 -;; dq 0x0 -;; dq 0x0 -;; dq 0x0 - -; constant used to shift/fold one XMM reg down by 4 XMM widths -global fold_4:data internal -fold_4: -dq 0x00000001c6e41596 -dq 0x0000000154442bd4 - - -;value, which when xored with pshufb_shf_table entry gives shr value -global mask3:data internal -mask3: dq 0x8080808080808080, 0x8080808080808080 - -%ifndef CRC_TABLE -%define CRC_TABLE -; Place marker in library to avoid linker warning -align 4 -global CrcTable:data internal -CrcTable: - dd 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba - dd 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3 - dd 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988 - dd 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91 - dd 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de - dd 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7 - dd 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec - dd 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5 - dd 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172 - dd 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b - dd 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940 - dd 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59 - dd 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116 - dd 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f - dd 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924 - dd 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d - dd 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a - dd 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433 - dd 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818 - dd 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01 - dd 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e - dd 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457 - dd 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c - dd 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65 - dd 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2 - dd 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb - dd 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0 - dd 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9 - dd 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086 - dd 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f - dd 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4 - dd 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad - dd 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a - dd 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683 - dd 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8 - dd 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1 - dd 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe - dd 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7 - dd 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc - dd 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5 - dd 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252 - dd 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b - dd 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60 - dd 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79 - dd 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236 - dd 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f - dd 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04 - dd 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d - dd 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a - dd 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713 - dd 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38 - dd 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21 - dd 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e - dd 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777 - dd 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c - dd 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45 - dd 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2 - dd 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db - dd 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0 - dd 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9 - dd 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6 - dd 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf - dd 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94 - dd 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d -End_CrcTable: - -%endif ;; CRC_TABLE - -%endif ;; CRC_DATA diff --git a/ceph/src/isa-l/igzip/crc_utils_01.asm b/ceph/src/isa-l/igzip/crc_utils_01.asm deleted file mode 100644 index ba8111453..000000000 --- a/ceph/src/isa-l/igzip/crc_utils_01.asm +++ /dev/null @@ -1,195 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Copyright(c) 2011-2016 Intel Corporation All rights reserved. -; -; 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 Intel Corporation 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 -; 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. -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -%include "options.asm" -%include "reg_sizes.asm" - -; Functional versions of CRC macros - -%include "igzip_buffer_utils_01.asm" - -extern fold_4 - -%define crc_0 xmm0 ; in/out: crc state -%define crc_1 xmm1 ; in/out: crc state -%define crc_2 xmm2 ; in/out: crc state -%define crc_3 xmm3 ; in/out: crc state -%define crc_fold xmm4 ; in: (loaded from fold_4) -%define crc_tmp0 xmm5 ; tmp -%define crc_tmp1 xmm6 ; tmp -%define crc_tmp2 xmm7 ; tmp -%define crc_tmp3 xmm8 ; tmp -%define crc_tmp4 xmm9 ; tmp -%define tmp4 rax - -; copy x bytes (rounded up to 16 bytes) from src to dst with crc -; src & dst are unaligned -; void copy_in_crc(uint8_t *dst, uint8_t *src, uint32_t size, uint32_t *crc) -; arg 1: rcx: pointer to dst -; arg 2: rdx: pointer to src -; arg 3: r8: size (in bytes) -; arg 4: r9: pointer to CRC -;; %if 0 -global copy_in_crc_01 -copy_in_crc_01: -%ifidn __OUTPUT_FORMAT__, elf64 - mov r9, rcx - mov r8, rdx - mov rdx, rsi - mov rcx, rdi -%endif - - ; Save xmm registers that need to be preserved. - sub rsp, 8 + 4*16 - movdqa [rsp+0*16], xmm6 - movdqa [rsp+1*16], xmm7 - movdqa [rsp+2*16], xmm8 - movdqa [rsp+3*16], xmm9 - - movdqa crc_0, [r9 + 0*16] - movdqa crc_1, [r9 + 1*16] - movdqa crc_2, [r9 + 2*16] - movdqa crc_3, [r9 + 3*16] - - movdqa crc_fold, [fold_4 WRT_OPT] - COPY_IN_CRC rcx, rdx, r8, tmp4, crc_0, crc_1, crc_2, crc_3, \ - crc_fold, \ - crc_tmp0, crc_tmp1, crc_tmp2, crc_tmp3, crc_tmp4 - - movdqa [r9 + 0*16], crc_0 - movdqa [r9 + 1*16], crc_1 - movdqa [r9 + 2*16], crc_2 - movdqa [r9 + 3*16], crc_3 - - movdqa xmm9, [rsp+3*16] - movdqa xmm8, [rsp+2*16] - movdqa xmm7, [rsp+1*16] - movdqa xmm6, [rsp+0*16] - add rsp, 8 + 4*16 -ret - -; Convert 512-bit CRC data to real 32-bit value -; uint32_t crc_512to32(uint32_t *crc) -; arg 1: rcx: pointer to CRC -; returns: eax: 32 bit crc -global crc_512to32_01 -crc_512to32_01: -%ifidn __OUTPUT_FORMAT__, elf64 - mov rcx, rdi -%endif - - movdqa crc_0, [rcx + 0*16] - movdqa crc_1, [rcx + 1*16] - movdqa crc_2, [rcx + 2*16] - movdqa crc_3, [rcx + 3*16] - - movdqa crc_fold, [rk1 WRT_OPT] ;k1 - - ; fold the 4 xmm registers to 1 xmm register with different constants - movdqa crc_tmp0, crc_0 - pclmulqdq crc_0, crc_fold, 0x1 - pclmulqdq crc_tmp0, crc_fold, 0x10 - pxor crc_1, crc_tmp0 - pxor crc_1, crc_0 - - movdqa crc_tmp0, crc_1 - pclmulqdq crc_1, crc_fold, 0x1 - pclmulqdq crc_tmp0, crc_fold, 0x10 - pxor crc_2, crc_tmp0 - pxor crc_2, crc_1 - - movdqa crc_tmp0, crc_2 - pclmulqdq crc_2, crc_fold, 0x1 - pclmulqdq crc_tmp0, crc_fold, 0x10 - pxor crc_3, crc_tmp0 - pxor crc_3, crc_2 - - - movdqa crc_fold, [rk5 WRT_OPT] - movdqa crc_0, crc_3 - - pclmulqdq crc_3, crc_fold, 0 - - psrldq crc_0, 8 - - pxor crc_3, crc_0 - - movdqa crc_0, crc_3 - - - pslldq crc_3, 4 - - pclmulqdq crc_3, crc_fold, 0x10 - - - pxor crc_3, crc_0 - - pand crc_3, [mask2 WRT_OPT] - - movdqa crc_1, crc_3 - - movdqa crc_2, crc_3 - - movdqa crc_fold, [rk7 WRT_OPT] - - - pclmulqdq crc_3, crc_fold, 0 - pxor crc_3, crc_2 - - pand crc_3, [mask WRT_OPT] - - movdqa crc_2, crc_3 - - pclmulqdq crc_3, crc_fold, 0x10 - - pxor crc_3, crc_2 - - pxor crc_3, crc_1 - - pextrd eax, crc_3, 2 - - not eax - - ret -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - -section .data - -align 16 - -rk1: dq 0x00000000ccaa009e -rk2: dq 0x00000001751997d0 -rk5: dq 0x00000000ccaa009e -rk6: dq 0x0000000163cd6124 -rk7: dq 0x00000001f7011640 -rk8: dq 0x00000001db710640 - -mask: dq 0xFFFFFFFFFFFFFFFF, 0x0000000000000000 -mask2: dq 0xFFFFFFFF00000000, 0xFFFFFFFFFFFFFFFF diff --git a/ceph/src/isa-l/igzip/crc_utils_04.asm b/ceph/src/isa-l/igzip/crc_utils_04.asm deleted file mode 100644 index 8cb8c3bc0..000000000 --- a/ceph/src/isa-l/igzip/crc_utils_04.asm +++ /dev/null @@ -1,194 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Copyright(c) 2011-2016 Intel Corporation All rights reserved. -; -; 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 Intel Corporation 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 -; 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. -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -%include "options.asm" -%include "reg_sizes.asm" - -; Functional versions of CRC macros - -%include "igzip_buffer_utils_04.asm" - -extern fold_4 - -%define crc_0 xmm0 ; in/out: crc state -%define crc_1 xmm1 ; in/out: crc state -%define crc_2 xmm2 ; in/out: crc state -%define crc_3 xmm3 ; in/out: crc state -%define crc_fold xmm4 ; in: (loaded from fold_4) -%define crc_tmp0 xmm5 ; tmp -%define crc_tmp1 xmm6 ; tmp -%define crc_tmp2 xmm7 ; tmp -%define crc_tmp3 xmm8 ; tmp -%define crc_tmp4 xmm9 ; tmp -%define tmp4 rax - -; copy x bytes (rounded up to 16 bytes) from src to dst with crc -; src & dst are unaligned -; void copy_in_crc(uint8_t *dst, uint8_t *src, uint32_t size, uint32_t *crc) -; arg 1: rcx: pointer to dst -; arg 2: rdx: pointer to src -; arg 3: r8: size (in bytes) -; arg 4: r9: pointer to CRC -;; %if 0 -global copy_in_crc_04 -copy_in_crc_04: -%ifidn __OUTPUT_FORMAT__, elf64 - mov r9, rcx - mov r8, rdx - mov rdx, rsi - mov rcx, rdi -%endif - - ; Save xmm registers that need to be preserved. - sub rsp, 8 + 4*16 - vmovdqa [rsp+0*16], xmm6 - vmovdqa [rsp+1*16], xmm7 - vmovdqa [rsp+2*16], xmm8 - vmovdqa [rsp+3*16], xmm9 - - vmovdqa crc_0, [r9 + 0*16] - vmovdqa crc_1, [r9 + 1*16] - vmovdqa crc_2, [r9 + 2*16] - vmovdqa crc_3, [r9 + 3*16] - - vmovdqa crc_fold, [fold_4 WRT_OPT] - COPY_IN_CRC rcx, rdx, r8, tmp4, crc_0, crc_1, crc_2, crc_3, \ - crc_fold, \ - crc_tmp0, crc_tmp1, crc_tmp2, crc_tmp3, crc_tmp4 - - vmovdqa [r9 + 0*16], crc_0 - vmovdqa [r9 + 1*16], crc_1 - vmovdqa [r9 + 2*16], crc_2 - vmovdqa [r9 + 3*16], crc_3 - - vmovdqa xmm9, [rsp+3*16] - vmovdqa xmm8, [rsp+2*16] - vmovdqa xmm7, [rsp+1*16] - vmovdqa xmm6, [rsp+0*16] - add rsp, 8 + 4*16 -ret - -; Convert 512-bit CRC data to real 32-bit value -; uint32_t crc_512to32(uint32_t *crc) -; arg 1: rcx: pointer to CRC -; returns: eax: 32 bit crc -global crc_512to32_04 -crc_512to32_04: -%ifidn __OUTPUT_FORMAT__, elf64 - mov rcx, rdi -%endif - - vmovdqa crc_0, [rcx + 0*16] - vmovdqa crc_1, [rcx + 1*16] - vmovdqa crc_2, [rcx + 2*16] - vmovdqa crc_3, [rcx + 3*16] - - vmovdqa crc_fold, [rk1 WRT_OPT] ;k1 - - ; fold the 4 xmm registers to 1 xmm register with different constants - vmovdqa crc_tmp0, crc_0 - vpclmulqdq crc_0, crc_fold, 0x1 - vpclmulqdq crc_tmp0, crc_fold, 0x10 - vpxor crc_1, crc_tmp0 - vpxor crc_1, crc_0 - - vmovdqa crc_tmp0, crc_1 - vpclmulqdq crc_1, crc_fold, 0x1 - vpclmulqdq crc_tmp0, crc_fold, 0x10 - vpxor crc_2, crc_tmp0 - vpxor crc_2, crc_1 - - vmovdqa crc_tmp0, crc_2 - vpclmulqdq crc_2, crc_fold, 0x1 - vpclmulqdq crc_tmp0, crc_fold, 0x10 - vpxor crc_3, crc_tmp0 - vpxor crc_3, crc_2 - - - vmovdqa crc_fold, [rk5 WRT_OPT] - vmovdqa crc_0, crc_3 - - vpclmulqdq crc_3, crc_fold, 0 - - vpsrldq crc_0, 8 - - vpxor crc_3, crc_0 - - vmovdqa crc_0, crc_3 - - - vpslldq crc_3, 4 - - vpclmulqdq crc_3, crc_fold, 0x10 - - - vpxor crc_3, crc_0 - - vpand crc_3, [mask2 WRT_OPT] - - vmovdqa crc_1, crc_3 - - vmovdqa crc_2, crc_3 - - vmovdqa crc_fold, [rk7 WRT_OPT] - - vpclmulqdq crc_3, crc_fold, 0 - vpxor crc_3, crc_2 - - vpand crc_3, [mask WRT_OPT] - - vmovdqa crc_2, crc_3 - - vpclmulqdq crc_3, crc_fold, 0x10 - - vpxor crc_3, crc_2 - - vpxor crc_3, crc_1 - - vpextrd eax, crc_3, 2 - - not eax - - ret -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - -section .data - -align 16 - -rk1: dq 0x00000000ccaa009e -rk2: dq 0x00000001751997d0 -rk5: dq 0x00000000ccaa009e -rk6: dq 0x0000000163cd6124 -rk7: dq 0x00000001f7011640 -rk8: dq 0x00000001db710640 - -mask: dq 0xFFFFFFFFFFFFFFFF, 0x0000000000000000 -mask2: dq 0xFFFFFFFF00000000, 0xFFFFFFFFFFFFFFFF diff --git a/ceph/src/isa-l/igzip/data_struct2.asm b/ceph/src/isa-l/igzip/data_struct2.asm index e09907151..925686fda 100644 --- a/ceph/src/isa-l/igzip/data_struct2.asm +++ b/ceph/src/isa-l/igzip/data_struct2.asm @@ -63,6 +63,53 @@ FIELD _m_out_start, 8, 8 %assign _BitBuf2_size _FIELD_OFFSET %assign _BitBuf2_align _STRUCT_ALIGN +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%define HIST_ELEM_SIZE 4 + +START_FIELDS ;; isal_mod_hist + +;; name size align +FIELD _d_hist, 30*HIST_ELEM_SIZE, HIST_ELEM_SIZE +FIELD _ll_hist, 513*HIST_ELEM_SIZE, HIST_ELEM_SIZE + +%assign _isal_mod_hist_size _FIELD_OFFSET +%assign _isal_mod_hist_align _STRUCT_ALIGN + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +%define HUFF_CODE_SIZE 4 + +START_FIELDS ;; hufftables_icf + +;; name size align +FIELD _dist_table, 31 * HUFF_CODE_SIZE, HUFF_CODE_SIZE +FIELD _lit_len_table, 513 * HUFF_CODE_SIZE, HUFF_CODE_SIZE + +%assign _hufftables_icf_size _FIELD_OFFSET +%assign _hufftables_icf_align _STRUCT_ALIGN + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +%define DEF_MAX_HDR_SIZE 328 +START_FIELDS ;; level_2_buf + +;; name size align +FIELD _encode_tables, _hufftables_icf_size, _hufftables_icf_align +FIELD _deflate_hdr_buf_used, 8, 8 +FIELD _deflate_hdr_buf, DEF_MAX_HDR_SIZE, 1 +FIELD _icf_buf_next, 8, 8 +FIELD _icf_buf_avail_out, 8, 8 +FIELD _icf_buf_start, 0, 0 + +%assign _level_2_buf_size _FIELD_OFFSET +%assign _level_2_buf_align _STRUCT_ALIGN + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -73,20 +120,19 @@ START_FIELDS ;; isal_zstate FIELD _b_bytes_valid, 4, 4 FIELD _b_bytes_processed, 4, 4 FIELD _file_start, 8, 8 -FIELD _crc, 64, 16 +FIELD _crc, 4, 4 FIELD _bitbuf, _BitBuf2_size, _BitBuf2_align FIELD _state, 4, 4 FIELD _count, 4, 4 FIELD _tmp_out_buff, 16, 1 FIELD _tmp_out_start, 4, 4 FIELD _tmp_out_end, 4, 4 -FIELD _last_flush, 4, 4 -FIELD _has_gzip_hdr, 4, 4 FIELD _has_eob, 4, 4 FIELD _has_eob_hdr, 4, 4 -FIELD _left_over, 4, 4 -FIELD _buffer, BSIZE+16, 32 -FIELD _head, HASH_SIZE*2, 16 +FIELD _has_hist, 4, 4 +FIELD _hist, _isal_mod_hist_size, _isal_mod_hist_align +FIELD _buffer, BSIZE, 32 +FIELD _head, IGZIP_HASH_SIZE*2, 16 %assign _isal_zstate_size _FIELD_OFFSET %assign _isal_zstate_align _STRUCT_ALIGN @@ -97,6 +143,8 @@ _bitbuf_m_out_buf equ _bitbuf+_m_out_buf _bitbuf_m_out_end equ _bitbuf+_m_out_end _bitbuf_m_out_start equ _bitbuf+_m_out_start +_hist_lit_len equ _hist+_ll_hist +_hist_dist equ _hist+_d_hist ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -111,8 +159,12 @@ FIELD _next_out, 8, 8 FIELD _avail_out, 4, 4 FIELD _total_out, 4, 4 FIELD _hufftables, 8, 8 +FIELD _level, 4, 4 +FIELD _level_buf_size, 4, 4 +FIELD _level_buf, 8, 8 FIELD _end_of_stream, 4, 4 FIELD _flush, 4, 4 +FIELD _gzip_flag, 4, 4 FIELD _internal_state, _isal_zstate_size, _isal_zstate_align %assign _isal_zstream_size _FIELD_OFFSET @@ -128,11 +180,9 @@ _internal_state_count equ _internal_state+_count _internal_state_tmp_out_buff equ _internal_state+_tmp_out_buff _internal_state_tmp_out_start equ _internal_state+_tmp_out_start _internal_state_tmp_out_end equ _internal_state+_tmp_out_end -_internal_state_last_flush equ _internal_state+_last_flush -_internal_state_has_gzip_hdr equ _internal_state+_has_gzip_hdr _internal_state_has_eob equ _internal_state+_has_eob _internal_state_has_eob_hdr equ _internal_state+_has_eob_hdr -_internal_state_left_over equ _internal_state+_left_over +_internal_state_has_hist equ _internal_state+_has_hist _internal_state_buffer equ _internal_state+_buffer _internal_state_head equ _internal_state+_head _internal_state_bitbuf_m_bits equ _internal_state+_bitbuf_m_bits @@ -140,16 +190,22 @@ _internal_state_bitbuf_m_bit_count equ _internal_state+_bitbuf_m_bit_count _internal_state_bitbuf_m_out_buf equ _internal_state+_bitbuf_m_out_buf _internal_state_bitbuf_m_out_end equ _internal_state+_bitbuf_m_out_end _internal_state_bitbuf_m_out_start equ _internal_state+_bitbuf_m_out_start +_internal_state_hist_lit_len equ _internal_state+_hist_lit_len +_internal_state_hist_dist equ _internal_state+_hist_dist ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -ZSTATE_HDR equ 1 -ZSTATE_BODY equ 2 -ZSTATE_FLUSH_READ_BUFFER equ 3 -ZSTATE_SYNC_FLUSH equ 4 -ZSTATE_TRL equ 6 +;; Internal States +ZSTATE_NEW_HDR equ 0 +ZSTATE_HDR equ (ZSTATE_NEW_HDR + 1) +ZSTATE_CREATE_HDR equ (ZSTATE_HDR + 1) +ZSTATE_BODY equ (ZSTATE_CREATE_HDR + 1) +ZSTATE_FLUSH_READ_BUFFER equ (ZSTATE_BODY + 1) +ZSTATE_FLUSH_ICF_BUFFER equ (ZSTATE_FLUSH_READ_BUFFER + 1) +ZSTATE_SYNC_FLUSH equ (ZSTATE_FLUSH_ICF_BUFFER + 1) +ZSTATE_FLUSH_WRITE_BUFFER equ (ZSTATE_SYNC_FLUSH + 1) +ZSTATE_TRL equ (ZSTATE_FLUSH_WRITE_BUFFER + 1) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/ceph/src/isa-l/igzip/encode_df.c b/ceph/src/isa-l/igzip/encode_df.c new file mode 100644 index 000000000..633b8ce67 --- /dev/null +++ b/ceph/src/isa-l/igzip/encode_df.c @@ -0,0 +1,36 @@ +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +# include +#else +# include +#endif + +#include "encode_df.h" +#include "bitbuf2.h" + +struct deflate_icf *encode_deflate_icf_base(struct deflate_icf *next_in, + struct deflate_icf *end_in, struct BitBuf2 *bb, + struct hufftables_icf *hufftables) +{ + struct huff_code lsym, dsym; + + while (next_in < end_in && !is_full(bb)) { + lsym = hufftables->lit_len_table[next_in->lit_len]; + dsym = hufftables->dist_table[next_in->lit_dist]; + + // insert ll code, dist_code, and extra_bits + write_bits_unsafe(bb, lsym.code_and_extra, lsym.length); + write_bits_unsafe(bb, dsym.code, dsym.length); + write_bits_unsafe(bb, next_in->dist_extra, dsym.extra_bit_count); + flush_bits(bb); + + next_in++; + } + + return next_in; +} diff --git a/ceph/src/isa-l/igzip/encode_df.h b/ceph/src/isa-l/igzip/encode_df.h new file mode 100644 index 000000000..40b785e36 --- /dev/null +++ b/ceph/src/isa-l/igzip/encode_df.h @@ -0,0 +1,21 @@ +#ifndef ENCODE_DF_H +#define ENCODE_DF_H + +#include +#include "huff_codes.h" + +/* Deflate Intermediate Compression Format */ +#define LIT_LEN_BIT_COUNT 10 +#define DIST_LIT_BIT_COUNT 9 +#define ICF_DIST_OFFSET LIT_LEN_BIT_COUNT +#define NULL_DIST_SYM 30 + +struct deflate_icf { + uint32_t lit_len:LIT_LEN_BIT_COUNT; + uint32_t lit_dist:DIST_LIT_BIT_COUNT; + uint32_t dist_extra:32 - DIST_LIT_BIT_COUNT - ICF_DIST_OFFSET; +}; + +struct deflate_icf *encode_deflate_icf(struct deflate_icf *next_in, struct deflate_icf *end_in, + struct BitBuf2 *bb, struct hufftables_icf * hufftables); +#endif diff --git a/ceph/src/isa-l/igzip/encode_df_04.asm b/ceph/src/isa-l/igzip/encode_df_04.asm new file mode 100644 index 000000000..dbf01be54 --- /dev/null +++ b/ceph/src/isa-l/igzip/encode_df_04.asm @@ -0,0 +1,4 @@ +%define ARCH 04 +%define USE_HSWNI + +%include "encode_df_asm.asm" diff --git a/ceph/src/isa-l/igzip/encode_df_asm.asm b/ceph/src/isa-l/igzip/encode_df_asm.asm new file mode 100644 index 000000000..62ada29c8 --- /dev/null +++ b/ceph/src/isa-l/igzip/encode_df_asm.asm @@ -0,0 +1,527 @@ +%include "reg_sizes.asm" +%include "lz0a_const.asm" +%include "data_struct2.asm" +%include "stdmac.asm" + +; tree entry is 4 bytes: +; lit/len tree (513 entries) +; | 3 | 2 | 1 | 0 | +; | len | code | +; +; dist tree +; | 3 | 2 | 1 | 0 | +; |eblen:codlen| code | + +; token format: +; DIST_OFFSET:0 : lit/len +; 31:(DIST_OFFSET + 5) : dist Extra Bits +; (DIST_OFFSET + 5):DIST_OFFSET : dist code +; lit/len: 0-256 (literal) +; 257-512 (dist + 254) + +; returns final token pointer +; equal to token_end if successful +; uint32_t* encode_df(uint32_t *token_start, uint32_t *token_end, +; BitBuf *out_buf, uint32_t *trees); + +%ifidn __OUTPUT_FORMAT__, win64 +%define arg1 rcx +%define arg2 rdx +%define arg3 r8 +%define arg4 r9 +%define sym rsi +%define dsym rdi +%define hufftables r9 +%define ptr r11 +%else +; Linux +%define arg1 rdi +%define arg2 rsi +%define arg3 rdx +%define arg4 rcx +%define sym r9 +%define dsym r8 +%define hufftables r11 +%define ptr rdi +%endif + +%define in_buf_end arg2 +%define bitbuf arg3 +%define out_buf bitbuf +; bit_count is rcx +%define bits rax +%define data r12 +%define tmp rbx +%define len dsym +%define tmp2 r10 +%define end_ptr rbp + +%define LIT_MASK ((0x1 << LIT_LEN_BIT_COUNT) - 1) +%define DIST_MASK ((0x1 << DIST_LIT_BIT_COUNT) - 1) + +%define codes1 ymm1 +%define code_lens1 ymm2 +%define codes2 ymm3 +%define code_lens2 ymm4 +%define codes3 ymm5 +%define code_lens3 ymm6 +%define codes4 ymm7 +%define syms ymm7 + +%define code_lens4 ymm8 +%define dsyms ymm8 + +%define ytmp ymm9 +%define codes_lookup1 ymm10 +%define codes_lookup2 ymm11 +%define datas ymm12 +%define ybits ymm13 +%define ybits_count ymm14 +%define yoffset_mask ymm15 + +%define VECTOR_SIZE 0x20 +%define VECTOR_LOOP_PROCESSED (2 * VECTOR_SIZE) +%define VECTOR_SLOP 0x20 - 8 + +gpr_save_mem_offset equ 0 +gpr_save_mem_size equ 8 * 6 +xmm_save_mem_offset equ gpr_save_mem_offset + gpr_save_mem_size +xmm_save_mem_size equ 10 * 16 +bitbuf_mem_offset equ xmm_save_mem_offset + xmm_save_mem_size +bitbuf_mem_size equ 8 +stack_size equ gpr_save_mem_size + xmm_save_mem_size + bitbuf_mem_size + + +%macro FUNC_SAVE 0 + sub rsp, stack_size + mov [rsp + gpr_save_mem_offset + 0*8], rbx + mov [rsp + gpr_save_mem_offset + 1*8], rbp + mov [rsp + gpr_save_mem_offset + 2*8], r12 + +%ifidn __OUTPUT_FORMAT__, win64 + mov [rsp + gpr_save_mem_offset + 3*8], rsi + mov [rsp + gpr_save_mem_offset + 4*8], rdi + + MOVDQU [rsp + xmm_save_mem_offset + 0*8], xmm6 + MOVDQU [rsp + xmm_save_mem_offset + 1*8], xmm7 + MOVDQU [rsp + xmm_save_mem_offset + 2*8], xmm8 + MOVDQU [rsp + xmm_save_mem_offset + 3*8], xmm9 + MOVDQU [rsp + xmm_save_mem_offset + 4*8], xmm10 + MOVDQU [rsp + xmm_save_mem_offset + 5*8], xmm11 + MOVDQU [rsp + xmm_save_mem_offset + 6*8], xmm12 + MOVDQU [rsp + xmm_save_mem_offset + 7*8], xmm13 + MOVDQU [rsp + xmm_save_mem_offset + 8*8], xmm14 + MOVDQU [rsp + xmm_save_mem_offset + 9*8], xmm15 +%endif + +%endm + +%macro FUNC_RESTORE 0 + mov rbx, [rsp + gpr_save_mem_offset + 0*8] + mov rbp, [rsp + gpr_save_mem_offset + 1*8] + mov r12, [rsp + gpr_save_mem_offset + 2*8] + +%ifidn __OUTPUT_FORMAT__, win64 + mov rsi, [rsp + gpr_save_mem_offset + 3*8] + mov rdi, [rsp + gpr_save_mem_offset + 4*8] + + MOVDQU xmm6, [rsp + xmm_save_mem_offset + 0*8] + MOVDQU xmm7, [rsp + xmm_save_mem_offset + 1*8] + MOVDQU xmm8, [rsp + xmm_save_mem_offset + 2*8] + MOVDQU xmm9, [rsp + xmm_save_mem_offset + 3*8] + MOVDQU xmm10, [rsp + xmm_save_mem_offset + 4*8] + MOVDQU xmm11, [rsp + xmm_save_mem_offset + 5*8] + MOVDQU xmm12, [rsp + xmm_save_mem_offset + 6*8] + MOVDQU xmm13, [rsp + xmm_save_mem_offset + 7*8] + MOVDQU xmm14, [rsp + xmm_save_mem_offset + 8*8] + MOVDQU xmm15, [rsp + xmm_save_mem_offset + 9*8] +%endif + add rsp, stack_size + +%endmacro + +global encode_deflate_icf_ %+ ARCH +encode_deflate_icf_ %+ ARCH: + FUNC_SAVE + +%ifnidn ptr, arg1 + mov ptr, arg1 +%endif +%ifnidn hufftables, arg4 + mov hufftables, arg4 +%endif + + mov [rsp + bitbuf_mem_offset], bitbuf + mov bits, [bitbuf + _m_bits] + mov ecx, [bitbuf + _m_bit_count] + mov end_ptr, [bitbuf + _m_out_end] + mov out_buf, [bitbuf + _m_out_buf] ; clobbers bitbuf + + sub end_ptr, VECTOR_SLOP + sub in_buf_end, VECTOR_LOOP_PROCESSED + cmp ptr, in_buf_end + jge .finish + + vpcmpeqq ytmp, ytmp, ytmp + vmovdqu datas, [ptr] + vpand syms, datas, [lit_mask] + vpgatherdd codes_lookup1, [hufftables + _lit_len_table + 4 * syms], ytmp + + vpcmpeqq ytmp, ytmp, ytmp + vpsrld dsyms, datas, DIST_OFFSET + vpand dsyms, dsyms, [dist_mask] + vpgatherdd codes_lookup2, [hufftables + _dist_table + 4 * dsyms], ytmp + + vmovq ybits %+ x, bits + vmovq ybits_count %+ x, rcx + vmovdqa yoffset_mask, [offset_mask] + +.main_loop: + ;; Sets codes1 to contain lit/len codes andcode_lens1 the corresponding lengths + vpsrld code_lens1, codes_lookup1, 24 + vpand codes1, codes_lookup1, [lit_icr_mask] + + ;; Sets codes2 to contain dist codes, code_lens2 the corresponding lengths, + ;; and code_lens3 the extra bit counts + vpblendw codes2, ybits, codes_lookup2, 0x55 ;Bits 8 and above of ybits are 0 + vpsrld code_lens2, codes_lookup2, 24 + vpsrld code_lens3, codes_lookup2, 16 + vpand code_lens3, [eb_icr_mask] + + ;; Set codes3 to contain the extra bits + vpsrld codes3, datas, EXTRA_BITS_OFFSET + + cmp out_buf, end_ptr + ja .main_loop_exit + + ;; Start code lookups for next iteration + add ptr, VECTOR_SIZE + vpcmpeqq ytmp, ytmp, ytmp + vmovdqu datas, [ptr] + vpand syms, datas, [lit_mask] + vpgatherdd codes_lookup1, [hufftables + _lit_len_table + 4 * syms], ytmp + + vpcmpeqq ytmp, ytmp, ytmp + vpsrld dsyms, datas, DIST_OFFSET + vpand dsyms, dsyms, [dist_mask] + vpgatherdd codes_lookup2, [hufftables + _dist_table + 4 * dsyms], ytmp + + ;; Merge dist code with extra bits + vpsllvd codes3, codes3, code_lens2 + vpxor codes2, codes2, codes3 + vpaddd code_lens2, code_lens2, code_lens3 + + ;; Check for long codes + vpaddd code_lens3, code_lens1, code_lens2 + vpcmpgtd ytmp, code_lens3, [max_write_d] + vptest ytmp, ytmp + jnz .long_codes + + ;; Merge dist and len codes + vpsllvd codes2, codes2, code_lens1 + vpxor codes1, codes1, codes2 + + ;; Split buffer data into qwords, ytmp is 0 after last branch + vpblendd codes3, ytmp, codes1, 0x55 + vpsrlq codes1, codes1, 32 + vpsrlq code_lens1, code_lens3, 32 + vpblendd code_lens3, ytmp, code_lens3, 0x55 + + ;; Merge bitbuf bits + vpsllvq codes3, codes3, ybits_count + vpxor codes3, codes3, ybits + vpaddq code_lens3, code_lens3, ybits_count + + ;; Merge two symbols into qwords + vpsllvq codes1, codes1, code_lens3 + vpxor codes1, codes1, codes3 + vpaddq code_lens1, code_lens1, code_lens3 + + ;; Split buffer data into dqwords, ytmp is 0 after last branch + vpblendd codes2, ytmp, codes1, 0x33 + vpblendd code_lens2, ytmp, code_lens1, 0x33 + vpsrldq codes1, 8 + vpsrldq code_lens1, 8 + + ;; Merge two qwords into dqwords + vmovdqa ytmp, [q_64] + vpsubq code_lens3, ytmp, code_lens2 + vpsrlvq codes3, codes1, code_lens3 + vpslldq codes3, codes3, 8 + + vpsllvq codes1, codes1, code_lens2 + + vpxor codes1, codes1, codes3 + vpxor codes1, codes1, codes2 + vpaddq code_lens1, code_lens1, code_lens2 + + vmovq tmp, code_lens1 %+ x ;Number of bytes + shr tmp, 3 + vpand ybits_count, code_lens1, yoffset_mask ;Extra bits + + ;; bit shift upper dqword combined bits to line up with lower dqword + vextracti128 codes2 %+ x, codes1, 1 + vextracti128 code_lens2 %+ x, code_lens1, 1 + + vpbroadcastq ybits_count, ybits_count %+ x + vpsrldq codes3, codes2, 1 + vpsllvq codes2, codes2, ybits_count + vpsllvq codes3, codes3, ybits_count + vpslldq codes3, codes3, 1 + vpor codes2, codes2, codes3 + + ; Write out lower dqword of combined bits + vmovdqu [out_buf], codes1 + movzx bits, byte [out_buf + tmp] + vmovq codes1 %+ x, bits + vpaddq code_lens1, code_lens1, code_lens2 + + vmovq tmp2, code_lens1 %+ x ;Number of bytes + shr tmp2, 3 + vpand ybits_count, code_lens1, yoffset_mask ;Extra bits + + ; Write out upper dqword of combined bits + vpor codes1 %+ x, codes1 %+ x, codes2 %+ x + vmovdqu [out_buf + tmp], codes1 %+ x + add out_buf, tmp2 + movzx bits, byte [out_buf] + vmovq ybits %+ x, bits + + cmp ptr, in_buf_end + jbe .main_loop + +.main_loop_exit: + vmovq rcx, ybits_count %+ x + vmovq bits, ybits %+ x + jmp .finish + +.long_codes: + add end_ptr, VECTOR_SLOP + sub ptr, VECTOR_SIZE + + vpxor ytmp, ytmp, ytmp + vpblendd codes3, ytmp, codes1, 0x55 + vpblendd code_lens3, ytmp, code_lens1, 0x55 + vpblendd codes4, ytmp, codes2, 0x55 + + vpsllvq codes4, codes4, code_lens3 + vpxor codes3, codes3, codes4 + vpaddd code_lens3, code_lens1, code_lens2 + + vpsrlq codes1, codes1, 32 + vpsrlq code_lens1, code_lens1, 32 + vpsrlq codes2, codes2, 32 + + vpsllvq codes2, codes2, code_lens1 + vpxor codes1, codes1, codes2 + + vpsrlq code_lens1, code_lens3, 32 + vpblendd code_lens3, ytmp, code_lens3, 0x55 + + ;; Merge bitbuf bits + vpsllvq codes3, codes3, ybits_count + vpxor codes3, codes3, ybits + vpaddq code_lens3, code_lens3, ybits_count + vpaddq code_lens1, code_lens1, code_lens3 + + xor bits, bits + xor rcx, rcx + vpsubq code_lens1, code_lens1, code_lens3 +%rep 2 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + cmp out_buf, end_ptr + ja .overflow + ;; insert LL code + vmovq sym, codes3 %+ x + vmovq tmp2, code_lens3 %+ x + SHLX sym, sym, rcx + or bits, sym + add rcx, tmp2 + + ; empty bits + mov [out_buf], bits + mov tmp, rcx + shr tmp, 3 ; byte count + add out_buf, tmp + mov tmp, rcx + and rcx, ~7 + SHRX bits, bits, rcx + mov rcx, tmp + and rcx, 7 + add ptr, 4 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + cmp out_buf, end_ptr + ja .overflow + ;; insert LL code + vmovq sym, codes1 %+ x + vmovq tmp2, code_lens1 %+ x + SHLX sym, sym, rcx + or bits, sym + add rcx, tmp2 + + ; empty bits + mov [out_buf], bits + mov tmp, rcx + shr tmp, 3 ; byte count + add out_buf, tmp + mov tmp, rcx + and rcx, ~7 + SHRX bits, bits, rcx + mov rcx, tmp + and rcx, 7 + add ptr, 4 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + cmp out_buf, end_ptr + ja .overflow + ;; insert LL code + vpextrq sym, codes3 %+ x, 1 + vpextrq tmp2, code_lens3 %+ x, 1 + SHLX sym, sym, rcx + or bits, sym + add rcx, tmp2 + + ; empty bits + mov [out_buf], bits + mov tmp, rcx + shr tmp, 3 ; byte count + add out_buf, tmp + mov tmp, rcx + and rcx, ~7 + SHRX bits, bits, rcx + mov rcx, tmp + and rcx, 7 + add ptr, 4 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + cmp out_buf, end_ptr + ja .overflow + ;; insert LL code + vpextrq sym, codes1 %+ x, 1 + vpextrq tmp2, code_lens1 %+ x, 1 + SHLX sym, sym, rcx + or bits, sym + add rcx, tmp2 + + ; empty bits + mov [out_buf], bits + mov tmp, rcx + shr tmp, 3 ; byte count + add out_buf, tmp + mov tmp, rcx + and rcx, ~7 + SHRX bits, bits, rcx + mov rcx, tmp + and rcx, 7 + add ptr, 4 + + vextracti128 codes3 %+ x, codes3, 1 + vextracti128 code_lens3 %+ x, code_lens3, 1 + vextracti128 codes1 %+ x, codes1, 1 + vextracti128 code_lens1 %+ x, code_lens1, 1 +%endrep + sub end_ptr, VECTOR_SLOP + + vmovq ybits %+ x, bits + vmovq ybits_count %+ x, rcx + cmp ptr, in_buf_end + jbe .main_loop + +.finish: + add in_buf_end, VECTOR_LOOP_PROCESSED + add end_ptr, VECTOR_SLOP + + cmp ptr, in_buf_end + jge .overflow + +.finish_loop: + mov DWORD(data), [ptr] + + cmp out_buf, end_ptr + ja .overflow + + mov sym, data + and sym, LIT_MASK ; sym has ll_code + mov DWORD(sym), [hufftables + _lit_len_table + sym * 4] + + ; look up dist sym + mov dsym, data + shr dsym, DIST_OFFSET + and dsym, DIST_MASK + mov DWORD(dsym), [hufftables + _dist_table + dsym * 4] + + ; insert LL code + ; sym: 31:24 length; 23:0 code + mov tmp2, sym + and sym, 0xFFFFFF + SHLX sym, sym, rcx + shr tmp2, 24 + or bits, sym + add rcx, tmp2 + + ; insert dist code + movzx tmp, WORD(dsym) + SHLX tmp, tmp, rcx + or bits, tmp + mov tmp, dsym + shr tmp, 24 + add rcx, tmp + + ; insert dist extra bits + shr data, EXTRA_BITS_OFFSET + add ptr, 4 + SHLX data, data, rcx + or bits, data + shr dsym, 16 + and dsym, 0xFF + add rcx, dsym + + ; empty bits + mov [out_buf], bits + mov tmp, rcx + shr tmp, 3 ; byte count + add out_buf, tmp + mov tmp, rcx + and rcx, ~7 + SHRX bits, bits, rcx + mov rcx, tmp + and rcx, 7 + + cmp ptr, in_buf_end + jb .finish_loop + +.overflow: + mov tmp, [rsp + bitbuf_mem_offset] + mov [tmp + _m_bits], bits + mov [tmp + _m_bit_count], ecx + mov [tmp + _m_out_buf], out_buf + + mov rax, ptr + + FUNC_RESTORE + + ret + +section .data + align 32 +max_write_d: + dd 0x1c, 0x1d, 0x20, 0x20, 0x1e, 0x1e, 0x1e, 0x1e +offset_mask: + dq 0x0000000000000007, 0x0000000000000000 + dq 0x0000000000000000, 0x0000000000000000 +q_64: + dq 0x0000000000000040, 0x0000000000000000 + dq 0x0000000000000040, 0x0000000000000000 +lit_mask: + dd LIT_MASK, LIT_MASK, LIT_MASK, LIT_MASK + dd LIT_MASK, LIT_MASK, LIT_MASK, LIT_MASK +dist_mask: + dd DIST_MASK, DIST_MASK, DIST_MASK, DIST_MASK + dd DIST_MASK, DIST_MASK, DIST_MASK, DIST_MASK +lit_icr_mask: + dd 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF + dd 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF +eb_icr_mask: + dd 0x000000FF, 0x000000FF, 0x000000FF, 0x000000FF + dd 0x000000FF, 0x000000FF, 0x000000FF, 0x000000FF diff --git a/ceph/src/isa-l/igzip/flatten_ll.c b/ceph/src/isa-l/igzip/flatten_ll.c new file mode 100644 index 000000000..1eb13b559 --- /dev/null +++ b/ceph/src/isa-l/igzip/flatten_ll.c @@ -0,0 +1,41 @@ +#include +#include +#include + +#include "flatten_ll.h" + +void flatten_ll(uint32_t * ll_hist) +{ + uint32_t i, j; + uint32_t *s = ll_hist, x, *p; + + s[265] += s[266]; + s[266] = s[267] + s[268]; + s[267] = s[269] + s[270]; + s[268] = s[271] + s[272]; + s[269] = s[273] + s[274] + s[275] + s[276]; + s[270] = s[277] + s[278] + s[279] + s[280]; + s[271] = s[281] + s[282] + s[283] + s[284]; + s[272] = s[285] + s[286] + s[287] + s[288]; + p = s + 289; + for (i = 273; i < 277; i++) { + x = *(p++); + for (j = 1; j < 8; j++) + x += *(p++); + s[i] = x; + } + for (; i < 281; i++) { + x = *(p++); + for (j = 1; j < 16; j++) + x += *(p++); + s[i] = x; + } + for (; i < 285; i++) { + x = *(p++); + for (j = 1; j < 32; j++) + x += *(p++); + s[i] = x; + } + s[284] -= s[512]; + s[285] = s[512]; +} diff --git a/ceph/src/isa-l/igzip/flatten_ll.h b/ceph/src/isa-l/igzip/flatten_ll.h new file mode 100644 index 000000000..9aaf89106 --- /dev/null +++ b/ceph/src/isa-l/igzip/flatten_ll.h @@ -0,0 +1,3 @@ +#include + +void flatten_ll(uint32_t *ll_hist); diff --git a/ceph/src/isa-l/igzip/generate_constant_block_header.c b/ceph/src/isa-l/igzip/generate_constant_block_header.c deleted file mode 100644 index 99bcf4829..000000000 --- a/ceph/src/isa-l/igzip/generate_constant_block_header.c +++ /dev/null @@ -1,118 +0,0 @@ -/********************************************************************** - Copyright(c) 2011-2016 Intel Corporation All rights reserved. - - 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 Intel Corporation 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 - 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. -**********************************************************************/ - -#include -#include -#include "huff_codes.h" -#include "bitbuf2.h" - -#define MAX_HEADER_SIZE 350 -#define BLOCK_SIZE 16*1024 - -void fprint_header(FILE * outfile, uint8_t * header, uint64_t bit_count) -{ - int i; - fprintf(outfile, "unsigned char data[] = {"); - for (i = 0; i < bit_count / 8; i++) { - if ((i & 7) == 0) - fprintf(outfile, "\n\t"); - else - fprintf(outfile, " "); - fprintf(outfile, "0x%02x,", header[i]); - } - - if ((i & 7) == 0) - fprintf(outfile, "\n\t"); - else - fprintf(outfile, " "); - fprintf(outfile, "0x%02x", header[i]); - fprintf(outfile, "\t};\n\n"); - -} - -int main(int argc, char **argv) -{ - /* Generates a header for a constant block, along with some manual - * twiddling to create a header with the desired properties*/ - uint8_t stream[BLOCK_SIZE]; - struct isal_huff_histogram histogram; - uint64_t *lit_histogram = histogram.lit_len_histogram; - uint64_t *dist_histogram = histogram.dist_histogram; - uint8_t header[MAX_HEADER_SIZE]; - struct huff_tree lit_tree, dist_tree; - struct huff_tree lit_tree_array[2 * LIT_LEN - 1], dist_tree_array[2 * DIST_LEN - 1]; - struct huff_code lit_huff_table[LIT_LEN], dist_huff_table[DIST_LEN]; - uint64_t bit_count; - - uint8_t repeated_char = 0x00; - - memset(header, 0, sizeof(header)); - memset(&histogram, 0, sizeof(histogram)); /* Initialize histograms. */ - memset(stream, repeated_char, sizeof(stream)); - memset(lit_tree_array, 0, sizeof(lit_tree_array)); - memset(dist_tree_array, 0, sizeof(dist_tree_array)); - memset(lit_huff_table, 0, sizeof(lit_huff_table)); - memset(dist_huff_table, 0, sizeof(dist_huff_table)); - - isal_update_histogram(stream, sizeof(stream), &histogram); - - /* These are set to manually change the histogram to create a header with the - * desired properties. In this case, the header is modified so that it is byte - * unaligned by 6 bits, so that 0 is a 2 bit code, so that the header plus the - * encoding of one 0 is byte aligned*/ - lit_histogram[repeated_char] = 20; - lit_histogram[280] = 2; - lit_histogram[264] = 5; - lit_histogram[282] = 0; - - lit_tree = create_symbol_subset_huff_tree(lit_tree_array, lit_histogram, LIT_LEN); - dist_tree = create_symbol_subset_huff_tree(dist_tree_array, dist_histogram, DIST_LEN); - if (create_huff_lookup(lit_huff_table, LIT_LEN, lit_tree, 15) > 0) { - printf("Error, code with invalid length for Deflate standard.\n"); - return 1; - } - - if (create_huff_lookup(dist_huff_table, DIST_LEN, dist_tree, 15) > 0) { - printf("Error, code with invalid length for Deflate standard.\n"); - return 1; - } - - /* Remove litral symbol corresponding to the unoptimal look back - * distance of 258 found by gen_histogram*/ - dist_huff_table[16].length = 0; - - bit_count = create_header(header, sizeof(header), lit_huff_table, dist_huff_table, 1); - printf("Header for %x\n", repeated_char); - fprintf(stdout, "Complete Bytes: %lu\n", bit_count / 8); - fprintf(stdout, "Byte Offset: %lu\n\n", (bit_count) & 7); - fprint_header(stdout, header, bit_count); - printf("\n"); - - return 0; -} diff --git a/ceph/src/isa-l/igzip/generate_custom_hufftables.c b/ceph/src/isa-l/igzip/generate_custom_hufftables.c index 9e7ee5f92..d0958b917 100644 --- a/ceph/src/isa-l/igzip/generate_custom_hufftables.c +++ b/ceph/src/isa-l/igzip/generate_custom_hufftables.c @@ -45,48 +45,29 @@ * generate_custom_hufftables are the same as the default parameters used by * igzip. * - * *WARNING* generate custom hufftables must be compiled with a HIST_SIZE that - * is at least as large as the HIST_SIZE used by igzip. By default HIST_SIZE is - * 8, the maximum usable HIST_SIZE is 32. The reason for this is to generate - * better compression. Igzip cannot produce look back distances with sizes - * larger than the HIST_SIZE * 1024 igzip was compiled with, so look back - * distances with sizes larger than HIST_SIZE * 1024 are not assigned a huffman - * code. + * *WARNING* generate custom hufftables must be compiled with a IGZIP_HIST_SIZE + * that is at least as large as the IGZIP_HIST_SIZE used by igzip. By default + * IGZIP_HIST_SIZE is 32K, the maximum usable IGZIP_HIST_SIZE is 32K. The reason + * for this is to generate better compression. Igzip cannot produce look back + * distances with sizes larger than the IGZIP_HIST_SIZE igzip was compiled with, + * so look back distances with sizes larger than IGZIP_HIST_SIZE are not + * assigned a huffman code. The definition of LONGER_HUFFTABLES must be + * consistent as well since that definition changes the size of the structures + * printed by this tool. * - * To improve compression ratio, the compile time option LIT_SUB is provided to - * allow generating custom hufftables which only use a subset of all possible - * literals. This can be useful for getting better compression when it is known - * that the data being compressed will never contain certain symbols, for - * example text files. If this option is used, it needs to be checked that every - * possible literal is in fact given a valid code in the output hufftable. This - * can be done by checking that every required literal has a positive value for - * the length of the code associated with that literal. Literals which have not - * been given codes will have a code length of zero. The compile time option - * PRINT_CODES (described below) can be used to help manually perform this - * check. - * - * The compile time parameter PRINT_CODES causes the literal/length huffman code - * and the distance huffman code created by generate_custom_hufftables to be - * printed out. This is printed out where each line corresponds to a different - * symbol. The first column is the symbol used to represent each literal (Lit), - * end of block symbol (EOB), length (Len) or distance (Dist), the second column - * is the associated code value, and the third column is the length in bits of - * that code. */ #include #include #include -#include "huff_codes.h" -#include "bitbuf2.h" +#include +#include +#include "igzip_lib.h" /*These max code lengths are limited by how the data is stored in * hufftables.asm. The deflate standard max is 15.*/ -#define LONG_DCODE_OFFSET 26 -#define SHORT_DCODE_OFFSET 20 - -#define MAX_HEADER_SIZE IGZIP_MAX_DEF_HDR_SIZE +#define MAX_HEADER_SIZE ISAL_DEF_MAX_HDR_SIZE #define GZIP_HEADER_SIZE 10 #define GZIP_TRAILER_SIZE 8 @@ -184,108 +165,76 @@ void fprint_uint32_table(FILE * outfile, uint32_t * table, uint64_t length, char } -/** - * @brief Prints a table of uint64_t elements to a file. - * @param outfile: the file the table is printed to. - * @param table: the table to be printed. - * @param length: number of elements to be printed. - * @param header: header to append in front of the table. - * @param footer: footer to append at the end of the table. - */ -void fprint_uint64_table(FILE * outfile, uint64_t * table, uint64_t length, char *header, - char *footer) -{ - int i; - fprintf(outfile, "%s\n", header); - for (i = 0; i < length - 1; i++) - fprintf(outfile, "\t0x%016" PRIx64 ",\n", table[i]); - fprintf(outfile, "\t0x%016" PRIx64, table[i]); - fprintf(outfile, "%s", footer); - -} - -void fprint_hufftables(FILE * output_file, uint8_t * header, uint32_t bit_count, - uint16_t * lit_code_table, uint8_t * lit_code_size_table, - uint16_t * dcodes_code_table, uint8_t * dcodes_code_size_table, - uint32_t * packed_len_table, uint32_t * packed_dist_table) +void fprint_hufftables(FILE * output_file, char *hufftables_name, + struct isal_hufftables *hufftables) { - fprintf(output_file, "struct isal_hufftables hufftables_default = {\n\n"); - - fprint_uint8_table(output_file, header, (bit_count + 7) / 8, - "\t.deflate_hdr = {", "\t},\n\n", "\t\t"); - fprintf(output_file, "\t.deflate_hdr_count = %d,\n", bit_count / 8); - fprintf(output_file, "\t.deflate_hdr_extra_bits = %d,\n\n", bit_count & 7); - - fprint_uint32_table(output_file, packed_dist_table, SHORT_DIST_TABLE_SIZE, - "\t.dist_table = {", ",\n", "\t\t"); - fprint_uint32_table(output_file, &packed_dist_table[SHORT_DIST_TABLE_SIZE], - LONG_DIST_TABLE_SIZE - SHORT_DIST_TABLE_SIZE, - "#ifdef LONGER_HUFFTABLE", - "\n#endif /* LONGER_HUFFTABLE */\n\t},\n\n", "\t\t"); - - fprint_uint32_table(output_file, packed_len_table, LEN_TABLE_SIZE, "\t.len_table = {", - "\t},\n\n", "\t\t"); - fprint_uint16_table(output_file, lit_code_table, LIT_TABLE_SIZE, "\t.lit_table = {", - "\t},\n\n", "\t\t"); - fprint_uint8_table(output_file, lit_code_size_table, LIT_TABLE_SIZE, - "\t.lit_table_sizes = {", "\t},\n\n", "\t\t"); - - fprintf(output_file, "#ifndef LONGER_HUFFTABLE\n"); - fprint_uint16_table(output_file, dcodes_code_table + SHORT_DCODE_OFFSET, - DIST_LEN - SHORT_DCODE_OFFSET, "\t.dcodes = {", "\t},\n\n", - "\t\t"); - fprint_uint8_table(output_file, dcodes_code_size_table + SHORT_DCODE_OFFSET, - DIST_LEN - SHORT_DCODE_OFFSET, "\t.dcodes_sizes = {", "\t}\n", - "\t\t"); - fprintf(output_file, "#else\n"); - fprint_uint16_table(output_file, dcodes_code_table + LONG_DCODE_OFFSET, - DIST_LEN - LONG_DCODE_OFFSET, "\t.dcodes = {", "\t},\n\n", "\t\t"); - fprint_uint8_table(output_file, dcodes_code_size_table + LONG_DCODE_OFFSET, - DIST_LEN - LONG_DCODE_OFFSET, "\t.dcodes_sizes = {", "\t}\n", - "\t\t"); - fprintf(output_file, "#endif\n"); + fprintf(output_file, "struct isal_hufftables %s = {\n\n", hufftables_name); + + fprint_uint8_table(output_file, hufftables->deflate_hdr, + hufftables->deflate_hdr_count + + (hufftables->deflate_hdr_extra_bits + 7) / 8, + "\t.deflate_hdr = {", "},\n\n", "\t\t"); + + fprintf(output_file, "\t.deflate_hdr_count = %d,\n", hufftables->deflate_hdr_count); + fprintf(output_file, "\t.deflate_hdr_extra_bits = %d,\n\n", + hufftables->deflate_hdr_extra_bits); + + fprint_uint32_table(output_file, hufftables->dist_table, IGZIP_DIST_TABLE_SIZE, + "\t.dist_table = {", "},\n\n", "\t\t"); + + fprint_uint32_table(output_file, hufftables->len_table, IGZIP_LEN_TABLE_SIZE, + "\t.len_table = {", "},\n\n", "\t\t"); + + fprint_uint16_table(output_file, hufftables->lit_table, IGZIP_LIT_TABLE_SIZE, + "\t.lit_table = {", "},\n\n", "\t\t"); + fprint_uint8_table(output_file, hufftables->lit_table_sizes, IGZIP_LIT_TABLE_SIZE, + "\t.lit_table_sizes = {", "},\n\n", "\t\t"); + + fprint_uint16_table(output_file, hufftables->dcodes, + ISAL_DEF_DIST_SYMBOLS - IGZIP_DECODE_OFFSET, + "\t.dcodes = {", "},\n\n", "\t\t"); + fprint_uint8_table(output_file, hufftables->dcodes_sizes, + ISAL_DEF_DIST_SYMBOLS - IGZIP_DECODE_OFFSET, + "\t.dcodes_sizes = {", "}\n", "\t\t"); fprintf(output_file, "};\n"); } -void fprint_header(FILE * output_file, uint8_t * header, uint32_t bit_count, - uint16_t * lit_code_table, uint8_t * lit_code_size_table, - uint16_t * dcodes_code_table, uint8_t * dcodes_code_size_table, - uint32_t * packed_len_table, uint32_t * packed_dist_table) +void fprint_header(FILE * output_file) { + fprintf(output_file, "#include \n"); fprintf(output_file, "#include \n\n"); + fprintf(output_file, "#if IGZIP_HIST_SIZE > %d\n" + "# error \"Invalid history size for the custom hufftable\"\n" + "#endif\n", IGZIP_HIST_SIZE); + +#ifdef LONGER_HUFFTABLE + fprintf(output_file, "#ifndef LONGER_HUFFTABLE\n" + "# error \"Custom hufftable requires LONGER_HUFFTABLE to be defined \"\n" + "#endif\n"); +#else + fprintf(output_file, "#ifdef LONGER_HUFFTABLE\n" + "# error \"Custom hufftable requires LONGER_HUFFTABLE to not be defined \"\n" + "#endif\n"); +#endif + fprintf(output_file, "\n"); + fprintf(output_file, "const uint8_t gzip_hdr[] = {\n" "\t0x1f, 0x8b, 0x08, 0x00, 0x00,\n" "\t0x00, 0x00, 0x00, 0x00, 0xff\t};\n\n"); fprintf(output_file, "const uint32_t gzip_hdr_bytes = %d;\n", GZIP_HEADER_SIZE); - fprintf(output_file, "const uint32_t gzip_trl_bytes = %d;\n\n", GZIP_TRAILER_SIZE); - - fprint_hufftables(output_file, header, bit_count, lit_code_table, lit_code_size_table, - dcodes_code_table, dcodes_code_size_table, packed_len_table, - packed_dist_table); + fprintf(output_file, "const uint32_t gzip_trl_bytes = %d;\n", GZIP_TRAILER_SIZE); } int main(int argc, char *argv[]) { long int file_length; uint8_t *stream = NULL; + struct isal_hufftables hufftables; struct isal_huff_histogram histogram; - uint64_t *lit_histogram = histogram.lit_len_histogram; - uint64_t *dist_histogram = histogram.dist_histogram; - uint8_t header[MAX_HEADER_SIZE]; + struct isal_zstream tmp_stream; FILE *file; - struct huff_tree lit_tree, dist_tree; - struct huff_tree lit_tree_array[2 * LIT_LEN - 1], dist_tree_array[2 * DIST_LEN - 1]; - struct huff_code lit_huff_table[LIT_LEN], dist_huff_table[DIST_LEN]; - uint64_t bit_count; - uint32_t packed_len_table[LEN_TABLE_SIZE]; - uint32_t packed_dist_table[LONG_DIST_TABLE_SIZE]; - uint16_t lit_code_table[LIT_TABLE_SIZE]; - uint16_t dcodes_code_table[DIST_LEN]; - uint8_t lit_code_size_table[LIT_TABLE_SIZE]; - uint8_t dcodes_code_size_table[DIST_LEN]; - int max_dist = convert_dist_to_dist_sym(D); if (argc == 1) { printf("Error, no input file.\n"); @@ -293,10 +242,6 @@ int main(int argc, char *argv[]) } memset(&histogram, 0, sizeof(histogram)); /* Initialize histograms. */ - memset(lit_tree_array, 0, sizeof(lit_tree_array)); - memset(dist_tree_array, 0, sizeof(dist_tree_array)); - memset(lit_huff_table, 0, sizeof(lit_huff_table)); - memset(dist_huff_table, 0, sizeof(dist_huff_table)); while (argc > 1) { printf("Processing %s\n", argv[argc - 1]); @@ -332,92 +277,25 @@ int main(int argc, char *argv[]) argc--; } - /* Create a huffman tree corresponding to the histograms created in - * gen_histogram*/ -#ifdef LIT_SUB - int j; - /* Guarantee every possible repeat length is given a symbol. It is hard - * to guarantee data will never have a repeat of a given length */ - for (j = LIT_TABLE_SIZE; j < LIT_LEN; j++) - if (lit_histogram[j] == 0) - lit_histogram[j]++; - - lit_tree = create_symbol_subset_huff_tree(lit_tree_array, lit_histogram, LIT_LEN); -#else - lit_tree = create_huff_tree(lit_tree_array, lit_histogram, LIT_LEN); -#endif - dist_tree = create_huff_tree(dist_tree_array, dist_histogram, max_dist + 1); + isal_create_hufftables(&hufftables, &histogram); - /* Create a look up table to represent huffman tree above in deflate - * standard form after it has been modified to satisfy max depth - * criteria.*/ - if (create_huff_lookup(lit_huff_table, LIT_LEN, lit_tree, MAX_DEFLATE_CODE_LEN) > 0) { - printf("Error, code with invalid length for Deflate standard.\n"); + file = fopen("hufftables_c.c", "w"); + if (file == NULL) { + printf("Error creating file hufftables_c.c\n"); return 1; } - if (create_huff_lookup(dist_huff_table, DIST_LEN, dist_tree, MAX_DEFLATE_CODE_LEN) > 0) { - printf("Error, code with invalid length for Deflate standard.\n"); - return 1; - } + fprint_header(file); - if (are_hufftables_useable(lit_huff_table, dist_huff_table)) { - if (create_huff_lookup - (lit_huff_table, LIT_LEN, lit_tree, MAX_SAFE_LIT_CODE_LEN) > 0) - printf("Error, code with invalid length for Deflate standard.\n"); - return 1; + fprintf(file, "\n"); - if (create_huff_lookup - (dist_huff_table, DIST_LEN, dist_tree, MAX_SAFE_DIST_CODE_LEN) > 0) - printf("Error, code with invalid length for Deflate standard.\n"); - return 1; + fprint_hufftables(file, "hufftables_default", &hufftables); - if (are_hufftables_useable(lit_huff_table, dist_huff_table)) { - printf("Error, hufftable is not usable\n"); - return 1; - } - } -#ifdef PRINT_CODES - int i; - printf("Lit/Len codes\n"); - for (i = 0; i < LIT_TABLE_SIZE - 1; i++) - printf("Lit %3d: Code 0x%04x, Code_Len %d\n", i, lit_huff_table[i].code, - lit_huff_table[i].length); - - printf("EOB %3d: Code 0x%04x, Code_Len %d\n", 256, lit_huff_table[256].code, - lit_huff_table[256].length); - - for (i = LIT_TABLE_SIZE; i < LIT_LEN; i++) - printf("Len %d: Code 0x%04x, Code_Len %d\n", i, lit_huff_table[i].code, - lit_huff_table[i].length); - printf("\n"); - - printf("Dist codes \n"); - for (i = 0; i < DIST_LEN; i++) - printf("Dist %2d: Code 0x%04x, Code_Len %d\n", i, dist_huff_table[i].code, - dist_huff_table[i].length); - printf("\n"); -#endif - - create_code_tables(lit_code_table, lit_code_size_table, LIT_TABLE_SIZE, - lit_huff_table); - create_code_tables(dcodes_code_table, dcodes_code_size_table, DIST_LEN, - dist_huff_table); - create_packed_len_table(packed_len_table, lit_huff_table); - create_packed_dist_table(packed_dist_table, LONG_DIST_TABLE_SIZE, dist_huff_table); - - bit_count = - create_header(header, sizeof(header), lit_huff_table, dist_huff_table, LAST_BLOCK); - - file = fopen("hufftables_c.c", "w"); - if (file == NULL) { - printf("Error creating file hufftables_c.c\n"); - return 1; - } + fprintf(file, "\n"); - fprint_header(file, header, bit_count, lit_code_table, lit_code_size_table, - dcodes_code_table, dcodes_code_size_table, packed_len_table, - packed_dist_table); + isal_deflate_stateless_init(&tmp_stream); + isal_deflate_set_hufftables(&tmp_stream, NULL, IGZIP_HUFFTABLE_STATIC); + fprint_hufftables(file, "hufftables_static", tmp_stream.hufftables); fclose(file); diff --git a/ceph/src/isa-l/igzip/heap_macros.asm b/ceph/src/isa-l/igzip/heap_macros.asm new file mode 100644 index 000000000..e41baf97c --- /dev/null +++ b/ceph/src/isa-l/igzip/heap_macros.asm @@ -0,0 +1,69 @@ +; heapify heap, heap_size, i, child, tmp1, tmp2, tmpd +%macro heapify2 7 +%define %%heap %1 ; qword ptr +%define %%heap_size %2 ; dword +%define %%i %3 ; dword +%define %%child %4 ; dword +%define %%tmp1 %5 ; qword +%define %%tmp2 %6 ; qword +%define %%tmpd %7 ; dword + align 16 +%%heapify1: + lea %%child, [%%i + %%i] + cmp %%child, %%heap_size + ja %%end_heapify1 + mov %%tmp1, [%%heap + %%child] + mov %%tmpd, %%child + mov %%tmp2, [%%heap + %%child) + 8] + lea %%child, [%%child + 1] + cmove %%tmp2, %%tmp1 + cmp %%tmp1, %%tmp2 + cmovbe %%child, %%tmpd + cmovbe %%tmp2, %%tmp1 + ; child is correct, %%tmp2 = heap[child] + mov %%tmp1, [%%heap + %%i] + cmp %%tmp1, %%tmp2 + jbe %%end_heapify1 + mov [%%heap + %%i], %%tmp2 + mov [%%heap + %%child], %%tmp1 + mov %%i, %%child + jmp %%heapify1 +%%end_heapify1 +%endm + +; heapify heap, heap_size, i, child, tmp1, tmp2, tmpd, tmp3 +%macro heapify 8 +%define %%heap %1 ; qword ptr +%define %%heap_size %2 ; qword +%define %%i %3 ; qword +%define %%child %4 ; qword +%define %%tmp1 %5 ; qword +%define %%tmp2 %6 ; qword +%define %%tmpd %7 ; qword +%define %%tmp3 %8 + align 16 +%%heapify1: + lea %%child, [%%i + %%i] +; mov %%child, %%i +; add %%child, %%child + cmp %%child, %%heap_size + ja %%end_heapify1 + mov %%tmp1, [%%heap + %%child*8] + mov %%tmp2, [%%heap + %%child*8 + 8] + mov %%tmp3, [%%heap + %%i*8] + mov %%tmpd, %%child + add %%tmpd, 1 + + cmp %%tmp2, %%tmp1 + cmovb %%child, %%tmpd + cmovb %%tmp1, %%tmp2 + ; child is correct, tmp1 = heap[child] + cmp %%tmp3, %%tmp1 + jbe %%end_heapify1 + ; swap i and child + mov [%%heap + %%i*8], %%tmp1 + mov [%%heap + %%child*8], %%tmp3 + mov %%i, %%child + jmp %%heapify1 +%%end_heapify1: +%endm diff --git a/ceph/src/isa-l/igzip/huff_codes.c b/ceph/src/isa-l/igzip/huff_codes.c index d69c99d9e..c8b2035d2 100644 --- a/ceph/src/isa-l/igzip/huff_codes.c +++ b/ceph/src/isa-l/igzip/huff_codes.c @@ -34,120 +34,644 @@ #include "igzip_lib.h" #include "huff_codes.h" #include "huffman.h" - -#define LENGTH_BITS 5 +#include "bitbuf2.h" +#include "flatten_ll.h" /* The order code length codes are written in the dynamic code header. This is * defined in RFC 1951 page 13 */ static const uint8_t code_length_code_order[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; -int heap_push(struct huff_tree element, struct histheap *heap) +const uint32_t len_code_extra_bits[] = { + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x1, 0x1, 0x1, 0x2, 0x2, 0x2, 0x2, + 0x3, 0x3, 0x3, 0x3, 0x4, 0x4, 0x4, 0x4, + 0x5, 0x5, 0x5, 0x5, 0x0 +}; + +const uint32_t dist_code_extra_bits[] = { + 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x2, 0x2, + 0x3, 0x3, 0x4, 0x4, 0x5, 0x5, 0x6, 0x6, + 0x7, 0x7, 0x8, 0x8, 0x9, 0x9, 0xa, 0xa, + 0xb, 0xb, 0xc, 0xc, 0xd, 0xd +}; + +struct hufftables_icf static_hufftables = { + .lit_len_table = { + {.code_and_extra = 0x00c,.length2 = 0x8}, + {.code_and_extra = 0x08c,.length2 = 0x8}, + {.code_and_extra = 0x04c,.length2 = 0x8}, + {.code_and_extra = 0x0cc,.length2 = 0x8}, + {.code_and_extra = 0x02c,.length2 = 0x8}, + {.code_and_extra = 0x0ac,.length2 = 0x8}, + {.code_and_extra = 0x06c,.length2 = 0x8}, + {.code_and_extra = 0x0ec,.length2 = 0x8}, + {.code_and_extra = 0x01c,.length2 = 0x8}, + {.code_and_extra = 0x09c,.length2 = 0x8}, + {.code_and_extra = 0x05c,.length2 = 0x8}, + {.code_and_extra = 0x0dc,.length2 = 0x8}, + {.code_and_extra = 0x03c,.length2 = 0x8}, + {.code_and_extra = 0x0bc,.length2 = 0x8}, + {.code_and_extra = 0x07c,.length2 = 0x8}, + {.code_and_extra = 0x0fc,.length2 = 0x8}, + {.code_and_extra = 0x002,.length2 = 0x8}, + {.code_and_extra = 0x082,.length2 = 0x8}, + {.code_and_extra = 0x042,.length2 = 0x8}, + {.code_and_extra = 0x0c2,.length2 = 0x8}, + {.code_and_extra = 0x022,.length2 = 0x8}, + {.code_and_extra = 0x0a2,.length2 = 0x8}, + {.code_and_extra = 0x062,.length2 = 0x8}, + {.code_and_extra = 0x0e2,.length2 = 0x8}, + {.code_and_extra = 0x012,.length2 = 0x8}, + {.code_and_extra = 0x092,.length2 = 0x8}, + {.code_and_extra = 0x052,.length2 = 0x8}, + {.code_and_extra = 0x0d2,.length2 = 0x8}, + {.code_and_extra = 0x032,.length2 = 0x8}, + {.code_and_extra = 0x0b2,.length2 = 0x8}, + {.code_and_extra = 0x072,.length2 = 0x8}, + {.code_and_extra = 0x0f2,.length2 = 0x8}, + {.code_and_extra = 0x00a,.length2 = 0x8}, + {.code_and_extra = 0x08a,.length2 = 0x8}, + {.code_and_extra = 0x04a,.length2 = 0x8}, + {.code_and_extra = 0x0ca,.length2 = 0x8}, + {.code_and_extra = 0x02a,.length2 = 0x8}, + {.code_and_extra = 0x0aa,.length2 = 0x8}, + {.code_and_extra = 0x06a,.length2 = 0x8}, + {.code_and_extra = 0x0ea,.length2 = 0x8}, + {.code_and_extra = 0x01a,.length2 = 0x8}, + {.code_and_extra = 0x09a,.length2 = 0x8}, + {.code_and_extra = 0x05a,.length2 = 0x8}, + {.code_and_extra = 0x0da,.length2 = 0x8}, + {.code_and_extra = 0x03a,.length2 = 0x8}, + {.code_and_extra = 0x0ba,.length2 = 0x8}, + {.code_and_extra = 0x07a,.length2 = 0x8}, + {.code_and_extra = 0x0fa,.length2 = 0x8}, + {.code_and_extra = 0x006,.length2 = 0x8}, + {.code_and_extra = 0x086,.length2 = 0x8}, + {.code_and_extra = 0x046,.length2 = 0x8}, + {.code_and_extra = 0x0c6,.length2 = 0x8}, + {.code_and_extra = 0x026,.length2 = 0x8}, + {.code_and_extra = 0x0a6,.length2 = 0x8}, + {.code_and_extra = 0x066,.length2 = 0x8}, + {.code_and_extra = 0x0e6,.length2 = 0x8}, + {.code_and_extra = 0x016,.length2 = 0x8}, + {.code_and_extra = 0x096,.length2 = 0x8}, + {.code_and_extra = 0x056,.length2 = 0x8}, + {.code_and_extra = 0x0d6,.length2 = 0x8}, + {.code_and_extra = 0x036,.length2 = 0x8}, + {.code_and_extra = 0x0b6,.length2 = 0x8}, + {.code_and_extra = 0x076,.length2 = 0x8}, + {.code_and_extra = 0x0f6,.length2 = 0x8}, + {.code_and_extra = 0x00e,.length2 = 0x8}, + {.code_and_extra = 0x08e,.length2 = 0x8}, + {.code_and_extra = 0x04e,.length2 = 0x8}, + {.code_and_extra = 0x0ce,.length2 = 0x8}, + {.code_and_extra = 0x02e,.length2 = 0x8}, + {.code_and_extra = 0x0ae,.length2 = 0x8}, + {.code_and_extra = 0x06e,.length2 = 0x8}, + {.code_and_extra = 0x0ee,.length2 = 0x8}, + {.code_and_extra = 0x01e,.length2 = 0x8}, + {.code_and_extra = 0x09e,.length2 = 0x8}, + {.code_and_extra = 0x05e,.length2 = 0x8}, + {.code_and_extra = 0x0de,.length2 = 0x8}, + {.code_and_extra = 0x03e,.length2 = 0x8}, + {.code_and_extra = 0x0be,.length2 = 0x8}, + {.code_and_extra = 0x07e,.length2 = 0x8}, + {.code_and_extra = 0x0fe,.length2 = 0x8}, + {.code_and_extra = 0x001,.length2 = 0x8}, + {.code_and_extra = 0x081,.length2 = 0x8}, + {.code_and_extra = 0x041,.length2 = 0x8}, + {.code_and_extra = 0x0c1,.length2 = 0x8}, + {.code_and_extra = 0x021,.length2 = 0x8}, + {.code_and_extra = 0x0a1,.length2 = 0x8}, + {.code_and_extra = 0x061,.length2 = 0x8}, + {.code_and_extra = 0x0e1,.length2 = 0x8}, + {.code_and_extra = 0x011,.length2 = 0x8}, + {.code_and_extra = 0x091,.length2 = 0x8}, + {.code_and_extra = 0x051,.length2 = 0x8}, + {.code_and_extra = 0x0d1,.length2 = 0x8}, + {.code_and_extra = 0x031,.length2 = 0x8}, + {.code_and_extra = 0x0b1,.length2 = 0x8}, + {.code_and_extra = 0x071,.length2 = 0x8}, + {.code_and_extra = 0x0f1,.length2 = 0x8}, + {.code_and_extra = 0x009,.length2 = 0x8}, + {.code_and_extra = 0x089,.length2 = 0x8}, + {.code_and_extra = 0x049,.length2 = 0x8}, + {.code_and_extra = 0x0c9,.length2 = 0x8}, + {.code_and_extra = 0x029,.length2 = 0x8}, + {.code_and_extra = 0x0a9,.length2 = 0x8}, + {.code_and_extra = 0x069,.length2 = 0x8}, + {.code_and_extra = 0x0e9,.length2 = 0x8}, + {.code_and_extra = 0x019,.length2 = 0x8}, + {.code_and_extra = 0x099,.length2 = 0x8}, + {.code_and_extra = 0x059,.length2 = 0x8}, + {.code_and_extra = 0x0d9,.length2 = 0x8}, + {.code_and_extra = 0x039,.length2 = 0x8}, + {.code_and_extra = 0x0b9,.length2 = 0x8}, + {.code_and_extra = 0x079,.length2 = 0x8}, + {.code_and_extra = 0x0f9,.length2 = 0x8}, + {.code_and_extra = 0x005,.length2 = 0x8}, + {.code_and_extra = 0x085,.length2 = 0x8}, + {.code_and_extra = 0x045,.length2 = 0x8}, + {.code_and_extra = 0x0c5,.length2 = 0x8}, + {.code_and_extra = 0x025,.length2 = 0x8}, + {.code_and_extra = 0x0a5,.length2 = 0x8}, + {.code_and_extra = 0x065,.length2 = 0x8}, + {.code_and_extra = 0x0e5,.length2 = 0x8}, + {.code_and_extra = 0x015,.length2 = 0x8}, + {.code_and_extra = 0x095,.length2 = 0x8}, + {.code_and_extra = 0x055,.length2 = 0x8}, + {.code_and_extra = 0x0d5,.length2 = 0x8}, + {.code_and_extra = 0x035,.length2 = 0x8}, + {.code_and_extra = 0x0b5,.length2 = 0x8}, + {.code_and_extra = 0x075,.length2 = 0x8}, + {.code_and_extra = 0x0f5,.length2 = 0x8}, + {.code_and_extra = 0x00d,.length2 = 0x8}, + {.code_and_extra = 0x08d,.length2 = 0x8}, + {.code_and_extra = 0x04d,.length2 = 0x8}, + {.code_and_extra = 0x0cd,.length2 = 0x8}, + {.code_and_extra = 0x02d,.length2 = 0x8}, + {.code_and_extra = 0x0ad,.length2 = 0x8}, + {.code_and_extra = 0x06d,.length2 = 0x8}, + {.code_and_extra = 0x0ed,.length2 = 0x8}, + {.code_and_extra = 0x01d,.length2 = 0x8}, + {.code_and_extra = 0x09d,.length2 = 0x8}, + {.code_and_extra = 0x05d,.length2 = 0x8}, + {.code_and_extra = 0x0dd,.length2 = 0x8}, + {.code_and_extra = 0x03d,.length2 = 0x8}, + {.code_and_extra = 0x0bd,.length2 = 0x8}, + {.code_and_extra = 0x07d,.length2 = 0x8}, + {.code_and_extra = 0x0fd,.length2 = 0x8}, + {.code_and_extra = 0x013,.length2 = 0x9}, + {.code_and_extra = 0x113,.length2 = 0x9}, + {.code_and_extra = 0x093,.length2 = 0x9}, + {.code_and_extra = 0x193,.length2 = 0x9}, + {.code_and_extra = 0x053,.length2 = 0x9}, + {.code_and_extra = 0x153,.length2 = 0x9}, + {.code_and_extra = 0x0d3,.length2 = 0x9}, + {.code_and_extra = 0x1d3,.length2 = 0x9}, + {.code_and_extra = 0x033,.length2 = 0x9}, + {.code_and_extra = 0x133,.length2 = 0x9}, + {.code_and_extra = 0x0b3,.length2 = 0x9}, + {.code_and_extra = 0x1b3,.length2 = 0x9}, + {.code_and_extra = 0x073,.length2 = 0x9}, + {.code_and_extra = 0x173,.length2 = 0x9}, + {.code_and_extra = 0x0f3,.length2 = 0x9}, + {.code_and_extra = 0x1f3,.length2 = 0x9}, + {.code_and_extra = 0x00b,.length2 = 0x9}, + {.code_and_extra = 0x10b,.length2 = 0x9}, + {.code_and_extra = 0x08b,.length2 = 0x9}, + {.code_and_extra = 0x18b,.length2 = 0x9}, + {.code_and_extra = 0x04b,.length2 = 0x9}, + {.code_and_extra = 0x14b,.length2 = 0x9}, + {.code_and_extra = 0x0cb,.length2 = 0x9}, + {.code_and_extra = 0x1cb,.length2 = 0x9}, + {.code_and_extra = 0x02b,.length2 = 0x9}, + {.code_and_extra = 0x12b,.length2 = 0x9}, + {.code_and_extra = 0x0ab,.length2 = 0x9}, + {.code_and_extra = 0x1ab,.length2 = 0x9}, + {.code_and_extra = 0x06b,.length2 = 0x9}, + {.code_and_extra = 0x16b,.length2 = 0x9}, + {.code_and_extra = 0x0eb,.length2 = 0x9}, + {.code_and_extra = 0x1eb,.length2 = 0x9}, + {.code_and_extra = 0x01b,.length2 = 0x9}, + {.code_and_extra = 0x11b,.length2 = 0x9}, + {.code_and_extra = 0x09b,.length2 = 0x9}, + {.code_and_extra = 0x19b,.length2 = 0x9}, + {.code_and_extra = 0x05b,.length2 = 0x9}, + {.code_and_extra = 0x15b,.length2 = 0x9}, + {.code_and_extra = 0x0db,.length2 = 0x9}, + {.code_and_extra = 0x1db,.length2 = 0x9}, + {.code_and_extra = 0x03b,.length2 = 0x9}, + {.code_and_extra = 0x13b,.length2 = 0x9}, + {.code_and_extra = 0x0bb,.length2 = 0x9}, + {.code_and_extra = 0x1bb,.length2 = 0x9}, + {.code_and_extra = 0x07b,.length2 = 0x9}, + {.code_and_extra = 0x17b,.length2 = 0x9}, + {.code_and_extra = 0x0fb,.length2 = 0x9}, + {.code_and_extra = 0x1fb,.length2 = 0x9}, + {.code_and_extra = 0x007,.length2 = 0x9}, + {.code_and_extra = 0x107,.length2 = 0x9}, + {.code_and_extra = 0x087,.length2 = 0x9}, + {.code_and_extra = 0x187,.length2 = 0x9}, + {.code_and_extra = 0x047,.length2 = 0x9}, + {.code_and_extra = 0x147,.length2 = 0x9}, + {.code_and_extra = 0x0c7,.length2 = 0x9}, + {.code_and_extra = 0x1c7,.length2 = 0x9}, + {.code_and_extra = 0x027,.length2 = 0x9}, + {.code_and_extra = 0x127,.length2 = 0x9}, + {.code_and_extra = 0x0a7,.length2 = 0x9}, + {.code_and_extra = 0x1a7,.length2 = 0x9}, + {.code_and_extra = 0x067,.length2 = 0x9}, + {.code_and_extra = 0x167,.length2 = 0x9}, + {.code_and_extra = 0x0e7,.length2 = 0x9}, + {.code_and_extra = 0x1e7,.length2 = 0x9}, + {.code_and_extra = 0x017,.length2 = 0x9}, + {.code_and_extra = 0x117,.length2 = 0x9}, + {.code_and_extra = 0x097,.length2 = 0x9}, + {.code_and_extra = 0x197,.length2 = 0x9}, + {.code_and_extra = 0x057,.length2 = 0x9}, + {.code_and_extra = 0x157,.length2 = 0x9}, + {.code_and_extra = 0x0d7,.length2 = 0x9}, + {.code_and_extra = 0x1d7,.length2 = 0x9}, + {.code_and_extra = 0x037,.length2 = 0x9}, + {.code_and_extra = 0x137,.length2 = 0x9}, + {.code_and_extra = 0x0b7,.length2 = 0x9}, + {.code_and_extra = 0x1b7,.length2 = 0x9}, + {.code_and_extra = 0x077,.length2 = 0x9}, + {.code_and_extra = 0x177,.length2 = 0x9}, + {.code_and_extra = 0x0f7,.length2 = 0x9}, + {.code_and_extra = 0x1f7,.length2 = 0x9}, + {.code_and_extra = 0x00f,.length2 = 0x9}, + {.code_and_extra = 0x10f,.length2 = 0x9}, + {.code_and_extra = 0x08f,.length2 = 0x9}, + {.code_and_extra = 0x18f,.length2 = 0x9}, + {.code_and_extra = 0x04f,.length2 = 0x9}, + {.code_and_extra = 0x14f,.length2 = 0x9}, + {.code_and_extra = 0x0cf,.length2 = 0x9}, + {.code_and_extra = 0x1cf,.length2 = 0x9}, + {.code_and_extra = 0x02f,.length2 = 0x9}, + {.code_and_extra = 0x12f,.length2 = 0x9}, + {.code_and_extra = 0x0af,.length2 = 0x9}, + {.code_and_extra = 0x1af,.length2 = 0x9}, + {.code_and_extra = 0x06f,.length2 = 0x9}, + {.code_and_extra = 0x16f,.length2 = 0x9}, + {.code_and_extra = 0x0ef,.length2 = 0x9}, + {.code_and_extra = 0x1ef,.length2 = 0x9}, + {.code_and_extra = 0x01f,.length2 = 0x9}, + {.code_and_extra = 0x11f,.length2 = 0x9}, + {.code_and_extra = 0x09f,.length2 = 0x9}, + {.code_and_extra = 0x19f,.length2 = 0x9}, + {.code_and_extra = 0x05f,.length2 = 0x9}, + {.code_and_extra = 0x15f,.length2 = 0x9}, + {.code_and_extra = 0x0df,.length2 = 0x9}, + {.code_and_extra = 0x1df,.length2 = 0x9}, + {.code_and_extra = 0x03f,.length2 = 0x9}, + {.code_and_extra = 0x13f,.length2 = 0x9}, + {.code_and_extra = 0x0bf,.length2 = 0x9}, + {.code_and_extra = 0x1bf,.length2 = 0x9}, + {.code_and_extra = 0x07f,.length2 = 0x9}, + {.code_and_extra = 0x17f,.length2 = 0x9}, + {.code_and_extra = 0x0ff,.length2 = 0x9}, + {.code_and_extra = 0x1ff,.length2 = 0x9}, + {.code_and_extra = 0x000,.length2 = 0x7}, + {.code_and_extra = 0x040,.length2 = 0x7}, + {.code_and_extra = 0x020,.length2 = 0x7}, + {.code_and_extra = 0x060,.length2 = 0x7}, + {.code_and_extra = 0x010,.length2 = 0x7}, + {.code_and_extra = 0x050,.length2 = 0x7}, + {.code_and_extra = 0x030,.length2 = 0x7}, + {.code_and_extra = 0x070,.length2 = 0x7}, + {.code_and_extra = 0x008,.length2 = 0x7}, + {.code_and_extra = 0x048,.length2 = 0x7}, + {.code_and_extra = 0x028,.length2 = 0x7}, + {.code_and_extra = 0x068,.length2 = 0x7}, + {.code_and_extra = 0x018,.length2 = 0x7}, + {.code_and_extra = 0x058,.length2 = 0x7}, + {.code_and_extra = 0x038,.length2 = 0x7}, + {.code_and_extra = 0x078,.length2 = 0x7}, + {.code_and_extra = 0x004,.length2 = 0x7}, + {.code_and_extra = 0x044,.length2 = 0x7}, + {.code_and_extra = 0x024,.length2 = 0x7}, + {.code_and_extra = 0x064,.length2 = 0x7}, + {.code_and_extra = 0x014,.length2 = 0x7}, + {.code_and_extra = 0x054,.length2 = 0x7}, + {.code_and_extra = 0x034,.length2 = 0x7}, + {.code_and_extra = 0x074,.length2 = 0x7}, + {.code_and_extra = 0x003,.length2 = 0x8}, + {.code_and_extra = 0x083,.length2 = 0x8}, + {.code_and_extra = 0x043,.length2 = 0x8}, + {.code_and_extra = 0x0c3,.length2 = 0x8}, + {.code_and_extra = 0x023,.length2 = 0x8}, + {.code_and_extra = 0x0a3,.length2 = 0x8}, + {.code_and_extra = 0x063,.length2 = 0x8}, + {.code_and_extra = 0x0e3,.length2 = 0x8}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}, + {.code_and_extra = 0x000,.length2 = 0x0}}, + .dist_table = { + {.code_and_extra = 0x000,.length2 = 0x5}, + {.code_and_extra = 0x010,.length2 = 0x5}, + {.code_and_extra = 0x008,.length2 = 0x5}, + {.code_and_extra = 0x018,.length2 = 0x5}, + {.code_and_extra = 0x10004,.length2 = 0x5}, + {.code_and_extra = 0x10014,.length2 = 0x5}, + {.code_and_extra = 0x2000c,.length2 = 0x5}, + {.code_and_extra = 0x2001c,.length2 = 0x5}, + {.code_and_extra = 0x30002,.length2 = 0x5}, + {.code_and_extra = 0x30012,.length2 = 0x5}, + {.code_and_extra = 0x4000a,.length2 = 0x5}, + {.code_and_extra = 0x4001a,.length2 = 0x5}, + {.code_and_extra = 0x50006,.length2 = 0x5}, + {.code_and_extra = 0x50016,.length2 = 0x5}, + {.code_and_extra = 0x6000e,.length2 = 0x5}, + {.code_and_extra = 0x6001e,.length2 = 0x5}, + {.code_and_extra = 0x70001,.length2 = 0x5}, + {.code_and_extra = 0x70011,.length2 = 0x5}, + {.code_and_extra = 0x80009,.length2 = 0x5}, + {.code_and_extra = 0x80019,.length2 = 0x5}, + {.code_and_extra = 0x90005,.length2 = 0x5}, + {.code_and_extra = 0x90015,.length2 = 0x5}, + {.code_and_extra = 0xa000d,.length2 = 0x5}, + {.code_and_extra = 0xa001d,.length2 = 0x5}, + {.code_and_extra = 0xb0003,.length2 = 0x5}, + {.code_and_extra = 0xb0013,.length2 = 0x5}, + {.code_and_extra = 0xc000b,.length2 = 0x5}, + {.code_and_extra = 0xc001b,.length2 = 0x5}, + {.code_and_extra = 0xd0007,.length2 = 0x5}, + {.code_and_extra = 0xd0017,.length2 = 0x5}, + {.code_and_extra = 0x000,.length2 = 0x0}} +}; + +struct slver { + uint16_t snum; + uint8_t ver; + uint8_t core; +}; + +/* Version info */ +struct slver isal_update_histogram_slver_00010085; +struct slver isal_update_histogram_slver = { 0x0085, 0x01, 0x00 }; + +struct slver isal_create_hufftables_slver_00010086; +struct slver isal_create_hufftables_slver = { 0x0086, 0x01, 0x00 }; + +struct slver isal_create_hufftables_subset_slver_00010087; +struct slver isal_create_hufftables_subset_slver = { 0x0087, 0x01, 0x00 }; + +extern uint32_t build_huff_tree(struct heap_tree *heap, uint64_t heap_size, uint64_t node_ptr); +extern void build_heap(uint64_t * heap, uint64_t heap_size); + +static const uint8_t bitrev8[0x100] = { + 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, + 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, + 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, + 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, + 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, + 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, + 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, + 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, + 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, + 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, + 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, + 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA, + 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, + 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, + 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, + 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, + 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, + 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1, + 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, + 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, + 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, + 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, + 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, + 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, + 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, + 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, + 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, + 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, + 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, + 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, + 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, + 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF +}; + +// bit reverse low order LENGTH bits in code, and return result in low order bits +static inline uint16_t bit_reverse(uint16_t code, uint32_t length) { - uint16_t index; - uint16_t parent; - assert(heap->size < MAX_HISTHEAP_SIZE); - index = heap->size; - heap->size += 1; - parent = (index - 1) / 2; - while ((index != 0) && (heap->tree[parent].frequency > element.frequency)) { - heap->tree[index] = heap->tree[parent]; - index = parent; - parent = (index - 1) / 2; - - } - heap->tree[index] = element; - - return index; + code = (bitrev8[code & 0x00FF] << 8) | (bitrev8[code >> 8]); + return (code >> (16 - length)); } -struct huff_tree heap_pop(struct histheap *heap) -{ - struct huff_tree root, temp; - uint16_t index = 0; - uint16_t child = 1; - assert(heap->size > 0); - root = heap->tree[index]; - heap->size--; - heap->tree[index] = heap->tree[heap->size]; - - while (child + 1 < heap->size) { - if (heap->tree[child].frequency < heap->tree[index].frequency - || heap->tree[child + 1].frequency < heap->tree[index].frequency) { - if (heap->tree[child].frequency > heap->tree[child + 1].frequency) - child += 1; - temp = heap->tree[index]; - heap->tree[index] = heap->tree[child]; - heap->tree[child] = temp; - index = child; - child = 2 * child + 1; - } else { - break; - } - } - - if (child < heap->size) { - if (heap->tree[child].frequency < heap->tree[index].frequency) { - temp = heap->tree[index]; - heap->tree[index] = heap->tree[child]; - heap->tree[child] = temp; - } - } - - return root; - -} - -struct linked_list_node *pop_from_front(struct linked_list *list) -{ - struct linked_list_node *temp; - - temp = list->start; - if (list->start != NULL) { - list->start = list->start->next; - if (list->start != NULL) - list->start->previous = NULL; - else - list->end = NULL; - list->length -= 1; - } - return temp; -} - -void append_to_front(struct linked_list *list, struct linked_list_node *new_element) -{ - new_element->next = list->start; - new_element->previous = NULL; - if (list->start != NULL) - list->start->previous = new_element; - else - list->end = new_element; - list->start = new_element; - list->length += 1; - - return; -} - -void append_to_back(struct linked_list *list, struct linked_list_node *new_element) -{ - new_element->previous = list->end; - new_element->next = NULL; - if (list->end != NULL) - list->end->next = new_element; - else - list->start = new_element; - list->end = new_element; - list->length += 1; - - return; -} - -void isal_update_histogram(uint8_t * start_stream, int length, - struct isal_huff_histogram *histogram) +void isal_update_histogram_base(uint8_t * start_stream, int length, + struct isal_huff_histogram *histogram) { uint32_t literal = 0, hash; - uint8_t *last_seen[HASH_SIZE]; - uint8_t *current, *seen, *end_stream, *next_hash, *end; + uint16_t seen, *last_seen = histogram->hash_table; + uint8_t *current, *end_stream, *next_hash, *end; uint32_t match_length; uint32_t dist; uint64_t *lit_len_histogram = histogram->lit_len_histogram; @@ -157,18 +681,20 @@ void isal_update_histogram(uint8_t * start_stream, int length, return; end_stream = start_stream + length; - memset(last_seen, 0, sizeof(last_seen)); /* Initialize last_seen to be 0. */ + memset(last_seen, 0, sizeof(histogram->hash_table)); /* Initialize last_seen to be 0. */ for (current = start_stream; current < end_stream - 3; current++) { literal = *(uint32_t *) current; hash = compute_hash(literal) & HASH_MASK; seen = last_seen[hash]; - last_seen[hash] = current; - dist = current - seen; - if (dist < D) { - match_length = compare258(seen, current, end_stream - current); + last_seen[hash] = (current - start_stream) & 0xFFFF; + dist = (current - start_stream - seen) & 0xFFFF; + if (dist - 1 < D - 1) { + assert(start_stream <= current - dist); + match_length = + compare258(current - dist, current, end_stream - current); if (match_length >= SHORTEST_MATCH) { next_hash = current; -#ifdef LIMIT_HASH_UPDATE +#ifdef ISAL_LIMIT_HASH_UPDATE end = next_hash + 3; #else end = next_hash + match_length; @@ -179,7 +705,7 @@ void isal_update_histogram(uint8_t * start_stream, int length, for (; next_hash < end; next_hash++) { literal = *(uint32_t *) next_hash; hash = compute_hash(literal) & HASH_MASK; - last_seen[hash] = next_hash; + last_seen[hash] = (next_hash - start_stream) & 0xFFFF; } dist_histogram[convert_dist_to_dist_sym(dist)] += 1; @@ -194,10 +720,10 @@ void isal_update_histogram(uint8_t * start_stream, int length, literal = literal >> 8; hash = compute_hash(literal) & HASH_MASK; seen = last_seen[hash]; - last_seen[hash] = current; - dist = current - seen; + last_seen[hash] = (current - start_stream) & 0xFFFF; + dist = (current - start_stream - seen) & 0xFFFF; if (dist < D) { - match_length = compare258(seen, current, end_stream - current); + match_length = compare258(current - dist, current, end_stream - current); if (match_length >= SHORTEST_MATCH) { dist_histogram[convert_dist_to_dist_sym(dist)] += 1; lit_len_histogram[convert_length_to_len_sym(match_length)] += 1; @@ -271,229 +797,186 @@ uint32_t convert_length_to_len_sym(uint32_t length) return 285; } -struct huff_tree create_symbol_subset_huff_tree(struct huff_tree *tree_array, - uint64_t * histogram, uint32_t size) -{ - /* Assumes there are at least 2 symbols. */ - int i; - uint32_t node_index; - struct huff_tree tree; - struct histheap heap; - - heap.size = 0; +// Upon return, codes[] contains the code lengths, +// and bl_count is the count of the lengths - tree.right = tree.left = NULL; +/* Init heap with the histogram, and return the histogram size */ +static inline uint32_t init_heap32(struct heap_tree *heap_space, uint32_t * histogram, + uint32_t hist_size) +{ + uint32_t heap_size, i; - /* Intitializes heap for construction of the huffman tree */ - for (i = 0; i < size; i++) { - tree.value = i; - tree.frequency = histogram[i]; - tree_array[i] = tree; + memset(heap_space, 0, sizeof(struct heap_tree)); - /* If symbol does not appear (has frequency 0), ignore it. */ - if (tree_array[i].frequency != 0) - heap_push(tree, &heap); + heap_size = 0; + for (i = 0; i < hist_size; i++) { + if (histogram[i] != 0) + heap_space->heap[++heap_size] = + (((uint64_t) histogram[i]) << FREQ_SHIFT) | i; } - node_index = size; - - /* Construct the huffman tree */ - while (heap.size > 1) { - - tree = heap_pop(&heap); - tree_array[node_index].frequency = tree.frequency; - tree_array[node_index].left = &tree_array[tree.value]; - - tree = heap_pop(&heap); - tree_array[node_index].frequency += tree.frequency; - tree_array[node_index].right = &tree_array[tree.value]; - - tree_array[node_index].value = node_index; - heap_push(tree_array[node_index], &heap); - - node_index += 1; + // make sure heap has at least two elements in it + if (heap_size < 2) { + if (heap_size == 0) { + heap_space->heap[1] = 1ULL << FREQ_SHIFT; + heap_space->heap[2] = (1ULL << FREQ_SHIFT) | 1; + heap_size = 2; + } else { + // heap size == 1 + if (histogram[0] == 0) + heap_space->heap[2] = 1ULL << FREQ_SHIFT; + else + heap_space->heap[2] = (1ULL << FREQ_SHIFT) | 1; + heap_size = 2; + } } - return heap_pop(&heap); + build_heap(heap_space->heap, heap_size); + + return heap_size; } -struct huff_tree create_huff_tree(struct huff_tree *tree_array, uint64_t * histogram, - uint32_t size) +static inline uint32_t init_heap64(struct heap_tree *heap_space, uint64_t * histogram, + uint64_t hist_size) { - int i; - uint32_t node_index; - struct huff_tree tree; - struct histheap heap; + uint32_t heap_size, i; - heap.size = 0; + memset(heap_space, 0, sizeof(struct heap_tree)); - tree.right = tree.left = NULL; - - /* Intitializes heap for construction of the huffman tree */ - for (i = 0; i < size; i++) { - tree.value = i; - tree.frequency = histogram[i]; - tree_array[i] = tree; - heap_push(tree, &heap); + heap_size = 0; + for (i = 0; i < hist_size; i++) { + if (histogram[i] != 0) + heap_space->heap[++heap_size] = ((histogram[i]) << FREQ_SHIFT) | i; } - node_index = size; - - /* Construct the huffman tree */ - while (heap.size > 1) { - - tree = heap_pop(&heap); - tree_array[node_index].frequency = tree.frequency; - tree_array[node_index].left = &tree_array[tree.value]; - - tree = heap_pop(&heap); - tree_array[node_index].frequency += tree.frequency; - tree_array[node_index].right = &tree_array[tree.value]; - - tree_array[node_index].value = node_index; - heap_push(tree_array[node_index], &heap); - - node_index += 1; + // make sure heap has at least two elements in it + if (heap_size < 2) { + if (heap_size == 0) { + heap_space->heap[1] = 1ULL << FREQ_SHIFT; + heap_space->heap[2] = (1ULL << FREQ_SHIFT) | 1; + heap_size = 2; + } else { + // heap size == 1 + if (histogram[0] == 0) + heap_space->heap[2] = 1ULL << FREQ_SHIFT; + else + heap_space->heap[2] = (1ULL << FREQ_SHIFT) | 1; + heap_size = 2; + } } - return heap_pop(&heap); + build_heap(heap_space->heap, heap_size); + + return heap_size; } -int create_huff_lookup(struct huff_code *huff_lookup_table, int table_length, - struct huff_tree root, uint8_t max_depth) +static inline uint32_t init_heap64_complete(struct heap_tree *heap_space, uint64_t * histogram, + uint64_t hist_size) { - /* Used to create a count of number of elements with a given code length */ - uint16_t count[MAX_HUFF_TREE_DEPTH + 1]; + uint32_t heap_size, i; - memset(count, 0, sizeof(count)); + memset(heap_space, 0, sizeof(struct heap_tree)); - if (find_code_lengths(huff_lookup_table, count, root, max_depth) != 0) - return 1; + heap_size = 0; + for (i = 0; i < hist_size; i++) + heap_space->heap[++heap_size] = ((histogram[i]) << FREQ_SHIFT) | i; - set_huff_codes(huff_lookup_table, table_length, count); + build_heap(heap_space->heap, heap_size); - return 0; + return heap_size; } -int find_code_lengths(struct huff_code *huff_lookup_table, uint16_t * count, - struct huff_tree root, uint8_t max_depth) +static inline uint32_t fix_code_lens(struct heap_tree *heap_space, uint32_t root_node, + uint32_t * bl_count, uint32_t max_code_len) { - struct linked_list depth_array[MAX_HUFF_TREE_DEPTH + 2]; - struct linked_list_node linked_lists[MAX_HISTHEAP_SIZE]; - struct linked_list_node *temp; - uint16_t extra_nodes = 0; - int i, j; - - memset(depth_array, 0, sizeof(depth_array)); - memset(linked_lists, 0, sizeof(linked_lists)); - for (i = 0; i < MAX_HISTHEAP_SIZE; i++) - linked_lists[i].value = i; - - huffman_tree_traversal(depth_array, linked_lists, &extra_nodes, max_depth, root, 0); - - /* This for loop fixes up the huffman tree to have a maximum depth not exceeding - * max_depth. This algorithm works by removing all elements below max_depth, - * filling up the empty leafs which are created with elements form the huffman - * tree and then iteratively pushing down the least frequent leaf that is above - * max_depth to a depth 1 lower, and moving up a leaf below max_depth to that - * same depth.*/ - for (i = MAX_HUFF_TREE_DEPTH + 1; i > max_depth; i--) { - - /* find element to push up the tree */ - while (depth_array[i].start != NULL) { - if (extra_nodes > 0) { - temp = pop_from_front(&depth_array[i]); - append_to_back(&depth_array[max_depth], temp); - extra_nodes -= 1; - - } else { - assert(depth_array[max_depth].length % 2 == 0); - assert(extra_nodes == 0); - - /* find element to push down in the tree */ - for (j = max_depth - 1; j >= 0; j--) - if (depth_array[j].start != NULL) - break; - - /* No element available to push down further. */ - if (j < 0) - return 1; - - temp = pop_from_front(&depth_array[i]); - append_to_front(&depth_array[j + 1], temp); - - temp = pop_from_front(&depth_array[j]); - append_to_back(&depth_array[j + 1], temp); + struct tree_node *tree = heap_space->tree; + uint64_t *code_len_count = heap_space->code_len_count; + uint32_t i, j, k, child, depth, code_len; + + // compute code lengths and code length counts + code_len = 0; + j = root_node; + for (i = root_node; i <= HEAP_TREE_NODE_START; i++) { + child = tree[i].child; + if (child > MAX_HISTHEAP_SIZE) { + depth = 1 + tree[i].depth; + + tree[child].depth = depth; + tree[child - 1].depth = depth; + } else { + tree[j++] = tree[i]; + depth = tree[i].depth; + while (code_len < depth) { + code_len++; + code_len_count[code_len] = 0; } + code_len_count[depth]++; } } - for (i = 0; i < MAX_HUFF_TREE_DEPTH + 2; i++) { - temp = depth_array[i].start; + if (code_len > max_code_len) { + while (code_len > max_code_len) { + assert(code_len_count[code_len] > 1); + for (i = max_code_len - 1; i != 0; i--) + if (code_len_count[i] != 0) + break; + assert(i != 0); + code_len_count[i]--; + code_len_count[i + 1] += 2; + code_len_count[code_len - 1]++; + code_len_count[code_len] -= 2; + if (code_len_count[code_len] == 0) + code_len--; + } + + for (i = 1; i <= code_len; i++) + bl_count[i] = code_len_count[i]; + for (; i <= max_code_len; i++) + bl_count[i] = 0; - while (temp != NULL) { - huff_lookup_table[temp->value].length = i; - count[i] += 1; - temp = temp->next; + for (k = 1; code_len_count[k] == 0; k++) ; + for (i = root_node; i < j; i++) { + tree[i].depth = k; + code_len_count[k]--; + for (; code_len_count[k] == 0; k++) ; } + } else { + for (i = 1; i <= code_len; i++) + bl_count[i] = code_len_count[i]; + for (; i <= max_code_len; i++) + bl_count[i] = 0; } - return 0; + + return j; } -void huffman_tree_traversal(struct linked_list *depth_array, - struct linked_list_node *linked_lists, uint16_t * extra_nodes, - uint8_t max_depth, struct huff_tree current_node, - uint16_t current_depth) +static inline void +gen_huff_code_lens(struct heap_tree *heap_space, uint32_t heap_size, uint32_t * bl_count, + struct huff_code *codes, uint32_t codes_count, uint32_t max_code_len) { - /* This algorithm performs a traversal of the huffman tree. It is setup - * to visit the leaves in order of frequency and bin elements into a - * linked list by depth.*/ - if (current_node.left == NULL) { - if (current_depth < MAX_HUFF_TREE_DEPTH + 1) - append_to_front(&depth_array[current_depth], - &linked_lists[current_node.value]); - else - append_to_front(&depth_array[MAX_HUFF_TREE_DEPTH + 1], - &linked_lists[current_node.value]); - return; - - } else if (current_depth == max_depth) - *extra_nodes += 1; + struct tree_node *tree = heap_space->tree; + uint32_t root_node = HEAP_TREE_NODE_START, node_ptr; + uint32_t end_node; - if (current_node.left->frequency < current_node.right->frequency) { - huffman_tree_traversal(depth_array, linked_lists, extra_nodes, max_depth, - *current_node.right, current_depth + 1); - huffman_tree_traversal(depth_array, linked_lists, extra_nodes, max_depth, - *current_node.left, current_depth + 1); + root_node = build_huff_tree(heap_space, heap_size, root_node); - } else { - huffman_tree_traversal(depth_array, linked_lists, extra_nodes, max_depth, - *current_node.left, current_depth + 1); - huffman_tree_traversal(depth_array, linked_lists, extra_nodes, max_depth, - *current_node.right, current_depth + 1); - } + end_node = fix_code_lens(heap_space, root_node, bl_count, max_code_len); -} + memset(codes, 0, codes_count * sizeof(*codes)); + for (node_ptr = root_node; node_ptr < end_node; node_ptr++) + codes[tree[node_ptr].child].length = tree[node_ptr].depth; -/* - * Returns integer with first length bits reversed and all higher bits zeroed - */ -uint16_t bit_reverse(uint16_t bits, uint8_t length) -{ - bits = ((bits >> 1) & 0x55555555) | ((bits & 0x55555555) << 1); // swap bits - bits = ((bits >> 2) & 0x33333333) | ((bits & 0x33333333) << 2); // swap pairs - bits = ((bits >> 4) & 0x0F0F0F0F) | ((bits & 0x0F0F0F0F) << 4); // swap nibbles - bits = ((bits >> 8) & 0x00FF00FF) | ((bits & 0x00FF00FF) << 8); // swap bytes - return bits >> (16 - length); } -void set_huff_codes(struct huff_code *huff_code_table, int table_length, uint16_t * count) +inline uint32_t set_huff_codes(struct huff_code *huff_code_table, int table_length, + uint32_t * count) { /* Uses the algorithm mentioned in the deflate standard, Rfc 1951. */ int i; uint16_t code = 0; uint16_t next_code[MAX_HUFF_TREE_DEPTH + 1]; + uint32_t max_code = 0; next_code[0] = code; @@ -506,62 +989,103 @@ void set_huff_codes(struct huff_code *huff_code_table, int table_length, uint16_ bit_reverse(next_code[huff_code_table[i].length], huff_code_table[i].length); next_code[huff_code_table[i].length] += 1; + max_code = i; } } - return; + return max_code; } -int create_header(uint8_t * header, uint32_t header_length, struct huff_code *lit_huff_table, - struct huff_code *dist_huff_table, uint32_t end_of_block) +// on input, codes contain the code lengths +// on output, code contains: +// 23:16 code length +// 15:0 code value in low order bits +// returns max code value +static inline uint32_t set_dist_huff_codes(struct huff_code *codes, uint32_t * bl_count) { - int i; - uint64_t histogram[HUFF_LEN]; - uint16_t huffman_rep[LIT_LEN + DIST_LEN]; - uint16_t extra_bits[LIT_LEN + DIST_LEN]; - uint16_t length; - struct huff_tree root; - struct huff_tree tree_array[2 * HUFF_LEN - 1]; - struct huff_code lookup_table[HUFF_LEN]; - struct huff_code combined_table[LIT_LEN + DIST_LEN]; + uint32_t code, code_len, bits, i; + uint32_t next_code[MAX_DEFLATE_CODE_LEN + 1]; + uint32_t max_code = 0; + const uint32_t num_codes = DIST_LEN; + + code = bl_count[0] = 0; + for (bits = 1; bits <= MAX_HUFF_TREE_DEPTH; bits++) { + code = (code + bl_count[bits - 1]) << 1; + next_code[bits] = code; + } + for (i = 0; i < num_codes; i++) { + code_len = codes[i].length; + if (code_len != 0) { + codes[i].code = bit_reverse(next_code[code_len], code_len); + codes[i].extra_bit_count = dist_code_extra_bits[i]; + next_code[code_len] += 1; + max_code = i; + } + } + return max_code; +} - /* hlit, hdist, and hclen are defined in RFC 1951 page 13 */ - uint32_t hlit, hdist, hclen; +int create_huffman_header(struct BitBuf2 *header_bitbuf, + struct huff_code *lookup_table, + struct rl_code *huffman_rep, + uint16_t huffman_rep_length, uint32_t end_of_block, + uint32_t hclen, uint32_t hlit, uint32_t hdist) +{ + /* hlit, hdist, hclen are as defined in the deflate standard, head is the + * first three deflate header bits.*/ + int i; uint64_t bit_count; + uint64_t data; + struct huff_code huffman_value; + const uint32_t extra_bits[3] = { 2, 3, 7 }; - memset(lookup_table, 0, sizeof(lookup_table)); + bit_count = buffer_bits_used(header_bitbuf); - /* Calculate hlit */ - for (i = LIT_LEN - 1; i > 256; i--) - if (lit_huff_table[i].length != 0) - break; + data = (end_of_block ? 5 : 4) | (hlit << 3) | (hdist << 8) | (hclen << 13); + data |= ((lookup_table[code_length_code_order[0]].length) << DYN_HDR_START_LEN); + write_bits(header_bitbuf, data, DYN_HDR_START_LEN + 3); + data = 0; + for (i = hclen + 3; i >= 1; i--) + data = (data << 3) | lookup_table[code_length_code_order[i]].length; - hlit = i - 256; + write_bits(header_bitbuf, data, (hclen + 3) * 3); - /* Calculate hdist */ - for (i = DIST_LEN - 1; i > 0; i--) - if (dist_huff_table[i].length != 0) - break; + for (i = 0; i < huffman_rep_length; i++) { + huffman_value = lookup_table[huffman_rep[i].code]; - hdist = i; + write_bits(header_bitbuf, (uint64_t) huffman_value.code, + (uint32_t) huffman_value.length); - /* Combine huffman tables for run length encoding */ - for (i = 0; i < 257 + hlit; i++) - combined_table[i] = lit_huff_table[i]; - for (i = 0; i < 1 + hdist; i++) - combined_table[i + hlit + 257] = dist_huff_table[i]; + if (huffman_rep[i].code > 15) { + write_bits(header_bitbuf, (uint64_t) huffman_rep[i].extra_bits, + (uint32_t) extra_bits[huffman_rep[i].code - 16]); + } + } + bit_count = buffer_bits_used(header_bitbuf) - bit_count; + + return bit_count; +} - memset(extra_bits, 0, LIT_LEN + DIST_LEN); - memset(histogram, 0, sizeof(histogram)); +inline int create_header(struct BitBuf2 *header_bitbuf, struct rl_code *huffman_rep, + uint32_t length, uint64_t * histogram, uint32_t hlit, + uint32_t hdist, uint32_t end_of_block) +{ + int i; + + uint32_t heap_size; + struct heap_tree heap_space; + uint32_t code_len_count[MAX_HUFF_TREE_DEPTH + 1]; + struct huff_code lookup_table[HUFF_LEN]; - /* Create a run length encoded representation of the literal/lenght and - * distance huffman trees. */ - length = create_huffman_rep(huffman_rep, histogram, extra_bits, - combined_table, hlit + 257 + hdist + 1); + /* hlit, hdist, and hclen are defined in RFC 1951 page 13 */ + uint32_t hclen; + uint64_t bit_count; /* Create a huffman tree to encode run length encoded representation. */ - root = create_symbol_subset_huff_tree(tree_array, histogram, HUFF_LEN); - create_huff_lookup(lookup_table, HUFF_LEN, root, 7); + heap_size = init_heap64(&heap_space, histogram, HUFF_LEN); + gen_huff_code_lens(&heap_space, heap_size, code_len_count, + (struct huff_code *)lookup_table, HUFF_LEN, 7); + set_huff_codes(lookup_table, HUFF_LEN, code_len_count); /* Calculate hclen */ for (i = CODE_LEN_CODES - 1; i > 3; i--) /* i must be at least 4 */ @@ -571,150 +1095,120 @@ int create_header(uint8_t * header, uint32_t header_length, struct huff_code *li hclen = i - 3; /* Generate actual header. */ - bit_count = create_huffman_header(header, header_length, lookup_table, huffman_rep, - extra_bits, length, end_of_block, hclen, hlit, - hdist); + bit_count = create_huffman_header(header_bitbuf, lookup_table, huffman_rep, + length, end_of_block, hclen, hlit, hdist); return bit_count; } -uint16_t create_huffman_rep(uint16_t * huffman_rep, uint64_t * histogram, - uint16_t * extra_bits, struct huff_code * huff_table, uint16_t len) +static inline + struct rl_code *write_rl(struct rl_code *pout, uint16_t last_len, uint32_t run_len, + uint64_t * counts) { - uint16_t current_in_index = 0, current_out_index = 0, run_length, last_code; - - while (current_in_index < len) { - last_code = huff_table[current_in_index].length; - run_length = 0; - - while (current_in_index < len - && last_code == huff_table[current_in_index].length) { - run_length += 1; - current_in_index += 1; + if (last_len == 0) { + while (run_len > 138) { + pout->code = 18; + pout->extra_bits = 138 - 11; + pout++; + run_len -= 138; + counts[18]++; } - - current_out_index = flush_repeats(huffman_rep, histogram, extra_bits, - last_code, run_length, current_out_index); - } - return current_out_index; -} - -uint16_t flush_repeats(uint16_t * huffman_rep, uint64_t * histogram, uint16_t * extra_bits, - uint16_t last_code, uint16_t run_length, uint16_t current_index) -{ - int j; - - if (last_code != 0 && last_code < HUFF_LEN && run_length > 0) { - huffman_rep[current_index++] = last_code; - histogram[last_code] += 1; - run_length -= 1; - - } - - if (run_length < SHORTEST_MATCH) { - for (j = 0; j < run_length; j++) { - huffman_rep[current_index++] = last_code; - histogram[last_code] += 1; + // 1 <= run_len <= 138 + if (run_len > 10) { + pout->code = 18; + pout->extra_bits = run_len - 11; + pout++; + counts[18]++; + } else if (run_len > 2) { + pout->code = 17; + pout->extra_bits = run_len - 3; + pout++; + counts[17]++; + } else if (run_len == 1) { + pout->code = 0; + pout->extra_bits = 0; + pout++; + counts[0]++; + } else { + assert(run_len == 2); + pout[0].code = 0; + pout[0].extra_bits = 0; + pout[1].code = 0; + pout[1].extra_bits = 0; + pout += 2; + counts[0] += 2; } } else { - if (last_code == 0) { - /* The values 138 is the maximum repeat length - * represented with code 18. The value 10 is the maximum - * repeate length represented with 17. */ - for (; run_length > 138; run_length -= 138) { - huffman_rep[current_index] = 0x12; - extra_bits[current_index++] = 0x7F7; - histogram[18]++; + // last_len != 0 + pout->code = last_len; + pout->extra_bits = 0; + pout++; + counts[last_len]++; + run_len--; + if (run_len != 0) { + while (run_len > 6) { + pout->code = 16; + pout->extra_bits = 6 - 3; + pout++; + run_len -= 6; + counts[16]++; } - - if (run_length > 10) { - huffman_rep[current_index] = 18; - extra_bits[current_index++] = ((run_length - 11) << 4) | 7; - histogram[18] += 1; - - } else if (run_length >= SHORTEST_MATCH) { - huffman_rep[current_index] = 17; - extra_bits[current_index++] = ((run_length - 3) << 4) | 3; - histogram[17] += 1; - - } else { - for (j = 0; j < run_length; j++) { - huffman_rep[current_index++] = last_code; - histogram[last_code] += 1; - } - } - - } else { - for (; run_length > 6; run_length -= 6) { - huffman_rep[current_index] = 0x10; - extra_bits[current_index++] = 0x32; - histogram[16]++; - } - - if (run_length >= SHORTEST_MATCH) { - huffman_rep[current_index] = 16; - extra_bits[current_index++] = ((run_length - 3) << 4) | 2; - histogram[16] += 1; - - } else { - for (j = 0; j < run_length; j++) { - huffman_rep[current_index++] = last_code; - histogram[last_code] += 1; - } + // 1 <= run_len <= 6 + switch (run_len) { + case 1: + pout->code = last_len; + pout->extra_bits = 0; + pout++; + counts[last_len]++; + break; + case 2: + pout[0].code = last_len; + pout[0].extra_bits = 0; + pout[1].code = last_len; + pout[1].extra_bits = 0; + pout += 2; + counts[last_len] += 2; + break; + default: // 3...6 + pout->code = 16; + pout->extra_bits = run_len - 3; + pout++; + counts[16]++; } } - } - - return current_index; + return pout; } -int create_huffman_header(uint8_t * header, uint32_t header_length, - struct huff_code *lookup_table, uint16_t * huffman_rep, - uint16_t * extra_bits, uint16_t huffman_rep_length, - uint32_t end_of_block, uint32_t hclen, uint32_t hlit, uint32_t hdist) +// convert codes into run-length symbols, write symbols into OUT +// generate histogram into COUNTS (assumed to be initialized to 0) +// Format of OUT: +// 4:0 code (0...18) +// 15:8 Extra bits (0...127) +// returns number of symbols in out +static inline uint32_t rl_encode(uint16_t * codes, uint32_t num_codes, uint64_t * counts, + struct rl_code *out) { - /* hlit, hdist, hclen are as defined in the deflate standard, head is the - * first three deflate header bits.*/ - int i; - uint32_t head; - uint64_t bit_count; - struct huff_code huffman_value; - struct BitBuf2 header_bitbuf; - - if (end_of_block) - head = 0x05; - else - head = 0x04; - - set_buf(&header_bitbuf, header, header_length); - init(&header_bitbuf); - - write_bits(&header_bitbuf, (head | (hlit << 3) | (hdist << 8) | (hclen << 13)), - DYN_HDR_START_LEN); - - uint64_t tmp = 0; - for (i = hclen + 3; i >= 0; i--) { - tmp = (tmp << 3) | lookup_table[code_length_code_order[i]].length; - } - - write_bits(&header_bitbuf, tmp, (hclen + 4) * 3); - - for (i = 0; i < huffman_rep_length; i++) { - huffman_value = lookup_table[huffman_rep[i]]; - - write_bits(&header_bitbuf, (uint64_t) huffman_value.code, - (uint32_t) huffman_value.length); - - if (huffman_rep[i] > 15) { - write_bits(&header_bitbuf, (uint64_t) extra_bits[i] >> 4, - (uint32_t) extra_bits[i] & 0xF); + uint32_t i, run_len; + uint16_t last_len, len; + struct rl_code *pout; + + pout = out; + last_len = codes[0]; + run_len = 1; + for (i = 1; i < num_codes; i++) { + len = codes[i]; + if (len == last_len) { + run_len++; + continue; } + pout = write_rl(pout, last_len, run_len, counts); + last_len = len; + run_len = 1; } - bit_count = 8 * buffer_used(&header_bitbuf) + header_bitbuf.m_bit_count; - flush(&header_bitbuf); + pout = write_rl(pout, last_len, run_len, counts); - return bit_count; + return (uint32_t) (pout - out); } void create_code_tables(uint16_t * code_table, uint8_t * code_length_table, uint32_t length, @@ -832,11 +1326,20 @@ int are_hufftables_useable(struct huff_code *lit_len_hufftable, int isal_create_hufftables(struct isal_hufftables *hufftables, struct isal_huff_histogram *histogram) { - struct huff_tree lit_tree, dist_tree; - struct huff_tree lit_tree_array[2 * LIT_LEN - 1], dist_tree_array[2 * DIST_LEN - 1]; struct huff_code lit_huff_table[LIT_LEN], dist_huff_table[DIST_LEN]; uint64_t bit_count; - int max_dist = convert_dist_to_dist_sym(IGZIP_D); + int max_dist = convert_dist_to_dist_sym(IGZIP_HIST_SIZE); + struct heap_tree heap_space; + uint32_t heap_size; + uint32_t code_len_count[MAX_HUFF_TREE_DEPTH + 1]; + struct BitBuf2 header_bitbuf; + uint32_t max_lit_len_sym; + uint32_t max_dist_sym; + uint32_t hlit, hdist, i; + uint16_t combined_table[LIT_LEN + DIST_LEN]; + uint64_t count_histogram[HUFF_LEN]; + struct rl_code rl_huff[LIT_LEN + DIST_LEN]; + uint32_t rl_huff_len; uint32_t *dist_table = hufftables->dist_table; uint32_t *len_table = hufftables->len_table; @@ -849,44 +1352,61 @@ int isal_create_hufftables(struct isal_hufftables *hufftables, uint64_t *dist_histogram = histogram->dist_histogram; memset(hufftables, 0, sizeof(struct isal_hufftables)); - memset(lit_tree_array, 0, sizeof(lit_tree_array)); - memset(dist_tree_array, 0, sizeof(dist_tree_array)); - memset(lit_huff_table, 0, sizeof(lit_huff_table)); - memset(dist_huff_table, 0, sizeof(dist_huff_table)); - lit_tree = create_huff_tree(lit_tree_array, lit_len_histogram, LIT_LEN); - dist_tree = create_huff_tree(dist_tree_array, dist_histogram, max_dist + 1); + heap_size = init_heap64_complete(&heap_space, lit_len_histogram, LIT_LEN); + gen_huff_code_lens(&heap_space, heap_size, code_len_count, + (struct huff_code *)lit_huff_table, LIT_LEN, MAX_DEFLATE_CODE_LEN); + max_lit_len_sym = set_huff_codes(lit_huff_table, LIT_LEN, code_len_count); - if (create_huff_lookup(lit_huff_table, LIT_LEN, lit_tree, MAX_DEFLATE_CODE_LEN) > 0) - return INVALID_LIT_LEN_HUFFCODE; - - if (create_huff_lookup(dist_huff_table, DIST_LEN, dist_tree, MAX_DEFLATE_CODE_LEN) > 0) - return INVALID_DIST_HUFFCODE; + heap_size = init_heap64_complete(&heap_space, dist_histogram, DIST_LEN); + gen_huff_code_lens(&heap_space, heap_size, code_len_count, + (struct huff_code *)dist_huff_table, max_dist, + MAX_DEFLATE_CODE_LEN); + max_dist_sym = set_huff_codes(dist_huff_table, DIST_LEN, code_len_count); if (are_hufftables_useable(lit_huff_table, dist_huff_table)) { - if (create_huff_lookup - (lit_huff_table, LIT_LEN, lit_tree, MAX_SAFE_LIT_CODE_LEN) > 0) - return INVALID_LIT_LEN_HUFFCODE; - - if (create_huff_lookup - (dist_huff_table, DIST_LEN, dist_tree, MAX_SAFE_DIST_CODE_LEN) > 0) - return INVALID_DIST_HUFFCODE; + heap_size = init_heap64_complete(&heap_space, lit_len_histogram, LIT_LEN); + gen_huff_code_lens(&heap_space, heap_size, code_len_count, + (struct huff_code *)lit_huff_table, LIT_LEN, + MAX_SAFE_LIT_CODE_LEN); + max_lit_len_sym = set_huff_codes(lit_huff_table, LIT_LEN, code_len_count); + + heap_size = init_heap64_complete(&heap_space, dist_histogram, DIST_LEN); + gen_huff_code_lens(&heap_space, heap_size, code_len_count, + (struct huff_code *)dist_huff_table, max_dist, + MAX_SAFE_DIST_CODE_LEN); + max_dist_sym = set_huff_codes(dist_huff_table, DIST_LEN, code_len_count); - if (are_hufftables_useable(lit_huff_table, dist_huff_table)) - return INVALID_HUFFCODE; } create_code_tables(dcodes, dcodes_sizes, DIST_LEN - DCODE_OFFSET, dist_huff_table + DCODE_OFFSET); - create_code_tables(lit_table, lit_table_sizes, LIT_TABLE_SIZE, lit_huff_table); + create_code_tables(lit_table, lit_table_sizes, IGZIP_LIT_TABLE_SIZE, lit_huff_table); create_packed_len_table(len_table, lit_huff_table); - create_packed_dist_table(dist_table, DIST_TABLE_SIZE, dist_huff_table); + create_packed_dist_table(dist_table, IGZIP_DIST_TABLE_SIZE, dist_huff_table); + + set_buf(&header_bitbuf, deflate_hdr, sizeof(deflate_hdr)); + init(&header_bitbuf); + + hlit = max_lit_len_sym - 256; + hdist = max_dist_sym; + + /* Run length encode the length and distance huffman codes */ + memset(count_histogram, 0, sizeof(count_histogram)); + for (i = 0; i < 257 + hlit; i++) + combined_table[i] = lit_huff_table[i].length; + for (i = 0; i < 1 + hdist; i++) + combined_table[i + hlit + 257] = dist_huff_table[i].length; + rl_huff_len = + rl_encode(combined_table, hlit + 257 + hdist + 1, count_histogram, rl_huff); + /* Create header */ bit_count = - create_header(deflate_hdr, sizeof(deflate_hdr), lit_huff_table, dist_huff_table, - LAST_BLOCK); + create_header(&header_bitbuf, rl_huff, rl_huff_len, + count_histogram, hlit, hdist, LAST_BLOCK); + flush(&header_bitbuf); hufftables->deflate_hdr_count = bit_count / 8; hufftables->deflate_hdr_extra_bits = bit_count % 8; @@ -897,11 +1417,20 @@ int isal_create_hufftables(struct isal_hufftables *hufftables, int isal_create_hufftables_subset(struct isal_hufftables *hufftables, struct isal_huff_histogram *histogram) { - struct huff_tree lit_tree, dist_tree; - struct huff_tree lit_tree_array[2 * LIT_LEN - 1], dist_tree_array[2 * DIST_LEN - 1]; struct huff_code lit_huff_table[LIT_LEN], dist_huff_table[DIST_LEN]; uint64_t bit_count; - int j, max_dist = convert_dist_to_dist_sym(IGZIP_D); + int max_dist = convert_dist_to_dist_sym(IGZIP_HIST_SIZE); + struct heap_tree heap_space; + uint32_t heap_size; + uint32_t code_len_count[MAX_HUFF_TREE_DEPTH + 1]; + struct BitBuf2 header_bitbuf; + uint32_t max_lit_len_sym; + uint32_t max_dist_sym; + uint32_t hlit, hdist, i; + uint16_t combined_table[LIT_LEN + DIST_LEN]; + uint64_t count_histogram[HUFF_LEN]; + struct rl_code rl_huff[LIT_LEN + DIST_LEN]; + uint32_t rl_huff_len; uint32_t *dist_table = hufftables->dist_table; uint32_t *len_table = hufftables->len_table; @@ -914,51 +1443,183 @@ int isal_create_hufftables_subset(struct isal_hufftables *hufftables, uint64_t *dist_histogram = histogram->dist_histogram; memset(hufftables, 0, sizeof(struct isal_hufftables)); - memset(lit_tree_array, 0, sizeof(lit_tree_array)); - memset(dist_tree_array, 0, sizeof(dist_tree_array)); - memset(lit_huff_table, 0, sizeof(lit_huff_table)); - memset(dist_huff_table, 0, sizeof(dist_huff_table)); - - for (j = LIT_TABLE_SIZE; j < LIT_LEN; j++) - if (lit_len_histogram[j] == 0) - lit_len_histogram[j]++; - - lit_tree = create_symbol_subset_huff_tree(lit_tree_array, lit_len_histogram, LIT_LEN); - dist_tree = create_huff_tree(dist_tree_array, dist_histogram, max_dist + 1); - if (create_huff_lookup(lit_huff_table, LIT_LEN, lit_tree, MAX_DEFLATE_CODE_LEN) > 0) - return INVALID_LIT_LEN_HUFFCODE; + heap_size = init_heap64(&heap_space, lit_len_histogram, LIT_LEN); + gen_huff_code_lens(&heap_space, heap_size, code_len_count, + (struct huff_code *)lit_huff_table, LIT_LEN, MAX_DEFLATE_CODE_LEN); + max_lit_len_sym = set_huff_codes(lit_huff_table, LIT_LEN, code_len_count); - if (create_huff_lookup(dist_huff_table, DIST_LEN, dist_tree, MAX_DEFLATE_CODE_LEN) > 0) - return INVALID_DIST_HUFFCODE; + heap_size = init_heap64_complete(&heap_space, dist_histogram, DIST_LEN); + gen_huff_code_lens(&heap_space, heap_size, code_len_count, + (struct huff_code *)dist_huff_table, max_dist, + MAX_DEFLATE_CODE_LEN); + max_dist_sym = set_huff_codes(dist_huff_table, DIST_LEN, code_len_count); if (are_hufftables_useable(lit_huff_table, dist_huff_table)) { - if (create_huff_lookup - (lit_huff_table, LIT_LEN, lit_tree, MAX_SAFE_LIT_CODE_LEN) > 0) - return INVALID_LIT_LEN_HUFFCODE; + heap_size = init_heap64_complete(&heap_space, lit_len_histogram, LIT_LEN); + gen_huff_code_lens(&heap_space, heap_size, code_len_count, + (struct huff_code *)lit_huff_table, LIT_LEN, + MAX_SAFE_LIT_CODE_LEN); + max_lit_len_sym = set_huff_codes(lit_huff_table, LIT_LEN, code_len_count); + + heap_size = init_heap64_complete(&heap_space, dist_histogram, DIST_LEN); + gen_huff_code_lens(&heap_space, heap_size, code_len_count, + (struct huff_code *)dist_huff_table, max_dist, + MAX_SAFE_DIST_CODE_LEN); + max_dist_sym = set_huff_codes(dist_huff_table, DIST_LEN, code_len_count); - if (create_huff_lookup - (dist_huff_table, DIST_LEN, dist_tree, MAX_SAFE_DIST_CODE_LEN) > 0) - return INVALID_DIST_HUFFCODE; - - if (are_hufftables_useable(lit_huff_table, dist_huff_table)) - return INVALID_HUFFCODE; } create_code_tables(dcodes, dcodes_sizes, DIST_LEN - DCODE_OFFSET, dist_huff_table + DCODE_OFFSET); - create_code_tables(lit_table, lit_table_sizes, LIT_TABLE_SIZE, lit_huff_table); + create_code_tables(lit_table, lit_table_sizes, IGZIP_LIT_TABLE_SIZE, lit_huff_table); create_packed_len_table(len_table, lit_huff_table); - create_packed_dist_table(dist_table, DIST_TABLE_SIZE, dist_huff_table); + create_packed_dist_table(dist_table, IGZIP_DIST_TABLE_SIZE, dist_huff_table); + + set_buf(&header_bitbuf, deflate_hdr, sizeof(deflate_hdr)); + init(&header_bitbuf); + + hlit = max_lit_len_sym - 256; + hdist = max_dist_sym; + + /* Run length encode the length and distance huffman codes */ + memset(count_histogram, 0, sizeof(count_histogram)); + for (i = 0; i < 257 + hlit; i++) + combined_table[i] = lit_huff_table[i].length; + for (i = 0; i < 1 + hdist; i++) + combined_table[i + hlit + 257] = dist_huff_table[i].length; + rl_huff_len = + rl_encode(combined_table, hlit + 257 + hdist + 1, count_histogram, rl_huff); + /* Create header */ bit_count = - create_header(deflate_hdr, sizeof(deflate_hdr), lit_huff_table, dist_huff_table, - LAST_BLOCK); + create_header(&header_bitbuf, rl_huff, rl_huff_len, + count_histogram, hlit, hdist, LAST_BLOCK); + flush(&header_bitbuf); hufftables->deflate_hdr_count = bit_count / 8; hufftables->deflate_hdr_extra_bits = bit_count % 8; return 0; } + +void expand_hufftables_icf(struct hufftables_icf *hufftables) +{ + uint32_t i, eb, j, k, len, code; + struct huff_code orig[21], *p_code; + struct huff_code *lit_len_codes = hufftables->lit_len_table; + struct huff_code *dist_codes = hufftables->dist_table; + + for (i = 0; i < 21; i++) + orig[i] = lit_len_codes[i + 265]; + + p_code = &lit_len_codes[265]; + + i = 0; + for (eb = 1; eb < 6; eb++) { + for (k = 0; k < 4; k++) { + len = orig[i].length; + code = orig[i++].code; + for (j = 0; j < (1u << eb); j++) { + p_code->code_and_extra = code | (j << len); + p_code->length = len + eb; + p_code++; + } + } // end for k + } // end for eb + // fix up last record + p_code[-1] = orig[i]; + + dist_codes[DIST_LEN].code_and_extra = 0; + dist_codes[DIST_LEN].length = 0; +} + +void +create_hufftables_icf(struct BitBuf2 *bb, struct hufftables_icf *hufftables, + struct isal_mod_hist *hist, uint32_t end_of_block) +{ + uint32_t bl_count[MAX_DEFLATE_CODE_LEN + 1]; + uint32_t max_ll_code, max_d_code; + struct heap_tree heap_space; + uint32_t heap_size; + struct rl_code cl_tokens[LIT_LEN + DIST_LEN]; + uint32_t num_cl_tokens; + uint64_t cl_counts[CODE_LEN_CODES]; + uint16_t combined_table[LIT_LEN + DIST_LEN]; + int i; + uint64_t compressed_len = 0; + uint64_t static_compressed_len = 3; /* The static header size */ + struct BitBuf2 bb_tmp; + + struct huff_code *ll_codes = hufftables->lit_len_table; + struct huff_code *d_codes = hufftables->dist_table; + uint32_t *ll_hist = hist->ll_hist; + uint32_t *d_hist = hist->d_hist; + struct huff_code *static_ll_codes = static_hufftables.lit_len_table; + struct huff_code *static_d_codes = static_hufftables.dist_table; + + memcpy(&bb_tmp, bb, sizeof(struct BitBuf2)); + + flatten_ll(hist->ll_hist); + + // make sure EOB is present + if (ll_hist[256] == 0) + ll_hist[256] = 1; + + heap_size = init_heap32(&heap_space, ll_hist, LIT_LEN); + gen_huff_code_lens(&heap_space, heap_size, bl_count, + ll_codes, LIT_LEN, MAX_DEFLATE_CODE_LEN); + max_ll_code = set_huff_codes(ll_codes, LIT_LEN, bl_count); + + heap_size = init_heap32(&heap_space, d_hist, DIST_LEN); + gen_huff_code_lens(&heap_space, heap_size, bl_count, d_codes, + DIST_LEN, MAX_DEFLATE_CODE_LEN); + max_d_code = set_dist_huff_codes(d_codes, bl_count); + + assert(max_ll_code >= 256); // must be EOB code + assert(max_d_code != 0); + + /* Run length encode the length and distance huffman codes */ + memset(cl_counts, 0, sizeof(cl_counts)); + + for (i = 0; i <= 256; i++) { + combined_table[i] = ll_codes[i].length; + compressed_len += ll_codes[i].length * ll_hist[i]; + static_compressed_len += static_ll_codes[i].length * ll_hist[i]; + } + + for (; i < max_ll_code + 1; i++) { + combined_table[i] = ll_codes[i].length; + compressed_len += + (ll_codes[i].length + len_code_extra_bits[i - 257]) * ll_hist[i]; + static_compressed_len += + (static_ll_codes[i].length + len_code_extra_bits[i - 257]) * ll_hist[i]; + } + + for (i = 0; i < max_d_code + 1; i++) { + combined_table[i + max_ll_code + 1] = d_codes[i].length; + compressed_len += (d_codes[i].length + dist_code_extra_bits[i]) * d_hist[i]; + static_compressed_len += + (static_d_codes[i].length + dist_code_extra_bits[i]) * d_hist[i]; + } + + expand_hufftables_icf(hufftables); + + num_cl_tokens = + rl_encode(combined_table, max_ll_code + max_d_code + 2, cl_counts, cl_tokens); + + /* Create header */ + create_header(bb, cl_tokens, num_cl_tokens, cl_counts, max_ll_code - 256, max_d_code, + end_of_block); + compressed_len += 8 * buffer_used(bb) + bb->m_bit_count; + + if (static_compressed_len < compressed_len) { + memcpy(hufftables, &static_hufftables, sizeof(struct hufftables_icf)); + expand_hufftables_icf(hufftables); + memcpy(bb, &bb_tmp, sizeof(struct BitBuf2)); + end_of_block = end_of_block ? 1 : 0; + write_bits(bb, 0x2 | end_of_block, 3); + } +} diff --git a/ceph/src/isa-l/igzip/huff_codes.h b/ceph/src/isa-l/igzip/huff_codes.h index 9f6312fb1..bc7a89174 100644 --- a/ceph/src/isa-l/igzip/huff_codes.h +++ b/ceph/src/isa-l/igzip/huff_codes.h @@ -43,26 +43,26 @@ # include #endif -#define LIT_LEN IGZIP_LIT_LEN -#define DIST_LEN IGZIP_DIST_LEN +#define LIT_LEN ISAL_DEF_LIT_LEN_SYMBOLS +#define DIST_LEN ISAL_DEF_DIST_SYMBOLS #define CODE_LEN_CODES 19 #define HUFF_LEN 19 #ifdef LONGER_HUFFTABLE # define DCODE_OFFSET 26 #else -# define DCODE_OFFSET 20 +# define DCODE_OFFSET 0 #endif #define DYN_HDR_START_LEN 17 #define MAX_HISTHEAP_SIZE LIT_LEN #define MAX_HUFF_TREE_DEPTH 15 -#define D IGZIP_D /* Amount of history */ +#define D IGZIP_HIST_SIZE /* Amount of history */ #define MAX_DEFLATE_CODE_LEN 15 #define MAX_SAFE_LIT_CODE_LEN 13 #define MAX_SAFE_DIST_CODE_LEN 12 #define LONG_DIST_TABLE_SIZE 8192 -#define SHORT_DIST_TABLE_SIZE 1024 +#define SHORT_DIST_TABLE_SIZE 2 #define LEN_TABLE_SIZE 256 #define LIT_TABLE_SIZE 257 #define LAST_BLOCK 1 @@ -76,81 +76,60 @@ #define INVALID_DIST_HUFFCODE 1 #define INVALID_HUFFCODE 1 +#define HASH_MASK (IGZIP_HASH_SIZE - 1) +#define SHORTEST_MATCH 4 + +#define LENGTH_BITS 5 +#define FREQ_SHIFT 16 +#define FREQ_MASK_HI (0xFFFFFFFFFFFF0000) +#define DEPTH_SHIFT 24 +#define DEPTH_MASK 0x7F +#define DEPTH_MASK_HI (DEPTH_MASK << DEPTH_SHIFT) +#define DEPTH_1 (1 << DEPTH_SHIFT) +#define HEAP_TREE_SIZE (3*MAX_HISTHEAP_SIZE + 1) +#define HEAP_TREE_NODE_START (HEAP_TREE_SIZE-1) +#define MAX_BL_CODE_LEN 7 + /** * @brief Structure used to store huffman codes */ struct huff_code { - uint16_t code; - uint8_t length; + union { + struct { + uint16_t code; + uint8_t extra_bit_count; + uint8_t length; + }; + struct { + uint32_t code_and_extra:24; + uint32_t length2:8; + }; + }; }; -/** - * @brief Binary tree used to store and create a huffman tree. - */ -struct huff_tree { - uint16_t value; - uint64_t frequency; - struct huff_tree *left; - struct huff_tree *right; +struct tree_node { + uint32_t child; + uint32_t depth; }; -/** - * @brief Nodes in a doubly linked list. - */ -struct linked_list_node { - uint16_t value; - struct linked_list_node *next; - struct linked_list_node *previous; +struct heap_tree { + union { + uint64_t heap[HEAP_TREE_SIZE]; + uint64_t code_len_count[MAX_HUFF_TREE_DEPTH + 1]; + struct tree_node tree[HEAP_TREE_SIZE]; + }; }; -/** - * @brief This structure is a doubly linked list. - */ -struct linked_list { - uint64_t length; - struct linked_list_node *start; - struct linked_list_node *end; +struct rl_code { + uint8_t code; + uint8_t extra_bits; }; -/** - * @brief This is a binary minheap structure which stores huffman trees. - * @details The huffman trees are sorted by the frequency of the root. - * The structure is represented in a fixed sized array. - */ -struct histheap { - struct huff_tree tree[MAX_HISTHEAP_SIZE]; - uint16_t size; +struct hufftables_icf { + struct huff_code dist_table[31]; + struct huff_code lit_len_table[513]; }; -/** - * @brief Inserts a hufftree into a histheap. - * @param element: the hufftree to be inserted - * @param heap: the heap which element is being inserted into. - * @requires This function assumes the heap has enough allocated space. - * @returns Returns the index in heap of the inserted element - */ -int heap_push(struct huff_tree element, struct histheap *heap); - -/** - * @brief Removes the top element from the heap and returns it. - */ -struct huff_tree heap_pop(struct histheap *heap); - -/** - * @brief Removes the first element from list and returns it. - */ -struct linked_list_node *pop_from_front(struct linked_list *list); - -/** - * @brief Adds new_element to the front of list. - */ -void append_to_front(struct linked_list *list, struct linked_list_node *new_element); - -/** - * @brief Adds new_element to the end of list. - */ -void append_to_back(struct linked_list *list, struct linked_list_node *new_element); - /** * @brief Returns the deflate symbol value for a repeat length. */ @@ -161,68 +140,6 @@ uint32_t convert_length_to_len_sym(uint32_t length); */ uint32_t convert_dist_to_dist_sym(uint32_t dist); -/** - * Constructs a huffman tree on tree_array which only uses elements with non-zero frequency. - * @requires Assumes there will be at least two symbols in the produced tree. - * @requires tree_array must have length at least 2*size-1, and size must be less than 286. - * @param tree_array: array of huff_tree elements used to create a huffman tree, the first - * size elements of the array are the leaf elements in the huffman tree. - * @param histogram: a histogram of the frequency of elements in tree_array. - * @param size: the number of leaf elements in the huffman tree. -*/ -struct huff_tree create_symbol_subset_huff_tree(struct huff_tree *tree_array, - uint64_t * histogram, uint32_t size); - -/** - * @brief Construct a huffman tree on tree_array which uses every symbol. - * @requires tree_array must have length at least 2*size-1, and size must be less than 286. - * @param tree_array: array of huff_tree elements used to create a huffman tree, the first - * @param size elements of the array are the leaf elements in the huffman tree. - * @param histogram: a histogram of the frequency of elements in tree_array. - * @param size: the number of leaf elements in the huffman tree. - */ -struct huff_tree create_huff_tree(struct huff_tree *tree_array, uint64_t * histogram, - uint32_t size); - -/** - * @brief Creates a deflate compliant huffman tree with maximum depth max_depth. - * @details The huffman tree is represented as a lookup table. - * @param huff_lookup_table: The output lookup table. - * @param table_length: The length of table. - * @param root: the input huffman tree the created tree is based on. - * @param max_depth: maximum depth the huffman tree can have - * @returns Returns 0 if sucessful and returns 1 otherwise. - */ -int create_huff_lookup(struct huff_code *huff_lookup_table, int table_length, - struct huff_tree root, uint8_t max_depth); - -/** - * @brief Determines the code length for every value in a huffmant tree. - * @param huff_lookup_table: An output lookup table used to store the code lengths - * @param corresponding to the possible values - * @param count: An output histogram representing code length versus number of occurences. - * @param current_node: A node of the huffman tree being analyzed currently. - * @param current_depth: The depth of the current node in the huffman tree. - * @returns Returns 0 if sucessful and returns 1 otherwise. - */ -int find_code_lengths(struct huff_code *huff_lookup_table, uint16_t * count, - struct huff_tree root, uint8_t max_depth); - -/** - * @brief Creates an array of linked lists. - * @detail Each linked list contains all the elements with codes of a given length for - * lengths less than 16, and an list for all elements with codes at least 16. These lists - * are sorted by frequency from least frequent to most frequent within any given code length. - * @param depth_array: depth_array[i] is a linked list of elements with code length i - * @param linked_lists: An input structure the linked lists in depth array are built on. - * @param current_node: the current node being visited in a huffman tree - * @param current_depth: the depth of current_node in a huffman tree - */ -void huffman_tree_traversal(struct linked_list *depth_array, - struct linked_list_node *linked_lists, uint16_t * extra_nodes, - uint8_t max_depth, struct huff_tree current_node, - uint16_t current_depth); - /** * @brief Determines the code each element of a deflate compliant huffman tree and stores * it in a lookup table @@ -231,10 +148,7 @@ void huffman_tree_traversal(struct linked_list *depth_array, * @param table_length: The length of table. * @param count: a histogram representing the number of occurences of codes of a given length */ -void set_huff_codes(struct huff_code *table, int table_length, uint16_t * count); - -/* Reverse the first length bits in bits and returns that value */ -uint16_t bit_reverse(uint16_t bits, uint8_t length); +uint32_t set_huff_codes(struct huff_code *table, int table_length, uint32_t * count); /** * @brief Checks if a literal/length huffman table can be stored in the igzip hufftables files. @@ -260,32 +174,8 @@ uint16_t valid_dist_huff_table(struct huff_code *huff_code_table); * @param end_of_block: Value determining whether end of block header is produced or not; * 0 corresponds to not end of block and all other inputs correspond to end of block. */ -int create_header(uint8_t *header, uint32_t header_length, struct huff_code *lit_huff_table, - struct huff_code *dist_huff_table, uint32_t end_of_block); - -/** - * @brief Creates a run length encoded reprsentation of huff_table. - * @details Also creates a histogram representing the frequency of each symbols - * @returns Returns the number of symbols written into huffman_rep. - * @param huffman_rep: The output run length encoded version of huff_table. - * @param histogram: The output histogram of frequencies of elements in huffman_rep. - * @param extra_bits: An output table storing extra bits associated with huffman_rep. - * @param huff_table: The input huffman_table or concatonation of huffman_tables. - * @parma len: The length of huff_table. - */ -uint16_t create_huffman_rep(uint16_t * huffman_rep, uint64_t * histogram, - uint16_t * extra_bits, struct huff_code *huff_table, uint16_t len); - -/** - * @brief Flushes the symbols for a repeat of last_code for length run_length into huffman_rep. - * @param huffman_rep: pointer to array containing the output huffman_rep. - * @param histogram: histogram of elements seen in huffman_rep. - * @param extra_bits: an array holding extra bits for the corresponding symbol in huffman_rep. - * @param huff_table: a concatenated list of huffman lookup tables. - * @param current_index: The next spot elements will be written in huffman_rep. - */ -uint16_t flush_repeats(uint16_t * huffman_rep, uint64_t * histogram, uint16_t * extra_bits, - uint16_t last_code, uint16_t run_length, uint16_t current_index); +int create_header(struct BitBuf2 *header_bitbuf, struct rl_code *huffman_rep, uint32_t length, + uint64_t * histogram, uint32_t hlit, uint32_t hdist, uint32_t end_of_block); /** * @brief Creates the header for run length encoded huffman trees. @@ -300,10 +190,10 @@ uint16_t flush_repeats(uint16_t * huffman_rep, uint64_t * histogram, uint16_t * * @param hlit: Length of literal/length table minus 257. * @parm hdist: Length of distance table minus 1. */ -int create_huffman_header(uint8_t *header, uint32_t header_length, struct huff_code *lookup_table, - uint16_t * huffman_rep, uint16_t * extra_bits, - uint16_t huffman_rep_length, uint32_t end_of_block, uint32_t hclen, - uint32_t hlit, uint32_t hdist); +int create_huffman_header(struct BitBuf2 *header_bitbuf, struct huff_code *lookup_table, + struct rl_code * huffman_rep, uint16_t huffman_rep_length, + uint32_t end_of_block, uint32_t hclen, uint32_t hlit, + uint32_t hdist); /** * @brief Creates a two table representation of huffman codes. @@ -345,4 +235,18 @@ void create_packed_dist_table(uint32_t * packed_table, uint32_t length, */ int are_hufftables_useable(struct huff_code *lit_len_hufftable, struct huff_code *dist_hufftable); + +/** + * @brief Creates a representation of the huffman code from a histogram used to + * decompress the intermediate compression format. + * + * @param bb: bitbuf structure where the header huffman code header is written + * @param hufftables: output huffman code representation + * @param hist: histogram used to generat huffman code + * @param end_of_block: flag whether this is the final huffman code + */ +void +create_hufftables_icf(struct BitBuf2 *bb, struct hufftables_icf * hufftables, + struct isal_mod_hist *hist, uint32_t end_of_block); + #endif diff --git a/ceph/src/isa-l/igzip/huffman.asm b/ceph/src/isa-l/igzip/huffman.asm index fbe402ce6..daf9eda67 100644 --- a/ceph/src/isa-l/igzip/huffman.asm +++ b/ceph/src/isa-l/igzip/huffman.asm @@ -41,14 +41,14 @@ %define DECODE_OFFSET 26 %endif %else - %define DIST_TABLE_SIZE 1024 - %define DECODE_OFFSET 20 + %define DIST_TABLE_SIZE 2 + %define DECODE_OFFSET 0 %endif %define LEN_TABLE_SIZE 256 %define LIT_TABLE_SIZE 257 -%define DIST_TABLE_START (IGZIP_MAX_DEF_HDR_SIZE + 8) +%define DIST_TABLE_START (ISAL_DEF_MAX_HDR_SIZE + 8) %define DIST_TABLE_OFFSET (DIST_TABLE_START + - 4 * 1) %define LEN_TABLE_OFFSET (DIST_TABLE_START + DIST_TABLE_SIZE * 4 - 4*3) %define LIT_TABLE_OFFSET (DIST_TABLE_START + 4 * DIST_TABLE_SIZE + 4 * LEN_TABLE_SIZE) @@ -58,7 +58,7 @@ ;; /** @brief Holds the huffman tree used to huffman encode the input stream **/ ;; struct isal_hufftables { ;; // deflate huffman tree header -;; uint8_t deflate_huff_hdr[IGZIP_MAX_DEF_HDR_SIZE]; +;; uint8_t deflate_huff_hdr[ISAL_DEF_MAX_HDR_SIZE]; ;; ;; //!< Number of whole bytes in deflate_huff_hdr ;; uint32_t deflate_huff_hdr_count; @@ -90,7 +90,7 @@ %define %%len %3d ; 32-bit OUT %define %%hufftables %4 ; address of the hufftable - mov %%len, [%%hufftables + DIST_TABLE_OFFSET + 4*%%dist ] + mov %%len, [%%hufftables + DIST_TABLE_OFFSET + 4*(%%dist + 1) ] mov %%code, %%len and %%len, 0x1F; shr %%code, 5 @@ -117,45 +117,43 @@ ; Uses RCX, clobbers dist ; void compute_dist_code dist, code, len %macro compute_dist_code 4 -%define %%dist %1d ; IN, clobbered +%define %%dist %1 ; IN, clobbered %define %%distq %1 %define %%code %2 ; OUT %define %%len %3 ; OUT %define %%hufftables %4 - dec %%dist - bsr ecx, %%dist ; ecx = msb = bsr(dist) - dec ecx ; ecx = num_extra_bits = msb - N - mov %%code, 1 - shl %%code, CL - dec %%code ; code = ((1 << num_extra_bits) - 1) - and %%code, %%dist ; code = extra_bits - shr %%dist, CL ; dist >>= num_extra_bits - lea %%dist, [%%dist + 2*ecx] ; dist = sym = dist + num_extra_bits*2 - mov %%len, ecx ; len = num_extra_bits - movzx ecx, byte [hufftables + DCODE_TABLE_SIZE_OFFSET + %%distq WRT_OPT] + bsr rcx, %%dist ; ecx = msb = bsr(dist) + dec rcx ; ecx = num_extra_bits = msb - N + BZHI %%code, %%dist, rcx, %%len + SHRX %%dist, %%dist, rcx ; dist >>= num_extra_bits + lea %%dist, [%%dist + 2*rcx] ; dist = sym = dist + num_extra_bits*2 + mov %%len, rcx ; len = num_extra_bits + movzx rcx, byte [hufftables + DCODE_TABLE_SIZE_OFFSET + %%distq WRT_OPT] movzx %%dist, word [hufftables + DCODE_TABLE_OFFSET + 2 * %%distq WRT_OPT] - shl %%code, CL ; code = extra_bits << (sym & 0xF) + SHLX %%code, %%code, rcx ; code = extra_bits << (sym & 0xF) or %%code, %%dist ; code = (sym >> 4) | (extra_bits << (sym & 0xF)) - add %%len, ecx ; len = num_extra_bits + (sym & 0xF) + add %%len, rcx ; len = num_extra_bits + (sym & 0xF) %endm ; Uses RCX, clobbers dist ; get_dist_code dist, code, len %macro get_dist_code 4 -%define %%dist %1d ; 32-bit IN, clobbered +%define %%dist %1 ; 32-bit IN, clobbered %define %%distq %1 ; 64-bit IN, clobbered -%define %%code %2d ; 32-bit OUT -%define %%len %3d ; 32-bit OUT +%define %%code %2 ; 32-bit OUT +%define %%len %3 ; 32-bit OUT %define %%hufftables %4 - cmp %%dist, DIST_TABLE_SIZE + cmp %%dist, DIST_TABLE_SIZE - 1 jg %%do_compute - mov %%len, [hufftables + DIST_TABLE_OFFSET + 4*%%distq WRT_OPT] +%ifndef IACA + mov %%len %+ d, dword [hufftables + DIST_TABLE_OFFSET + 4*(%%distq + 1) WRT_OPT] mov %%code, %%len and %%len, 0x1F; shr %%code, 5 jmp %%done +%endif %%do_compute: compute_dist_code %%distq, %%code, %%len, %%hufftables %%done: @@ -170,6 +168,49 @@ %endif +; Macros for doing Huffman Encoding + +; Assumes (dist != 0) +; Uses RCX, clobbers dist +; void compute_dist_code dist, code, len +%macro compute_dist_icf_code 3 +%define %%dist %1 ; IN, clobbered +%define %%distq %1 +%define %%code %2 ; OUT +%define %%tmp1 %3 + + bsr rcx, %%dist ; ecx = msb = bsr(dist) + dec rcx ; ecx = num_extra_bits = msb - N + BZHI %%code, %%dist, rcx, %%tmp1 + SHRX %%dist, %%dist, rcx ; dist >>= num_extra_bits + lea %%dist, [%%dist + 2*rcx] ; code = sym = dist + num_extra_bits*2 + shl %%code, EXTRA_BITS_OFFSET - DIST_OFFSET + add %%code, %%dist ; code = extra_bits | sym + +%endm + +; Uses RCX, clobbers dist +; get_dist_code dist, code, len +%macro get_dist_icf_code 3 +%define %%dist %1 ; 32-bit IN, clobbered +%define %%distq %1 ; 64-bit IN, clobbered +%define %%code %2 ; 32-bit OUT +%define %%tmp1 %3 + + cmp %%dist, 1 + jg %%do_compute + +%ifnidn %%code, %%dist + mov %%code, %%dist +%endif + jmp %%done +%%do_compute: + compute_dist_icf_code %%distq, %%code, %%tmp1 +%%done: + shl %%code, DIST_OFFSET +%endm + + ; "len" can be same register as "length" ; get_len_code length, code, len %macro get_len_code 4 @@ -202,7 +243,6 @@ %define %%result %1d ; 32-bit reg %define %%data %2d ; 32-bit reg (low byte not clobbered) - and %%data, 0x00FFFFFF xor %%result, %%result crc32 %%result, %%data %endm diff --git a/ceph/src/isa-l/igzip/huffman.h b/ceph/src/isa-l/igzip/huffman.h index 0116deab1..0553b8157 100644 --- a/ceph/src/isa-l/igzip/huffman.h +++ b/ceph/src/isa-l/igzip/huffman.h @@ -39,13 +39,6 @@ # include #endif -#ifndef IGZIP_USE_GZIP_FORMAT -# define DEFLATE 1 -#endif - - -extern uint32_t CrcTable[256]; - static inline uint32_t bsr(uint32_t val) { uint32_t msb; @@ -75,7 +68,7 @@ static inline uint32_t tzcnt(uint64_t val) static void compute_dist_code(struct isal_hufftables *hufftables, uint16_t dist, uint64_t *p_code, uint64_t *p_len) { - assert(dist > DIST_TABLE_SIZE); + assert(dist > IGZIP_DIST_TABLE_SIZE); dist -= 1; uint32_t msb; @@ -92,8 +85,8 @@ static void compute_dist_code(struct isal_hufftables *hufftables, uint16_t dist, dist >>= num_extra_bits; sym = dist + 2 * num_extra_bits; assert(sym < 30); - code = hufftables->dcodes[sym - DECODE_OFFSET]; - len = hufftables->dcodes_sizes[sym - DECODE_OFFSET]; + code = hufftables->dcodes[sym - IGZIP_DECODE_OFFSET]; + len = hufftables->dcodes_sizes[sym - IGZIP_DECODE_OFFSET]; *p_code = code | (extra_bits << len); *p_len = len + num_extra_bits; } @@ -104,7 +97,7 @@ static inline void get_dist_code(struct isal_hufftables *hufftables, uint32_t di dist = 0; assert(dist >= 1); assert(dist <= 32768); - if (dist <= DIST_TABLE_SIZE) { + if (dist <= IGZIP_DIST_TABLE_SIZE) { uint64_t code_len; code_len = hufftables->dist_table[dist - 1]; *code = code_len >> 5; @@ -133,13 +126,54 @@ static inline void get_lit_code(struct isal_hufftables *hufftables, uint32_t lit *len = hufftables->lit_table_sizes[lit]; } +static void compute_dist_icf_code(uint32_t dist, uint32_t *code, uint32_t *extra_bits) +{ + uint32_t msb; + uint32_t num_extra_bits; + + dist -= 1; + msb = bsr(dist); + assert(msb >= 1); + num_extra_bits = msb - 2; + *extra_bits = dist & ((1 << num_extra_bits) - 1); + dist >>= num_extra_bits; + *code = dist + 2 * num_extra_bits; + assert(*code < 30); +} + +static inline void get_dist_icf_code(uint32_t dist, uint32_t *code, uint32_t *extra_bits) +{ + assert(dist >= 1); + assert(dist <= 32768); + if (dist <= 2) { + *code = dist - 1; + *extra_bits = 0; + } else { + compute_dist_icf_code(dist, code, extra_bits); + } +} + +static inline void get_len_icf_code(uint32_t length, uint32_t *code) +{ + assert(length >= 3); + assert(length <= 258); + + *code = length + 254; +} + +static inline void get_lit_icf_code(uint32_t lit, uint32_t *code) +{ + assert(lit <= 256); + + *code = lit; +} + /** * @brief Returns a hash of the first 3 bytes of input data. */ static inline uint32_t compute_hash(uint32_t data) { - data &= 0x00FFFFFF; -#ifdef __SSE4_1__ +#ifdef __SSE4_2__ return _mm_crc32_u32(0, data); @@ -147,7 +181,7 @@ static inline uint32_t compute_hash(uint32_t data) /* Use multiplication to create a hash, 0xBDD06057 is a prime number */ return ((uint64_t)data * 0xB2D06057) >> 16; -#endif /* __SSE4_1__ */ +#endif /* __SSE4_2__ */ } @@ -211,16 +245,3 @@ static inline int compare258(uint8_t * str1, uint8_t * str2, uint32_t max_length return count; } - -static inline void update_crc(uint32_t* crc, uint8_t * start, uint32_t length) -{ -#ifndef DEFLATE - uint8_t *end = start + length; - - while (start < end) - *crc = (*crc >> 8) ^ CrcTable[(*crc & 0x000000FF) ^ *start++]; -#else - return; -#endif -} - diff --git a/ceph/src/isa-l/igzip/hufftables_c.c b/ceph/src/isa-l/igzip/hufftables_c.c index 2f37bbc0d..a82acef1d 100644 --- a/ceph/src/isa-l/igzip/hufftables_c.c +++ b/ceph/src/isa-l/igzip/hufftables_c.c @@ -29,2500 +29,6704 @@ #include #include -uint8_t const gzip_hdr[10] = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff +#if (IGZIP_HIST_SIZE <= 8192) + +const uint8_t gzip_hdr[] = { + 0x1f, 0x8b, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff }; const uint32_t gzip_hdr_bytes = 10; const uint32_t gzip_trl_bytes = 8; -const struct isal_hufftables hufftables_default = { +struct isal_hufftables hufftables_default = { .deflate_hdr = { - 0xed, 0xfd, 0x6d, 0xc7, 0xb6, 0x6d, 0xd7, 0x34, - 0x3d, 0xef, 0xc7, 0x7e, 0x1c, 0xfb, 0xb1, 0x1f, - 0xcb, 0x7c, 0xec, 0xfb, 0xf1, 0xb2, 0x1f, 0xfb, - 0xcb, 0x71, 0xec, 0xc7, 0xbe, 0x1f, 0xc7, 0xb4, - 0xce, 0xfb, 0xb1, 0x6f, 0xcb, 0xbc, 0xec, 0xeb, - 0xb2, 0xce, 0xeb, 0x7a, 0x6c, 0xfb, 0x76, 0xec, - 0xc7, 0x71, 0x6c, 0xcb, 0xb6, 0x6c, 0xc7, 0xb1, - 0x6e, 0xeb, 0xb6, 0x6e, 0xdb, 0xba, 0x1d, 0xfb, - 0xb6, 0x6e, 0xdb, 0xb6, 0xaf, 0xeb, 0xb2, 0x6d, - 0xc7, 0x7a, 0xec, 0xdb, 0xb6, 0xed, 0xcb, 0x31, - 0xaf, 0xf3, 0x3c, 0x2d, 0xcb, 0x32, 0x6f, 0xdb, - 0xbc, 0xcc, 0xf3, 0xb2, 0xcd, 0x2f, 0xcb, 0xb2, - 0x2e, 0xc7, 0xb6, 0xad, 0xc7, 0x7e, 0xbc, 0xbf, - 0xee, 0xfb, 0xb1, 0xbf, 0x1e, 0xc7, 0xb1, 0x1f, - 0xc7, 0xfe, 0x72, 0xbc, 0xec, 0xfb, 0x7e, 0xec, - 0xfb, 0x71, 0xec, 0x2f, 0xc7, 0xeb, 0xbe, 0x1f, - 0xc7, 0xfe, 0x72, 0xbc, 0xec, 0xfb, 0x71, 0x1c, - 0xfb, 0x71, 0xec, 0xfb, 0xf1, 0xbe, 0x1f, 0xc7, - 0xbe, 0x1f, 0xc7, 0xb1, 0xbf, 0x1d, 0x6f, 0xfb, - 0x7e, 0xbc, 0xed, 0xaf, 0xc7, 0xb1, 0xef, 0xc7, - 0xb1, 0x1f, 0xef, 0xfb, 0x31, 0xc6, 0x34, 0xcd, - 0xf3, 0x32, 0xbf, 0x2c, 0xf3, 0xba, 0x6e, 0xeb, - 0x7a, 0x6c, 0xc7, 0xb1, 0x6f, 0xc7, 0x7e, 0x1c, - 0xfb, 0xb6, 0xad, 0xdb, 0xbc, 0x2d, 0xf3, 0x34, - 0x8d, 0x31, 0xa6, 0x31, 0x7a, 0xf4, 0x18, 0xd3, - 0x34, 0x6d, 0xaf }, + 0xed, 0xf9, 0x09, 0x60, 0x54, 0xd5, 0xf9, 0x37, + 0x00, 0x9f, 0x90, 0x04, 0xc8, 0x40, 0x00, 0x77, + 0xdb, 0x5a, 0x38, 0x22, 0x4a, 0xd0, 0xc9, 0x98, + 0x15, 0x02, 0x20, 0x24, 0x09, 0x5b, 0x10, 0x20, + 0x12, 0x10, 0x77, 0x39, 0x33, 0xf7, 0xcc, 0xcc, + 0x25, 0x77, 0xee, 0x1d, 0xef, 0xbd, 0x37, 0xc3, + 0x50, 0x55, 0x5a, 0x6d, 0xb5, 0xb5, 0xad, 0x76, + 0xdf, 0x5b, 0xdb, 0x5a, 0x6b, 0x77, 0xdb, 0xda, + 0xbd, 0x56, 0x84, 0xb6, 0xda, 0x55, 0xbb, 0xef, + 0x2d, 0x56, 0x5b, 0xed, 0x2a, 0x56, 0xdb, 0x62, + 0x8b, 0xe4, 0xfb, 0x7e, 0xcf, 0x39, 0x77, 0xe6, + 0x24, 0x09, 0xae, 0xfd, 0xbf, 0xef, 0xff, 0xfd, + 0xbe, 0x22, 0x92, 0xdc, 0x7b, 0xcf, 0x79, 0xce, + 0xb3, 0x9f, 0xdf, 0xf3, 0x3c}, - .deflate_hdr_count = 203, + .deflate_hdr_count = 109, .deflate_hdr_extra_bits = 0, -#ifdef LONGER_HUFFTABLE .dist_table = { - 0x00001be9, 0x00003be9, 0x00000be8, 0x000007e9, - 0x000001e7, 0x000009e7, 0x000027ea, 0x000067ea, - 0x000003e9, 0x000013e9, 0x000023e9, 0x000033e9, - 0x000005e8, 0x00000de8, 0x000015e8, 0x00001de8, - 0x00000068, 0x00000468, 0x00000868, 0x00000c68, - 0x00001068, 0x00001468, 0x00001868, 0x00001c68, - 0x00000268, 0x00000668, 0x00000a68, 0x00000e68, - 0x00001268, 0x00001668, 0x00001a68, 0x00001e68, - 0x00000048, 0x00000248, 0x00000448, 0x00000648, - 0x00000848, 0x00000a48, 0x00000c48, 0x00000e48, - 0x00001048, 0x00001248, 0x00001448, 0x00001648, - 0x00001848, 0x00001a48, 0x00001c48, 0x00001e48, - 0x00000148, 0x00000348, 0x00000548, 0x00000748, - 0x00000948, 0x00000b48, 0x00000d48, 0x00000f48, - 0x00001148, 0x00001348, 0x00001548, 0x00001748, - 0x00001948, 0x00001b48, 0x00001d48, 0x00001f48, - 0x000000c9, 0x000002c9, 0x000004c9, 0x000006c9, - 0x000008c9, 0x00000ac9, 0x00000cc9, 0x00000ec9, - 0x000010c9, 0x000012c9, 0x000014c9, 0x000016c9, - 0x000018c9, 0x00001ac9, 0x00001cc9, 0x00001ec9, - 0x000020c9, 0x000022c9, 0x000024c9, 0x000026c9, - 0x000028c9, 0x00002ac9, 0x00002cc9, 0x00002ec9, - 0x000030c9, 0x000032c9, 0x000034c9, 0x000036c9, - 0x000038c9, 0x00003ac9, 0x00003cc9, 0x00003ec9, - 0x0000016a, 0x0000056a, 0x0000096a, 0x00000d6a, - 0x0000116a, 0x0000156a, 0x0000196a, 0x00001d6a, - 0x0000216a, 0x0000256a, 0x0000296a, 0x00002d6a, - 0x0000316a, 0x0000356a, 0x0000396a, 0x00003d6a, - 0x0000416a, 0x0000456a, 0x0000496a, 0x00004d6a, - 0x0000516a, 0x0000556a, 0x0000596a, 0x00005d6a, - 0x0000616a, 0x0000656a, 0x0000696a, 0x00006d6a, - 0x0000716a, 0x0000756a, 0x0000796a, 0x00007d6a, - 0x000001ca, 0x000003ca, 0x000005ca, 0x000007ca, - 0x000009ca, 0x00000bca, 0x00000dca, 0x00000fca, - 0x000011ca, 0x000013ca, 0x000015ca, 0x000017ca, - 0x000019ca, 0x00001bca, 0x00001dca, 0x00001fca, - 0x000021ca, 0x000023ca, 0x000025ca, 0x000027ca, - 0x000029ca, 0x00002bca, 0x00002dca, 0x00002fca, - 0x000031ca, 0x000033ca, 0x000035ca, 0x000037ca, - 0x000039ca, 0x00003bca, 0x00003dca, 0x00003fca, - 0x000041ca, 0x000043ca, 0x000045ca, 0x000047ca, - 0x000049ca, 0x00004bca, 0x00004dca, 0x00004fca, - 0x000051ca, 0x000053ca, 0x000055ca, 0x000057ca, - 0x000059ca, 0x00005bca, 0x00005dca, 0x00005fca, - 0x000061ca, 0x000063ca, 0x000065ca, 0x000067ca, - 0x000069ca, 0x00006bca, 0x00006dca, 0x00006fca, - 0x000071ca, 0x000073ca, 0x000075ca, 0x000077ca, - 0x000079ca, 0x00007bca, 0x00007dca, 0x00007fca, - 0x0000002a, 0x0000022a, 0x0000042a, 0x0000062a, - 0x0000082a, 0x00000a2a, 0x00000c2a, 0x00000e2a, - 0x0000102a, 0x0000122a, 0x0000142a, 0x0000162a, - 0x0000182a, 0x00001a2a, 0x00001c2a, 0x00001e2a, - 0x0000202a, 0x0000222a, 0x0000242a, 0x0000262a, - 0x0000282a, 0x00002a2a, 0x00002c2a, 0x00002e2a, - 0x0000302a, 0x0000322a, 0x0000342a, 0x0000362a, - 0x0000382a, 0x00003a2a, 0x00003c2a, 0x00003e2a, - 0x0000402a, 0x0000422a, 0x0000442a, 0x0000462a, - 0x0000482a, 0x00004a2a, 0x00004c2a, 0x00004e2a, - 0x0000502a, 0x0000522a, 0x0000542a, 0x0000562a, - 0x0000582a, 0x00005a2a, 0x00005c2a, 0x00005e2a, - 0x0000602a, 0x0000622a, 0x0000642a, 0x0000662a, - 0x0000682a, 0x00006a2a, 0x00006c2a, 0x00006e2a, - 0x0000702a, 0x0000722a, 0x0000742a, 0x0000762a, - 0x0000782a, 0x00007a2a, 0x00007c2a, 0x00007e2a, - 0x0000000a, 0x0000010a, 0x0000020a, 0x0000030a, - 0x0000040a, 0x0000050a, 0x0000060a, 0x0000070a, - 0x0000080a, 0x0000090a, 0x00000a0a, 0x00000b0a, - 0x00000c0a, 0x00000d0a, 0x00000e0a, 0x00000f0a, - 0x0000100a, 0x0000110a, 0x0000120a, 0x0000130a, - 0x0000140a, 0x0000150a, 0x0000160a, 0x0000170a, - 0x0000180a, 0x0000190a, 0x00001a0a, 0x00001b0a, - 0x00001c0a, 0x00001d0a, 0x00001e0a, 0x00001f0a, - 0x0000200a, 0x0000210a, 0x0000220a, 0x0000230a, - 0x0000240a, 0x0000250a, 0x0000260a, 0x0000270a, - 0x0000280a, 0x0000290a, 0x00002a0a, 0x00002b0a, - 0x00002c0a, 0x00002d0a, 0x00002e0a, 0x00002f0a, - 0x0000300a, 0x0000310a, 0x0000320a, 0x0000330a, - 0x0000340a, 0x0000350a, 0x0000360a, 0x0000370a, - 0x0000380a, 0x0000390a, 0x00003a0a, 0x00003b0a, - 0x00003c0a, 0x00003d0a, 0x00003e0a, 0x00003f0a, - 0x0000400a, 0x0000410a, 0x0000420a, 0x0000430a, - 0x0000440a, 0x0000450a, 0x0000460a, 0x0000470a, - 0x0000480a, 0x0000490a, 0x00004a0a, 0x00004b0a, - 0x00004c0a, 0x00004d0a, 0x00004e0a, 0x00004f0a, - 0x0000500a, 0x0000510a, 0x0000520a, 0x0000530a, - 0x0000540a, 0x0000550a, 0x0000560a, 0x0000570a, - 0x0000580a, 0x0000590a, 0x00005a0a, 0x00005b0a, - 0x00005c0a, 0x00005d0a, 0x00005e0a, 0x00005f0a, - 0x0000600a, 0x0000610a, 0x0000620a, 0x0000630a, - 0x0000640a, 0x0000650a, 0x0000660a, 0x0000670a, - 0x0000680a, 0x0000690a, 0x00006a0a, 0x00006b0a, - 0x00006c0a, 0x00006d0a, 0x00006e0a, 0x00006f0a, - 0x0000700a, 0x0000710a, 0x0000720a, 0x0000730a, - 0x0000740a, 0x0000750a, 0x0000760a, 0x0000770a, - 0x0000780a, 0x0000790a, 0x00007a0a, 0x00007b0a, - 0x00007c0a, 0x00007d0a, 0x00007e0a, 0x00007f0a, - 0x0000012b, 0x0000032b, 0x0000052b, 0x0000072b, - 0x0000092b, 0x00000b2b, 0x00000d2b, 0x00000f2b, - 0x0000112b, 0x0000132b, 0x0000152b, 0x0000172b, - 0x0000192b, 0x00001b2b, 0x00001d2b, 0x00001f2b, - 0x0000212b, 0x0000232b, 0x0000252b, 0x0000272b, - 0x0000292b, 0x00002b2b, 0x00002d2b, 0x00002f2b, - 0x0000312b, 0x0000332b, 0x0000352b, 0x0000372b, - 0x0000392b, 0x00003b2b, 0x00003d2b, 0x00003f2b, - 0x0000412b, 0x0000432b, 0x0000452b, 0x0000472b, - 0x0000492b, 0x00004b2b, 0x00004d2b, 0x00004f2b, - 0x0000512b, 0x0000532b, 0x0000552b, 0x0000572b, - 0x0000592b, 0x00005b2b, 0x00005d2b, 0x00005f2b, - 0x0000612b, 0x0000632b, 0x0000652b, 0x0000672b, - 0x0000692b, 0x00006b2b, 0x00006d2b, 0x00006f2b, - 0x0000712b, 0x0000732b, 0x0000752b, 0x0000772b, - 0x0000792b, 0x00007b2b, 0x00007d2b, 0x00007f2b, - 0x0000812b, 0x0000832b, 0x0000852b, 0x0000872b, - 0x0000892b, 0x00008b2b, 0x00008d2b, 0x00008f2b, - 0x0000912b, 0x0000932b, 0x0000952b, 0x0000972b, - 0x0000992b, 0x00009b2b, 0x00009d2b, 0x00009f2b, - 0x0000a12b, 0x0000a32b, 0x0000a52b, 0x0000a72b, - 0x0000a92b, 0x0000ab2b, 0x0000ad2b, 0x0000af2b, - 0x0000b12b, 0x0000b32b, 0x0000b52b, 0x0000b72b, - 0x0000b92b, 0x0000bb2b, 0x0000bd2b, 0x0000bf2b, - 0x0000c12b, 0x0000c32b, 0x0000c52b, 0x0000c72b, - 0x0000c92b, 0x0000cb2b, 0x0000cd2b, 0x0000cf2b, - 0x0000d12b, 0x0000d32b, 0x0000d52b, 0x0000d72b, - 0x0000d92b, 0x0000db2b, 0x0000dd2b, 0x0000df2b, - 0x0000e12b, 0x0000e32b, 0x0000e52b, 0x0000e72b, - 0x0000e92b, 0x0000eb2b, 0x0000ed2b, 0x0000ef2b, - 0x0000f12b, 0x0000f32b, 0x0000f52b, 0x0000f72b, - 0x0000f92b, 0x0000fb2b, 0x0000fd2b, 0x0000ff2b, - 0x0000008b, 0x0000018b, 0x0000028b, 0x0000038b, - 0x0000048b, 0x0000058b, 0x0000068b, 0x0000078b, - 0x0000088b, 0x0000098b, 0x00000a8b, 0x00000b8b, - 0x00000c8b, 0x00000d8b, 0x00000e8b, 0x00000f8b, - 0x0000108b, 0x0000118b, 0x0000128b, 0x0000138b, - 0x0000148b, 0x0000158b, 0x0000168b, 0x0000178b, - 0x0000188b, 0x0000198b, 0x00001a8b, 0x00001b8b, - 0x00001c8b, 0x00001d8b, 0x00001e8b, 0x00001f8b, - 0x0000208b, 0x0000218b, 0x0000228b, 0x0000238b, - 0x0000248b, 0x0000258b, 0x0000268b, 0x0000278b, - 0x0000288b, 0x0000298b, 0x00002a8b, 0x00002b8b, - 0x00002c8b, 0x00002d8b, 0x00002e8b, 0x00002f8b, - 0x0000308b, 0x0000318b, 0x0000328b, 0x0000338b, - 0x0000348b, 0x0000358b, 0x0000368b, 0x0000378b, - 0x0000388b, 0x0000398b, 0x00003a8b, 0x00003b8b, - 0x00003c8b, 0x00003d8b, 0x00003e8b, 0x00003f8b, - 0x0000408b, 0x0000418b, 0x0000428b, 0x0000438b, - 0x0000448b, 0x0000458b, 0x0000468b, 0x0000478b, - 0x0000488b, 0x0000498b, 0x00004a8b, 0x00004b8b, - 0x00004c8b, 0x00004d8b, 0x00004e8b, 0x00004f8b, - 0x0000508b, 0x0000518b, 0x0000528b, 0x0000538b, - 0x0000548b, 0x0000558b, 0x0000568b, 0x0000578b, - 0x0000588b, 0x0000598b, 0x00005a8b, 0x00005b8b, - 0x00005c8b, 0x00005d8b, 0x00005e8b, 0x00005f8b, - 0x0000608b, 0x0000618b, 0x0000628b, 0x0000638b, - 0x0000648b, 0x0000658b, 0x0000668b, 0x0000678b, - 0x0000688b, 0x0000698b, 0x00006a8b, 0x00006b8b, - 0x00006c8b, 0x00006d8b, 0x00006e8b, 0x00006f8b, - 0x0000708b, 0x0000718b, 0x0000728b, 0x0000738b, - 0x0000748b, 0x0000758b, 0x0000768b, 0x0000778b, - 0x0000788b, 0x0000798b, 0x00007a8b, 0x00007b8b, - 0x00007c8b, 0x00007d8b, 0x00007e8b, 0x00007f8b, - 0x0000808b, 0x0000818b, 0x0000828b, 0x0000838b, - 0x0000848b, 0x0000858b, 0x0000868b, 0x0000878b, - 0x0000888b, 0x0000898b, 0x00008a8b, 0x00008b8b, - 0x00008c8b, 0x00008d8b, 0x00008e8b, 0x00008f8b, - 0x0000908b, 0x0000918b, 0x0000928b, 0x0000938b, - 0x0000948b, 0x0000958b, 0x0000968b, 0x0000978b, - 0x0000988b, 0x0000998b, 0x00009a8b, 0x00009b8b, - 0x00009c8b, 0x00009d8b, 0x00009e8b, 0x00009f8b, - 0x0000a08b, 0x0000a18b, 0x0000a28b, 0x0000a38b, - 0x0000a48b, 0x0000a58b, 0x0000a68b, 0x0000a78b, - 0x0000a88b, 0x0000a98b, 0x0000aa8b, 0x0000ab8b, - 0x0000ac8b, 0x0000ad8b, 0x0000ae8b, 0x0000af8b, - 0x0000b08b, 0x0000b18b, 0x0000b28b, 0x0000b38b, - 0x0000b48b, 0x0000b58b, 0x0000b68b, 0x0000b78b, - 0x0000b88b, 0x0000b98b, 0x0000ba8b, 0x0000bb8b, - 0x0000bc8b, 0x0000bd8b, 0x0000be8b, 0x0000bf8b, - 0x0000c08b, 0x0000c18b, 0x0000c28b, 0x0000c38b, - 0x0000c48b, 0x0000c58b, 0x0000c68b, 0x0000c78b, - 0x0000c88b, 0x0000c98b, 0x0000ca8b, 0x0000cb8b, - 0x0000cc8b, 0x0000cd8b, 0x0000ce8b, 0x0000cf8b, - 0x0000d08b, 0x0000d18b, 0x0000d28b, 0x0000d38b, - 0x0000d48b, 0x0000d58b, 0x0000d68b, 0x0000d78b, - 0x0000d88b, 0x0000d98b, 0x0000da8b, 0x0000db8b, - 0x0000dc8b, 0x0000dd8b, 0x0000de8b, 0x0000df8b, - 0x0000e08b, 0x0000e18b, 0x0000e28b, 0x0000e38b, - 0x0000e48b, 0x0000e58b, 0x0000e68b, 0x0000e78b, - 0x0000e88b, 0x0000e98b, 0x0000ea8b, 0x0000eb8b, - 0x0000ec8b, 0x0000ed8b, 0x0000ee8b, 0x0000ef8b, - 0x0000f08b, 0x0000f18b, 0x0000f28b, 0x0000f38b, - 0x0000f48b, 0x0000f58b, 0x0000f68b, 0x0000f78b, - 0x0000f88b, 0x0000f98b, 0x0000fa8b, 0x0000fb8b, - 0x0000fc8b, 0x0000fd8b, 0x0000fe8b, 0x0000ff8b, - 0x000000ac, 0x000002ac, 0x000004ac, 0x000006ac, - 0x000008ac, 0x00000aac, 0x00000cac, 0x00000eac, - 0x000010ac, 0x000012ac, 0x000014ac, 0x000016ac, - 0x000018ac, 0x00001aac, 0x00001cac, 0x00001eac, - 0x000020ac, 0x000022ac, 0x000024ac, 0x000026ac, - 0x000028ac, 0x00002aac, 0x00002cac, 0x00002eac, - 0x000030ac, 0x000032ac, 0x000034ac, 0x000036ac, - 0x000038ac, 0x00003aac, 0x00003cac, 0x00003eac, - 0x000040ac, 0x000042ac, 0x000044ac, 0x000046ac, - 0x000048ac, 0x00004aac, 0x00004cac, 0x00004eac, - 0x000050ac, 0x000052ac, 0x000054ac, 0x000056ac, - 0x000058ac, 0x00005aac, 0x00005cac, 0x00005eac, - 0x000060ac, 0x000062ac, 0x000064ac, 0x000066ac, - 0x000068ac, 0x00006aac, 0x00006cac, 0x00006eac, - 0x000070ac, 0x000072ac, 0x000074ac, 0x000076ac, - 0x000078ac, 0x00007aac, 0x00007cac, 0x00007eac, - 0x000080ac, 0x000082ac, 0x000084ac, 0x000086ac, - 0x000088ac, 0x00008aac, 0x00008cac, 0x00008eac, - 0x000090ac, 0x000092ac, 0x000094ac, 0x000096ac, - 0x000098ac, 0x00009aac, 0x00009cac, 0x00009eac, - 0x0000a0ac, 0x0000a2ac, 0x0000a4ac, 0x0000a6ac, - 0x0000a8ac, 0x0000aaac, 0x0000acac, 0x0000aeac, - 0x0000b0ac, 0x0000b2ac, 0x0000b4ac, 0x0000b6ac, - 0x0000b8ac, 0x0000baac, 0x0000bcac, 0x0000beac, - 0x0000c0ac, 0x0000c2ac, 0x0000c4ac, 0x0000c6ac, - 0x0000c8ac, 0x0000caac, 0x0000ccac, 0x0000ceac, - 0x0000d0ac, 0x0000d2ac, 0x0000d4ac, 0x0000d6ac, - 0x0000d8ac, 0x0000daac, 0x0000dcac, 0x0000deac, - 0x0000e0ac, 0x0000e2ac, 0x0000e4ac, 0x0000e6ac, - 0x0000e8ac, 0x0000eaac, 0x0000ecac, 0x0000eeac, - 0x0000f0ac, 0x0000f2ac, 0x0000f4ac, 0x0000f6ac, - 0x0000f8ac, 0x0000faac, 0x0000fcac, 0x0000feac, - 0x000100ac, 0x000102ac, 0x000104ac, 0x000106ac, - 0x000108ac, 0x00010aac, 0x00010cac, 0x00010eac, - 0x000110ac, 0x000112ac, 0x000114ac, 0x000116ac, - 0x000118ac, 0x00011aac, 0x00011cac, 0x00011eac, - 0x000120ac, 0x000122ac, 0x000124ac, 0x000126ac, - 0x000128ac, 0x00012aac, 0x00012cac, 0x00012eac, - 0x000130ac, 0x000132ac, 0x000134ac, 0x000136ac, - 0x000138ac, 0x00013aac, 0x00013cac, 0x00013eac, - 0x000140ac, 0x000142ac, 0x000144ac, 0x000146ac, - 0x000148ac, 0x00014aac, 0x00014cac, 0x00014eac, - 0x000150ac, 0x000152ac, 0x000154ac, 0x000156ac, - 0x000158ac, 0x00015aac, 0x00015cac, 0x00015eac, - 0x000160ac, 0x000162ac, 0x000164ac, 0x000166ac, - 0x000168ac, 0x00016aac, 0x00016cac, 0x00016eac, - 0x000170ac, 0x000172ac, 0x000174ac, 0x000176ac, - 0x000178ac, 0x00017aac, 0x00017cac, 0x00017eac, - 0x000180ac, 0x000182ac, 0x000184ac, 0x000186ac, - 0x000188ac, 0x00018aac, 0x00018cac, 0x00018eac, - 0x000190ac, 0x000192ac, 0x000194ac, 0x000196ac, - 0x000198ac, 0x00019aac, 0x00019cac, 0x00019eac, - 0x0001a0ac, 0x0001a2ac, 0x0001a4ac, 0x0001a6ac, - 0x0001a8ac, 0x0001aaac, 0x0001acac, 0x0001aeac, - 0x0001b0ac, 0x0001b2ac, 0x0001b4ac, 0x0001b6ac, - 0x0001b8ac, 0x0001baac, 0x0001bcac, 0x0001beac, - 0x0001c0ac, 0x0001c2ac, 0x0001c4ac, 0x0001c6ac, - 0x0001c8ac, 0x0001caac, 0x0001ccac, 0x0001ceac, - 0x0001d0ac, 0x0001d2ac, 0x0001d4ac, 0x0001d6ac, - 0x0001d8ac, 0x0001daac, 0x0001dcac, 0x0001deac, - 0x0001e0ac, 0x0001e2ac, 0x0001e4ac, 0x0001e6ac, - 0x0001e8ac, 0x0001eaac, 0x0001ecac, 0x0001eeac, - 0x0001f0ac, 0x0001f2ac, 0x0001f4ac, 0x0001f6ac, - 0x0001f8ac, 0x0001faac, 0x0001fcac, 0x0001feac, - 0x000001ad, 0x000003ad, 0x000005ad, 0x000007ad, - 0x000009ad, 0x00000bad, 0x00000dad, 0x00000fad, - 0x000011ad, 0x000013ad, 0x000015ad, 0x000017ad, - 0x000019ad, 0x00001bad, 0x00001dad, 0x00001fad, - 0x000021ad, 0x000023ad, 0x000025ad, 0x000027ad, - 0x000029ad, 0x00002bad, 0x00002dad, 0x00002fad, - 0x000031ad, 0x000033ad, 0x000035ad, 0x000037ad, - 0x000039ad, 0x00003bad, 0x00003dad, 0x00003fad, - 0x000041ad, 0x000043ad, 0x000045ad, 0x000047ad, - 0x000049ad, 0x00004bad, 0x00004dad, 0x00004fad, - 0x000051ad, 0x000053ad, 0x000055ad, 0x000057ad, - 0x000059ad, 0x00005bad, 0x00005dad, 0x00005fad, - 0x000061ad, 0x000063ad, 0x000065ad, 0x000067ad, - 0x000069ad, 0x00006bad, 0x00006dad, 0x00006fad, - 0x000071ad, 0x000073ad, 0x000075ad, 0x000077ad, - 0x000079ad, 0x00007bad, 0x00007dad, 0x00007fad, - 0x000081ad, 0x000083ad, 0x000085ad, 0x000087ad, - 0x000089ad, 0x00008bad, 0x00008dad, 0x00008fad, - 0x000091ad, 0x000093ad, 0x000095ad, 0x000097ad, - 0x000099ad, 0x00009bad, 0x00009dad, 0x00009fad, - 0x0000a1ad, 0x0000a3ad, 0x0000a5ad, 0x0000a7ad, - 0x0000a9ad, 0x0000abad, 0x0000adad, 0x0000afad, - 0x0000b1ad, 0x0000b3ad, 0x0000b5ad, 0x0000b7ad, - 0x0000b9ad, 0x0000bbad, 0x0000bdad, 0x0000bfad, - 0x0000c1ad, 0x0000c3ad, 0x0000c5ad, 0x0000c7ad, - 0x0000c9ad, 0x0000cbad, 0x0000cdad, 0x0000cfad, - 0x0000d1ad, 0x0000d3ad, 0x0000d5ad, 0x0000d7ad, - 0x0000d9ad, 0x0000dbad, 0x0000ddad, 0x0000dfad, - 0x0000e1ad, 0x0000e3ad, 0x0000e5ad, 0x0000e7ad, - 0x0000e9ad, 0x0000ebad, 0x0000edad, 0x0000efad, - 0x0000f1ad, 0x0000f3ad, 0x0000f5ad, 0x0000f7ad, - 0x0000f9ad, 0x0000fbad, 0x0000fdad, 0x0000ffad, - 0x000101ad, 0x000103ad, 0x000105ad, 0x000107ad, - 0x000109ad, 0x00010bad, 0x00010dad, 0x00010fad, - 0x000111ad, 0x000113ad, 0x000115ad, 0x000117ad, - 0x000119ad, 0x00011bad, 0x00011dad, 0x00011fad, - 0x000121ad, 0x000123ad, 0x000125ad, 0x000127ad, - 0x000129ad, 0x00012bad, 0x00012dad, 0x00012fad, - 0x000131ad, 0x000133ad, 0x000135ad, 0x000137ad, - 0x000139ad, 0x00013bad, 0x00013dad, 0x00013fad, - 0x000141ad, 0x000143ad, 0x000145ad, 0x000147ad, - 0x000149ad, 0x00014bad, 0x00014dad, 0x00014fad, - 0x000151ad, 0x000153ad, 0x000155ad, 0x000157ad, - 0x000159ad, 0x00015bad, 0x00015dad, 0x00015fad, - 0x000161ad, 0x000163ad, 0x000165ad, 0x000167ad, - 0x000169ad, 0x00016bad, 0x00016dad, 0x00016fad, - 0x000171ad, 0x000173ad, 0x000175ad, 0x000177ad, - 0x000179ad, 0x00017bad, 0x00017dad, 0x00017fad, - 0x000181ad, 0x000183ad, 0x000185ad, 0x000187ad, - 0x000189ad, 0x00018bad, 0x00018dad, 0x00018fad, - 0x000191ad, 0x000193ad, 0x000195ad, 0x000197ad, - 0x000199ad, 0x00019bad, 0x00019dad, 0x00019fad, - 0x0001a1ad, 0x0001a3ad, 0x0001a5ad, 0x0001a7ad, - 0x0001a9ad, 0x0001abad, 0x0001adad, 0x0001afad, - 0x0001b1ad, 0x0001b3ad, 0x0001b5ad, 0x0001b7ad, - 0x0001b9ad, 0x0001bbad, 0x0001bdad, 0x0001bfad, - 0x0001c1ad, 0x0001c3ad, 0x0001c5ad, 0x0001c7ad, - 0x0001c9ad, 0x0001cbad, 0x0001cdad, 0x0001cfad, - 0x0001d1ad, 0x0001d3ad, 0x0001d5ad, 0x0001d7ad, - 0x0001d9ad, 0x0001dbad, 0x0001ddad, 0x0001dfad, - 0x0001e1ad, 0x0001e3ad, 0x0001e5ad, 0x0001e7ad, - 0x0001e9ad, 0x0001ebad, 0x0001edad, 0x0001efad, - 0x0001f1ad, 0x0001f3ad, 0x0001f5ad, 0x0001f7ad, - 0x0001f9ad, 0x0001fbad, 0x0001fdad, 0x0001ffad, - 0x000201ad, 0x000203ad, 0x000205ad, 0x000207ad, - 0x000209ad, 0x00020bad, 0x00020dad, 0x00020fad, - 0x000211ad, 0x000213ad, 0x000215ad, 0x000217ad, - 0x000219ad, 0x00021bad, 0x00021dad, 0x00021fad, - 0x000221ad, 0x000223ad, 0x000225ad, 0x000227ad, - 0x000229ad, 0x00022bad, 0x00022dad, 0x00022fad, - 0x000231ad, 0x000233ad, 0x000235ad, 0x000237ad, - 0x000239ad, 0x00023bad, 0x00023dad, 0x00023fad, - 0x000241ad, 0x000243ad, 0x000245ad, 0x000247ad, - 0x000249ad, 0x00024bad, 0x00024dad, 0x00024fad, - 0x000251ad, 0x000253ad, 0x000255ad, 0x000257ad, - 0x000259ad, 0x00025bad, 0x00025dad, 0x00025fad, - 0x000261ad, 0x000263ad, 0x000265ad, 0x000267ad, - 0x000269ad, 0x00026bad, 0x00026dad, 0x00026fad, - 0x000271ad, 0x000273ad, 0x000275ad, 0x000277ad, - 0x000279ad, 0x00027bad, 0x00027dad, 0x00027fad, - 0x000281ad, 0x000283ad, 0x000285ad, 0x000287ad, - 0x000289ad, 0x00028bad, 0x00028dad, 0x00028fad, - 0x000291ad, 0x000293ad, 0x000295ad, 0x000297ad, - 0x000299ad, 0x00029bad, 0x00029dad, 0x00029fad, - 0x0002a1ad, 0x0002a3ad, 0x0002a5ad, 0x0002a7ad, - 0x0002a9ad, 0x0002abad, 0x0002adad, 0x0002afad, - 0x0002b1ad, 0x0002b3ad, 0x0002b5ad, 0x0002b7ad, - 0x0002b9ad, 0x0002bbad, 0x0002bdad, 0x0002bfad, - 0x0002c1ad, 0x0002c3ad, 0x0002c5ad, 0x0002c7ad, - 0x0002c9ad, 0x0002cbad, 0x0002cdad, 0x0002cfad, - 0x0002d1ad, 0x0002d3ad, 0x0002d5ad, 0x0002d7ad, - 0x0002d9ad, 0x0002dbad, 0x0002ddad, 0x0002dfad, - 0x0002e1ad, 0x0002e3ad, 0x0002e5ad, 0x0002e7ad, - 0x0002e9ad, 0x0002ebad, 0x0002edad, 0x0002efad, - 0x0002f1ad, 0x0002f3ad, 0x0002f5ad, 0x0002f7ad, - 0x0002f9ad, 0x0002fbad, 0x0002fdad, 0x0002ffad, - 0x000301ad, 0x000303ad, 0x000305ad, 0x000307ad, - 0x000309ad, 0x00030bad, 0x00030dad, 0x00030fad, - 0x000311ad, 0x000313ad, 0x000315ad, 0x000317ad, - 0x000319ad, 0x00031bad, 0x00031dad, 0x00031fad, - 0x000321ad, 0x000323ad, 0x000325ad, 0x000327ad, - 0x000329ad, 0x00032bad, 0x00032dad, 0x00032fad, - 0x000331ad, 0x000333ad, 0x000335ad, 0x000337ad, - 0x000339ad, 0x00033bad, 0x00033dad, 0x00033fad, - 0x000341ad, 0x000343ad, 0x000345ad, 0x000347ad, - 0x000349ad, 0x00034bad, 0x00034dad, 0x00034fad, - 0x000351ad, 0x000353ad, 0x000355ad, 0x000357ad, - 0x000359ad, 0x00035bad, 0x00035dad, 0x00035fad, - 0x000361ad, 0x000363ad, 0x000365ad, 0x000367ad, - 0x000369ad, 0x00036bad, 0x00036dad, 0x00036fad, - 0x000371ad, 0x000373ad, 0x000375ad, 0x000377ad, - 0x000379ad, 0x00037bad, 0x00037dad, 0x00037fad, - 0x000381ad, 0x000383ad, 0x000385ad, 0x000387ad, - 0x000389ad, 0x00038bad, 0x00038dad, 0x00038fad, - 0x000391ad, 0x000393ad, 0x000395ad, 0x000397ad, - 0x000399ad, 0x00039bad, 0x00039dad, 0x00039fad, - 0x0003a1ad, 0x0003a3ad, 0x0003a5ad, 0x0003a7ad, - 0x0003a9ad, 0x0003abad, 0x0003adad, 0x0003afad, - 0x0003b1ad, 0x0003b3ad, 0x0003b5ad, 0x0003b7ad, - 0x0003b9ad, 0x0003bbad, 0x0003bdad, 0x0003bfad, - 0x0003c1ad, 0x0003c3ad, 0x0003c5ad, 0x0003c7ad, - 0x0003c9ad, 0x0003cbad, 0x0003cdad, 0x0003cfad, - 0x0003d1ad, 0x0003d3ad, 0x0003d5ad, 0x0003d7ad, - 0x0003d9ad, 0x0003dbad, 0x0003ddad, 0x0003dfad, - 0x0003e1ad, 0x0003e3ad, 0x0003e5ad, 0x0003e7ad, - 0x0003e9ad, 0x0003ebad, 0x0003edad, 0x0003efad, - 0x0003f1ad, 0x0003f3ad, 0x0003f5ad, 0x0003f7ad, - 0x0003f9ad, 0x0003fbad, 0x0003fdad, 0x0003ffad, - 0x0000036e, 0x0000076e, 0x00000b6e, 0x00000f6e, - 0x0000136e, 0x0000176e, 0x00001b6e, 0x00001f6e, - 0x0000236e, 0x0000276e, 0x00002b6e, 0x00002f6e, - 0x0000336e, 0x0000376e, 0x00003b6e, 0x00003f6e, - 0x0000436e, 0x0000476e, 0x00004b6e, 0x00004f6e, - 0x0000536e, 0x0000576e, 0x00005b6e, 0x00005f6e, - 0x0000636e, 0x0000676e, 0x00006b6e, 0x00006f6e, - 0x0000736e, 0x0000776e, 0x00007b6e, 0x00007f6e, - 0x0000836e, 0x0000876e, 0x00008b6e, 0x00008f6e, - 0x0000936e, 0x0000976e, 0x00009b6e, 0x00009f6e, - 0x0000a36e, 0x0000a76e, 0x0000ab6e, 0x0000af6e, - 0x0000b36e, 0x0000b76e, 0x0000bb6e, 0x0000bf6e, - 0x0000c36e, 0x0000c76e, 0x0000cb6e, 0x0000cf6e, - 0x0000d36e, 0x0000d76e, 0x0000db6e, 0x0000df6e, - 0x0000e36e, 0x0000e76e, 0x0000eb6e, 0x0000ef6e, - 0x0000f36e, 0x0000f76e, 0x0000fb6e, 0x0000ff6e, - 0x0001036e, 0x0001076e, 0x00010b6e, 0x00010f6e, - 0x0001136e, 0x0001176e, 0x00011b6e, 0x00011f6e, - 0x0001236e, 0x0001276e, 0x00012b6e, 0x00012f6e, - 0x0001336e, 0x0001376e, 0x00013b6e, 0x00013f6e, - 0x0001436e, 0x0001476e, 0x00014b6e, 0x00014f6e, - 0x0001536e, 0x0001576e, 0x00015b6e, 0x00015f6e, - 0x0001636e, 0x0001676e, 0x00016b6e, 0x00016f6e, - 0x0001736e, 0x0001776e, 0x00017b6e, 0x00017f6e, - 0x0001836e, 0x0001876e, 0x00018b6e, 0x00018f6e, - 0x0001936e, 0x0001976e, 0x00019b6e, 0x00019f6e, - 0x0001a36e, 0x0001a76e, 0x0001ab6e, 0x0001af6e, - 0x0001b36e, 0x0001b76e, 0x0001bb6e, 0x0001bf6e, - 0x0001c36e, 0x0001c76e, 0x0001cb6e, 0x0001cf6e, - 0x0001d36e, 0x0001d76e, 0x0001db6e, 0x0001df6e, - 0x0001e36e, 0x0001e76e, 0x0001eb6e, 0x0001ef6e, - 0x0001f36e, 0x0001f76e, 0x0001fb6e, 0x0001ff6e, - 0x0002036e, 0x0002076e, 0x00020b6e, 0x00020f6e, - 0x0002136e, 0x0002176e, 0x00021b6e, 0x00021f6e, - 0x0002236e, 0x0002276e, 0x00022b6e, 0x00022f6e, - 0x0002336e, 0x0002376e, 0x00023b6e, 0x00023f6e, - 0x0002436e, 0x0002476e, 0x00024b6e, 0x00024f6e, - 0x0002536e, 0x0002576e, 0x00025b6e, 0x00025f6e, - 0x0002636e, 0x0002676e, 0x00026b6e, 0x00026f6e, - 0x0002736e, 0x0002776e, 0x00027b6e, 0x00027f6e, - 0x0002836e, 0x0002876e, 0x00028b6e, 0x00028f6e, - 0x0002936e, 0x0002976e, 0x00029b6e, 0x00029f6e, - 0x0002a36e, 0x0002a76e, 0x0002ab6e, 0x0002af6e, - 0x0002b36e, 0x0002b76e, 0x0002bb6e, 0x0002bf6e, - 0x0002c36e, 0x0002c76e, 0x0002cb6e, 0x0002cf6e, - 0x0002d36e, 0x0002d76e, 0x0002db6e, 0x0002df6e, - 0x0002e36e, 0x0002e76e, 0x0002eb6e, 0x0002ef6e, - 0x0002f36e, 0x0002f76e, 0x0002fb6e, 0x0002ff6e, - 0x0003036e, 0x0003076e, 0x00030b6e, 0x00030f6e, - 0x0003136e, 0x0003176e, 0x00031b6e, 0x00031f6e, - 0x0003236e, 0x0003276e, 0x00032b6e, 0x00032f6e, - 0x0003336e, 0x0003376e, 0x00033b6e, 0x00033f6e, - 0x0003436e, 0x0003476e, 0x00034b6e, 0x00034f6e, - 0x0003536e, 0x0003576e, 0x00035b6e, 0x00035f6e, - 0x0003636e, 0x0003676e, 0x00036b6e, 0x00036f6e, - 0x0003736e, 0x0003776e, 0x00037b6e, 0x00037f6e, - 0x0003836e, 0x0003876e, 0x00038b6e, 0x00038f6e, - 0x0003936e, 0x0003976e, 0x00039b6e, 0x00039f6e, - 0x0003a36e, 0x0003a76e, 0x0003ab6e, 0x0003af6e, - 0x0003b36e, 0x0003b76e, 0x0003bb6e, 0x0003bf6e, - 0x0003c36e, 0x0003c76e, 0x0003cb6e, 0x0003cf6e, - 0x0003d36e, 0x0003d76e, 0x0003db6e, 0x0003df6e, - 0x0003e36e, 0x0003e76e, 0x0003eb6e, 0x0003ef6e, - 0x0003f36e, 0x0003f76e, 0x0003fb6e, 0x0003ff6e, - 0x0004036e, 0x0004076e, 0x00040b6e, 0x00040f6e, - 0x0004136e, 0x0004176e, 0x00041b6e, 0x00041f6e, - 0x0004236e, 0x0004276e, 0x00042b6e, 0x00042f6e, - 0x0004336e, 0x0004376e, 0x00043b6e, 0x00043f6e, - 0x0004436e, 0x0004476e, 0x00044b6e, 0x00044f6e, - 0x0004536e, 0x0004576e, 0x00045b6e, 0x00045f6e, - 0x0004636e, 0x0004676e, 0x00046b6e, 0x00046f6e, - 0x0004736e, 0x0004776e, 0x00047b6e, 0x00047f6e, - 0x0004836e, 0x0004876e, 0x00048b6e, 0x00048f6e, - 0x0004936e, 0x0004976e, 0x00049b6e, 0x00049f6e, - 0x0004a36e, 0x0004a76e, 0x0004ab6e, 0x0004af6e, - 0x0004b36e, 0x0004b76e, 0x0004bb6e, 0x0004bf6e, - 0x0004c36e, 0x0004c76e, 0x0004cb6e, 0x0004cf6e, - 0x0004d36e, 0x0004d76e, 0x0004db6e, 0x0004df6e, - 0x0004e36e, 0x0004e76e, 0x0004eb6e, 0x0004ef6e, - 0x0004f36e, 0x0004f76e, 0x0004fb6e, 0x0004ff6e, - 0x0005036e, 0x0005076e, 0x00050b6e, 0x00050f6e, - 0x0005136e, 0x0005176e, 0x00051b6e, 0x00051f6e, - 0x0005236e, 0x0005276e, 0x00052b6e, 0x00052f6e, - 0x0005336e, 0x0005376e, 0x00053b6e, 0x00053f6e, - 0x0005436e, 0x0005476e, 0x00054b6e, 0x00054f6e, - 0x0005536e, 0x0005576e, 0x00055b6e, 0x00055f6e, - 0x0005636e, 0x0005676e, 0x00056b6e, 0x00056f6e, - 0x0005736e, 0x0005776e, 0x00057b6e, 0x00057f6e, - 0x0005836e, 0x0005876e, 0x00058b6e, 0x00058f6e, - 0x0005936e, 0x0005976e, 0x00059b6e, 0x00059f6e, - 0x0005a36e, 0x0005a76e, 0x0005ab6e, 0x0005af6e, - 0x0005b36e, 0x0005b76e, 0x0005bb6e, 0x0005bf6e, - 0x0005c36e, 0x0005c76e, 0x0005cb6e, 0x0005cf6e, - 0x0005d36e, 0x0005d76e, 0x0005db6e, 0x0005df6e, - 0x0005e36e, 0x0005e76e, 0x0005eb6e, 0x0005ef6e, - 0x0005f36e, 0x0005f76e, 0x0005fb6e, 0x0005ff6e, - 0x0006036e, 0x0006076e, 0x00060b6e, 0x00060f6e, - 0x0006136e, 0x0006176e, 0x00061b6e, 0x00061f6e, - 0x0006236e, 0x0006276e, 0x00062b6e, 0x00062f6e, - 0x0006336e, 0x0006376e, 0x00063b6e, 0x00063f6e, - 0x0006436e, 0x0006476e, 0x00064b6e, 0x00064f6e, - 0x0006536e, 0x0006576e, 0x00065b6e, 0x00065f6e, - 0x0006636e, 0x0006676e, 0x00066b6e, 0x00066f6e, - 0x0006736e, 0x0006776e, 0x00067b6e, 0x00067f6e, - 0x0006836e, 0x0006876e, 0x00068b6e, 0x00068f6e, - 0x0006936e, 0x0006976e, 0x00069b6e, 0x00069f6e, - 0x0006a36e, 0x0006a76e, 0x0006ab6e, 0x0006af6e, - 0x0006b36e, 0x0006b76e, 0x0006bb6e, 0x0006bf6e, - 0x0006c36e, 0x0006c76e, 0x0006cb6e, 0x0006cf6e, - 0x0006d36e, 0x0006d76e, 0x0006db6e, 0x0006df6e, - 0x0006e36e, 0x0006e76e, 0x0006eb6e, 0x0006ef6e, - 0x0006f36e, 0x0006f76e, 0x0006fb6e, 0x0006ff6e, - 0x0007036e, 0x0007076e, 0x00070b6e, 0x00070f6e, - 0x0007136e, 0x0007176e, 0x00071b6e, 0x00071f6e, - 0x0007236e, 0x0007276e, 0x00072b6e, 0x00072f6e, - 0x0007336e, 0x0007376e, 0x00073b6e, 0x00073f6e, - 0x0007436e, 0x0007476e, 0x00074b6e, 0x00074f6e, - 0x0007536e, 0x0007576e, 0x00075b6e, 0x00075f6e, - 0x0007636e, 0x0007676e, 0x00076b6e, 0x00076f6e, - 0x0007736e, 0x0007776e, 0x00077b6e, 0x00077f6e, - 0x0007836e, 0x0007876e, 0x00078b6e, 0x00078f6e, - 0x0007936e, 0x0007976e, 0x00079b6e, 0x00079f6e, - 0x0007a36e, 0x0007a76e, 0x0007ab6e, 0x0007af6e, - 0x0007b36e, 0x0007b76e, 0x0007bb6e, 0x0007bf6e, - 0x0007c36e, 0x0007c76e, 0x0007cb6e, 0x0007cf6e, - 0x0007d36e, 0x0007d76e, 0x0007db6e, 0x0007df6e, - 0x0007e36e, 0x0007e76e, 0x0007eb6e, 0x0007ef6e, - 0x0007f36e, 0x0007f76e, 0x0007fb6e, 0x0007ff6e, - 0x000000ef, 0x000004ef, 0x000008ef, 0x00000cef, - 0x000010ef, 0x000014ef, 0x000018ef, 0x00001cef, - 0x000020ef, 0x000024ef, 0x000028ef, 0x00002cef, - 0x000030ef, 0x000034ef, 0x000038ef, 0x00003cef, - 0x000040ef, 0x000044ef, 0x000048ef, 0x00004cef, - 0x000050ef, 0x000054ef, 0x000058ef, 0x00005cef, - 0x000060ef, 0x000064ef, 0x000068ef, 0x00006cef, - 0x000070ef, 0x000074ef, 0x000078ef, 0x00007cef, - 0x000080ef, 0x000084ef, 0x000088ef, 0x00008cef, - 0x000090ef, 0x000094ef, 0x000098ef, 0x00009cef, - 0x0000a0ef, 0x0000a4ef, 0x0000a8ef, 0x0000acef, - 0x0000b0ef, 0x0000b4ef, 0x0000b8ef, 0x0000bcef, - 0x0000c0ef, 0x0000c4ef, 0x0000c8ef, 0x0000ccef, - 0x0000d0ef, 0x0000d4ef, 0x0000d8ef, 0x0000dcef, - 0x0000e0ef, 0x0000e4ef, 0x0000e8ef, 0x0000ecef, - 0x0000f0ef, 0x0000f4ef, 0x0000f8ef, 0x0000fcef, - 0x000100ef, 0x000104ef, 0x000108ef, 0x00010cef, - 0x000110ef, 0x000114ef, 0x000118ef, 0x00011cef, - 0x000120ef, 0x000124ef, 0x000128ef, 0x00012cef, - 0x000130ef, 0x000134ef, 0x000138ef, 0x00013cef, - 0x000140ef, 0x000144ef, 0x000148ef, 0x00014cef, - 0x000150ef, 0x000154ef, 0x000158ef, 0x00015cef, - 0x000160ef, 0x000164ef, 0x000168ef, 0x00016cef, - 0x000170ef, 0x000174ef, 0x000178ef, 0x00017cef, - 0x000180ef, 0x000184ef, 0x000188ef, 0x00018cef, - 0x000190ef, 0x000194ef, 0x000198ef, 0x00019cef, - 0x0001a0ef, 0x0001a4ef, 0x0001a8ef, 0x0001acef, - 0x0001b0ef, 0x0001b4ef, 0x0001b8ef, 0x0001bcef, - 0x0001c0ef, 0x0001c4ef, 0x0001c8ef, 0x0001ccef, - 0x0001d0ef, 0x0001d4ef, 0x0001d8ef, 0x0001dcef, - 0x0001e0ef, 0x0001e4ef, 0x0001e8ef, 0x0001ecef, - 0x0001f0ef, 0x0001f4ef, 0x0001f8ef, 0x0001fcef, - 0x000200ef, 0x000204ef, 0x000208ef, 0x00020cef, - 0x000210ef, 0x000214ef, 0x000218ef, 0x00021cef, - 0x000220ef, 0x000224ef, 0x000228ef, 0x00022cef, - 0x000230ef, 0x000234ef, 0x000238ef, 0x00023cef, - 0x000240ef, 0x000244ef, 0x000248ef, 0x00024cef, - 0x000250ef, 0x000254ef, 0x000258ef, 0x00025cef, - 0x000260ef, 0x000264ef, 0x000268ef, 0x00026cef, - 0x000270ef, 0x000274ef, 0x000278ef, 0x00027cef, - 0x000280ef, 0x000284ef, 0x000288ef, 0x00028cef, - 0x000290ef, 0x000294ef, 0x000298ef, 0x00029cef, - 0x0002a0ef, 0x0002a4ef, 0x0002a8ef, 0x0002acef, - 0x0002b0ef, 0x0002b4ef, 0x0002b8ef, 0x0002bcef, - 0x0002c0ef, 0x0002c4ef, 0x0002c8ef, 0x0002ccef, - 0x0002d0ef, 0x0002d4ef, 0x0002d8ef, 0x0002dcef, - 0x0002e0ef, 0x0002e4ef, 0x0002e8ef, 0x0002ecef, - 0x0002f0ef, 0x0002f4ef, 0x0002f8ef, 0x0002fcef, - 0x000300ef, 0x000304ef, 0x000308ef, 0x00030cef, - 0x000310ef, 0x000314ef, 0x000318ef, 0x00031cef, - 0x000320ef, 0x000324ef, 0x000328ef, 0x00032cef, - 0x000330ef, 0x000334ef, 0x000338ef, 0x00033cef, - 0x000340ef, 0x000344ef, 0x000348ef, 0x00034cef, - 0x000350ef, 0x000354ef, 0x000358ef, 0x00035cef, - 0x000360ef, 0x000364ef, 0x000368ef, 0x00036cef, - 0x000370ef, 0x000374ef, 0x000378ef, 0x00037cef, - 0x000380ef, 0x000384ef, 0x000388ef, 0x00038cef, - 0x000390ef, 0x000394ef, 0x000398ef, 0x00039cef, - 0x0003a0ef, 0x0003a4ef, 0x0003a8ef, 0x0003acef, - 0x0003b0ef, 0x0003b4ef, 0x0003b8ef, 0x0003bcef, - 0x0003c0ef, 0x0003c4ef, 0x0003c8ef, 0x0003ccef, - 0x0003d0ef, 0x0003d4ef, 0x0003d8ef, 0x0003dcef, - 0x0003e0ef, 0x0003e4ef, 0x0003e8ef, 0x0003ecef, - 0x0003f0ef, 0x0003f4ef, 0x0003f8ef, 0x0003fcef, - 0x000400ef, 0x000404ef, 0x000408ef, 0x00040cef, - 0x000410ef, 0x000414ef, 0x000418ef, 0x00041cef, - 0x000420ef, 0x000424ef, 0x000428ef, 0x00042cef, - 0x000430ef, 0x000434ef, 0x000438ef, 0x00043cef, - 0x000440ef, 0x000444ef, 0x000448ef, 0x00044cef, - 0x000450ef, 0x000454ef, 0x000458ef, 0x00045cef, - 0x000460ef, 0x000464ef, 0x000468ef, 0x00046cef, - 0x000470ef, 0x000474ef, 0x000478ef, 0x00047cef, - 0x000480ef, 0x000484ef, 0x000488ef, 0x00048cef, - 0x000490ef, 0x000494ef, 0x000498ef, 0x00049cef, - 0x0004a0ef, 0x0004a4ef, 0x0004a8ef, 0x0004acef, - 0x0004b0ef, 0x0004b4ef, 0x0004b8ef, 0x0004bcef, - 0x0004c0ef, 0x0004c4ef, 0x0004c8ef, 0x0004ccef, - 0x0004d0ef, 0x0004d4ef, 0x0004d8ef, 0x0004dcef, - 0x0004e0ef, 0x0004e4ef, 0x0004e8ef, 0x0004ecef, - 0x0004f0ef, 0x0004f4ef, 0x0004f8ef, 0x0004fcef, - 0x000500ef, 0x000504ef, 0x000508ef, 0x00050cef, - 0x000510ef, 0x000514ef, 0x000518ef, 0x00051cef, - 0x000520ef, 0x000524ef, 0x000528ef, 0x00052cef, - 0x000530ef, 0x000534ef, 0x000538ef, 0x00053cef, - 0x000540ef, 0x000544ef, 0x000548ef, 0x00054cef, - 0x000550ef, 0x000554ef, 0x000558ef, 0x00055cef, - 0x000560ef, 0x000564ef, 0x000568ef, 0x00056cef, - 0x000570ef, 0x000574ef, 0x000578ef, 0x00057cef, - 0x000580ef, 0x000584ef, 0x000588ef, 0x00058cef, - 0x000590ef, 0x000594ef, 0x000598ef, 0x00059cef, - 0x0005a0ef, 0x0005a4ef, 0x0005a8ef, 0x0005acef, - 0x0005b0ef, 0x0005b4ef, 0x0005b8ef, 0x0005bcef, - 0x0005c0ef, 0x0005c4ef, 0x0005c8ef, 0x0005ccef, - 0x0005d0ef, 0x0005d4ef, 0x0005d8ef, 0x0005dcef, - 0x0005e0ef, 0x0005e4ef, 0x0005e8ef, 0x0005ecef, - 0x0005f0ef, 0x0005f4ef, 0x0005f8ef, 0x0005fcef, - 0x000600ef, 0x000604ef, 0x000608ef, 0x00060cef, - 0x000610ef, 0x000614ef, 0x000618ef, 0x00061cef, - 0x000620ef, 0x000624ef, 0x000628ef, 0x00062cef, - 0x000630ef, 0x000634ef, 0x000638ef, 0x00063cef, - 0x000640ef, 0x000644ef, 0x000648ef, 0x00064cef, - 0x000650ef, 0x000654ef, 0x000658ef, 0x00065cef, - 0x000660ef, 0x000664ef, 0x000668ef, 0x00066cef, - 0x000670ef, 0x000674ef, 0x000678ef, 0x00067cef, - 0x000680ef, 0x000684ef, 0x000688ef, 0x00068cef, - 0x000690ef, 0x000694ef, 0x000698ef, 0x00069cef, - 0x0006a0ef, 0x0006a4ef, 0x0006a8ef, 0x0006acef, - 0x0006b0ef, 0x0006b4ef, 0x0006b8ef, 0x0006bcef, - 0x0006c0ef, 0x0006c4ef, 0x0006c8ef, 0x0006ccef, - 0x0006d0ef, 0x0006d4ef, 0x0006d8ef, 0x0006dcef, - 0x0006e0ef, 0x0006e4ef, 0x0006e8ef, 0x0006ecef, - 0x0006f0ef, 0x0006f4ef, 0x0006f8ef, 0x0006fcef, - 0x000700ef, 0x000704ef, 0x000708ef, 0x00070cef, - 0x000710ef, 0x000714ef, 0x000718ef, 0x00071cef, - 0x000720ef, 0x000724ef, 0x000728ef, 0x00072cef, - 0x000730ef, 0x000734ef, 0x000738ef, 0x00073cef, - 0x000740ef, 0x000744ef, 0x000748ef, 0x00074cef, - 0x000750ef, 0x000754ef, 0x000758ef, 0x00075cef, - 0x000760ef, 0x000764ef, 0x000768ef, 0x00076cef, - 0x000770ef, 0x000774ef, 0x000778ef, 0x00077cef, - 0x000780ef, 0x000784ef, 0x000788ef, 0x00078cef, - 0x000790ef, 0x000794ef, 0x000798ef, 0x00079cef, - 0x0007a0ef, 0x0007a4ef, 0x0007a8ef, 0x0007acef, - 0x0007b0ef, 0x0007b4ef, 0x0007b8ef, 0x0007bcef, - 0x0007c0ef, 0x0007c4ef, 0x0007c8ef, 0x0007ccef, - 0x0007d0ef, 0x0007d4ef, 0x0007d8ef, 0x0007dcef, - 0x0007e0ef, 0x0007e4ef, 0x0007e8ef, 0x0007ecef, - 0x0007f0ef, 0x0007f4ef, 0x0007f8ef, 0x0007fcef, - 0x000800ef, 0x000804ef, 0x000808ef, 0x00080cef, - 0x000810ef, 0x000814ef, 0x000818ef, 0x00081cef, - 0x000820ef, 0x000824ef, 0x000828ef, 0x00082cef, - 0x000830ef, 0x000834ef, 0x000838ef, 0x00083cef, - 0x000840ef, 0x000844ef, 0x000848ef, 0x00084cef, - 0x000850ef, 0x000854ef, 0x000858ef, 0x00085cef, - 0x000860ef, 0x000864ef, 0x000868ef, 0x00086cef, - 0x000870ef, 0x000874ef, 0x000878ef, 0x00087cef, - 0x000880ef, 0x000884ef, 0x000888ef, 0x00088cef, - 0x000890ef, 0x000894ef, 0x000898ef, 0x00089cef, - 0x0008a0ef, 0x0008a4ef, 0x0008a8ef, 0x0008acef, - 0x0008b0ef, 0x0008b4ef, 0x0008b8ef, 0x0008bcef, - 0x0008c0ef, 0x0008c4ef, 0x0008c8ef, 0x0008ccef, - 0x0008d0ef, 0x0008d4ef, 0x0008d8ef, 0x0008dcef, - 0x0008e0ef, 0x0008e4ef, 0x0008e8ef, 0x0008ecef, - 0x0008f0ef, 0x0008f4ef, 0x0008f8ef, 0x0008fcef, - 0x000900ef, 0x000904ef, 0x000908ef, 0x00090cef, - 0x000910ef, 0x000914ef, 0x000918ef, 0x00091cef, - 0x000920ef, 0x000924ef, 0x000928ef, 0x00092cef, - 0x000930ef, 0x000934ef, 0x000938ef, 0x00093cef, - 0x000940ef, 0x000944ef, 0x000948ef, 0x00094cef, - 0x000950ef, 0x000954ef, 0x000958ef, 0x00095cef, - 0x000960ef, 0x000964ef, 0x000968ef, 0x00096cef, - 0x000970ef, 0x000974ef, 0x000978ef, 0x00097cef, - 0x000980ef, 0x000984ef, 0x000988ef, 0x00098cef, - 0x000990ef, 0x000994ef, 0x000998ef, 0x00099cef, - 0x0009a0ef, 0x0009a4ef, 0x0009a8ef, 0x0009acef, - 0x0009b0ef, 0x0009b4ef, 0x0009b8ef, 0x0009bcef, - 0x0009c0ef, 0x0009c4ef, 0x0009c8ef, 0x0009ccef, - 0x0009d0ef, 0x0009d4ef, 0x0009d8ef, 0x0009dcef, - 0x0009e0ef, 0x0009e4ef, 0x0009e8ef, 0x0009ecef, - 0x0009f0ef, 0x0009f4ef, 0x0009f8ef, 0x0009fcef, - 0x000a00ef, 0x000a04ef, 0x000a08ef, 0x000a0cef, - 0x000a10ef, 0x000a14ef, 0x000a18ef, 0x000a1cef, - 0x000a20ef, 0x000a24ef, 0x000a28ef, 0x000a2cef, - 0x000a30ef, 0x000a34ef, 0x000a38ef, 0x000a3cef, - 0x000a40ef, 0x000a44ef, 0x000a48ef, 0x000a4cef, - 0x000a50ef, 0x000a54ef, 0x000a58ef, 0x000a5cef, - 0x000a60ef, 0x000a64ef, 0x000a68ef, 0x000a6cef, - 0x000a70ef, 0x000a74ef, 0x000a78ef, 0x000a7cef, - 0x000a80ef, 0x000a84ef, 0x000a88ef, 0x000a8cef, - 0x000a90ef, 0x000a94ef, 0x000a98ef, 0x000a9cef, - 0x000aa0ef, 0x000aa4ef, 0x000aa8ef, 0x000aacef, - 0x000ab0ef, 0x000ab4ef, 0x000ab8ef, 0x000abcef, - 0x000ac0ef, 0x000ac4ef, 0x000ac8ef, 0x000accef, - 0x000ad0ef, 0x000ad4ef, 0x000ad8ef, 0x000adcef, - 0x000ae0ef, 0x000ae4ef, 0x000ae8ef, 0x000aecef, - 0x000af0ef, 0x000af4ef, 0x000af8ef, 0x000afcef, - 0x000b00ef, 0x000b04ef, 0x000b08ef, 0x000b0cef, - 0x000b10ef, 0x000b14ef, 0x000b18ef, 0x000b1cef, - 0x000b20ef, 0x000b24ef, 0x000b28ef, 0x000b2cef, - 0x000b30ef, 0x000b34ef, 0x000b38ef, 0x000b3cef, - 0x000b40ef, 0x000b44ef, 0x000b48ef, 0x000b4cef, - 0x000b50ef, 0x000b54ef, 0x000b58ef, 0x000b5cef, - 0x000b60ef, 0x000b64ef, 0x000b68ef, 0x000b6cef, - 0x000b70ef, 0x000b74ef, 0x000b78ef, 0x000b7cef, - 0x000b80ef, 0x000b84ef, 0x000b88ef, 0x000b8cef, - 0x000b90ef, 0x000b94ef, 0x000b98ef, 0x000b9cef, - 0x000ba0ef, 0x000ba4ef, 0x000ba8ef, 0x000bacef, - 0x000bb0ef, 0x000bb4ef, 0x000bb8ef, 0x000bbcef, - 0x000bc0ef, 0x000bc4ef, 0x000bc8ef, 0x000bccef, - 0x000bd0ef, 0x000bd4ef, 0x000bd8ef, 0x000bdcef, - 0x000be0ef, 0x000be4ef, 0x000be8ef, 0x000becef, - 0x000bf0ef, 0x000bf4ef, 0x000bf8ef, 0x000bfcef, - 0x000c00ef, 0x000c04ef, 0x000c08ef, 0x000c0cef, - 0x000c10ef, 0x000c14ef, 0x000c18ef, 0x000c1cef, - 0x000c20ef, 0x000c24ef, 0x000c28ef, 0x000c2cef, - 0x000c30ef, 0x000c34ef, 0x000c38ef, 0x000c3cef, - 0x000c40ef, 0x000c44ef, 0x000c48ef, 0x000c4cef, - 0x000c50ef, 0x000c54ef, 0x000c58ef, 0x000c5cef, - 0x000c60ef, 0x000c64ef, 0x000c68ef, 0x000c6cef, - 0x000c70ef, 0x000c74ef, 0x000c78ef, 0x000c7cef, - 0x000c80ef, 0x000c84ef, 0x000c88ef, 0x000c8cef, - 0x000c90ef, 0x000c94ef, 0x000c98ef, 0x000c9cef, - 0x000ca0ef, 0x000ca4ef, 0x000ca8ef, 0x000cacef, - 0x000cb0ef, 0x000cb4ef, 0x000cb8ef, 0x000cbcef, - 0x000cc0ef, 0x000cc4ef, 0x000cc8ef, 0x000cccef, - 0x000cd0ef, 0x000cd4ef, 0x000cd8ef, 0x000cdcef, - 0x000ce0ef, 0x000ce4ef, 0x000ce8ef, 0x000cecef, - 0x000cf0ef, 0x000cf4ef, 0x000cf8ef, 0x000cfcef, - 0x000d00ef, 0x000d04ef, 0x000d08ef, 0x000d0cef, - 0x000d10ef, 0x000d14ef, 0x000d18ef, 0x000d1cef, - 0x000d20ef, 0x000d24ef, 0x000d28ef, 0x000d2cef, - 0x000d30ef, 0x000d34ef, 0x000d38ef, 0x000d3cef, - 0x000d40ef, 0x000d44ef, 0x000d48ef, 0x000d4cef, - 0x000d50ef, 0x000d54ef, 0x000d58ef, 0x000d5cef, - 0x000d60ef, 0x000d64ef, 0x000d68ef, 0x000d6cef, - 0x000d70ef, 0x000d74ef, 0x000d78ef, 0x000d7cef, - 0x000d80ef, 0x000d84ef, 0x000d88ef, 0x000d8cef, - 0x000d90ef, 0x000d94ef, 0x000d98ef, 0x000d9cef, - 0x000da0ef, 0x000da4ef, 0x000da8ef, 0x000dacef, - 0x000db0ef, 0x000db4ef, 0x000db8ef, 0x000dbcef, - 0x000dc0ef, 0x000dc4ef, 0x000dc8ef, 0x000dccef, - 0x000dd0ef, 0x000dd4ef, 0x000dd8ef, 0x000ddcef, - 0x000de0ef, 0x000de4ef, 0x000de8ef, 0x000decef, - 0x000df0ef, 0x000df4ef, 0x000df8ef, 0x000dfcef, - 0x000e00ef, 0x000e04ef, 0x000e08ef, 0x000e0cef, - 0x000e10ef, 0x000e14ef, 0x000e18ef, 0x000e1cef, - 0x000e20ef, 0x000e24ef, 0x000e28ef, 0x000e2cef, - 0x000e30ef, 0x000e34ef, 0x000e38ef, 0x000e3cef, - 0x000e40ef, 0x000e44ef, 0x000e48ef, 0x000e4cef, - 0x000e50ef, 0x000e54ef, 0x000e58ef, 0x000e5cef, - 0x000e60ef, 0x000e64ef, 0x000e68ef, 0x000e6cef, - 0x000e70ef, 0x000e74ef, 0x000e78ef, 0x000e7cef, - 0x000e80ef, 0x000e84ef, 0x000e88ef, 0x000e8cef, - 0x000e90ef, 0x000e94ef, 0x000e98ef, 0x000e9cef, - 0x000ea0ef, 0x000ea4ef, 0x000ea8ef, 0x000eacef, - 0x000eb0ef, 0x000eb4ef, 0x000eb8ef, 0x000ebcef, - 0x000ec0ef, 0x000ec4ef, 0x000ec8ef, 0x000eccef, - 0x000ed0ef, 0x000ed4ef, 0x000ed8ef, 0x000edcef, - 0x000ee0ef, 0x000ee4ef, 0x000ee8ef, 0x000eecef, - 0x000ef0ef, 0x000ef4ef, 0x000ef8ef, 0x000efcef, - 0x000f00ef, 0x000f04ef, 0x000f08ef, 0x000f0cef, - 0x000f10ef, 0x000f14ef, 0x000f18ef, 0x000f1cef, - 0x000f20ef, 0x000f24ef, 0x000f28ef, 0x000f2cef, - 0x000f30ef, 0x000f34ef, 0x000f38ef, 0x000f3cef, - 0x000f40ef, 0x000f44ef, 0x000f48ef, 0x000f4cef, - 0x000f50ef, 0x000f54ef, 0x000f58ef, 0x000f5cef, - 0x000f60ef, 0x000f64ef, 0x000f68ef, 0x000f6cef, - 0x000f70ef, 0x000f74ef, 0x000f78ef, 0x000f7cef, - 0x000f80ef, 0x000f84ef, 0x000f88ef, 0x000f8cef, - 0x000f90ef, 0x000f94ef, 0x000f98ef, 0x000f9cef, - 0x000fa0ef, 0x000fa4ef, 0x000fa8ef, 0x000facef, - 0x000fb0ef, 0x000fb4ef, 0x000fb8ef, 0x000fbcef, - 0x000fc0ef, 0x000fc4ef, 0x000fc8ef, 0x000fccef, - 0x000fd0ef, 0x000fd4ef, 0x000fd8ef, 0x000fdcef, - 0x000fe0ef, 0x000fe4ef, 0x000fe8ef, 0x000fecef, - 0x000ff0ef, 0x000ff4ef, 0x000ff8ef, 0x000ffcef, - 0x000002ef, 0x000006ef, 0x00000aef, 0x00000eef, - 0x000012ef, 0x000016ef, 0x00001aef, 0x00001eef, - 0x000022ef, 0x000026ef, 0x00002aef, 0x00002eef, - 0x000032ef, 0x000036ef, 0x00003aef, 0x00003eef, - 0x000042ef, 0x000046ef, 0x00004aef, 0x00004eef, - 0x000052ef, 0x000056ef, 0x00005aef, 0x00005eef, - 0x000062ef, 0x000066ef, 0x00006aef, 0x00006eef, - 0x000072ef, 0x000076ef, 0x00007aef, 0x00007eef, - 0x000082ef, 0x000086ef, 0x00008aef, 0x00008eef, - 0x000092ef, 0x000096ef, 0x00009aef, 0x00009eef, - 0x0000a2ef, 0x0000a6ef, 0x0000aaef, 0x0000aeef, - 0x0000b2ef, 0x0000b6ef, 0x0000baef, 0x0000beef, - 0x0000c2ef, 0x0000c6ef, 0x0000caef, 0x0000ceef, - 0x0000d2ef, 0x0000d6ef, 0x0000daef, 0x0000deef, - 0x0000e2ef, 0x0000e6ef, 0x0000eaef, 0x0000eeef, - 0x0000f2ef, 0x0000f6ef, 0x0000faef, 0x0000feef, - 0x000102ef, 0x000106ef, 0x00010aef, 0x00010eef, - 0x000112ef, 0x000116ef, 0x00011aef, 0x00011eef, - 0x000122ef, 0x000126ef, 0x00012aef, 0x00012eef, - 0x000132ef, 0x000136ef, 0x00013aef, 0x00013eef, - 0x000142ef, 0x000146ef, 0x00014aef, 0x00014eef, - 0x000152ef, 0x000156ef, 0x00015aef, 0x00015eef, - 0x000162ef, 0x000166ef, 0x00016aef, 0x00016eef, - 0x000172ef, 0x000176ef, 0x00017aef, 0x00017eef, - 0x000182ef, 0x000186ef, 0x00018aef, 0x00018eef, - 0x000192ef, 0x000196ef, 0x00019aef, 0x00019eef, - 0x0001a2ef, 0x0001a6ef, 0x0001aaef, 0x0001aeef, - 0x0001b2ef, 0x0001b6ef, 0x0001baef, 0x0001beef, - 0x0001c2ef, 0x0001c6ef, 0x0001caef, 0x0001ceef, - 0x0001d2ef, 0x0001d6ef, 0x0001daef, 0x0001deef, - 0x0001e2ef, 0x0001e6ef, 0x0001eaef, 0x0001eeef, - 0x0001f2ef, 0x0001f6ef, 0x0001faef, 0x0001feef, - 0x000202ef, 0x000206ef, 0x00020aef, 0x00020eef, - 0x000212ef, 0x000216ef, 0x00021aef, 0x00021eef, - 0x000222ef, 0x000226ef, 0x00022aef, 0x00022eef, - 0x000232ef, 0x000236ef, 0x00023aef, 0x00023eef, - 0x000242ef, 0x000246ef, 0x00024aef, 0x00024eef, - 0x000252ef, 0x000256ef, 0x00025aef, 0x00025eef, - 0x000262ef, 0x000266ef, 0x00026aef, 0x00026eef, - 0x000272ef, 0x000276ef, 0x00027aef, 0x00027eef, - 0x000282ef, 0x000286ef, 0x00028aef, 0x00028eef, - 0x000292ef, 0x000296ef, 0x00029aef, 0x00029eef, - 0x0002a2ef, 0x0002a6ef, 0x0002aaef, 0x0002aeef, - 0x0002b2ef, 0x0002b6ef, 0x0002baef, 0x0002beef, - 0x0002c2ef, 0x0002c6ef, 0x0002caef, 0x0002ceef, - 0x0002d2ef, 0x0002d6ef, 0x0002daef, 0x0002deef, - 0x0002e2ef, 0x0002e6ef, 0x0002eaef, 0x0002eeef, - 0x0002f2ef, 0x0002f6ef, 0x0002faef, 0x0002feef, - 0x000302ef, 0x000306ef, 0x00030aef, 0x00030eef, - 0x000312ef, 0x000316ef, 0x00031aef, 0x00031eef, - 0x000322ef, 0x000326ef, 0x00032aef, 0x00032eef, - 0x000332ef, 0x000336ef, 0x00033aef, 0x00033eef, - 0x000342ef, 0x000346ef, 0x00034aef, 0x00034eef, - 0x000352ef, 0x000356ef, 0x00035aef, 0x00035eef, - 0x000362ef, 0x000366ef, 0x00036aef, 0x00036eef, - 0x000372ef, 0x000376ef, 0x00037aef, 0x00037eef, - 0x000382ef, 0x000386ef, 0x00038aef, 0x00038eef, - 0x000392ef, 0x000396ef, 0x00039aef, 0x00039eef, - 0x0003a2ef, 0x0003a6ef, 0x0003aaef, 0x0003aeef, - 0x0003b2ef, 0x0003b6ef, 0x0003baef, 0x0003beef, - 0x0003c2ef, 0x0003c6ef, 0x0003caef, 0x0003ceef, - 0x0003d2ef, 0x0003d6ef, 0x0003daef, 0x0003deef, - 0x0003e2ef, 0x0003e6ef, 0x0003eaef, 0x0003eeef, - 0x0003f2ef, 0x0003f6ef, 0x0003faef, 0x0003feef, - 0x000402ef, 0x000406ef, 0x00040aef, 0x00040eef, - 0x000412ef, 0x000416ef, 0x00041aef, 0x00041eef, - 0x000422ef, 0x000426ef, 0x00042aef, 0x00042eef, - 0x000432ef, 0x000436ef, 0x00043aef, 0x00043eef, - 0x000442ef, 0x000446ef, 0x00044aef, 0x00044eef, - 0x000452ef, 0x000456ef, 0x00045aef, 0x00045eef, - 0x000462ef, 0x000466ef, 0x00046aef, 0x00046eef, - 0x000472ef, 0x000476ef, 0x00047aef, 0x00047eef, - 0x000482ef, 0x000486ef, 0x00048aef, 0x00048eef, - 0x000492ef, 0x000496ef, 0x00049aef, 0x00049eef, - 0x0004a2ef, 0x0004a6ef, 0x0004aaef, 0x0004aeef, - 0x0004b2ef, 0x0004b6ef, 0x0004baef, 0x0004beef, - 0x0004c2ef, 0x0004c6ef, 0x0004caef, 0x0004ceef, - 0x0004d2ef, 0x0004d6ef, 0x0004daef, 0x0004deef, - 0x0004e2ef, 0x0004e6ef, 0x0004eaef, 0x0004eeef, - 0x0004f2ef, 0x0004f6ef, 0x0004faef, 0x0004feef, - 0x000502ef, 0x000506ef, 0x00050aef, 0x00050eef, - 0x000512ef, 0x000516ef, 0x00051aef, 0x00051eef, - 0x000522ef, 0x000526ef, 0x00052aef, 0x00052eef, - 0x000532ef, 0x000536ef, 0x00053aef, 0x00053eef, - 0x000542ef, 0x000546ef, 0x00054aef, 0x00054eef, - 0x000552ef, 0x000556ef, 0x00055aef, 0x00055eef, - 0x000562ef, 0x000566ef, 0x00056aef, 0x00056eef, - 0x000572ef, 0x000576ef, 0x00057aef, 0x00057eef, - 0x000582ef, 0x000586ef, 0x00058aef, 0x00058eef, - 0x000592ef, 0x000596ef, 0x00059aef, 0x00059eef, - 0x0005a2ef, 0x0005a6ef, 0x0005aaef, 0x0005aeef, - 0x0005b2ef, 0x0005b6ef, 0x0005baef, 0x0005beef, - 0x0005c2ef, 0x0005c6ef, 0x0005caef, 0x0005ceef, - 0x0005d2ef, 0x0005d6ef, 0x0005daef, 0x0005deef, - 0x0005e2ef, 0x0005e6ef, 0x0005eaef, 0x0005eeef, - 0x0005f2ef, 0x0005f6ef, 0x0005faef, 0x0005feef, - 0x000602ef, 0x000606ef, 0x00060aef, 0x00060eef, - 0x000612ef, 0x000616ef, 0x00061aef, 0x00061eef, - 0x000622ef, 0x000626ef, 0x00062aef, 0x00062eef, - 0x000632ef, 0x000636ef, 0x00063aef, 0x00063eef, - 0x000642ef, 0x000646ef, 0x00064aef, 0x00064eef, - 0x000652ef, 0x000656ef, 0x00065aef, 0x00065eef, - 0x000662ef, 0x000666ef, 0x00066aef, 0x00066eef, - 0x000672ef, 0x000676ef, 0x00067aef, 0x00067eef, - 0x000682ef, 0x000686ef, 0x00068aef, 0x00068eef, - 0x000692ef, 0x000696ef, 0x00069aef, 0x00069eef, - 0x0006a2ef, 0x0006a6ef, 0x0006aaef, 0x0006aeef, - 0x0006b2ef, 0x0006b6ef, 0x0006baef, 0x0006beef, - 0x0006c2ef, 0x0006c6ef, 0x0006caef, 0x0006ceef, - 0x0006d2ef, 0x0006d6ef, 0x0006daef, 0x0006deef, - 0x0006e2ef, 0x0006e6ef, 0x0006eaef, 0x0006eeef, - 0x0006f2ef, 0x0006f6ef, 0x0006faef, 0x0006feef, - 0x000702ef, 0x000706ef, 0x00070aef, 0x00070eef, - 0x000712ef, 0x000716ef, 0x00071aef, 0x00071eef, - 0x000722ef, 0x000726ef, 0x00072aef, 0x00072eef, - 0x000732ef, 0x000736ef, 0x00073aef, 0x00073eef, - 0x000742ef, 0x000746ef, 0x00074aef, 0x00074eef, - 0x000752ef, 0x000756ef, 0x00075aef, 0x00075eef, - 0x000762ef, 0x000766ef, 0x00076aef, 0x00076eef, - 0x000772ef, 0x000776ef, 0x00077aef, 0x00077eef, - 0x000782ef, 0x000786ef, 0x00078aef, 0x00078eef, - 0x000792ef, 0x000796ef, 0x00079aef, 0x00079eef, - 0x0007a2ef, 0x0007a6ef, 0x0007aaef, 0x0007aeef, - 0x0007b2ef, 0x0007b6ef, 0x0007baef, 0x0007beef, - 0x0007c2ef, 0x0007c6ef, 0x0007caef, 0x0007ceef, - 0x0007d2ef, 0x0007d6ef, 0x0007daef, 0x0007deef, - 0x0007e2ef, 0x0007e6ef, 0x0007eaef, 0x0007eeef, - 0x0007f2ef, 0x0007f6ef, 0x0007faef, 0x0007feef, - 0x000802ef, 0x000806ef, 0x00080aef, 0x00080eef, - 0x000812ef, 0x000816ef, 0x00081aef, 0x00081eef, - 0x000822ef, 0x000826ef, 0x00082aef, 0x00082eef, - 0x000832ef, 0x000836ef, 0x00083aef, 0x00083eef, - 0x000842ef, 0x000846ef, 0x00084aef, 0x00084eef, - 0x000852ef, 0x000856ef, 0x00085aef, 0x00085eef, - 0x000862ef, 0x000866ef, 0x00086aef, 0x00086eef, - 0x000872ef, 0x000876ef, 0x00087aef, 0x00087eef, - 0x000882ef, 0x000886ef, 0x00088aef, 0x00088eef, - 0x000892ef, 0x000896ef, 0x00089aef, 0x00089eef, - 0x0008a2ef, 0x0008a6ef, 0x0008aaef, 0x0008aeef, - 0x0008b2ef, 0x0008b6ef, 0x0008baef, 0x0008beef, - 0x0008c2ef, 0x0008c6ef, 0x0008caef, 0x0008ceef, - 0x0008d2ef, 0x0008d6ef, 0x0008daef, 0x0008deef, - 0x0008e2ef, 0x0008e6ef, 0x0008eaef, 0x0008eeef, - 0x0008f2ef, 0x0008f6ef, 0x0008faef, 0x0008feef, - 0x000902ef, 0x000906ef, 0x00090aef, 0x00090eef, - 0x000912ef, 0x000916ef, 0x00091aef, 0x00091eef, - 0x000922ef, 0x000926ef, 0x00092aef, 0x00092eef, - 0x000932ef, 0x000936ef, 0x00093aef, 0x00093eef, - 0x000942ef, 0x000946ef, 0x00094aef, 0x00094eef, - 0x000952ef, 0x000956ef, 0x00095aef, 0x00095eef, - 0x000962ef, 0x000966ef, 0x00096aef, 0x00096eef, - 0x000972ef, 0x000976ef, 0x00097aef, 0x00097eef, - 0x000982ef, 0x000986ef, 0x00098aef, 0x00098eef, - 0x000992ef, 0x000996ef, 0x00099aef, 0x00099eef, - 0x0009a2ef, 0x0009a6ef, 0x0009aaef, 0x0009aeef, - 0x0009b2ef, 0x0009b6ef, 0x0009baef, 0x0009beef, - 0x0009c2ef, 0x0009c6ef, 0x0009caef, 0x0009ceef, - 0x0009d2ef, 0x0009d6ef, 0x0009daef, 0x0009deef, - 0x0009e2ef, 0x0009e6ef, 0x0009eaef, 0x0009eeef, - 0x0009f2ef, 0x0009f6ef, 0x0009faef, 0x0009feef, - 0x000a02ef, 0x000a06ef, 0x000a0aef, 0x000a0eef, - 0x000a12ef, 0x000a16ef, 0x000a1aef, 0x000a1eef, - 0x000a22ef, 0x000a26ef, 0x000a2aef, 0x000a2eef, - 0x000a32ef, 0x000a36ef, 0x000a3aef, 0x000a3eef, - 0x000a42ef, 0x000a46ef, 0x000a4aef, 0x000a4eef, - 0x000a52ef, 0x000a56ef, 0x000a5aef, 0x000a5eef, - 0x000a62ef, 0x000a66ef, 0x000a6aef, 0x000a6eef, - 0x000a72ef, 0x000a76ef, 0x000a7aef, 0x000a7eef, - 0x000a82ef, 0x000a86ef, 0x000a8aef, 0x000a8eef, - 0x000a92ef, 0x000a96ef, 0x000a9aef, 0x000a9eef, - 0x000aa2ef, 0x000aa6ef, 0x000aaaef, 0x000aaeef, - 0x000ab2ef, 0x000ab6ef, 0x000abaef, 0x000abeef, - 0x000ac2ef, 0x000ac6ef, 0x000acaef, 0x000aceef, - 0x000ad2ef, 0x000ad6ef, 0x000adaef, 0x000adeef, - 0x000ae2ef, 0x000ae6ef, 0x000aeaef, 0x000aeeef, - 0x000af2ef, 0x000af6ef, 0x000afaef, 0x000afeef, - 0x000b02ef, 0x000b06ef, 0x000b0aef, 0x000b0eef, - 0x000b12ef, 0x000b16ef, 0x000b1aef, 0x000b1eef, - 0x000b22ef, 0x000b26ef, 0x000b2aef, 0x000b2eef, - 0x000b32ef, 0x000b36ef, 0x000b3aef, 0x000b3eef, - 0x000b42ef, 0x000b46ef, 0x000b4aef, 0x000b4eef, - 0x000b52ef, 0x000b56ef, 0x000b5aef, 0x000b5eef, - 0x000b62ef, 0x000b66ef, 0x000b6aef, 0x000b6eef, - 0x000b72ef, 0x000b76ef, 0x000b7aef, 0x000b7eef, - 0x000b82ef, 0x000b86ef, 0x000b8aef, 0x000b8eef, - 0x000b92ef, 0x000b96ef, 0x000b9aef, 0x000b9eef, - 0x000ba2ef, 0x000ba6ef, 0x000baaef, 0x000baeef, - 0x000bb2ef, 0x000bb6ef, 0x000bbaef, 0x000bbeef, - 0x000bc2ef, 0x000bc6ef, 0x000bcaef, 0x000bceef, - 0x000bd2ef, 0x000bd6ef, 0x000bdaef, 0x000bdeef, - 0x000be2ef, 0x000be6ef, 0x000beaef, 0x000beeef, - 0x000bf2ef, 0x000bf6ef, 0x000bfaef, 0x000bfeef, - 0x000c02ef, 0x000c06ef, 0x000c0aef, 0x000c0eef, - 0x000c12ef, 0x000c16ef, 0x000c1aef, 0x000c1eef, - 0x000c22ef, 0x000c26ef, 0x000c2aef, 0x000c2eef, - 0x000c32ef, 0x000c36ef, 0x000c3aef, 0x000c3eef, - 0x000c42ef, 0x000c46ef, 0x000c4aef, 0x000c4eef, - 0x000c52ef, 0x000c56ef, 0x000c5aef, 0x000c5eef, - 0x000c62ef, 0x000c66ef, 0x000c6aef, 0x000c6eef, - 0x000c72ef, 0x000c76ef, 0x000c7aef, 0x000c7eef, - 0x000c82ef, 0x000c86ef, 0x000c8aef, 0x000c8eef, - 0x000c92ef, 0x000c96ef, 0x000c9aef, 0x000c9eef, - 0x000ca2ef, 0x000ca6ef, 0x000caaef, 0x000caeef, - 0x000cb2ef, 0x000cb6ef, 0x000cbaef, 0x000cbeef, - 0x000cc2ef, 0x000cc6ef, 0x000ccaef, 0x000cceef, - 0x000cd2ef, 0x000cd6ef, 0x000cdaef, 0x000cdeef, - 0x000ce2ef, 0x000ce6ef, 0x000ceaef, 0x000ceeef, - 0x000cf2ef, 0x000cf6ef, 0x000cfaef, 0x000cfeef, - 0x000d02ef, 0x000d06ef, 0x000d0aef, 0x000d0eef, - 0x000d12ef, 0x000d16ef, 0x000d1aef, 0x000d1eef, - 0x000d22ef, 0x000d26ef, 0x000d2aef, 0x000d2eef, - 0x000d32ef, 0x000d36ef, 0x000d3aef, 0x000d3eef, - 0x000d42ef, 0x000d46ef, 0x000d4aef, 0x000d4eef, - 0x000d52ef, 0x000d56ef, 0x000d5aef, 0x000d5eef, - 0x000d62ef, 0x000d66ef, 0x000d6aef, 0x000d6eef, - 0x000d72ef, 0x000d76ef, 0x000d7aef, 0x000d7eef, - 0x000d82ef, 0x000d86ef, 0x000d8aef, 0x000d8eef, - 0x000d92ef, 0x000d96ef, 0x000d9aef, 0x000d9eef, - 0x000da2ef, 0x000da6ef, 0x000daaef, 0x000daeef, - 0x000db2ef, 0x000db6ef, 0x000dbaef, 0x000dbeef, - 0x000dc2ef, 0x000dc6ef, 0x000dcaef, 0x000dceef, - 0x000dd2ef, 0x000dd6ef, 0x000ddaef, 0x000ddeef, - 0x000de2ef, 0x000de6ef, 0x000deaef, 0x000deeef, - 0x000df2ef, 0x000df6ef, 0x000dfaef, 0x000dfeef, - 0x000e02ef, 0x000e06ef, 0x000e0aef, 0x000e0eef, - 0x000e12ef, 0x000e16ef, 0x000e1aef, 0x000e1eef, - 0x000e22ef, 0x000e26ef, 0x000e2aef, 0x000e2eef, - 0x000e32ef, 0x000e36ef, 0x000e3aef, 0x000e3eef, - 0x000e42ef, 0x000e46ef, 0x000e4aef, 0x000e4eef, - 0x000e52ef, 0x000e56ef, 0x000e5aef, 0x000e5eef, - 0x000e62ef, 0x000e66ef, 0x000e6aef, 0x000e6eef, - 0x000e72ef, 0x000e76ef, 0x000e7aef, 0x000e7eef, - 0x000e82ef, 0x000e86ef, 0x000e8aef, 0x000e8eef, - 0x000e92ef, 0x000e96ef, 0x000e9aef, 0x000e9eef, - 0x000ea2ef, 0x000ea6ef, 0x000eaaef, 0x000eaeef, - 0x000eb2ef, 0x000eb6ef, 0x000ebaef, 0x000ebeef, - 0x000ec2ef, 0x000ec6ef, 0x000ecaef, 0x000eceef, - 0x000ed2ef, 0x000ed6ef, 0x000edaef, 0x000edeef, - 0x000ee2ef, 0x000ee6ef, 0x000eeaef, 0x000eeeef, - 0x000ef2ef, 0x000ef6ef, 0x000efaef, 0x000efeef, - 0x000f02ef, 0x000f06ef, 0x000f0aef, 0x000f0eef, - 0x000f12ef, 0x000f16ef, 0x000f1aef, 0x000f1eef, - 0x000f22ef, 0x000f26ef, 0x000f2aef, 0x000f2eef, - 0x000f32ef, 0x000f36ef, 0x000f3aef, 0x000f3eef, - 0x000f42ef, 0x000f46ef, 0x000f4aef, 0x000f4eef, - 0x000f52ef, 0x000f56ef, 0x000f5aef, 0x000f5eef, - 0x000f62ef, 0x000f66ef, 0x000f6aef, 0x000f6eef, - 0x000f72ef, 0x000f76ef, 0x000f7aef, 0x000f7eef, - 0x000f82ef, 0x000f86ef, 0x000f8aef, 0x000f8eef, - 0x000f92ef, 0x000f96ef, 0x000f9aef, 0x000f9eef, - 0x000fa2ef, 0x000fa6ef, 0x000faaef, 0x000faeef, - 0x000fb2ef, 0x000fb6ef, 0x000fbaef, 0x000fbeef, - 0x000fc2ef, 0x000fc6ef, 0x000fcaef, 0x000fceef, - 0x000fd2ef, 0x000fd6ef, 0x000fdaef, 0x000fdeef, - 0x000fe2ef, 0x000fe6ef, 0x000feaef, 0x000feeef, - 0x000ff2ef, 0x000ff6ef, 0x000ffaef, 0x000ffeef, - 0x000017f4, 0x000057f4, 0x000097f4, 0x0000d7f4, - 0x000117f4, 0x000157f4, 0x000197f4, 0x0001d7f4, - 0x000217f4, 0x000257f4, 0x000297f4, 0x0002d7f4, - 0x000317f4, 0x000357f4, 0x000397f4, 0x0003d7f4, - 0x000417f4, 0x000457f4, 0x000497f4, 0x0004d7f4, - 0x000517f4, 0x000557f4, 0x000597f4, 0x0005d7f4, - 0x000617f4, 0x000657f4, 0x000697f4, 0x0006d7f4, - 0x000717f4, 0x000757f4, 0x000797f4, 0x0007d7f4, - 0x000817f4, 0x000857f4, 0x000897f4, 0x0008d7f4, - 0x000917f4, 0x000957f4, 0x000997f4, 0x0009d7f4, - 0x000a17f4, 0x000a57f4, 0x000a97f4, 0x000ad7f4, - 0x000b17f4, 0x000b57f4, 0x000b97f4, 0x000bd7f4, - 0x000c17f4, 0x000c57f4, 0x000c97f4, 0x000cd7f4, - 0x000d17f4, 0x000d57f4, 0x000d97f4, 0x000dd7f4, - 0x000e17f4, 0x000e57f4, 0x000e97f4, 0x000ed7f4, - 0x000f17f4, 0x000f57f4, 0x000f97f4, 0x000fd7f4, - 0x001017f4, 0x001057f4, 0x001097f4, 0x0010d7f4, - 0x001117f4, 0x001157f4, 0x001197f4, 0x0011d7f4, - 0x001217f4, 0x001257f4, 0x001297f4, 0x0012d7f4, - 0x001317f4, 0x001357f4, 0x001397f4, 0x0013d7f4, - 0x001417f4, 0x001457f4, 0x001497f4, 0x0014d7f4, - 0x001517f4, 0x001557f4, 0x001597f4, 0x0015d7f4, - 0x001617f4, 0x001657f4, 0x001697f4, 0x0016d7f4, - 0x001717f4, 0x001757f4, 0x001797f4, 0x0017d7f4, - 0x001817f4, 0x001857f4, 0x001897f4, 0x0018d7f4, - 0x001917f4, 0x001957f4, 0x001997f4, 0x0019d7f4, - 0x001a17f4, 0x001a57f4, 0x001a97f4, 0x001ad7f4, - 0x001b17f4, 0x001b57f4, 0x001b97f4, 0x001bd7f4, - 0x001c17f4, 0x001c57f4, 0x001c97f4, 0x001cd7f4, - 0x001d17f4, 0x001d57f4, 0x001d97f4, 0x001dd7f4, - 0x001e17f4, 0x001e57f4, 0x001e97f4, 0x001ed7f4, - 0x001f17f4, 0x001f57f4, 0x001f97f4, 0x001fd7f4, - 0x002017f4, 0x002057f4, 0x002097f4, 0x0020d7f4, - 0x002117f4, 0x002157f4, 0x002197f4, 0x0021d7f4, - 0x002217f4, 0x002257f4, 0x002297f4, 0x0022d7f4, - 0x002317f4, 0x002357f4, 0x002397f4, 0x0023d7f4, - 0x002417f4, 0x002457f4, 0x002497f4, 0x0024d7f4, - 0x002517f4, 0x002557f4, 0x002597f4, 0x0025d7f4, - 0x002617f4, 0x002657f4, 0x002697f4, 0x0026d7f4, - 0x002717f4, 0x002757f4, 0x002797f4, 0x0027d7f4, - 0x002817f4, 0x002857f4, 0x002897f4, 0x0028d7f4, - 0x002917f4, 0x002957f4, 0x002997f4, 0x0029d7f4, - 0x002a17f4, 0x002a57f4, 0x002a97f4, 0x002ad7f4, - 0x002b17f4, 0x002b57f4, 0x002b97f4, 0x002bd7f4, - 0x002c17f4, 0x002c57f4, 0x002c97f4, 0x002cd7f4, - 0x002d17f4, 0x002d57f4, 0x002d97f4, 0x002dd7f4, - 0x002e17f4, 0x002e57f4, 0x002e97f4, 0x002ed7f4, - 0x002f17f4, 0x002f57f4, 0x002f97f4, 0x002fd7f4, - 0x003017f4, 0x003057f4, 0x003097f4, 0x0030d7f4, - 0x003117f4, 0x003157f4, 0x003197f4, 0x0031d7f4, - 0x003217f4, 0x003257f4, 0x003297f4, 0x0032d7f4, - 0x003317f4, 0x003357f4, 0x003397f4, 0x0033d7f4, - 0x003417f4, 0x003457f4, 0x003497f4, 0x0034d7f4, - 0x003517f4, 0x003557f4, 0x003597f4, 0x0035d7f4, - 0x003617f4, 0x003657f4, 0x003697f4, 0x0036d7f4, - 0x003717f4, 0x003757f4, 0x003797f4, 0x0037d7f4, - 0x003817f4, 0x003857f4, 0x003897f4, 0x0038d7f4, - 0x003917f4, 0x003957f4, 0x003997f4, 0x0039d7f4, - 0x003a17f4, 0x003a57f4, 0x003a97f4, 0x003ad7f4, - 0x003b17f4, 0x003b57f4, 0x003b97f4, 0x003bd7f4, - 0x003c17f4, 0x003c57f4, 0x003c97f4, 0x003cd7f4, - 0x003d17f4, 0x003d57f4, 0x003d97f4, 0x003dd7f4, - 0x003e17f4, 0x003e57f4, 0x003e97f4, 0x003ed7f4, - 0x003f17f4, 0x003f57f4, 0x003f97f4, 0x003fd7f4, - 0x004017f4, 0x004057f4, 0x004097f4, 0x0040d7f4, - 0x004117f4, 0x004157f4, 0x004197f4, 0x0041d7f4, - 0x004217f4, 0x004257f4, 0x004297f4, 0x0042d7f4, - 0x004317f4, 0x004357f4, 0x004397f4, 0x0043d7f4, - 0x004417f4, 0x004457f4, 0x004497f4, 0x0044d7f4, - 0x004517f4, 0x004557f4, 0x004597f4, 0x0045d7f4, - 0x004617f4, 0x004657f4, 0x004697f4, 0x0046d7f4, - 0x004717f4, 0x004757f4, 0x004797f4, 0x0047d7f4, - 0x004817f4, 0x004857f4, 0x004897f4, 0x0048d7f4, - 0x004917f4, 0x004957f4, 0x004997f4, 0x0049d7f4, - 0x004a17f4, 0x004a57f4, 0x004a97f4, 0x004ad7f4, - 0x004b17f4, 0x004b57f4, 0x004b97f4, 0x004bd7f4, - 0x004c17f4, 0x004c57f4, 0x004c97f4, 0x004cd7f4, - 0x004d17f4, 0x004d57f4, 0x004d97f4, 0x004dd7f4, - 0x004e17f4, 0x004e57f4, 0x004e97f4, 0x004ed7f4, - 0x004f17f4, 0x004f57f4, 0x004f97f4, 0x004fd7f4, - 0x005017f4, 0x005057f4, 0x005097f4, 0x0050d7f4, - 0x005117f4, 0x005157f4, 0x005197f4, 0x0051d7f4, - 0x005217f4, 0x005257f4, 0x005297f4, 0x0052d7f4, - 0x005317f4, 0x005357f4, 0x005397f4, 0x0053d7f4, - 0x005417f4, 0x005457f4, 0x005497f4, 0x0054d7f4, - 0x005517f4, 0x005557f4, 0x005597f4, 0x0055d7f4, - 0x005617f4, 0x005657f4, 0x005697f4, 0x0056d7f4, - 0x005717f4, 0x005757f4, 0x005797f4, 0x0057d7f4, - 0x005817f4, 0x005857f4, 0x005897f4, 0x0058d7f4, - 0x005917f4, 0x005957f4, 0x005997f4, 0x0059d7f4, - 0x005a17f4, 0x005a57f4, 0x005a97f4, 0x005ad7f4, - 0x005b17f4, 0x005b57f4, 0x005b97f4, 0x005bd7f4, - 0x005c17f4, 0x005c57f4, 0x005c97f4, 0x005cd7f4, - 0x005d17f4, 0x005d57f4, 0x005d97f4, 0x005dd7f4, - 0x005e17f4, 0x005e57f4, 0x005e97f4, 0x005ed7f4, - 0x005f17f4, 0x005f57f4, 0x005f97f4, 0x005fd7f4, - 0x006017f4, 0x006057f4, 0x006097f4, 0x0060d7f4, - 0x006117f4, 0x006157f4, 0x006197f4, 0x0061d7f4, - 0x006217f4, 0x006257f4, 0x006297f4, 0x0062d7f4, - 0x006317f4, 0x006357f4, 0x006397f4, 0x0063d7f4, - 0x006417f4, 0x006457f4, 0x006497f4, 0x0064d7f4, - 0x006517f4, 0x006557f4, 0x006597f4, 0x0065d7f4, - 0x006617f4, 0x006657f4, 0x006697f4, 0x0066d7f4, - 0x006717f4, 0x006757f4, 0x006797f4, 0x0067d7f4, - 0x006817f4, 0x006857f4, 0x006897f4, 0x0068d7f4, - 0x006917f4, 0x006957f4, 0x006997f4, 0x0069d7f4, - 0x006a17f4, 0x006a57f4, 0x006a97f4, 0x006ad7f4, - 0x006b17f4, 0x006b57f4, 0x006b97f4, 0x006bd7f4, - 0x006c17f4, 0x006c57f4, 0x006c97f4, 0x006cd7f4, - 0x006d17f4, 0x006d57f4, 0x006d97f4, 0x006dd7f4, - 0x006e17f4, 0x006e57f4, 0x006e97f4, 0x006ed7f4, - 0x006f17f4, 0x006f57f4, 0x006f97f4, 0x006fd7f4, - 0x007017f4, 0x007057f4, 0x007097f4, 0x0070d7f4, - 0x007117f4, 0x007157f4, 0x007197f4, 0x0071d7f4, - 0x007217f4, 0x007257f4, 0x007297f4, 0x0072d7f4, - 0x007317f4, 0x007357f4, 0x007397f4, 0x0073d7f4, - 0x007417f4, 0x007457f4, 0x007497f4, 0x0074d7f4, - 0x007517f4, 0x007557f4, 0x007597f4, 0x0075d7f4, - 0x007617f4, 0x007657f4, 0x007697f4, 0x0076d7f4, - 0x007717f4, 0x007757f4, 0x007797f4, 0x0077d7f4, - 0x007817f4, 0x007857f4, 0x007897f4, 0x0078d7f4, - 0x007917f4, 0x007957f4, 0x007997f4, 0x0079d7f4, - 0x007a17f4, 0x007a57f4, 0x007a97f4, 0x007ad7f4, - 0x007b17f4, 0x007b57f4, 0x007b97f4, 0x007bd7f4, - 0x007c17f4, 0x007c57f4, 0x007c97f4, 0x007cd7f4, - 0x007d17f4, 0x007d57f4, 0x007d97f4, 0x007dd7f4, - 0x007e17f4, 0x007e57f4, 0x007e97f4, 0x007ed7f4, - 0x007f17f4, 0x007f57f4, 0x007f97f4, 0x007fd7f4, - 0x008017f4, 0x008057f4, 0x008097f4, 0x0080d7f4, - 0x008117f4, 0x008157f4, 0x008197f4, 0x0081d7f4, - 0x008217f4, 0x008257f4, 0x008297f4, 0x0082d7f4, - 0x008317f4, 0x008357f4, 0x008397f4, 0x0083d7f4, - 0x008417f4, 0x008457f4, 0x008497f4, 0x0084d7f4, - 0x008517f4, 0x008557f4, 0x008597f4, 0x0085d7f4, - 0x008617f4, 0x008657f4, 0x008697f4, 0x0086d7f4, - 0x008717f4, 0x008757f4, 0x008797f4, 0x0087d7f4, - 0x008817f4, 0x008857f4, 0x008897f4, 0x0088d7f4, - 0x008917f4, 0x008957f4, 0x008997f4, 0x0089d7f4, - 0x008a17f4, 0x008a57f4, 0x008a97f4, 0x008ad7f4, - 0x008b17f4, 0x008b57f4, 0x008b97f4, 0x008bd7f4, - 0x008c17f4, 0x008c57f4, 0x008c97f4, 0x008cd7f4, - 0x008d17f4, 0x008d57f4, 0x008d97f4, 0x008dd7f4, - 0x008e17f4, 0x008e57f4, 0x008e97f4, 0x008ed7f4, - 0x008f17f4, 0x008f57f4, 0x008f97f4, 0x008fd7f4, - 0x009017f4, 0x009057f4, 0x009097f4, 0x0090d7f4, - 0x009117f4, 0x009157f4, 0x009197f4, 0x0091d7f4, - 0x009217f4, 0x009257f4, 0x009297f4, 0x0092d7f4, - 0x009317f4, 0x009357f4, 0x009397f4, 0x0093d7f4, - 0x009417f4, 0x009457f4, 0x009497f4, 0x0094d7f4, - 0x009517f4, 0x009557f4, 0x009597f4, 0x0095d7f4, - 0x009617f4, 0x009657f4, 0x009697f4, 0x0096d7f4, - 0x009717f4, 0x009757f4, 0x009797f4, 0x0097d7f4, - 0x009817f4, 0x009857f4, 0x009897f4, 0x0098d7f4, - 0x009917f4, 0x009957f4, 0x009997f4, 0x0099d7f4, - 0x009a17f4, 0x009a57f4, 0x009a97f4, 0x009ad7f4, - 0x009b17f4, 0x009b57f4, 0x009b97f4, 0x009bd7f4, - 0x009c17f4, 0x009c57f4, 0x009c97f4, 0x009cd7f4, - 0x009d17f4, 0x009d57f4, 0x009d97f4, 0x009dd7f4, - 0x009e17f4, 0x009e57f4, 0x009e97f4, 0x009ed7f4, - 0x009f17f4, 0x009f57f4, 0x009f97f4, 0x009fd7f4, - 0x00a017f4, 0x00a057f4, 0x00a097f4, 0x00a0d7f4, - 0x00a117f4, 0x00a157f4, 0x00a197f4, 0x00a1d7f4, - 0x00a217f4, 0x00a257f4, 0x00a297f4, 0x00a2d7f4, - 0x00a317f4, 0x00a357f4, 0x00a397f4, 0x00a3d7f4, - 0x00a417f4, 0x00a457f4, 0x00a497f4, 0x00a4d7f4, - 0x00a517f4, 0x00a557f4, 0x00a597f4, 0x00a5d7f4, - 0x00a617f4, 0x00a657f4, 0x00a697f4, 0x00a6d7f4, - 0x00a717f4, 0x00a757f4, 0x00a797f4, 0x00a7d7f4, - 0x00a817f4, 0x00a857f4, 0x00a897f4, 0x00a8d7f4, - 0x00a917f4, 0x00a957f4, 0x00a997f4, 0x00a9d7f4, - 0x00aa17f4, 0x00aa57f4, 0x00aa97f4, 0x00aad7f4, - 0x00ab17f4, 0x00ab57f4, 0x00ab97f4, 0x00abd7f4, - 0x00ac17f4, 0x00ac57f4, 0x00ac97f4, 0x00acd7f4, - 0x00ad17f4, 0x00ad57f4, 0x00ad97f4, 0x00add7f4, - 0x00ae17f4, 0x00ae57f4, 0x00ae97f4, 0x00aed7f4, - 0x00af17f4, 0x00af57f4, 0x00af97f4, 0x00afd7f4, - 0x00b017f4, 0x00b057f4, 0x00b097f4, 0x00b0d7f4, - 0x00b117f4, 0x00b157f4, 0x00b197f4, 0x00b1d7f4, - 0x00b217f4, 0x00b257f4, 0x00b297f4, 0x00b2d7f4, - 0x00b317f4, 0x00b357f4, 0x00b397f4, 0x00b3d7f4, - 0x00b417f4, 0x00b457f4, 0x00b497f4, 0x00b4d7f4, - 0x00b517f4, 0x00b557f4, 0x00b597f4, 0x00b5d7f4, - 0x00b617f4, 0x00b657f4, 0x00b697f4, 0x00b6d7f4, - 0x00b717f4, 0x00b757f4, 0x00b797f4, 0x00b7d7f4, - 0x00b817f4, 0x00b857f4, 0x00b897f4, 0x00b8d7f4, - 0x00b917f4, 0x00b957f4, 0x00b997f4, 0x00b9d7f4, - 0x00ba17f4, 0x00ba57f4, 0x00ba97f4, 0x00bad7f4, - 0x00bb17f4, 0x00bb57f4, 0x00bb97f4, 0x00bbd7f4, - 0x00bc17f4, 0x00bc57f4, 0x00bc97f4, 0x00bcd7f4, - 0x00bd17f4, 0x00bd57f4, 0x00bd97f4, 0x00bdd7f4, - 0x00be17f4, 0x00be57f4, 0x00be97f4, 0x00bed7f4, - 0x00bf17f4, 0x00bf57f4, 0x00bf97f4, 0x00bfd7f4, - 0x00c017f4, 0x00c057f4, 0x00c097f4, 0x00c0d7f4, - 0x00c117f4, 0x00c157f4, 0x00c197f4, 0x00c1d7f4, - 0x00c217f4, 0x00c257f4, 0x00c297f4, 0x00c2d7f4, - 0x00c317f4, 0x00c357f4, 0x00c397f4, 0x00c3d7f4, - 0x00c417f4, 0x00c457f4, 0x00c497f4, 0x00c4d7f4, - 0x00c517f4, 0x00c557f4, 0x00c597f4, 0x00c5d7f4, - 0x00c617f4, 0x00c657f4, 0x00c697f4, 0x00c6d7f4, - 0x00c717f4, 0x00c757f4, 0x00c797f4, 0x00c7d7f4, - 0x00c817f4, 0x00c857f4, 0x00c897f4, 0x00c8d7f4, - 0x00c917f4, 0x00c957f4, 0x00c997f4, 0x00c9d7f4, - 0x00ca17f4, 0x00ca57f4, 0x00ca97f4, 0x00cad7f4, - 0x00cb17f4, 0x00cb57f4, 0x00cb97f4, 0x00cbd7f4, - 0x00cc17f4, 0x00cc57f4, 0x00cc97f4, 0x00ccd7f4, - 0x00cd17f4, 0x00cd57f4, 0x00cd97f4, 0x00cdd7f4, - 0x00ce17f4, 0x00ce57f4, 0x00ce97f4, 0x00ced7f4, - 0x00cf17f4, 0x00cf57f4, 0x00cf97f4, 0x00cfd7f4, - 0x00d017f4, 0x00d057f4, 0x00d097f4, 0x00d0d7f4, - 0x00d117f4, 0x00d157f4, 0x00d197f4, 0x00d1d7f4, - 0x00d217f4, 0x00d257f4, 0x00d297f4, 0x00d2d7f4, - 0x00d317f4, 0x00d357f4, 0x00d397f4, 0x00d3d7f4, - 0x00d417f4, 0x00d457f4, 0x00d497f4, 0x00d4d7f4, - 0x00d517f4, 0x00d557f4, 0x00d597f4, 0x00d5d7f4, - 0x00d617f4, 0x00d657f4, 0x00d697f4, 0x00d6d7f4, - 0x00d717f4, 0x00d757f4, 0x00d797f4, 0x00d7d7f4, - 0x00d817f4, 0x00d857f4, 0x00d897f4, 0x00d8d7f4, - 0x00d917f4, 0x00d957f4, 0x00d997f4, 0x00d9d7f4, - 0x00da17f4, 0x00da57f4, 0x00da97f4, 0x00dad7f4, - 0x00db17f4, 0x00db57f4, 0x00db97f4, 0x00dbd7f4, - 0x00dc17f4, 0x00dc57f4, 0x00dc97f4, 0x00dcd7f4, - 0x00dd17f4, 0x00dd57f4, 0x00dd97f4, 0x00ddd7f4, - 0x00de17f4, 0x00de57f4, 0x00de97f4, 0x00ded7f4, - 0x00df17f4, 0x00df57f4, 0x00df97f4, 0x00dfd7f4, - 0x00e017f4, 0x00e057f4, 0x00e097f4, 0x00e0d7f4, - 0x00e117f4, 0x00e157f4, 0x00e197f4, 0x00e1d7f4, - 0x00e217f4, 0x00e257f4, 0x00e297f4, 0x00e2d7f4, - 0x00e317f4, 0x00e357f4, 0x00e397f4, 0x00e3d7f4, - 0x00e417f4, 0x00e457f4, 0x00e497f4, 0x00e4d7f4, - 0x00e517f4, 0x00e557f4, 0x00e597f4, 0x00e5d7f4, - 0x00e617f4, 0x00e657f4, 0x00e697f4, 0x00e6d7f4, - 0x00e717f4, 0x00e757f4, 0x00e797f4, 0x00e7d7f4, - 0x00e817f4, 0x00e857f4, 0x00e897f4, 0x00e8d7f4, - 0x00e917f4, 0x00e957f4, 0x00e997f4, 0x00e9d7f4, - 0x00ea17f4, 0x00ea57f4, 0x00ea97f4, 0x00ead7f4, - 0x00eb17f4, 0x00eb57f4, 0x00eb97f4, 0x00ebd7f4, - 0x00ec17f4, 0x00ec57f4, 0x00ec97f4, 0x00ecd7f4, - 0x00ed17f4, 0x00ed57f4, 0x00ed97f4, 0x00edd7f4, - 0x00ee17f4, 0x00ee57f4, 0x00ee97f4, 0x00eed7f4, - 0x00ef17f4, 0x00ef57f4, 0x00ef97f4, 0x00efd7f4, - 0x00f017f4, 0x00f057f4, 0x00f097f4, 0x00f0d7f4, - 0x00f117f4, 0x00f157f4, 0x00f197f4, 0x00f1d7f4, - 0x00f217f4, 0x00f257f4, 0x00f297f4, 0x00f2d7f4, - 0x00f317f4, 0x00f357f4, 0x00f397f4, 0x00f3d7f4, - 0x00f417f4, 0x00f457f4, 0x00f497f4, 0x00f4d7f4, - 0x00f517f4, 0x00f557f4, 0x00f597f4, 0x00f5d7f4, - 0x00f617f4, 0x00f657f4, 0x00f697f4, 0x00f6d7f4, - 0x00f717f4, 0x00f757f4, 0x00f797f4, 0x00f7d7f4, - 0x00f817f4, 0x00f857f4, 0x00f897f4, 0x00f8d7f4, - 0x00f917f4, 0x00f957f4, 0x00f997f4, 0x00f9d7f4, - 0x00fa17f4, 0x00fa57f4, 0x00fa97f4, 0x00fad7f4, - 0x00fb17f4, 0x00fb57f4, 0x00fb97f4, 0x00fbd7f4, - 0x00fc17f4, 0x00fc57f4, 0x00fc97f4, 0x00fcd7f4, - 0x00fd17f4, 0x00fd57f4, 0x00fd97f4, 0x00fdd7f4, - 0x00fe17f4, 0x00fe57f4, 0x00fe97f4, 0x00fed7f4, - 0x00ff17f4, 0x00ff57f4, 0x00ff97f4, 0x00ffd7f4, - 0x010017f4, 0x010057f4, 0x010097f4, 0x0100d7f4, - 0x010117f4, 0x010157f4, 0x010197f4, 0x0101d7f4, - 0x010217f4, 0x010257f4, 0x010297f4, 0x0102d7f4, - 0x010317f4, 0x010357f4, 0x010397f4, 0x0103d7f4, - 0x010417f4, 0x010457f4, 0x010497f4, 0x0104d7f4, - 0x010517f4, 0x010557f4, 0x010597f4, 0x0105d7f4, - 0x010617f4, 0x010657f4, 0x010697f4, 0x0106d7f4, - 0x010717f4, 0x010757f4, 0x010797f4, 0x0107d7f4, - 0x010817f4, 0x010857f4, 0x010897f4, 0x0108d7f4, - 0x010917f4, 0x010957f4, 0x010997f4, 0x0109d7f4, - 0x010a17f4, 0x010a57f4, 0x010a97f4, 0x010ad7f4, - 0x010b17f4, 0x010b57f4, 0x010b97f4, 0x010bd7f4, - 0x010c17f4, 0x010c57f4, 0x010c97f4, 0x010cd7f4, - 0x010d17f4, 0x010d57f4, 0x010d97f4, 0x010dd7f4, - 0x010e17f4, 0x010e57f4, 0x010e97f4, 0x010ed7f4, - 0x010f17f4, 0x010f57f4, 0x010f97f4, 0x010fd7f4, - 0x011017f4, 0x011057f4, 0x011097f4, 0x0110d7f4, - 0x011117f4, 0x011157f4, 0x011197f4, 0x0111d7f4, - 0x011217f4, 0x011257f4, 0x011297f4, 0x0112d7f4, - 0x011317f4, 0x011357f4, 0x011397f4, 0x0113d7f4, - 0x011417f4, 0x011457f4, 0x011497f4, 0x0114d7f4, - 0x011517f4, 0x011557f4, 0x011597f4, 0x0115d7f4, - 0x011617f4, 0x011657f4, 0x011697f4, 0x0116d7f4, - 0x011717f4, 0x011757f4, 0x011797f4, 0x0117d7f4, - 0x011817f4, 0x011857f4, 0x011897f4, 0x0118d7f4, - 0x011917f4, 0x011957f4, 0x011997f4, 0x0119d7f4, - 0x011a17f4, 0x011a57f4, 0x011a97f4, 0x011ad7f4, - 0x011b17f4, 0x011b57f4, 0x011b97f4, 0x011bd7f4, - 0x011c17f4, 0x011c57f4, 0x011c97f4, 0x011cd7f4, - 0x011d17f4, 0x011d57f4, 0x011d97f4, 0x011dd7f4, - 0x011e17f4, 0x011e57f4, 0x011e97f4, 0x011ed7f4, - 0x011f17f4, 0x011f57f4, 0x011f97f4, 0x011fd7f4, - 0x012017f4, 0x012057f4, 0x012097f4, 0x0120d7f4, - 0x012117f4, 0x012157f4, 0x012197f4, 0x0121d7f4, - 0x012217f4, 0x012257f4, 0x012297f4, 0x0122d7f4, - 0x012317f4, 0x012357f4, 0x012397f4, 0x0123d7f4, - 0x012417f4, 0x012457f4, 0x012497f4, 0x0124d7f4, - 0x012517f4, 0x012557f4, 0x012597f4, 0x0125d7f4, - 0x012617f4, 0x012657f4, 0x012697f4, 0x0126d7f4, - 0x012717f4, 0x012757f4, 0x012797f4, 0x0127d7f4, - 0x012817f4, 0x012857f4, 0x012897f4, 0x0128d7f4, - 0x012917f4, 0x012957f4, 0x012997f4, 0x0129d7f4, - 0x012a17f4, 0x012a57f4, 0x012a97f4, 0x012ad7f4, - 0x012b17f4, 0x012b57f4, 0x012b97f4, 0x012bd7f4, - 0x012c17f4, 0x012c57f4, 0x012c97f4, 0x012cd7f4, - 0x012d17f4, 0x012d57f4, 0x012d97f4, 0x012dd7f4, - 0x012e17f4, 0x012e57f4, 0x012e97f4, 0x012ed7f4, - 0x012f17f4, 0x012f57f4, 0x012f97f4, 0x012fd7f4, - 0x013017f4, 0x013057f4, 0x013097f4, 0x0130d7f4, - 0x013117f4, 0x013157f4, 0x013197f4, 0x0131d7f4, - 0x013217f4, 0x013257f4, 0x013297f4, 0x0132d7f4, - 0x013317f4, 0x013357f4, 0x013397f4, 0x0133d7f4, - 0x013417f4, 0x013457f4, 0x013497f4, 0x0134d7f4, - 0x013517f4, 0x013557f4, 0x013597f4, 0x0135d7f4, - 0x013617f4, 0x013657f4, 0x013697f4, 0x0136d7f4, - 0x013717f4, 0x013757f4, 0x013797f4, 0x0137d7f4, - 0x013817f4, 0x013857f4, 0x013897f4, 0x0138d7f4, - 0x013917f4, 0x013957f4, 0x013997f4, 0x0139d7f4, - 0x013a17f4, 0x013a57f4, 0x013a97f4, 0x013ad7f4, - 0x013b17f4, 0x013b57f4, 0x013b97f4, 0x013bd7f4, - 0x013c17f4, 0x013c57f4, 0x013c97f4, 0x013cd7f4, - 0x013d17f4, 0x013d57f4, 0x013d97f4, 0x013dd7f4, - 0x013e17f4, 0x013e57f4, 0x013e97f4, 0x013ed7f4, - 0x013f17f4, 0x013f57f4, 0x013f97f4, 0x013fd7f4, - 0x014017f4, 0x014057f4, 0x014097f4, 0x0140d7f4, - 0x014117f4, 0x014157f4, 0x014197f4, 0x0141d7f4, - 0x014217f4, 0x014257f4, 0x014297f4, 0x0142d7f4, - 0x014317f4, 0x014357f4, 0x014397f4, 0x0143d7f4, - 0x014417f4, 0x014457f4, 0x014497f4, 0x0144d7f4, - 0x014517f4, 0x014557f4, 0x014597f4, 0x0145d7f4, - 0x014617f4, 0x014657f4, 0x014697f4, 0x0146d7f4, - 0x014717f4, 0x014757f4, 0x014797f4, 0x0147d7f4, - 0x014817f4, 0x014857f4, 0x014897f4, 0x0148d7f4, - 0x014917f4, 0x014957f4, 0x014997f4, 0x0149d7f4, - 0x014a17f4, 0x014a57f4, 0x014a97f4, 0x014ad7f4, - 0x014b17f4, 0x014b57f4, 0x014b97f4, 0x014bd7f4, - 0x014c17f4, 0x014c57f4, 0x014c97f4, 0x014cd7f4, - 0x014d17f4, 0x014d57f4, 0x014d97f4, 0x014dd7f4, - 0x014e17f4, 0x014e57f4, 0x014e97f4, 0x014ed7f4, - 0x014f17f4, 0x014f57f4, 0x014f97f4, 0x014fd7f4, - 0x015017f4, 0x015057f4, 0x015097f4, 0x0150d7f4, - 0x015117f4, 0x015157f4, 0x015197f4, 0x0151d7f4, - 0x015217f4, 0x015257f4, 0x015297f4, 0x0152d7f4, - 0x015317f4, 0x015357f4, 0x015397f4, 0x0153d7f4, - 0x015417f4, 0x015457f4, 0x015497f4, 0x0154d7f4, - 0x015517f4, 0x015557f4, 0x015597f4, 0x0155d7f4, - 0x015617f4, 0x015657f4, 0x015697f4, 0x0156d7f4, - 0x015717f4, 0x015757f4, 0x015797f4, 0x0157d7f4, - 0x015817f4, 0x015857f4, 0x015897f4, 0x0158d7f4, - 0x015917f4, 0x015957f4, 0x015997f4, 0x0159d7f4, - 0x015a17f4, 0x015a57f4, 0x015a97f4, 0x015ad7f4, - 0x015b17f4, 0x015b57f4, 0x015b97f4, 0x015bd7f4, - 0x015c17f4, 0x015c57f4, 0x015c97f4, 0x015cd7f4, - 0x015d17f4, 0x015d57f4, 0x015d97f4, 0x015dd7f4, - 0x015e17f4, 0x015e57f4, 0x015e97f4, 0x015ed7f4, - 0x015f17f4, 0x015f57f4, 0x015f97f4, 0x015fd7f4, - 0x016017f4, 0x016057f4, 0x016097f4, 0x0160d7f4, - 0x016117f4, 0x016157f4, 0x016197f4, 0x0161d7f4, - 0x016217f4, 0x016257f4, 0x016297f4, 0x0162d7f4, - 0x016317f4, 0x016357f4, 0x016397f4, 0x0163d7f4, - 0x016417f4, 0x016457f4, 0x016497f4, 0x0164d7f4, - 0x016517f4, 0x016557f4, 0x016597f4, 0x0165d7f4, - 0x016617f4, 0x016657f4, 0x016697f4, 0x0166d7f4, - 0x016717f4, 0x016757f4, 0x016797f4, 0x0167d7f4, - 0x016817f4, 0x016857f4, 0x016897f4, 0x0168d7f4, - 0x016917f4, 0x016957f4, 0x016997f4, 0x0169d7f4, - 0x016a17f4, 0x016a57f4, 0x016a97f4, 0x016ad7f4, - 0x016b17f4, 0x016b57f4, 0x016b97f4, 0x016bd7f4, - 0x016c17f4, 0x016c57f4, 0x016c97f4, 0x016cd7f4, - 0x016d17f4, 0x016d57f4, 0x016d97f4, 0x016dd7f4, - 0x016e17f4, 0x016e57f4, 0x016e97f4, 0x016ed7f4, - 0x016f17f4, 0x016f57f4, 0x016f97f4, 0x016fd7f4, - 0x017017f4, 0x017057f4, 0x017097f4, 0x0170d7f4, - 0x017117f4, 0x017157f4, 0x017197f4, 0x0171d7f4, - 0x017217f4, 0x017257f4, 0x017297f4, 0x0172d7f4, - 0x017317f4, 0x017357f4, 0x017397f4, 0x0173d7f4, - 0x017417f4, 0x017457f4, 0x017497f4, 0x0174d7f4, - 0x017517f4, 0x017557f4, 0x017597f4, 0x0175d7f4, - 0x017617f4, 0x017657f4, 0x017697f4, 0x0176d7f4, - 0x017717f4, 0x017757f4, 0x017797f4, 0x0177d7f4, - 0x017817f4, 0x017857f4, 0x017897f4, 0x0178d7f4, - 0x017917f4, 0x017957f4, 0x017997f4, 0x0179d7f4, - 0x017a17f4, 0x017a57f4, 0x017a97f4, 0x017ad7f4, - 0x017b17f4, 0x017b57f4, 0x017b97f4, 0x017bd7f4, - 0x017c17f4, 0x017c57f4, 0x017c97f4, 0x017cd7f4, - 0x017d17f4, 0x017d57f4, 0x017d97f4, 0x017dd7f4, - 0x017e17f4, 0x017e57f4, 0x017e97f4, 0x017ed7f4, - 0x017f17f4, 0x017f57f4, 0x017f97f4, 0x017fd7f4, - 0x018017f4, 0x018057f4, 0x018097f4, 0x0180d7f4, - 0x018117f4, 0x018157f4, 0x018197f4, 0x0181d7f4, - 0x018217f4, 0x018257f4, 0x018297f4, 0x0182d7f4, - 0x018317f4, 0x018357f4, 0x018397f4, 0x0183d7f4, - 0x018417f4, 0x018457f4, 0x018497f4, 0x0184d7f4, - 0x018517f4, 0x018557f4, 0x018597f4, 0x0185d7f4, - 0x018617f4, 0x018657f4, 0x018697f4, 0x0186d7f4, - 0x018717f4, 0x018757f4, 0x018797f4, 0x0187d7f4, - 0x018817f4, 0x018857f4, 0x018897f4, 0x0188d7f4, - 0x018917f4, 0x018957f4, 0x018997f4, 0x0189d7f4, - 0x018a17f4, 0x018a57f4, 0x018a97f4, 0x018ad7f4, - 0x018b17f4, 0x018b57f4, 0x018b97f4, 0x018bd7f4, - 0x018c17f4, 0x018c57f4, 0x018c97f4, 0x018cd7f4, - 0x018d17f4, 0x018d57f4, 0x018d97f4, 0x018dd7f4, - 0x018e17f4, 0x018e57f4, 0x018e97f4, 0x018ed7f4, - 0x018f17f4, 0x018f57f4, 0x018f97f4, 0x018fd7f4, - 0x019017f4, 0x019057f4, 0x019097f4, 0x0190d7f4, - 0x019117f4, 0x019157f4, 0x019197f4, 0x0191d7f4, - 0x019217f4, 0x019257f4, 0x019297f4, 0x0192d7f4, - 0x019317f4, 0x019357f4, 0x019397f4, 0x0193d7f4, - 0x019417f4, 0x019457f4, 0x019497f4, 0x0194d7f4, - 0x019517f4, 0x019557f4, 0x019597f4, 0x0195d7f4, - 0x019617f4, 0x019657f4, 0x019697f4, 0x0196d7f4, - 0x019717f4, 0x019757f4, 0x019797f4, 0x0197d7f4, - 0x019817f4, 0x019857f4, 0x019897f4, 0x0198d7f4, - 0x019917f4, 0x019957f4, 0x019997f4, 0x0199d7f4, - 0x019a17f4, 0x019a57f4, 0x019a97f4, 0x019ad7f4, - 0x019b17f4, 0x019b57f4, 0x019b97f4, 0x019bd7f4, - 0x019c17f4, 0x019c57f4, 0x019c97f4, 0x019cd7f4, - 0x019d17f4, 0x019d57f4, 0x019d97f4, 0x019dd7f4, - 0x019e17f4, 0x019e57f4, 0x019e97f4, 0x019ed7f4, - 0x019f17f4, 0x019f57f4, 0x019f97f4, 0x019fd7f4, - 0x01a017f4, 0x01a057f4, 0x01a097f4, 0x01a0d7f4, - 0x01a117f4, 0x01a157f4, 0x01a197f4, 0x01a1d7f4, - 0x01a217f4, 0x01a257f4, 0x01a297f4, 0x01a2d7f4, - 0x01a317f4, 0x01a357f4, 0x01a397f4, 0x01a3d7f4, - 0x01a417f4, 0x01a457f4, 0x01a497f4, 0x01a4d7f4, - 0x01a517f4, 0x01a557f4, 0x01a597f4, 0x01a5d7f4, - 0x01a617f4, 0x01a657f4, 0x01a697f4, 0x01a6d7f4, - 0x01a717f4, 0x01a757f4, 0x01a797f4, 0x01a7d7f4, - 0x01a817f4, 0x01a857f4, 0x01a897f4, 0x01a8d7f4, - 0x01a917f4, 0x01a957f4, 0x01a997f4, 0x01a9d7f4, - 0x01aa17f4, 0x01aa57f4, 0x01aa97f4, 0x01aad7f4, - 0x01ab17f4, 0x01ab57f4, 0x01ab97f4, 0x01abd7f4, - 0x01ac17f4, 0x01ac57f4, 0x01ac97f4, 0x01acd7f4, - 0x01ad17f4, 0x01ad57f4, 0x01ad97f4, 0x01add7f4, - 0x01ae17f4, 0x01ae57f4, 0x01ae97f4, 0x01aed7f4, - 0x01af17f4, 0x01af57f4, 0x01af97f4, 0x01afd7f4, - 0x01b017f4, 0x01b057f4, 0x01b097f4, 0x01b0d7f4, - 0x01b117f4, 0x01b157f4, 0x01b197f4, 0x01b1d7f4, - 0x01b217f4, 0x01b257f4, 0x01b297f4, 0x01b2d7f4, - 0x01b317f4, 0x01b357f4, 0x01b397f4, 0x01b3d7f4, - 0x01b417f4, 0x01b457f4, 0x01b497f4, 0x01b4d7f4, - 0x01b517f4, 0x01b557f4, 0x01b597f4, 0x01b5d7f4, - 0x01b617f4, 0x01b657f4, 0x01b697f4, 0x01b6d7f4, - 0x01b717f4, 0x01b757f4, 0x01b797f4, 0x01b7d7f4, - 0x01b817f4, 0x01b857f4, 0x01b897f4, 0x01b8d7f4, - 0x01b917f4, 0x01b957f4, 0x01b997f4, 0x01b9d7f4, - 0x01ba17f4, 0x01ba57f4, 0x01ba97f4, 0x01bad7f4, - 0x01bb17f4, 0x01bb57f4, 0x01bb97f4, 0x01bbd7f4, - 0x01bc17f4, 0x01bc57f4, 0x01bc97f4, 0x01bcd7f4, - 0x01bd17f4, 0x01bd57f4, 0x01bd97f4, 0x01bdd7f4, - 0x01be17f4, 0x01be57f4, 0x01be97f4, 0x01bed7f4, - 0x01bf17f4, 0x01bf57f4, 0x01bf97f4, 0x01bfd7f4, - 0x01c017f4, 0x01c057f4, 0x01c097f4, 0x01c0d7f4, - 0x01c117f4, 0x01c157f4, 0x01c197f4, 0x01c1d7f4, - 0x01c217f4, 0x01c257f4, 0x01c297f4, 0x01c2d7f4, - 0x01c317f4, 0x01c357f4, 0x01c397f4, 0x01c3d7f4, - 0x01c417f4, 0x01c457f4, 0x01c497f4, 0x01c4d7f4, - 0x01c517f4, 0x01c557f4, 0x01c597f4, 0x01c5d7f4, - 0x01c617f4, 0x01c657f4, 0x01c697f4, 0x01c6d7f4, - 0x01c717f4, 0x01c757f4, 0x01c797f4, 0x01c7d7f4, - 0x01c817f4, 0x01c857f4, 0x01c897f4, 0x01c8d7f4, - 0x01c917f4, 0x01c957f4, 0x01c997f4, 0x01c9d7f4, - 0x01ca17f4, 0x01ca57f4, 0x01ca97f4, 0x01cad7f4, - 0x01cb17f4, 0x01cb57f4, 0x01cb97f4, 0x01cbd7f4, - 0x01cc17f4, 0x01cc57f4, 0x01cc97f4, 0x01ccd7f4, - 0x01cd17f4, 0x01cd57f4, 0x01cd97f4, 0x01cdd7f4, - 0x01ce17f4, 0x01ce57f4, 0x01ce97f4, 0x01ced7f4, - 0x01cf17f4, 0x01cf57f4, 0x01cf97f4, 0x01cfd7f4, - 0x01d017f4, 0x01d057f4, 0x01d097f4, 0x01d0d7f4, - 0x01d117f4, 0x01d157f4, 0x01d197f4, 0x01d1d7f4, - 0x01d217f4, 0x01d257f4, 0x01d297f4, 0x01d2d7f4, - 0x01d317f4, 0x01d357f4, 0x01d397f4, 0x01d3d7f4, - 0x01d417f4, 0x01d457f4, 0x01d497f4, 0x01d4d7f4, - 0x01d517f4, 0x01d557f4, 0x01d597f4, 0x01d5d7f4, - 0x01d617f4, 0x01d657f4, 0x01d697f4, 0x01d6d7f4, - 0x01d717f4, 0x01d757f4, 0x01d797f4, 0x01d7d7f4, - 0x01d817f4, 0x01d857f4, 0x01d897f4, 0x01d8d7f4, - 0x01d917f4, 0x01d957f4, 0x01d997f4, 0x01d9d7f4, - 0x01da17f4, 0x01da57f4, 0x01da97f4, 0x01dad7f4, - 0x01db17f4, 0x01db57f4, 0x01db97f4, 0x01dbd7f4, - 0x01dc17f4, 0x01dc57f4, 0x01dc97f4, 0x01dcd7f4, - 0x01dd17f4, 0x01dd57f4, 0x01dd97f4, 0x01ddd7f4, - 0x01de17f4, 0x01de57f4, 0x01de97f4, 0x01ded7f4, - 0x01df17f4, 0x01df57f4, 0x01df97f4, 0x01dfd7f4, - 0x01e017f4, 0x01e057f4, 0x01e097f4, 0x01e0d7f4, - 0x01e117f4, 0x01e157f4, 0x01e197f4, 0x01e1d7f4, - 0x01e217f4, 0x01e257f4, 0x01e297f4, 0x01e2d7f4, - 0x01e317f4, 0x01e357f4, 0x01e397f4, 0x01e3d7f4, - 0x01e417f4, 0x01e457f4, 0x01e497f4, 0x01e4d7f4, - 0x01e517f4, 0x01e557f4, 0x01e597f4, 0x01e5d7f4, - 0x01e617f4, 0x01e657f4, 0x01e697f4, 0x01e6d7f4, - 0x01e717f4, 0x01e757f4, 0x01e797f4, 0x01e7d7f4, - 0x01e817f4, 0x01e857f4, 0x01e897f4, 0x01e8d7f4, - 0x01e917f4, 0x01e957f4, 0x01e997f4, 0x01e9d7f4, - 0x01ea17f4, 0x01ea57f4, 0x01ea97f4, 0x01ead7f4, - 0x01eb17f4, 0x01eb57f4, 0x01eb97f4, 0x01ebd7f4, - 0x01ec17f4, 0x01ec57f4, 0x01ec97f4, 0x01ecd7f4, - 0x01ed17f4, 0x01ed57f4, 0x01ed97f4, 0x01edd7f4, - 0x01ee17f4, 0x01ee57f4, 0x01ee97f4, 0x01eed7f4, - 0x01ef17f4, 0x01ef57f4, 0x01ef97f4, 0x01efd7f4, - 0x01f017f4, 0x01f057f4, 0x01f097f4, 0x01f0d7f4, - 0x01f117f4, 0x01f157f4, 0x01f197f4, 0x01f1d7f4, - 0x01f217f4, 0x01f257f4, 0x01f297f4, 0x01f2d7f4, - 0x01f317f4, 0x01f357f4, 0x01f397f4, 0x01f3d7f4, - 0x01f417f4, 0x01f457f4, 0x01f497f4, 0x01f4d7f4, - 0x01f517f4, 0x01f557f4, 0x01f597f4, 0x01f5d7f4, - 0x01f617f4, 0x01f657f4, 0x01f697f4, 0x01f6d7f4, - 0x01f717f4, 0x01f757f4, 0x01f797f4, 0x01f7d7f4, - 0x01f817f4, 0x01f857f4, 0x01f897f4, 0x01f8d7f4, - 0x01f917f4, 0x01f957f4, 0x01f997f4, 0x01f9d7f4, - 0x01fa17f4, 0x01fa57f4, 0x01fa97f4, 0x01fad7f4, - 0x01fb17f4, 0x01fb57f4, 0x01fb97f4, 0x01fbd7f4, - 0x01fc17f4, 0x01fc57f4, 0x01fc97f4, 0x01fcd7f4, - 0x01fd17f4, 0x01fd57f4, 0x01fd97f4, 0x01fdd7f4, - 0x01fe17f4, 0x01fe57f4, 0x01fe97f4, 0x01fed7f4, - 0x01ff17f4, 0x01ff57f4, 0x01ff97f4, 0x01ffd7f4, - 0x000037f4, 0x000077f4, 0x0000b7f4, 0x0000f7f4, - 0x000137f4, 0x000177f4, 0x0001b7f4, 0x0001f7f4, - 0x000237f4, 0x000277f4, 0x0002b7f4, 0x0002f7f4, - 0x000337f4, 0x000377f4, 0x0003b7f4, 0x0003f7f4, - 0x000437f4, 0x000477f4, 0x0004b7f4, 0x0004f7f4, - 0x000537f4, 0x000577f4, 0x0005b7f4, 0x0005f7f4, - 0x000637f4, 0x000677f4, 0x0006b7f4, 0x0006f7f4, - 0x000737f4, 0x000777f4, 0x0007b7f4, 0x0007f7f4, - 0x000837f4, 0x000877f4, 0x0008b7f4, 0x0008f7f4, - 0x000937f4, 0x000977f4, 0x0009b7f4, 0x0009f7f4, - 0x000a37f4, 0x000a77f4, 0x000ab7f4, 0x000af7f4, - 0x000b37f4, 0x000b77f4, 0x000bb7f4, 0x000bf7f4, - 0x000c37f4, 0x000c77f4, 0x000cb7f4, 0x000cf7f4, - 0x000d37f4, 0x000d77f4, 0x000db7f4, 0x000df7f4, - 0x000e37f4, 0x000e77f4, 0x000eb7f4, 0x000ef7f4, - 0x000f37f4, 0x000f77f4, 0x000fb7f4, 0x000ff7f4, - 0x001037f4, 0x001077f4, 0x0010b7f4, 0x0010f7f4, - 0x001137f4, 0x001177f4, 0x0011b7f4, 0x0011f7f4, - 0x001237f4, 0x001277f4, 0x0012b7f4, 0x0012f7f4, - 0x001337f4, 0x001377f4, 0x0013b7f4, 0x0013f7f4, - 0x001437f4, 0x001477f4, 0x0014b7f4, 0x0014f7f4, - 0x001537f4, 0x001577f4, 0x0015b7f4, 0x0015f7f4, - 0x001637f4, 0x001677f4, 0x0016b7f4, 0x0016f7f4, - 0x001737f4, 0x001777f4, 0x0017b7f4, 0x0017f7f4, - 0x001837f4, 0x001877f4, 0x0018b7f4, 0x0018f7f4, - 0x001937f4, 0x001977f4, 0x0019b7f4, 0x0019f7f4, - 0x001a37f4, 0x001a77f4, 0x001ab7f4, 0x001af7f4, - 0x001b37f4, 0x001b77f4, 0x001bb7f4, 0x001bf7f4, - 0x001c37f4, 0x001c77f4, 0x001cb7f4, 0x001cf7f4, - 0x001d37f4, 0x001d77f4, 0x001db7f4, 0x001df7f4, - 0x001e37f4, 0x001e77f4, 0x001eb7f4, 0x001ef7f4, - 0x001f37f4, 0x001f77f4, 0x001fb7f4, 0x001ff7f4, - 0x002037f4, 0x002077f4, 0x0020b7f4, 0x0020f7f4, - 0x002137f4, 0x002177f4, 0x0021b7f4, 0x0021f7f4, - 0x002237f4, 0x002277f4, 0x0022b7f4, 0x0022f7f4, - 0x002337f4, 0x002377f4, 0x0023b7f4, 0x0023f7f4, - 0x002437f4, 0x002477f4, 0x0024b7f4, 0x0024f7f4, - 0x002537f4, 0x002577f4, 0x0025b7f4, 0x0025f7f4, - 0x002637f4, 0x002677f4, 0x0026b7f4, 0x0026f7f4, - 0x002737f4, 0x002777f4, 0x0027b7f4, 0x0027f7f4, - 0x002837f4, 0x002877f4, 0x0028b7f4, 0x0028f7f4, - 0x002937f4, 0x002977f4, 0x0029b7f4, 0x0029f7f4, - 0x002a37f4, 0x002a77f4, 0x002ab7f4, 0x002af7f4, - 0x002b37f4, 0x002b77f4, 0x002bb7f4, 0x002bf7f4, - 0x002c37f4, 0x002c77f4, 0x002cb7f4, 0x002cf7f4, - 0x002d37f4, 0x002d77f4, 0x002db7f4, 0x002df7f4, - 0x002e37f4, 0x002e77f4, 0x002eb7f4, 0x002ef7f4, - 0x002f37f4, 0x002f77f4, 0x002fb7f4, 0x002ff7f4, - 0x003037f4, 0x003077f4, 0x0030b7f4, 0x0030f7f4, - 0x003137f4, 0x003177f4, 0x0031b7f4, 0x0031f7f4, - 0x003237f4, 0x003277f4, 0x0032b7f4, 0x0032f7f4, - 0x003337f4, 0x003377f4, 0x0033b7f4, 0x0033f7f4, - 0x003437f4, 0x003477f4, 0x0034b7f4, 0x0034f7f4, - 0x003537f4, 0x003577f4, 0x0035b7f4, 0x0035f7f4, - 0x003637f4, 0x003677f4, 0x0036b7f4, 0x0036f7f4, - 0x003737f4, 0x003777f4, 0x0037b7f4, 0x0037f7f4, - 0x003837f4, 0x003877f4, 0x0038b7f4, 0x0038f7f4, - 0x003937f4, 0x003977f4, 0x0039b7f4, 0x0039f7f4, - 0x003a37f4, 0x003a77f4, 0x003ab7f4, 0x003af7f4, - 0x003b37f4, 0x003b77f4, 0x003bb7f4, 0x003bf7f4, - 0x003c37f4, 0x003c77f4, 0x003cb7f4, 0x003cf7f4, - 0x003d37f4, 0x003d77f4, 0x003db7f4, 0x003df7f4, - 0x003e37f4, 0x003e77f4, 0x003eb7f4, 0x003ef7f4, - 0x003f37f4, 0x003f77f4, 0x003fb7f4, 0x003ff7f4, - 0x004037f4, 0x004077f4, 0x0040b7f4, 0x0040f7f4, - 0x004137f4, 0x004177f4, 0x0041b7f4, 0x0041f7f4, - 0x004237f4, 0x004277f4, 0x0042b7f4, 0x0042f7f4, - 0x004337f4, 0x004377f4, 0x0043b7f4, 0x0043f7f4, - 0x004437f4, 0x004477f4, 0x0044b7f4, 0x0044f7f4, - 0x004537f4, 0x004577f4, 0x0045b7f4, 0x0045f7f4, - 0x004637f4, 0x004677f4, 0x0046b7f4, 0x0046f7f4, - 0x004737f4, 0x004777f4, 0x0047b7f4, 0x0047f7f4, - 0x004837f4, 0x004877f4, 0x0048b7f4, 0x0048f7f4, - 0x004937f4, 0x004977f4, 0x0049b7f4, 0x0049f7f4, - 0x004a37f4, 0x004a77f4, 0x004ab7f4, 0x004af7f4, - 0x004b37f4, 0x004b77f4, 0x004bb7f4, 0x004bf7f4, - 0x004c37f4, 0x004c77f4, 0x004cb7f4, 0x004cf7f4, - 0x004d37f4, 0x004d77f4, 0x004db7f4, 0x004df7f4, - 0x004e37f4, 0x004e77f4, 0x004eb7f4, 0x004ef7f4, - 0x004f37f4, 0x004f77f4, 0x004fb7f4, 0x004ff7f4, - 0x005037f4, 0x005077f4, 0x0050b7f4, 0x0050f7f4, - 0x005137f4, 0x005177f4, 0x0051b7f4, 0x0051f7f4, - 0x005237f4, 0x005277f4, 0x0052b7f4, 0x0052f7f4, - 0x005337f4, 0x005377f4, 0x0053b7f4, 0x0053f7f4, - 0x005437f4, 0x005477f4, 0x0054b7f4, 0x0054f7f4, - 0x005537f4, 0x005577f4, 0x0055b7f4, 0x0055f7f4, - 0x005637f4, 0x005677f4, 0x0056b7f4, 0x0056f7f4, - 0x005737f4, 0x005777f4, 0x0057b7f4, 0x0057f7f4, - 0x005837f4, 0x005877f4, 0x0058b7f4, 0x0058f7f4, - 0x005937f4, 0x005977f4, 0x0059b7f4, 0x0059f7f4, - 0x005a37f4, 0x005a77f4, 0x005ab7f4, 0x005af7f4, - 0x005b37f4, 0x005b77f4, 0x005bb7f4, 0x005bf7f4, - 0x005c37f4, 0x005c77f4, 0x005cb7f4, 0x005cf7f4, - 0x005d37f4, 0x005d77f4, 0x005db7f4, 0x005df7f4, - 0x005e37f4, 0x005e77f4, 0x005eb7f4, 0x005ef7f4, - 0x005f37f4, 0x005f77f4, 0x005fb7f4, 0x005ff7f4, - 0x006037f4, 0x006077f4, 0x0060b7f4, 0x0060f7f4, - 0x006137f4, 0x006177f4, 0x0061b7f4, 0x0061f7f4, - 0x006237f4, 0x006277f4, 0x0062b7f4, 0x0062f7f4, - 0x006337f4, 0x006377f4, 0x0063b7f4, 0x0063f7f4, - 0x006437f4, 0x006477f4, 0x0064b7f4, 0x0064f7f4, - 0x006537f4, 0x006577f4, 0x0065b7f4, 0x0065f7f4, - 0x006637f4, 0x006677f4, 0x0066b7f4, 0x0066f7f4, - 0x006737f4, 0x006777f4, 0x0067b7f4, 0x0067f7f4, - 0x006837f4, 0x006877f4, 0x0068b7f4, 0x0068f7f4, - 0x006937f4, 0x006977f4, 0x0069b7f4, 0x0069f7f4, - 0x006a37f4, 0x006a77f4, 0x006ab7f4, 0x006af7f4, - 0x006b37f4, 0x006b77f4, 0x006bb7f4, 0x006bf7f4, - 0x006c37f4, 0x006c77f4, 0x006cb7f4, 0x006cf7f4, - 0x006d37f4, 0x006d77f4, 0x006db7f4, 0x006df7f4, - 0x006e37f4, 0x006e77f4, 0x006eb7f4, 0x006ef7f4, - 0x006f37f4, 0x006f77f4, 0x006fb7f4, 0x006ff7f4, - 0x007037f4, 0x007077f4, 0x0070b7f4, 0x0070f7f4, - 0x007137f4, 0x007177f4, 0x0071b7f4, 0x0071f7f4, - 0x007237f4, 0x007277f4, 0x0072b7f4, 0x0072f7f4, - 0x007337f4, 0x007377f4, 0x0073b7f4, 0x0073f7f4, - 0x007437f4, 0x007477f4, 0x0074b7f4, 0x0074f7f4, - 0x007537f4, 0x007577f4, 0x0075b7f4, 0x0075f7f4, - 0x007637f4, 0x007677f4, 0x0076b7f4, 0x0076f7f4, - 0x007737f4, 0x007777f4, 0x0077b7f4, 0x0077f7f4, - 0x007837f4, 0x007877f4, 0x0078b7f4, 0x0078f7f4, - 0x007937f4, 0x007977f4, 0x0079b7f4, 0x0079f7f4, - 0x007a37f4, 0x007a77f4, 0x007ab7f4, 0x007af7f4, - 0x007b37f4, 0x007b77f4, 0x007bb7f4, 0x007bf7f4, - 0x007c37f4, 0x007c77f4, 0x007cb7f4, 0x007cf7f4, - 0x007d37f4, 0x007d77f4, 0x007db7f4, 0x007df7f4, - 0x007e37f4, 0x007e77f4, 0x007eb7f4, 0x007ef7f4, - 0x007f37f4, 0x007f77f4, 0x007fb7f4, 0x007ff7f4, - 0x008037f4, 0x008077f4, 0x0080b7f4, 0x0080f7f4, - 0x008137f4, 0x008177f4, 0x0081b7f4, 0x0081f7f4, - 0x008237f4, 0x008277f4, 0x0082b7f4, 0x0082f7f4, - 0x008337f4, 0x008377f4, 0x0083b7f4, 0x0083f7f4, - 0x008437f4, 0x008477f4, 0x0084b7f4, 0x0084f7f4, - 0x008537f4, 0x008577f4, 0x0085b7f4, 0x0085f7f4, - 0x008637f4, 0x008677f4, 0x0086b7f4, 0x0086f7f4, - 0x008737f4, 0x008777f4, 0x0087b7f4, 0x0087f7f4, - 0x008837f4, 0x008877f4, 0x0088b7f4, 0x0088f7f4, - 0x008937f4, 0x008977f4, 0x0089b7f4, 0x0089f7f4, - 0x008a37f4, 0x008a77f4, 0x008ab7f4, 0x008af7f4, - 0x008b37f4, 0x008b77f4, 0x008bb7f4, 0x008bf7f4, - 0x008c37f4, 0x008c77f4, 0x008cb7f4, 0x008cf7f4, - 0x008d37f4, 0x008d77f4, 0x008db7f4, 0x008df7f4, - 0x008e37f4, 0x008e77f4, 0x008eb7f4, 0x008ef7f4, - 0x008f37f4, 0x008f77f4, 0x008fb7f4, 0x008ff7f4, - 0x009037f4, 0x009077f4, 0x0090b7f4, 0x0090f7f4, - 0x009137f4, 0x009177f4, 0x0091b7f4, 0x0091f7f4, - 0x009237f4, 0x009277f4, 0x0092b7f4, 0x0092f7f4, - 0x009337f4, 0x009377f4, 0x0093b7f4, 0x0093f7f4, - 0x009437f4, 0x009477f4, 0x0094b7f4, 0x0094f7f4, - 0x009537f4, 0x009577f4, 0x0095b7f4, 0x0095f7f4, - 0x009637f4, 0x009677f4, 0x0096b7f4, 0x0096f7f4, - 0x009737f4, 0x009777f4, 0x0097b7f4, 0x0097f7f4, - 0x009837f4, 0x009877f4, 0x0098b7f4, 0x0098f7f4, - 0x009937f4, 0x009977f4, 0x0099b7f4, 0x0099f7f4, - 0x009a37f4, 0x009a77f4, 0x009ab7f4, 0x009af7f4, - 0x009b37f4, 0x009b77f4, 0x009bb7f4, 0x009bf7f4, - 0x009c37f4, 0x009c77f4, 0x009cb7f4, 0x009cf7f4, - 0x009d37f4, 0x009d77f4, 0x009db7f4, 0x009df7f4, - 0x009e37f4, 0x009e77f4, 0x009eb7f4, 0x009ef7f4, - 0x009f37f4, 0x009f77f4, 0x009fb7f4, 0x009ff7f4, - 0x00a037f4, 0x00a077f4, 0x00a0b7f4, 0x00a0f7f4, - 0x00a137f4, 0x00a177f4, 0x00a1b7f4, 0x00a1f7f4, - 0x00a237f4, 0x00a277f4, 0x00a2b7f4, 0x00a2f7f4, - 0x00a337f4, 0x00a377f4, 0x00a3b7f4, 0x00a3f7f4, - 0x00a437f4, 0x00a477f4, 0x00a4b7f4, 0x00a4f7f4, - 0x00a537f4, 0x00a577f4, 0x00a5b7f4, 0x00a5f7f4, - 0x00a637f4, 0x00a677f4, 0x00a6b7f4, 0x00a6f7f4, - 0x00a737f4, 0x00a777f4, 0x00a7b7f4, 0x00a7f7f4, - 0x00a837f4, 0x00a877f4, 0x00a8b7f4, 0x00a8f7f4, - 0x00a937f4, 0x00a977f4, 0x00a9b7f4, 0x00a9f7f4, - 0x00aa37f4, 0x00aa77f4, 0x00aab7f4, 0x00aaf7f4, - 0x00ab37f4, 0x00ab77f4, 0x00abb7f4, 0x00abf7f4, - 0x00ac37f4, 0x00ac77f4, 0x00acb7f4, 0x00acf7f4, - 0x00ad37f4, 0x00ad77f4, 0x00adb7f4, 0x00adf7f4, - 0x00ae37f4, 0x00ae77f4, 0x00aeb7f4, 0x00aef7f4, - 0x00af37f4, 0x00af77f4, 0x00afb7f4, 0x00aff7f4, - 0x00b037f4, 0x00b077f4, 0x00b0b7f4, 0x00b0f7f4, - 0x00b137f4, 0x00b177f4, 0x00b1b7f4, 0x00b1f7f4, - 0x00b237f4, 0x00b277f4, 0x00b2b7f4, 0x00b2f7f4, - 0x00b337f4, 0x00b377f4, 0x00b3b7f4, 0x00b3f7f4, - 0x00b437f4, 0x00b477f4, 0x00b4b7f4, 0x00b4f7f4, - 0x00b537f4, 0x00b577f4, 0x00b5b7f4, 0x00b5f7f4, - 0x00b637f4, 0x00b677f4, 0x00b6b7f4, 0x00b6f7f4, - 0x00b737f4, 0x00b777f4, 0x00b7b7f4, 0x00b7f7f4, - 0x00b837f4, 0x00b877f4, 0x00b8b7f4, 0x00b8f7f4, - 0x00b937f4, 0x00b977f4, 0x00b9b7f4, 0x00b9f7f4, - 0x00ba37f4, 0x00ba77f4, 0x00bab7f4, 0x00baf7f4, - 0x00bb37f4, 0x00bb77f4, 0x00bbb7f4, 0x00bbf7f4, - 0x00bc37f4, 0x00bc77f4, 0x00bcb7f4, 0x00bcf7f4, - 0x00bd37f4, 0x00bd77f4, 0x00bdb7f4, 0x00bdf7f4, - 0x00be37f4, 0x00be77f4, 0x00beb7f4, 0x00bef7f4, - 0x00bf37f4, 0x00bf77f4, 0x00bfb7f4, 0x00bff7f4, - 0x00c037f4, 0x00c077f4, 0x00c0b7f4, 0x00c0f7f4, - 0x00c137f4, 0x00c177f4, 0x00c1b7f4, 0x00c1f7f4, - 0x00c237f4, 0x00c277f4, 0x00c2b7f4, 0x00c2f7f4, - 0x00c337f4, 0x00c377f4, 0x00c3b7f4, 0x00c3f7f4, - 0x00c437f4, 0x00c477f4, 0x00c4b7f4, 0x00c4f7f4, - 0x00c537f4, 0x00c577f4, 0x00c5b7f4, 0x00c5f7f4, - 0x00c637f4, 0x00c677f4, 0x00c6b7f4, 0x00c6f7f4, - 0x00c737f4, 0x00c777f4, 0x00c7b7f4, 0x00c7f7f4, - 0x00c837f4, 0x00c877f4, 0x00c8b7f4, 0x00c8f7f4, - 0x00c937f4, 0x00c977f4, 0x00c9b7f4, 0x00c9f7f4, - 0x00ca37f4, 0x00ca77f4, 0x00cab7f4, 0x00caf7f4, - 0x00cb37f4, 0x00cb77f4, 0x00cbb7f4, 0x00cbf7f4, - 0x00cc37f4, 0x00cc77f4, 0x00ccb7f4, 0x00ccf7f4, - 0x00cd37f4, 0x00cd77f4, 0x00cdb7f4, 0x00cdf7f4, - 0x00ce37f4, 0x00ce77f4, 0x00ceb7f4, 0x00cef7f4, - 0x00cf37f4, 0x00cf77f4, 0x00cfb7f4, 0x00cff7f4, - 0x00d037f4, 0x00d077f4, 0x00d0b7f4, 0x00d0f7f4, - 0x00d137f4, 0x00d177f4, 0x00d1b7f4, 0x00d1f7f4, - 0x00d237f4, 0x00d277f4, 0x00d2b7f4, 0x00d2f7f4, - 0x00d337f4, 0x00d377f4, 0x00d3b7f4, 0x00d3f7f4, - 0x00d437f4, 0x00d477f4, 0x00d4b7f4, 0x00d4f7f4, - 0x00d537f4, 0x00d577f4, 0x00d5b7f4, 0x00d5f7f4, - 0x00d637f4, 0x00d677f4, 0x00d6b7f4, 0x00d6f7f4, - 0x00d737f4, 0x00d777f4, 0x00d7b7f4, 0x00d7f7f4, - 0x00d837f4, 0x00d877f4, 0x00d8b7f4, 0x00d8f7f4, - 0x00d937f4, 0x00d977f4, 0x00d9b7f4, 0x00d9f7f4, - 0x00da37f4, 0x00da77f4, 0x00dab7f4, 0x00daf7f4, - 0x00db37f4, 0x00db77f4, 0x00dbb7f4, 0x00dbf7f4, - 0x00dc37f4, 0x00dc77f4, 0x00dcb7f4, 0x00dcf7f4, - 0x00dd37f4, 0x00dd77f4, 0x00ddb7f4, 0x00ddf7f4, - 0x00de37f4, 0x00de77f4, 0x00deb7f4, 0x00def7f4, - 0x00df37f4, 0x00df77f4, 0x00dfb7f4, 0x00dff7f4, - 0x00e037f4, 0x00e077f4, 0x00e0b7f4, 0x00e0f7f4, - 0x00e137f4, 0x00e177f4, 0x00e1b7f4, 0x00e1f7f4, - 0x00e237f4, 0x00e277f4, 0x00e2b7f4, 0x00e2f7f4, - 0x00e337f4, 0x00e377f4, 0x00e3b7f4, 0x00e3f7f4, - 0x00e437f4, 0x00e477f4, 0x00e4b7f4, 0x00e4f7f4, - 0x00e537f4, 0x00e577f4, 0x00e5b7f4, 0x00e5f7f4, - 0x00e637f4, 0x00e677f4, 0x00e6b7f4, 0x00e6f7f4, - 0x00e737f4, 0x00e777f4, 0x00e7b7f4, 0x00e7f7f4, - 0x00e837f4, 0x00e877f4, 0x00e8b7f4, 0x00e8f7f4, - 0x00e937f4, 0x00e977f4, 0x00e9b7f4, 0x00e9f7f4, - 0x00ea37f4, 0x00ea77f4, 0x00eab7f4, 0x00eaf7f4, - 0x00eb37f4, 0x00eb77f4, 0x00ebb7f4, 0x00ebf7f4, - 0x00ec37f4, 0x00ec77f4, 0x00ecb7f4, 0x00ecf7f4, - 0x00ed37f4, 0x00ed77f4, 0x00edb7f4, 0x00edf7f4, - 0x00ee37f4, 0x00ee77f4, 0x00eeb7f4, 0x00eef7f4, - 0x00ef37f4, 0x00ef77f4, 0x00efb7f4, 0x00eff7f4, - 0x00f037f4, 0x00f077f4, 0x00f0b7f4, 0x00f0f7f4, - 0x00f137f4, 0x00f177f4, 0x00f1b7f4, 0x00f1f7f4, - 0x00f237f4, 0x00f277f4, 0x00f2b7f4, 0x00f2f7f4, - 0x00f337f4, 0x00f377f4, 0x00f3b7f4, 0x00f3f7f4, - 0x00f437f4, 0x00f477f4, 0x00f4b7f4, 0x00f4f7f4, - 0x00f537f4, 0x00f577f4, 0x00f5b7f4, 0x00f5f7f4, - 0x00f637f4, 0x00f677f4, 0x00f6b7f4, 0x00f6f7f4, - 0x00f737f4, 0x00f777f4, 0x00f7b7f4, 0x00f7f7f4, - 0x00f837f4, 0x00f877f4, 0x00f8b7f4, 0x00f8f7f4, - 0x00f937f4, 0x00f977f4, 0x00f9b7f4, 0x00f9f7f4, - 0x00fa37f4, 0x00fa77f4, 0x00fab7f4, 0x00faf7f4, - 0x00fb37f4, 0x00fb77f4, 0x00fbb7f4, 0x00fbf7f4, - 0x00fc37f4, 0x00fc77f4, 0x00fcb7f4, 0x00fcf7f4, - 0x00fd37f4, 0x00fd77f4, 0x00fdb7f4, 0x00fdf7f4, - 0x00fe37f4, 0x00fe77f4, 0x00feb7f4, 0x00fef7f4, - 0x00ff37f4, 0x00ff77f4, 0x00ffb7f4, 0x00fff7f4, - 0x010037f4, 0x010077f4, 0x0100b7f4, 0x0100f7f4, - 0x010137f4, 0x010177f4, 0x0101b7f4, 0x0101f7f4, - 0x010237f4, 0x010277f4, 0x0102b7f4, 0x0102f7f4, - 0x010337f4, 0x010377f4, 0x0103b7f4, 0x0103f7f4, - 0x010437f4, 0x010477f4, 0x0104b7f4, 0x0104f7f4, - 0x010537f4, 0x010577f4, 0x0105b7f4, 0x0105f7f4, - 0x010637f4, 0x010677f4, 0x0106b7f4, 0x0106f7f4, - 0x010737f4, 0x010777f4, 0x0107b7f4, 0x0107f7f4, - 0x010837f4, 0x010877f4, 0x0108b7f4, 0x0108f7f4, - 0x010937f4, 0x010977f4, 0x0109b7f4, 0x0109f7f4, - 0x010a37f4, 0x010a77f4, 0x010ab7f4, 0x010af7f4, - 0x010b37f4, 0x010b77f4, 0x010bb7f4, 0x010bf7f4, - 0x010c37f4, 0x010c77f4, 0x010cb7f4, 0x010cf7f4, - 0x010d37f4, 0x010d77f4, 0x010db7f4, 0x010df7f4, - 0x010e37f4, 0x010e77f4, 0x010eb7f4, 0x010ef7f4, - 0x010f37f4, 0x010f77f4, 0x010fb7f4, 0x010ff7f4, - 0x011037f4, 0x011077f4, 0x0110b7f4, 0x0110f7f4, - 0x011137f4, 0x011177f4, 0x0111b7f4, 0x0111f7f4, - 0x011237f4, 0x011277f4, 0x0112b7f4, 0x0112f7f4, - 0x011337f4, 0x011377f4, 0x0113b7f4, 0x0113f7f4, - 0x011437f4, 0x011477f4, 0x0114b7f4, 0x0114f7f4, - 0x011537f4, 0x011577f4, 0x0115b7f4, 0x0115f7f4, - 0x011637f4, 0x011677f4, 0x0116b7f4, 0x0116f7f4, - 0x011737f4, 0x011777f4, 0x0117b7f4, 0x0117f7f4, - 0x011837f4, 0x011877f4, 0x0118b7f4, 0x0118f7f4, - 0x011937f4, 0x011977f4, 0x0119b7f4, 0x0119f7f4, - 0x011a37f4, 0x011a77f4, 0x011ab7f4, 0x011af7f4, - 0x011b37f4, 0x011b77f4, 0x011bb7f4, 0x011bf7f4, - 0x011c37f4, 0x011c77f4, 0x011cb7f4, 0x011cf7f4, - 0x011d37f4, 0x011d77f4, 0x011db7f4, 0x011df7f4, - 0x011e37f4, 0x011e77f4, 0x011eb7f4, 0x011ef7f4, - 0x011f37f4, 0x011f77f4, 0x011fb7f4, 0x011ff7f4, - 0x012037f4, 0x012077f4, 0x0120b7f4, 0x0120f7f4, - 0x012137f4, 0x012177f4, 0x0121b7f4, 0x0121f7f4, - 0x012237f4, 0x012277f4, 0x0122b7f4, 0x0122f7f4, - 0x012337f4, 0x012377f4, 0x0123b7f4, 0x0123f7f4, - 0x012437f4, 0x012477f4, 0x0124b7f4, 0x0124f7f4, - 0x012537f4, 0x012577f4, 0x0125b7f4, 0x0125f7f4, - 0x012637f4, 0x012677f4, 0x0126b7f4, 0x0126f7f4, - 0x012737f4, 0x012777f4, 0x0127b7f4, 0x0127f7f4, - 0x012837f4, 0x012877f4, 0x0128b7f4, 0x0128f7f4, - 0x012937f4, 0x012977f4, 0x0129b7f4, 0x0129f7f4, - 0x012a37f4, 0x012a77f4, 0x012ab7f4, 0x012af7f4, - 0x012b37f4, 0x012b77f4, 0x012bb7f4, 0x012bf7f4, - 0x012c37f4, 0x012c77f4, 0x012cb7f4, 0x012cf7f4, - 0x012d37f4, 0x012d77f4, 0x012db7f4, 0x012df7f4, - 0x012e37f4, 0x012e77f4, 0x012eb7f4, 0x012ef7f4, - 0x012f37f4, 0x012f77f4, 0x012fb7f4, 0x012ff7f4, - 0x013037f4, 0x013077f4, 0x0130b7f4, 0x0130f7f4, - 0x013137f4, 0x013177f4, 0x0131b7f4, 0x0131f7f4, - 0x013237f4, 0x013277f4, 0x0132b7f4, 0x0132f7f4, - 0x013337f4, 0x013377f4, 0x0133b7f4, 0x0133f7f4, - 0x013437f4, 0x013477f4, 0x0134b7f4, 0x0134f7f4, - 0x013537f4, 0x013577f4, 0x0135b7f4, 0x0135f7f4, - 0x013637f4, 0x013677f4, 0x0136b7f4, 0x0136f7f4, - 0x013737f4, 0x013777f4, 0x0137b7f4, 0x0137f7f4, - 0x013837f4, 0x013877f4, 0x0138b7f4, 0x0138f7f4, - 0x013937f4, 0x013977f4, 0x0139b7f4, 0x0139f7f4, - 0x013a37f4, 0x013a77f4, 0x013ab7f4, 0x013af7f4, - 0x013b37f4, 0x013b77f4, 0x013bb7f4, 0x013bf7f4, - 0x013c37f4, 0x013c77f4, 0x013cb7f4, 0x013cf7f4, - 0x013d37f4, 0x013d77f4, 0x013db7f4, 0x013df7f4, - 0x013e37f4, 0x013e77f4, 0x013eb7f4, 0x013ef7f4, - 0x013f37f4, 0x013f77f4, 0x013fb7f4, 0x013ff7f4, - 0x014037f4, 0x014077f4, 0x0140b7f4, 0x0140f7f4, - 0x014137f4, 0x014177f4, 0x0141b7f4, 0x0141f7f4, - 0x014237f4, 0x014277f4, 0x0142b7f4, 0x0142f7f4, - 0x014337f4, 0x014377f4, 0x0143b7f4, 0x0143f7f4, - 0x014437f4, 0x014477f4, 0x0144b7f4, 0x0144f7f4, - 0x014537f4, 0x014577f4, 0x0145b7f4, 0x0145f7f4, - 0x014637f4, 0x014677f4, 0x0146b7f4, 0x0146f7f4, - 0x014737f4, 0x014777f4, 0x0147b7f4, 0x0147f7f4, - 0x014837f4, 0x014877f4, 0x0148b7f4, 0x0148f7f4, - 0x014937f4, 0x014977f4, 0x0149b7f4, 0x0149f7f4, - 0x014a37f4, 0x014a77f4, 0x014ab7f4, 0x014af7f4, - 0x014b37f4, 0x014b77f4, 0x014bb7f4, 0x014bf7f4, - 0x014c37f4, 0x014c77f4, 0x014cb7f4, 0x014cf7f4, - 0x014d37f4, 0x014d77f4, 0x014db7f4, 0x014df7f4, - 0x014e37f4, 0x014e77f4, 0x014eb7f4, 0x014ef7f4, - 0x014f37f4, 0x014f77f4, 0x014fb7f4, 0x014ff7f4, - 0x015037f4, 0x015077f4, 0x0150b7f4, 0x0150f7f4, - 0x015137f4, 0x015177f4, 0x0151b7f4, 0x0151f7f4, - 0x015237f4, 0x015277f4, 0x0152b7f4, 0x0152f7f4, - 0x015337f4, 0x015377f4, 0x0153b7f4, 0x0153f7f4, - 0x015437f4, 0x015477f4, 0x0154b7f4, 0x0154f7f4, - 0x015537f4, 0x015577f4, 0x0155b7f4, 0x0155f7f4, - 0x015637f4, 0x015677f4, 0x0156b7f4, 0x0156f7f4, - 0x015737f4, 0x015777f4, 0x0157b7f4, 0x0157f7f4, - 0x015837f4, 0x015877f4, 0x0158b7f4, 0x0158f7f4, - 0x015937f4, 0x015977f4, 0x0159b7f4, 0x0159f7f4, - 0x015a37f4, 0x015a77f4, 0x015ab7f4, 0x015af7f4, - 0x015b37f4, 0x015b77f4, 0x015bb7f4, 0x015bf7f4, - 0x015c37f4, 0x015c77f4, 0x015cb7f4, 0x015cf7f4, - 0x015d37f4, 0x015d77f4, 0x015db7f4, 0x015df7f4, - 0x015e37f4, 0x015e77f4, 0x015eb7f4, 0x015ef7f4, - 0x015f37f4, 0x015f77f4, 0x015fb7f4, 0x015ff7f4, - 0x016037f4, 0x016077f4, 0x0160b7f4, 0x0160f7f4, - 0x016137f4, 0x016177f4, 0x0161b7f4, 0x0161f7f4, - 0x016237f4, 0x016277f4, 0x0162b7f4, 0x0162f7f4, - 0x016337f4, 0x016377f4, 0x0163b7f4, 0x0163f7f4, - 0x016437f4, 0x016477f4, 0x0164b7f4, 0x0164f7f4, - 0x016537f4, 0x016577f4, 0x0165b7f4, 0x0165f7f4, - 0x016637f4, 0x016677f4, 0x0166b7f4, 0x0166f7f4, - 0x016737f4, 0x016777f4, 0x0167b7f4, 0x0167f7f4, - 0x016837f4, 0x016877f4, 0x0168b7f4, 0x0168f7f4, - 0x016937f4, 0x016977f4, 0x0169b7f4, 0x0169f7f4, - 0x016a37f4, 0x016a77f4, 0x016ab7f4, 0x016af7f4, - 0x016b37f4, 0x016b77f4, 0x016bb7f4, 0x016bf7f4, - 0x016c37f4, 0x016c77f4, 0x016cb7f4, 0x016cf7f4, - 0x016d37f4, 0x016d77f4, 0x016db7f4, 0x016df7f4, - 0x016e37f4, 0x016e77f4, 0x016eb7f4, 0x016ef7f4, - 0x016f37f4, 0x016f77f4, 0x016fb7f4, 0x016ff7f4, - 0x017037f4, 0x017077f4, 0x0170b7f4, 0x0170f7f4, - 0x017137f4, 0x017177f4, 0x0171b7f4, 0x0171f7f4, - 0x017237f4, 0x017277f4, 0x0172b7f4, 0x0172f7f4, - 0x017337f4, 0x017377f4, 0x0173b7f4, 0x0173f7f4, - 0x017437f4, 0x017477f4, 0x0174b7f4, 0x0174f7f4, - 0x017537f4, 0x017577f4, 0x0175b7f4, 0x0175f7f4, - 0x017637f4, 0x017677f4, 0x0176b7f4, 0x0176f7f4, - 0x017737f4, 0x017777f4, 0x0177b7f4, 0x0177f7f4, - 0x017837f4, 0x017877f4, 0x0178b7f4, 0x0178f7f4, - 0x017937f4, 0x017977f4, 0x0179b7f4, 0x0179f7f4, - 0x017a37f4, 0x017a77f4, 0x017ab7f4, 0x017af7f4, - 0x017b37f4, 0x017b77f4, 0x017bb7f4, 0x017bf7f4, - 0x017c37f4, 0x017c77f4, 0x017cb7f4, 0x017cf7f4, - 0x017d37f4, 0x017d77f4, 0x017db7f4, 0x017df7f4, - 0x017e37f4, 0x017e77f4, 0x017eb7f4, 0x017ef7f4, - 0x017f37f4, 0x017f77f4, 0x017fb7f4, 0x017ff7f4, - 0x018037f4, 0x018077f4, 0x0180b7f4, 0x0180f7f4, - 0x018137f4, 0x018177f4, 0x0181b7f4, 0x0181f7f4, - 0x018237f4, 0x018277f4, 0x0182b7f4, 0x0182f7f4, - 0x018337f4, 0x018377f4, 0x0183b7f4, 0x0183f7f4, - 0x018437f4, 0x018477f4, 0x0184b7f4, 0x0184f7f4, - 0x018537f4, 0x018577f4, 0x0185b7f4, 0x0185f7f4, - 0x018637f4, 0x018677f4, 0x0186b7f4, 0x0186f7f4, - 0x018737f4, 0x018777f4, 0x0187b7f4, 0x0187f7f4, - 0x018837f4, 0x018877f4, 0x0188b7f4, 0x0188f7f4, - 0x018937f4, 0x018977f4, 0x0189b7f4, 0x0189f7f4, - 0x018a37f4, 0x018a77f4, 0x018ab7f4, 0x018af7f4, - 0x018b37f4, 0x018b77f4, 0x018bb7f4, 0x018bf7f4, - 0x018c37f4, 0x018c77f4, 0x018cb7f4, 0x018cf7f4, - 0x018d37f4, 0x018d77f4, 0x018db7f4, 0x018df7f4, - 0x018e37f4, 0x018e77f4, 0x018eb7f4, 0x018ef7f4, - 0x018f37f4, 0x018f77f4, 0x018fb7f4, 0x018ff7f4, - 0x019037f4, 0x019077f4, 0x0190b7f4, 0x0190f7f4, - 0x019137f4, 0x019177f4, 0x0191b7f4, 0x0191f7f4, - 0x019237f4, 0x019277f4, 0x0192b7f4, 0x0192f7f4, - 0x019337f4, 0x019377f4, 0x0193b7f4, 0x0193f7f4, - 0x019437f4, 0x019477f4, 0x0194b7f4, 0x0194f7f4, - 0x019537f4, 0x019577f4, 0x0195b7f4, 0x0195f7f4, - 0x019637f4, 0x019677f4, 0x0196b7f4, 0x0196f7f4, - 0x019737f4, 0x019777f4, 0x0197b7f4, 0x0197f7f4, - 0x019837f4, 0x019877f4, 0x0198b7f4, 0x0198f7f4, - 0x019937f4, 0x019977f4, 0x0199b7f4, 0x0199f7f4, - 0x019a37f4, 0x019a77f4, 0x019ab7f4, 0x019af7f4, - 0x019b37f4, 0x019b77f4, 0x019bb7f4, 0x019bf7f4, - 0x019c37f4, 0x019c77f4, 0x019cb7f4, 0x019cf7f4, - 0x019d37f4, 0x019d77f4, 0x019db7f4, 0x019df7f4, - 0x019e37f4, 0x019e77f4, 0x019eb7f4, 0x019ef7f4, - 0x019f37f4, 0x019f77f4, 0x019fb7f4, 0x019ff7f4, - 0x01a037f4, 0x01a077f4, 0x01a0b7f4, 0x01a0f7f4, - 0x01a137f4, 0x01a177f4, 0x01a1b7f4, 0x01a1f7f4, - 0x01a237f4, 0x01a277f4, 0x01a2b7f4, 0x01a2f7f4, - 0x01a337f4, 0x01a377f4, 0x01a3b7f4, 0x01a3f7f4, - 0x01a437f4, 0x01a477f4, 0x01a4b7f4, 0x01a4f7f4, - 0x01a537f4, 0x01a577f4, 0x01a5b7f4, 0x01a5f7f4, - 0x01a637f4, 0x01a677f4, 0x01a6b7f4, 0x01a6f7f4, - 0x01a737f4, 0x01a777f4, 0x01a7b7f4, 0x01a7f7f4, - 0x01a837f4, 0x01a877f4, 0x01a8b7f4, 0x01a8f7f4, - 0x01a937f4, 0x01a977f4, 0x01a9b7f4, 0x01a9f7f4, - 0x01aa37f4, 0x01aa77f4, 0x01aab7f4, 0x01aaf7f4, - 0x01ab37f4, 0x01ab77f4, 0x01abb7f4, 0x01abf7f4, - 0x01ac37f4, 0x01ac77f4, 0x01acb7f4, 0x01acf7f4, - 0x01ad37f4, 0x01ad77f4, 0x01adb7f4, 0x01adf7f4, - 0x01ae37f4, 0x01ae77f4, 0x01aeb7f4, 0x01aef7f4, - 0x01af37f4, 0x01af77f4, 0x01afb7f4, 0x01aff7f4, - 0x01b037f4, 0x01b077f4, 0x01b0b7f4, 0x01b0f7f4, - 0x01b137f4, 0x01b177f4, 0x01b1b7f4, 0x01b1f7f4, - 0x01b237f4, 0x01b277f4, 0x01b2b7f4, 0x01b2f7f4, - 0x01b337f4, 0x01b377f4, 0x01b3b7f4, 0x01b3f7f4, - 0x01b437f4, 0x01b477f4, 0x01b4b7f4, 0x01b4f7f4, - 0x01b537f4, 0x01b577f4, 0x01b5b7f4, 0x01b5f7f4, - 0x01b637f4, 0x01b677f4, 0x01b6b7f4, 0x01b6f7f4, - 0x01b737f4, 0x01b777f4, 0x01b7b7f4, 0x01b7f7f4, - 0x01b837f4, 0x01b877f4, 0x01b8b7f4, 0x01b8f7f4, - 0x01b937f4, 0x01b977f4, 0x01b9b7f4, 0x01b9f7f4, - 0x01ba37f4, 0x01ba77f4, 0x01bab7f4, 0x01baf7f4, - 0x01bb37f4, 0x01bb77f4, 0x01bbb7f4, 0x01bbf7f4, - 0x01bc37f4, 0x01bc77f4, 0x01bcb7f4, 0x01bcf7f4, - 0x01bd37f4, 0x01bd77f4, 0x01bdb7f4, 0x01bdf7f4, - 0x01be37f4, 0x01be77f4, 0x01beb7f4, 0x01bef7f4, - 0x01bf37f4, 0x01bf77f4, 0x01bfb7f4, 0x01bff7f4, - 0x01c037f4, 0x01c077f4, 0x01c0b7f4, 0x01c0f7f4, - 0x01c137f4, 0x01c177f4, 0x01c1b7f4, 0x01c1f7f4, - 0x01c237f4, 0x01c277f4, 0x01c2b7f4, 0x01c2f7f4, - 0x01c337f4, 0x01c377f4, 0x01c3b7f4, 0x01c3f7f4, - 0x01c437f4, 0x01c477f4, 0x01c4b7f4, 0x01c4f7f4, - 0x01c537f4, 0x01c577f4, 0x01c5b7f4, 0x01c5f7f4, - 0x01c637f4, 0x01c677f4, 0x01c6b7f4, 0x01c6f7f4, - 0x01c737f4, 0x01c777f4, 0x01c7b7f4, 0x01c7f7f4, - 0x01c837f4, 0x01c877f4, 0x01c8b7f4, 0x01c8f7f4, - 0x01c937f4, 0x01c977f4, 0x01c9b7f4, 0x01c9f7f4, - 0x01ca37f4, 0x01ca77f4, 0x01cab7f4, 0x01caf7f4, - 0x01cb37f4, 0x01cb77f4, 0x01cbb7f4, 0x01cbf7f4, - 0x01cc37f4, 0x01cc77f4, 0x01ccb7f4, 0x01ccf7f4, - 0x01cd37f4, 0x01cd77f4, 0x01cdb7f4, 0x01cdf7f4, - 0x01ce37f4, 0x01ce77f4, 0x01ceb7f4, 0x01cef7f4, - 0x01cf37f4, 0x01cf77f4, 0x01cfb7f4, 0x01cff7f4, - 0x01d037f4, 0x01d077f4, 0x01d0b7f4, 0x01d0f7f4, - 0x01d137f4, 0x01d177f4, 0x01d1b7f4, 0x01d1f7f4, - 0x01d237f4, 0x01d277f4, 0x01d2b7f4, 0x01d2f7f4, - 0x01d337f4, 0x01d377f4, 0x01d3b7f4, 0x01d3f7f4, - 0x01d437f4, 0x01d477f4, 0x01d4b7f4, 0x01d4f7f4, - 0x01d537f4, 0x01d577f4, 0x01d5b7f4, 0x01d5f7f4, - 0x01d637f4, 0x01d677f4, 0x01d6b7f4, 0x01d6f7f4, - 0x01d737f4, 0x01d777f4, 0x01d7b7f4, 0x01d7f7f4, - 0x01d837f4, 0x01d877f4, 0x01d8b7f4, 0x01d8f7f4, - 0x01d937f4, 0x01d977f4, 0x01d9b7f4, 0x01d9f7f4, - 0x01da37f4, 0x01da77f4, 0x01dab7f4, 0x01daf7f4, - 0x01db37f4, 0x01db77f4, 0x01dbb7f4, 0x01dbf7f4, - 0x01dc37f4, 0x01dc77f4, 0x01dcb7f4, 0x01dcf7f4, - 0x01dd37f4, 0x01dd77f4, 0x01ddb7f4, 0x01ddf7f4, - 0x01de37f4, 0x01de77f4, 0x01deb7f4, 0x01def7f4, - 0x01df37f4, 0x01df77f4, 0x01dfb7f4, 0x01dff7f4, - 0x01e037f4, 0x01e077f4, 0x01e0b7f4, 0x01e0f7f4, - 0x01e137f4, 0x01e177f4, 0x01e1b7f4, 0x01e1f7f4, - 0x01e237f4, 0x01e277f4, 0x01e2b7f4, 0x01e2f7f4, - 0x01e337f4, 0x01e377f4, 0x01e3b7f4, 0x01e3f7f4, - 0x01e437f4, 0x01e477f4, 0x01e4b7f4, 0x01e4f7f4, - 0x01e537f4, 0x01e577f4, 0x01e5b7f4, 0x01e5f7f4, - 0x01e637f4, 0x01e677f4, 0x01e6b7f4, 0x01e6f7f4, - 0x01e737f4, 0x01e777f4, 0x01e7b7f4, 0x01e7f7f4, - 0x01e837f4, 0x01e877f4, 0x01e8b7f4, 0x01e8f7f4, - 0x01e937f4, 0x01e977f4, 0x01e9b7f4, 0x01e9f7f4, - 0x01ea37f4, 0x01ea77f4, 0x01eab7f4, 0x01eaf7f4, - 0x01eb37f4, 0x01eb77f4, 0x01ebb7f4, 0x01ebf7f4, - 0x01ec37f4, 0x01ec77f4, 0x01ecb7f4, 0x01ecf7f4, - 0x01ed37f4, 0x01ed77f4, 0x01edb7f4, 0x01edf7f4, - 0x01ee37f4, 0x01ee77f4, 0x01eeb7f4, 0x01eef7f4, - 0x01ef37f4, 0x01ef77f4, 0x01efb7f4, 0x01eff7f4, - 0x01f037f4, 0x01f077f4, 0x01f0b7f4, 0x01f0f7f4, - 0x01f137f4, 0x01f177f4, 0x01f1b7f4, 0x01f1f7f4, - 0x01f237f4, 0x01f277f4, 0x01f2b7f4, 0x01f2f7f4, - 0x01f337f4, 0x01f377f4, 0x01f3b7f4, 0x01f3f7f4, - 0x01f437f4, 0x01f477f4, 0x01f4b7f4, 0x01f4f7f4, - 0x01f537f4, 0x01f577f4, 0x01f5b7f4, 0x01f5f7f4, - 0x01f637f4, 0x01f677f4, 0x01f6b7f4, 0x01f6f7f4, - 0x01f737f4, 0x01f777f4, 0x01f7b7f4, 0x01f7f7f4, - 0x01f837f4, 0x01f877f4, 0x01f8b7f4, 0x01f8f7f4, - 0x01f937f4, 0x01f977f4, 0x01f9b7f4, 0x01f9f7f4, - 0x01fa37f4, 0x01fa77f4, 0x01fab7f4, 0x01faf7f4, - 0x01fb37f4, 0x01fb77f4, 0x01fbb7f4, 0x01fbf7f4, - 0x01fc37f4, 0x01fc77f4, 0x01fcb7f4, 0x01fcf7f4, - 0x01fd37f4, 0x01fd77f4, 0x01fdb7f4, 0x01fdf7f4, - 0x01fe37f4, 0x01fe77f4, 0x01feb7f4, 0x01fef7f4, - 0x01ff37f4, 0x01ff77f4, 0x01ffb7f4, 0x01fff7f4 }, + 0x00000fe9, 0x00003fea, +#ifdef LONGER_HUFFTABLE + 0x00002fe9, 0x00007fea, 0x00001fea, 0x00005fea, + 0x000007e9, 0x000027e9, 0x000017ea, 0x000037ea, + 0x000057ea, 0x000077ea, 0x000001e8, 0x000009e8, + 0x000011e8, 0x000019e8, 0x000005e9, 0x00000de9, + 0x000015e9, 0x00001de9, 0x000025e9, 0x00002de9, + 0x000035e9, 0x00003de9, 0x000003e9, 0x00000be9, + 0x000013e9, 0x00001be9, 0x000023e9, 0x00002be9, + 0x000033e9, 0x00003be9, 0x00000169, 0x00000569, + 0x00000969, 0x00000d69, 0x00001169, 0x00001569, + 0x00001969, 0x00001d69, 0x00002169, 0x00002569, + 0x00002969, 0x00002d69, 0x00003169, 0x00003569, + 0x00003969, 0x00003d69, 0x00000369, 0x00000769, + 0x00000b69, 0x00000f69, 0x00001369, 0x00001769, + 0x00001b69, 0x00001f69, 0x00002369, 0x00002769, + 0x00002b69, 0x00002f69, 0x00003369, 0x00003769, + 0x00003b69, 0x00003f69, 0x00000089, 0x00000289, + 0x00000489, 0x00000689, 0x00000889, 0x00000a89, + 0x00000c89, 0x00000e89, 0x00001089, 0x00001289, + 0x00001489, 0x00001689, 0x00001889, 0x00001a89, + 0x00001c89, 0x00001e89, 0x00002089, 0x00002289, + 0x00002489, 0x00002689, 0x00002889, 0x00002a89, + 0x00002c89, 0x00002e89, 0x00003089, 0x00003289, + 0x00003489, 0x00003689, 0x00003889, 0x00003a89, + 0x00003c89, 0x00003e89, 0x000000ea, 0x000004ea, + 0x000008ea, 0x00000cea, 0x000010ea, 0x000014ea, + 0x000018ea, 0x00001cea, 0x000020ea, 0x000024ea, + 0x000028ea, 0x00002cea, 0x000030ea, 0x000034ea, + 0x000038ea, 0x00003cea, 0x000040ea, 0x000044ea, + 0x000048ea, 0x00004cea, 0x000050ea, 0x000054ea, + 0x000058ea, 0x00005cea, 0x000060ea, 0x000064ea, + 0x000068ea, 0x00006cea, 0x000070ea, 0x000074ea, + 0x000078ea, 0x00007cea, 0x0000018a, 0x0000038a, + 0x0000058a, 0x0000078a, 0x0000098a, 0x00000b8a, + 0x00000d8a, 0x00000f8a, 0x0000118a, 0x0000138a, + 0x0000158a, 0x0000178a, 0x0000198a, 0x00001b8a, + 0x00001d8a, 0x00001f8a, 0x0000218a, 0x0000238a, + 0x0000258a, 0x0000278a, 0x0000298a, 0x00002b8a, + 0x00002d8a, 0x00002f8a, 0x0000318a, 0x0000338a, + 0x0000358a, 0x0000378a, 0x0000398a, 0x00003b8a, + 0x00003d8a, 0x00003f8a, 0x0000418a, 0x0000438a, + 0x0000458a, 0x0000478a, 0x0000498a, 0x00004b8a, + 0x00004d8a, 0x00004f8a, 0x0000518a, 0x0000538a, + 0x0000558a, 0x0000578a, 0x0000598a, 0x00005b8a, + 0x00005d8a, 0x00005f8a, 0x0000618a, 0x0000638a, + 0x0000658a, 0x0000678a, 0x0000698a, 0x00006b8a, + 0x00006d8a, 0x00006f8a, 0x0000718a, 0x0000738a, + 0x0000758a, 0x0000778a, 0x0000798a, 0x00007b8a, + 0x00007d8a, 0x00007f8a, 0x0000004a, 0x0000024a, + 0x0000044a, 0x0000064a, 0x0000084a, 0x00000a4a, + 0x00000c4a, 0x00000e4a, 0x0000104a, 0x0000124a, + 0x0000144a, 0x0000164a, 0x0000184a, 0x00001a4a, + 0x00001c4a, 0x00001e4a, 0x0000204a, 0x0000224a, + 0x0000244a, 0x0000264a, 0x0000284a, 0x00002a4a, + 0x00002c4a, 0x00002e4a, 0x0000304a, 0x0000324a, + 0x0000344a, 0x0000364a, 0x0000384a, 0x00003a4a, + 0x00003c4a, 0x00003e4a, 0x0000404a, 0x0000424a, + 0x0000444a, 0x0000464a, 0x0000484a, 0x00004a4a, + 0x00004c4a, 0x00004e4a, 0x0000504a, 0x0000524a, + 0x0000544a, 0x0000564a, 0x0000584a, 0x00005a4a, + 0x00005c4a, 0x00005e4a, 0x0000604a, 0x0000624a, + 0x0000644a, 0x0000664a, 0x0000684a, 0x00006a4a, + 0x00006c4a, 0x00006e4a, 0x0000704a, 0x0000724a, + 0x0000744a, 0x0000764a, 0x0000784a, 0x00007a4a, + 0x00007c4a, 0x00007e4a, 0x0000014b, 0x0000034b, + 0x0000054b, 0x0000074b, 0x0000094b, 0x00000b4b, + 0x00000d4b, 0x00000f4b, 0x0000114b, 0x0000134b, + 0x0000154b, 0x0000174b, 0x0000194b, 0x00001b4b, + 0x00001d4b, 0x00001f4b, 0x0000214b, 0x0000234b, + 0x0000254b, 0x0000274b, 0x0000294b, 0x00002b4b, + 0x00002d4b, 0x00002f4b, 0x0000314b, 0x0000334b, + 0x0000354b, 0x0000374b, 0x0000394b, 0x00003b4b, + 0x00003d4b, 0x00003f4b, 0x0000414b, 0x0000434b, + 0x0000454b, 0x0000474b, 0x0000494b, 0x00004b4b, + 0x00004d4b, 0x00004f4b, 0x0000514b, 0x0000534b, + 0x0000554b, 0x0000574b, 0x0000594b, 0x00005b4b, + 0x00005d4b, 0x00005f4b, 0x0000614b, 0x0000634b, + 0x0000654b, 0x0000674b, 0x0000694b, 0x00006b4b, + 0x00006d4b, 0x00006f4b, 0x0000714b, 0x0000734b, + 0x0000754b, 0x0000774b, 0x0000794b, 0x00007b4b, + 0x00007d4b, 0x00007f4b, 0x0000814b, 0x0000834b, + 0x0000854b, 0x0000874b, 0x0000894b, 0x00008b4b, + 0x00008d4b, 0x00008f4b, 0x0000914b, 0x0000934b, + 0x0000954b, 0x0000974b, 0x0000994b, 0x00009b4b, + 0x00009d4b, 0x00009f4b, 0x0000a14b, 0x0000a34b, + 0x0000a54b, 0x0000a74b, 0x0000a94b, 0x0000ab4b, + 0x0000ad4b, 0x0000af4b, 0x0000b14b, 0x0000b34b, + 0x0000b54b, 0x0000b74b, 0x0000b94b, 0x0000bb4b, + 0x0000bd4b, 0x0000bf4b, 0x0000c14b, 0x0000c34b, + 0x0000c54b, 0x0000c74b, 0x0000c94b, 0x0000cb4b, + 0x0000cd4b, 0x0000cf4b, 0x0000d14b, 0x0000d34b, + 0x0000d54b, 0x0000d74b, 0x0000d94b, 0x0000db4b, + 0x0000dd4b, 0x0000df4b, 0x0000e14b, 0x0000e34b, + 0x0000e54b, 0x0000e74b, 0x0000e94b, 0x0000eb4b, + 0x0000ed4b, 0x0000ef4b, 0x0000f14b, 0x0000f34b, + 0x0000f54b, 0x0000f74b, 0x0000f94b, 0x0000fb4b, + 0x0000fd4b, 0x0000ff4b, 0x000000cb, 0x000002cb, + 0x000004cb, 0x000006cb, 0x000008cb, 0x00000acb, + 0x00000ccb, 0x00000ecb, 0x000010cb, 0x000012cb, + 0x000014cb, 0x000016cb, 0x000018cb, 0x00001acb, + 0x00001ccb, 0x00001ecb, 0x000020cb, 0x000022cb, + 0x000024cb, 0x000026cb, 0x000028cb, 0x00002acb, + 0x00002ccb, 0x00002ecb, 0x000030cb, 0x000032cb, + 0x000034cb, 0x000036cb, 0x000038cb, 0x00003acb, + 0x00003ccb, 0x00003ecb, 0x000040cb, 0x000042cb, + 0x000044cb, 0x000046cb, 0x000048cb, 0x00004acb, + 0x00004ccb, 0x00004ecb, 0x000050cb, 0x000052cb, + 0x000054cb, 0x000056cb, 0x000058cb, 0x00005acb, + 0x00005ccb, 0x00005ecb, 0x000060cb, 0x000062cb, + 0x000064cb, 0x000066cb, 0x000068cb, 0x00006acb, + 0x00006ccb, 0x00006ecb, 0x000070cb, 0x000072cb, + 0x000074cb, 0x000076cb, 0x000078cb, 0x00007acb, + 0x00007ccb, 0x00007ecb, 0x000080cb, 0x000082cb, + 0x000084cb, 0x000086cb, 0x000088cb, 0x00008acb, + 0x00008ccb, 0x00008ecb, 0x000090cb, 0x000092cb, + 0x000094cb, 0x000096cb, 0x000098cb, 0x00009acb, + 0x00009ccb, 0x00009ecb, 0x0000a0cb, 0x0000a2cb, + 0x0000a4cb, 0x0000a6cb, 0x0000a8cb, 0x0000aacb, + 0x0000accb, 0x0000aecb, 0x0000b0cb, 0x0000b2cb, + 0x0000b4cb, 0x0000b6cb, 0x0000b8cb, 0x0000bacb, + 0x0000bccb, 0x0000becb, 0x0000c0cb, 0x0000c2cb, + 0x0000c4cb, 0x0000c6cb, 0x0000c8cb, 0x0000cacb, + 0x0000cccb, 0x0000cecb, 0x0000d0cb, 0x0000d2cb, + 0x0000d4cb, 0x0000d6cb, 0x0000d8cb, 0x0000dacb, + 0x0000dccb, 0x0000decb, 0x0000e0cb, 0x0000e2cb, + 0x0000e4cb, 0x0000e6cb, 0x0000e8cb, 0x0000eacb, + 0x0000eccb, 0x0000eecb, 0x0000f0cb, 0x0000f2cb, + 0x0000f4cb, 0x0000f6cb, 0x0000f8cb, 0x0000facb, + 0x0000fccb, 0x0000fecb, 0x000001cc, 0x000003cc, + 0x000005cc, 0x000007cc, 0x000009cc, 0x00000bcc, + 0x00000dcc, 0x00000fcc, 0x000011cc, 0x000013cc, + 0x000015cc, 0x000017cc, 0x000019cc, 0x00001bcc, + 0x00001dcc, 0x00001fcc, 0x000021cc, 0x000023cc, + 0x000025cc, 0x000027cc, 0x000029cc, 0x00002bcc, + 0x00002dcc, 0x00002fcc, 0x000031cc, 0x000033cc, + 0x000035cc, 0x000037cc, 0x000039cc, 0x00003bcc, + 0x00003dcc, 0x00003fcc, 0x000041cc, 0x000043cc, + 0x000045cc, 0x000047cc, 0x000049cc, 0x00004bcc, + 0x00004dcc, 0x00004fcc, 0x000051cc, 0x000053cc, + 0x000055cc, 0x000057cc, 0x000059cc, 0x00005bcc, + 0x00005dcc, 0x00005fcc, 0x000061cc, 0x000063cc, + 0x000065cc, 0x000067cc, 0x000069cc, 0x00006bcc, + 0x00006dcc, 0x00006fcc, 0x000071cc, 0x000073cc, + 0x000075cc, 0x000077cc, 0x000079cc, 0x00007bcc, + 0x00007dcc, 0x00007fcc, 0x000081cc, 0x000083cc, + 0x000085cc, 0x000087cc, 0x000089cc, 0x00008bcc, + 0x00008dcc, 0x00008fcc, 0x000091cc, 0x000093cc, + 0x000095cc, 0x000097cc, 0x000099cc, 0x00009bcc, + 0x00009dcc, 0x00009fcc, 0x0000a1cc, 0x0000a3cc, + 0x0000a5cc, 0x0000a7cc, 0x0000a9cc, 0x0000abcc, + 0x0000adcc, 0x0000afcc, 0x0000b1cc, 0x0000b3cc, + 0x0000b5cc, 0x0000b7cc, 0x0000b9cc, 0x0000bbcc, + 0x0000bdcc, 0x0000bfcc, 0x0000c1cc, 0x0000c3cc, + 0x0000c5cc, 0x0000c7cc, 0x0000c9cc, 0x0000cbcc, + 0x0000cdcc, 0x0000cfcc, 0x0000d1cc, 0x0000d3cc, + 0x0000d5cc, 0x0000d7cc, 0x0000d9cc, 0x0000dbcc, + 0x0000ddcc, 0x0000dfcc, 0x0000e1cc, 0x0000e3cc, + 0x0000e5cc, 0x0000e7cc, 0x0000e9cc, 0x0000ebcc, + 0x0000edcc, 0x0000efcc, 0x0000f1cc, 0x0000f3cc, + 0x0000f5cc, 0x0000f7cc, 0x0000f9cc, 0x0000fbcc, + 0x0000fdcc, 0x0000ffcc, 0x000101cc, 0x000103cc, + 0x000105cc, 0x000107cc, 0x000109cc, 0x00010bcc, + 0x00010dcc, 0x00010fcc, 0x000111cc, 0x000113cc, + 0x000115cc, 0x000117cc, 0x000119cc, 0x00011bcc, + 0x00011dcc, 0x00011fcc, 0x000121cc, 0x000123cc, + 0x000125cc, 0x000127cc, 0x000129cc, 0x00012bcc, + 0x00012dcc, 0x00012fcc, 0x000131cc, 0x000133cc, + 0x000135cc, 0x000137cc, 0x000139cc, 0x00013bcc, + 0x00013dcc, 0x00013fcc, 0x000141cc, 0x000143cc, + 0x000145cc, 0x000147cc, 0x000149cc, 0x00014bcc, + 0x00014dcc, 0x00014fcc, 0x000151cc, 0x000153cc, + 0x000155cc, 0x000157cc, 0x000159cc, 0x00015bcc, + 0x00015dcc, 0x00015fcc, 0x000161cc, 0x000163cc, + 0x000165cc, 0x000167cc, 0x000169cc, 0x00016bcc, + 0x00016dcc, 0x00016fcc, 0x000171cc, 0x000173cc, + 0x000175cc, 0x000177cc, 0x000179cc, 0x00017bcc, + 0x00017dcc, 0x00017fcc, 0x000181cc, 0x000183cc, + 0x000185cc, 0x000187cc, 0x000189cc, 0x00018bcc, + 0x00018dcc, 0x00018fcc, 0x000191cc, 0x000193cc, + 0x000195cc, 0x000197cc, 0x000199cc, 0x00019bcc, + 0x00019dcc, 0x00019fcc, 0x0001a1cc, 0x0001a3cc, + 0x0001a5cc, 0x0001a7cc, 0x0001a9cc, 0x0001abcc, + 0x0001adcc, 0x0001afcc, 0x0001b1cc, 0x0001b3cc, + 0x0001b5cc, 0x0001b7cc, 0x0001b9cc, 0x0001bbcc, + 0x0001bdcc, 0x0001bfcc, 0x0001c1cc, 0x0001c3cc, + 0x0001c5cc, 0x0001c7cc, 0x0001c9cc, 0x0001cbcc, + 0x0001cdcc, 0x0001cfcc, 0x0001d1cc, 0x0001d3cc, + 0x0001d5cc, 0x0001d7cc, 0x0001d9cc, 0x0001dbcc, + 0x0001ddcc, 0x0001dfcc, 0x0001e1cc, 0x0001e3cc, + 0x0001e5cc, 0x0001e7cc, 0x0001e9cc, 0x0001ebcc, + 0x0001edcc, 0x0001efcc, 0x0001f1cc, 0x0001f3cc, + 0x0001f5cc, 0x0001f7cc, 0x0001f9cc, 0x0001fbcc, + 0x0001fdcc, 0x0001ffcc, 0x0000002c, 0x0000022c, + 0x0000042c, 0x0000062c, 0x0000082c, 0x00000a2c, + 0x00000c2c, 0x00000e2c, 0x0000102c, 0x0000122c, + 0x0000142c, 0x0000162c, 0x0000182c, 0x00001a2c, + 0x00001c2c, 0x00001e2c, 0x0000202c, 0x0000222c, + 0x0000242c, 0x0000262c, 0x0000282c, 0x00002a2c, + 0x00002c2c, 0x00002e2c, 0x0000302c, 0x0000322c, + 0x0000342c, 0x0000362c, 0x0000382c, 0x00003a2c, + 0x00003c2c, 0x00003e2c, 0x0000402c, 0x0000422c, + 0x0000442c, 0x0000462c, 0x0000482c, 0x00004a2c, + 0x00004c2c, 0x00004e2c, 0x0000502c, 0x0000522c, + 0x0000542c, 0x0000562c, 0x0000582c, 0x00005a2c, + 0x00005c2c, 0x00005e2c, 0x0000602c, 0x0000622c, + 0x0000642c, 0x0000662c, 0x0000682c, 0x00006a2c, + 0x00006c2c, 0x00006e2c, 0x0000702c, 0x0000722c, + 0x0000742c, 0x0000762c, 0x0000782c, 0x00007a2c, + 0x00007c2c, 0x00007e2c, 0x0000802c, 0x0000822c, + 0x0000842c, 0x0000862c, 0x0000882c, 0x00008a2c, + 0x00008c2c, 0x00008e2c, 0x0000902c, 0x0000922c, + 0x0000942c, 0x0000962c, 0x0000982c, 0x00009a2c, + 0x00009c2c, 0x00009e2c, 0x0000a02c, 0x0000a22c, + 0x0000a42c, 0x0000a62c, 0x0000a82c, 0x0000aa2c, + 0x0000ac2c, 0x0000ae2c, 0x0000b02c, 0x0000b22c, + 0x0000b42c, 0x0000b62c, 0x0000b82c, 0x0000ba2c, + 0x0000bc2c, 0x0000be2c, 0x0000c02c, 0x0000c22c, + 0x0000c42c, 0x0000c62c, 0x0000c82c, 0x0000ca2c, + 0x0000cc2c, 0x0000ce2c, 0x0000d02c, 0x0000d22c, + 0x0000d42c, 0x0000d62c, 0x0000d82c, 0x0000da2c, + 0x0000dc2c, 0x0000de2c, 0x0000e02c, 0x0000e22c, + 0x0000e42c, 0x0000e62c, 0x0000e82c, 0x0000ea2c, + 0x0000ec2c, 0x0000ee2c, 0x0000f02c, 0x0000f22c, + 0x0000f42c, 0x0000f62c, 0x0000f82c, 0x0000fa2c, + 0x0000fc2c, 0x0000fe2c, 0x0001002c, 0x0001022c, + 0x0001042c, 0x0001062c, 0x0001082c, 0x00010a2c, + 0x00010c2c, 0x00010e2c, 0x0001102c, 0x0001122c, + 0x0001142c, 0x0001162c, 0x0001182c, 0x00011a2c, + 0x00011c2c, 0x00011e2c, 0x0001202c, 0x0001222c, + 0x0001242c, 0x0001262c, 0x0001282c, 0x00012a2c, + 0x00012c2c, 0x00012e2c, 0x0001302c, 0x0001322c, + 0x0001342c, 0x0001362c, 0x0001382c, 0x00013a2c, + 0x00013c2c, 0x00013e2c, 0x0001402c, 0x0001422c, + 0x0001442c, 0x0001462c, 0x0001482c, 0x00014a2c, + 0x00014c2c, 0x00014e2c, 0x0001502c, 0x0001522c, + 0x0001542c, 0x0001562c, 0x0001582c, 0x00015a2c, + 0x00015c2c, 0x00015e2c, 0x0001602c, 0x0001622c, + 0x0001642c, 0x0001662c, 0x0001682c, 0x00016a2c, + 0x00016c2c, 0x00016e2c, 0x0001702c, 0x0001722c, + 0x0001742c, 0x0001762c, 0x0001782c, 0x00017a2c, + 0x00017c2c, 0x00017e2c, 0x0001802c, 0x0001822c, + 0x0001842c, 0x0001862c, 0x0001882c, 0x00018a2c, + 0x00018c2c, 0x00018e2c, 0x0001902c, 0x0001922c, + 0x0001942c, 0x0001962c, 0x0001982c, 0x00019a2c, + 0x00019c2c, 0x00019e2c, 0x0001a02c, 0x0001a22c, + 0x0001a42c, 0x0001a62c, 0x0001a82c, 0x0001aa2c, + 0x0001ac2c, 0x0001ae2c, 0x0001b02c, 0x0001b22c, + 0x0001b42c, 0x0001b62c, 0x0001b82c, 0x0001ba2c, + 0x0001bc2c, 0x0001be2c, 0x0001c02c, 0x0001c22c, + 0x0001c42c, 0x0001c62c, 0x0001c82c, 0x0001ca2c, + 0x0001cc2c, 0x0001ce2c, 0x0001d02c, 0x0001d22c, + 0x0001d42c, 0x0001d62c, 0x0001d82c, 0x0001da2c, + 0x0001dc2c, 0x0001de2c, 0x0001e02c, 0x0001e22c, + 0x0001e42c, 0x0001e62c, 0x0001e82c, 0x0001ea2c, + 0x0001ec2c, 0x0001ee2c, 0x0001f02c, 0x0001f22c, + 0x0001f42c, 0x0001f62c, 0x0001f82c, 0x0001fa2c, + 0x0001fc2c, 0x0001fe2c, 0x0000012d, 0x0000032d, + 0x0000052d, 0x0000072d, 0x0000092d, 0x00000b2d, + 0x00000d2d, 0x00000f2d, 0x0000112d, 0x0000132d, + 0x0000152d, 0x0000172d, 0x0000192d, 0x00001b2d, + 0x00001d2d, 0x00001f2d, 0x0000212d, 0x0000232d, + 0x0000252d, 0x0000272d, 0x0000292d, 0x00002b2d, + 0x00002d2d, 0x00002f2d, 0x0000312d, 0x0000332d, + 0x0000352d, 0x0000372d, 0x0000392d, 0x00003b2d, + 0x00003d2d, 0x00003f2d, 0x0000412d, 0x0000432d, + 0x0000452d, 0x0000472d, 0x0000492d, 0x00004b2d, + 0x00004d2d, 0x00004f2d, 0x0000512d, 0x0000532d, + 0x0000552d, 0x0000572d, 0x0000592d, 0x00005b2d, + 0x00005d2d, 0x00005f2d, 0x0000612d, 0x0000632d, + 0x0000652d, 0x0000672d, 0x0000692d, 0x00006b2d, + 0x00006d2d, 0x00006f2d, 0x0000712d, 0x0000732d, + 0x0000752d, 0x0000772d, 0x0000792d, 0x00007b2d, + 0x00007d2d, 0x00007f2d, 0x0000812d, 0x0000832d, + 0x0000852d, 0x0000872d, 0x0000892d, 0x00008b2d, + 0x00008d2d, 0x00008f2d, 0x0000912d, 0x0000932d, + 0x0000952d, 0x0000972d, 0x0000992d, 0x00009b2d, + 0x00009d2d, 0x00009f2d, 0x0000a12d, 0x0000a32d, + 0x0000a52d, 0x0000a72d, 0x0000a92d, 0x0000ab2d, + 0x0000ad2d, 0x0000af2d, 0x0000b12d, 0x0000b32d, + 0x0000b52d, 0x0000b72d, 0x0000b92d, 0x0000bb2d, + 0x0000bd2d, 0x0000bf2d, 0x0000c12d, 0x0000c32d, + 0x0000c52d, 0x0000c72d, 0x0000c92d, 0x0000cb2d, + 0x0000cd2d, 0x0000cf2d, 0x0000d12d, 0x0000d32d, + 0x0000d52d, 0x0000d72d, 0x0000d92d, 0x0000db2d, + 0x0000dd2d, 0x0000df2d, 0x0000e12d, 0x0000e32d, + 0x0000e52d, 0x0000e72d, 0x0000e92d, 0x0000eb2d, + 0x0000ed2d, 0x0000ef2d, 0x0000f12d, 0x0000f32d, + 0x0000f52d, 0x0000f72d, 0x0000f92d, 0x0000fb2d, + 0x0000fd2d, 0x0000ff2d, 0x0001012d, 0x0001032d, + 0x0001052d, 0x0001072d, 0x0001092d, 0x00010b2d, + 0x00010d2d, 0x00010f2d, 0x0001112d, 0x0001132d, + 0x0001152d, 0x0001172d, 0x0001192d, 0x00011b2d, + 0x00011d2d, 0x00011f2d, 0x0001212d, 0x0001232d, + 0x0001252d, 0x0001272d, 0x0001292d, 0x00012b2d, + 0x00012d2d, 0x00012f2d, 0x0001312d, 0x0001332d, + 0x0001352d, 0x0001372d, 0x0001392d, 0x00013b2d, + 0x00013d2d, 0x00013f2d, 0x0001412d, 0x0001432d, + 0x0001452d, 0x0001472d, 0x0001492d, 0x00014b2d, + 0x00014d2d, 0x00014f2d, 0x0001512d, 0x0001532d, + 0x0001552d, 0x0001572d, 0x0001592d, 0x00015b2d, + 0x00015d2d, 0x00015f2d, 0x0001612d, 0x0001632d, + 0x0001652d, 0x0001672d, 0x0001692d, 0x00016b2d, + 0x00016d2d, 0x00016f2d, 0x0001712d, 0x0001732d, + 0x0001752d, 0x0001772d, 0x0001792d, 0x00017b2d, + 0x00017d2d, 0x00017f2d, 0x0001812d, 0x0001832d, + 0x0001852d, 0x0001872d, 0x0001892d, 0x00018b2d, + 0x00018d2d, 0x00018f2d, 0x0001912d, 0x0001932d, + 0x0001952d, 0x0001972d, 0x0001992d, 0x00019b2d, + 0x00019d2d, 0x00019f2d, 0x0001a12d, 0x0001a32d, + 0x0001a52d, 0x0001a72d, 0x0001a92d, 0x0001ab2d, + 0x0001ad2d, 0x0001af2d, 0x0001b12d, 0x0001b32d, + 0x0001b52d, 0x0001b72d, 0x0001b92d, 0x0001bb2d, + 0x0001bd2d, 0x0001bf2d, 0x0001c12d, 0x0001c32d, + 0x0001c52d, 0x0001c72d, 0x0001c92d, 0x0001cb2d, + 0x0001cd2d, 0x0001cf2d, 0x0001d12d, 0x0001d32d, + 0x0001d52d, 0x0001d72d, 0x0001d92d, 0x0001db2d, + 0x0001dd2d, 0x0001df2d, 0x0001e12d, 0x0001e32d, + 0x0001e52d, 0x0001e72d, 0x0001e92d, 0x0001eb2d, + 0x0001ed2d, 0x0001ef2d, 0x0001f12d, 0x0001f32d, + 0x0001f52d, 0x0001f72d, 0x0001f92d, 0x0001fb2d, + 0x0001fd2d, 0x0001ff2d, 0x0002012d, 0x0002032d, + 0x0002052d, 0x0002072d, 0x0002092d, 0x00020b2d, + 0x00020d2d, 0x00020f2d, 0x0002112d, 0x0002132d, + 0x0002152d, 0x0002172d, 0x0002192d, 0x00021b2d, + 0x00021d2d, 0x00021f2d, 0x0002212d, 0x0002232d, + 0x0002252d, 0x0002272d, 0x0002292d, 0x00022b2d, + 0x00022d2d, 0x00022f2d, 0x0002312d, 0x0002332d, + 0x0002352d, 0x0002372d, 0x0002392d, 0x00023b2d, + 0x00023d2d, 0x00023f2d, 0x0002412d, 0x0002432d, + 0x0002452d, 0x0002472d, 0x0002492d, 0x00024b2d, + 0x00024d2d, 0x00024f2d, 0x0002512d, 0x0002532d, + 0x0002552d, 0x0002572d, 0x0002592d, 0x00025b2d, + 0x00025d2d, 0x00025f2d, 0x0002612d, 0x0002632d, + 0x0002652d, 0x0002672d, 0x0002692d, 0x00026b2d, + 0x00026d2d, 0x00026f2d, 0x0002712d, 0x0002732d, + 0x0002752d, 0x0002772d, 0x0002792d, 0x00027b2d, + 0x00027d2d, 0x00027f2d, 0x0002812d, 0x0002832d, + 0x0002852d, 0x0002872d, 0x0002892d, 0x00028b2d, + 0x00028d2d, 0x00028f2d, 0x0002912d, 0x0002932d, + 0x0002952d, 0x0002972d, 0x0002992d, 0x00029b2d, + 0x00029d2d, 0x00029f2d, 0x0002a12d, 0x0002a32d, + 0x0002a52d, 0x0002a72d, 0x0002a92d, 0x0002ab2d, + 0x0002ad2d, 0x0002af2d, 0x0002b12d, 0x0002b32d, + 0x0002b52d, 0x0002b72d, 0x0002b92d, 0x0002bb2d, + 0x0002bd2d, 0x0002bf2d, 0x0002c12d, 0x0002c32d, + 0x0002c52d, 0x0002c72d, 0x0002c92d, 0x0002cb2d, + 0x0002cd2d, 0x0002cf2d, 0x0002d12d, 0x0002d32d, + 0x0002d52d, 0x0002d72d, 0x0002d92d, 0x0002db2d, + 0x0002dd2d, 0x0002df2d, 0x0002e12d, 0x0002e32d, + 0x0002e52d, 0x0002e72d, 0x0002e92d, 0x0002eb2d, + 0x0002ed2d, 0x0002ef2d, 0x0002f12d, 0x0002f32d, + 0x0002f52d, 0x0002f72d, 0x0002f92d, 0x0002fb2d, + 0x0002fd2d, 0x0002ff2d, 0x0003012d, 0x0003032d, + 0x0003052d, 0x0003072d, 0x0003092d, 0x00030b2d, + 0x00030d2d, 0x00030f2d, 0x0003112d, 0x0003132d, + 0x0003152d, 0x0003172d, 0x0003192d, 0x00031b2d, + 0x00031d2d, 0x00031f2d, 0x0003212d, 0x0003232d, + 0x0003252d, 0x0003272d, 0x0003292d, 0x00032b2d, + 0x00032d2d, 0x00032f2d, 0x0003312d, 0x0003332d, + 0x0003352d, 0x0003372d, 0x0003392d, 0x00033b2d, + 0x00033d2d, 0x00033f2d, 0x0003412d, 0x0003432d, + 0x0003452d, 0x0003472d, 0x0003492d, 0x00034b2d, + 0x00034d2d, 0x00034f2d, 0x0003512d, 0x0003532d, + 0x0003552d, 0x0003572d, 0x0003592d, 0x00035b2d, + 0x00035d2d, 0x00035f2d, 0x0003612d, 0x0003632d, + 0x0003652d, 0x0003672d, 0x0003692d, 0x00036b2d, + 0x00036d2d, 0x00036f2d, 0x0003712d, 0x0003732d, + 0x0003752d, 0x0003772d, 0x0003792d, 0x00037b2d, + 0x00037d2d, 0x00037f2d, 0x0003812d, 0x0003832d, + 0x0003852d, 0x0003872d, 0x0003892d, 0x00038b2d, + 0x00038d2d, 0x00038f2d, 0x0003912d, 0x0003932d, + 0x0003952d, 0x0003972d, 0x0003992d, 0x00039b2d, + 0x00039d2d, 0x00039f2d, 0x0003a12d, 0x0003a32d, + 0x0003a52d, 0x0003a72d, 0x0003a92d, 0x0003ab2d, + 0x0003ad2d, 0x0003af2d, 0x0003b12d, 0x0003b32d, + 0x0003b52d, 0x0003b72d, 0x0003b92d, 0x0003bb2d, + 0x0003bd2d, 0x0003bf2d, 0x0003c12d, 0x0003c32d, + 0x0003c52d, 0x0003c72d, 0x0003c92d, 0x0003cb2d, + 0x0003cd2d, 0x0003cf2d, 0x0003d12d, 0x0003d32d, + 0x0003d52d, 0x0003d72d, 0x0003d92d, 0x0003db2d, + 0x0003dd2d, 0x0003df2d, 0x0003e12d, 0x0003e32d, + 0x0003e52d, 0x0003e72d, 0x0003e92d, 0x0003eb2d, + 0x0003ed2d, 0x0003ef2d, 0x0003f12d, 0x0003f32d, + 0x0003f52d, 0x0003f72d, 0x0003f92d, 0x0003fb2d, + 0x0003fd2d, 0x0003ff2d, 0x000002ee, 0x000006ee, + 0x00000aee, 0x00000eee, 0x000012ee, 0x000016ee, + 0x00001aee, 0x00001eee, 0x000022ee, 0x000026ee, + 0x00002aee, 0x00002eee, 0x000032ee, 0x000036ee, + 0x00003aee, 0x00003eee, 0x000042ee, 0x000046ee, + 0x00004aee, 0x00004eee, 0x000052ee, 0x000056ee, + 0x00005aee, 0x00005eee, 0x000062ee, 0x000066ee, + 0x00006aee, 0x00006eee, 0x000072ee, 0x000076ee, + 0x00007aee, 0x00007eee, 0x000082ee, 0x000086ee, + 0x00008aee, 0x00008eee, 0x000092ee, 0x000096ee, + 0x00009aee, 0x00009eee, 0x0000a2ee, 0x0000a6ee, + 0x0000aaee, 0x0000aeee, 0x0000b2ee, 0x0000b6ee, + 0x0000baee, 0x0000beee, 0x0000c2ee, 0x0000c6ee, + 0x0000caee, 0x0000ceee, 0x0000d2ee, 0x0000d6ee, + 0x0000daee, 0x0000deee, 0x0000e2ee, 0x0000e6ee, + 0x0000eaee, 0x0000eeee, 0x0000f2ee, 0x0000f6ee, + 0x0000faee, 0x0000feee, 0x000102ee, 0x000106ee, + 0x00010aee, 0x00010eee, 0x000112ee, 0x000116ee, + 0x00011aee, 0x00011eee, 0x000122ee, 0x000126ee, + 0x00012aee, 0x00012eee, 0x000132ee, 0x000136ee, + 0x00013aee, 0x00013eee, 0x000142ee, 0x000146ee, + 0x00014aee, 0x00014eee, 0x000152ee, 0x000156ee, + 0x00015aee, 0x00015eee, 0x000162ee, 0x000166ee, + 0x00016aee, 0x00016eee, 0x000172ee, 0x000176ee, + 0x00017aee, 0x00017eee, 0x000182ee, 0x000186ee, + 0x00018aee, 0x00018eee, 0x000192ee, 0x000196ee, + 0x00019aee, 0x00019eee, 0x0001a2ee, 0x0001a6ee, + 0x0001aaee, 0x0001aeee, 0x0001b2ee, 0x0001b6ee, + 0x0001baee, 0x0001beee, 0x0001c2ee, 0x0001c6ee, + 0x0001caee, 0x0001ceee, 0x0001d2ee, 0x0001d6ee, + 0x0001daee, 0x0001deee, 0x0001e2ee, 0x0001e6ee, + 0x0001eaee, 0x0001eeee, 0x0001f2ee, 0x0001f6ee, + 0x0001faee, 0x0001feee, 0x000202ee, 0x000206ee, + 0x00020aee, 0x00020eee, 0x000212ee, 0x000216ee, + 0x00021aee, 0x00021eee, 0x000222ee, 0x000226ee, + 0x00022aee, 0x00022eee, 0x000232ee, 0x000236ee, + 0x00023aee, 0x00023eee, 0x000242ee, 0x000246ee, + 0x00024aee, 0x00024eee, 0x000252ee, 0x000256ee, + 0x00025aee, 0x00025eee, 0x000262ee, 0x000266ee, + 0x00026aee, 0x00026eee, 0x000272ee, 0x000276ee, + 0x00027aee, 0x00027eee, 0x000282ee, 0x000286ee, + 0x00028aee, 0x00028eee, 0x000292ee, 0x000296ee, + 0x00029aee, 0x00029eee, 0x0002a2ee, 0x0002a6ee, + 0x0002aaee, 0x0002aeee, 0x0002b2ee, 0x0002b6ee, + 0x0002baee, 0x0002beee, 0x0002c2ee, 0x0002c6ee, + 0x0002caee, 0x0002ceee, 0x0002d2ee, 0x0002d6ee, + 0x0002daee, 0x0002deee, 0x0002e2ee, 0x0002e6ee, + 0x0002eaee, 0x0002eeee, 0x0002f2ee, 0x0002f6ee, + 0x0002faee, 0x0002feee, 0x000302ee, 0x000306ee, + 0x00030aee, 0x00030eee, 0x000312ee, 0x000316ee, + 0x00031aee, 0x00031eee, 0x000322ee, 0x000326ee, + 0x00032aee, 0x00032eee, 0x000332ee, 0x000336ee, + 0x00033aee, 0x00033eee, 0x000342ee, 0x000346ee, + 0x00034aee, 0x00034eee, 0x000352ee, 0x000356ee, + 0x00035aee, 0x00035eee, 0x000362ee, 0x000366ee, + 0x00036aee, 0x00036eee, 0x000372ee, 0x000376ee, + 0x00037aee, 0x00037eee, 0x000382ee, 0x000386ee, + 0x00038aee, 0x00038eee, 0x000392ee, 0x000396ee, + 0x00039aee, 0x00039eee, 0x0003a2ee, 0x0003a6ee, + 0x0003aaee, 0x0003aeee, 0x0003b2ee, 0x0003b6ee, + 0x0003baee, 0x0003beee, 0x0003c2ee, 0x0003c6ee, + 0x0003caee, 0x0003ceee, 0x0003d2ee, 0x0003d6ee, + 0x0003daee, 0x0003deee, 0x0003e2ee, 0x0003e6ee, + 0x0003eaee, 0x0003eeee, 0x0003f2ee, 0x0003f6ee, + 0x0003faee, 0x0003feee, 0x000402ee, 0x000406ee, + 0x00040aee, 0x00040eee, 0x000412ee, 0x000416ee, + 0x00041aee, 0x00041eee, 0x000422ee, 0x000426ee, + 0x00042aee, 0x00042eee, 0x000432ee, 0x000436ee, + 0x00043aee, 0x00043eee, 0x000442ee, 0x000446ee, + 0x00044aee, 0x00044eee, 0x000452ee, 0x000456ee, + 0x00045aee, 0x00045eee, 0x000462ee, 0x000466ee, + 0x00046aee, 0x00046eee, 0x000472ee, 0x000476ee, + 0x00047aee, 0x00047eee, 0x000482ee, 0x000486ee, + 0x00048aee, 0x00048eee, 0x000492ee, 0x000496ee, + 0x00049aee, 0x00049eee, 0x0004a2ee, 0x0004a6ee, + 0x0004aaee, 0x0004aeee, 0x0004b2ee, 0x0004b6ee, + 0x0004baee, 0x0004beee, 0x0004c2ee, 0x0004c6ee, + 0x0004caee, 0x0004ceee, 0x0004d2ee, 0x0004d6ee, + 0x0004daee, 0x0004deee, 0x0004e2ee, 0x0004e6ee, + 0x0004eaee, 0x0004eeee, 0x0004f2ee, 0x0004f6ee, + 0x0004faee, 0x0004feee, 0x000502ee, 0x000506ee, + 0x00050aee, 0x00050eee, 0x000512ee, 0x000516ee, + 0x00051aee, 0x00051eee, 0x000522ee, 0x000526ee, + 0x00052aee, 0x00052eee, 0x000532ee, 0x000536ee, + 0x00053aee, 0x00053eee, 0x000542ee, 0x000546ee, + 0x00054aee, 0x00054eee, 0x000552ee, 0x000556ee, + 0x00055aee, 0x00055eee, 0x000562ee, 0x000566ee, + 0x00056aee, 0x00056eee, 0x000572ee, 0x000576ee, + 0x00057aee, 0x00057eee, 0x000582ee, 0x000586ee, + 0x00058aee, 0x00058eee, 0x000592ee, 0x000596ee, + 0x00059aee, 0x00059eee, 0x0005a2ee, 0x0005a6ee, + 0x0005aaee, 0x0005aeee, 0x0005b2ee, 0x0005b6ee, + 0x0005baee, 0x0005beee, 0x0005c2ee, 0x0005c6ee, + 0x0005caee, 0x0005ceee, 0x0005d2ee, 0x0005d6ee, + 0x0005daee, 0x0005deee, 0x0005e2ee, 0x0005e6ee, + 0x0005eaee, 0x0005eeee, 0x0005f2ee, 0x0005f6ee, + 0x0005faee, 0x0005feee, 0x000602ee, 0x000606ee, + 0x00060aee, 0x00060eee, 0x000612ee, 0x000616ee, + 0x00061aee, 0x00061eee, 0x000622ee, 0x000626ee, + 0x00062aee, 0x00062eee, 0x000632ee, 0x000636ee, + 0x00063aee, 0x00063eee, 0x000642ee, 0x000646ee, + 0x00064aee, 0x00064eee, 0x000652ee, 0x000656ee, + 0x00065aee, 0x00065eee, 0x000662ee, 0x000666ee, + 0x00066aee, 0x00066eee, 0x000672ee, 0x000676ee, + 0x00067aee, 0x00067eee, 0x000682ee, 0x000686ee, + 0x00068aee, 0x00068eee, 0x000692ee, 0x000696ee, + 0x00069aee, 0x00069eee, 0x0006a2ee, 0x0006a6ee, + 0x0006aaee, 0x0006aeee, 0x0006b2ee, 0x0006b6ee, + 0x0006baee, 0x0006beee, 0x0006c2ee, 0x0006c6ee, + 0x0006caee, 0x0006ceee, 0x0006d2ee, 0x0006d6ee, + 0x0006daee, 0x0006deee, 0x0006e2ee, 0x0006e6ee, + 0x0006eaee, 0x0006eeee, 0x0006f2ee, 0x0006f6ee, + 0x0006faee, 0x0006feee, 0x000702ee, 0x000706ee, + 0x00070aee, 0x00070eee, 0x000712ee, 0x000716ee, + 0x00071aee, 0x00071eee, 0x000722ee, 0x000726ee, + 0x00072aee, 0x00072eee, 0x000732ee, 0x000736ee, + 0x00073aee, 0x00073eee, 0x000742ee, 0x000746ee, + 0x00074aee, 0x00074eee, 0x000752ee, 0x000756ee, + 0x00075aee, 0x00075eee, 0x000762ee, 0x000766ee, + 0x00076aee, 0x00076eee, 0x000772ee, 0x000776ee, + 0x00077aee, 0x00077eee, 0x000782ee, 0x000786ee, + 0x00078aee, 0x00078eee, 0x000792ee, 0x000796ee, + 0x00079aee, 0x00079eee, 0x0007a2ee, 0x0007a6ee, + 0x0007aaee, 0x0007aeee, 0x0007b2ee, 0x0007b6ee, + 0x0007baee, 0x0007beee, 0x0007c2ee, 0x0007c6ee, + 0x0007caee, 0x0007ceee, 0x0007d2ee, 0x0007d6ee, + 0x0007daee, 0x0007deee, 0x0007e2ee, 0x0007e6ee, + 0x0007eaee, 0x0007eeee, 0x0007f2ee, 0x0007f6ee, + 0x0007faee, 0x0007feee, 0x0000000d, 0x0000010d, + 0x0000020d, 0x0000030d, 0x0000040d, 0x0000050d, + 0x0000060d, 0x0000070d, 0x0000080d, 0x0000090d, + 0x00000a0d, 0x00000b0d, 0x00000c0d, 0x00000d0d, + 0x00000e0d, 0x00000f0d, 0x0000100d, 0x0000110d, + 0x0000120d, 0x0000130d, 0x0000140d, 0x0000150d, + 0x0000160d, 0x0000170d, 0x0000180d, 0x0000190d, + 0x00001a0d, 0x00001b0d, 0x00001c0d, 0x00001d0d, + 0x00001e0d, 0x00001f0d, 0x0000200d, 0x0000210d, + 0x0000220d, 0x0000230d, 0x0000240d, 0x0000250d, + 0x0000260d, 0x0000270d, 0x0000280d, 0x0000290d, + 0x00002a0d, 0x00002b0d, 0x00002c0d, 0x00002d0d, + 0x00002e0d, 0x00002f0d, 0x0000300d, 0x0000310d, + 0x0000320d, 0x0000330d, 0x0000340d, 0x0000350d, + 0x0000360d, 0x0000370d, 0x0000380d, 0x0000390d, + 0x00003a0d, 0x00003b0d, 0x00003c0d, 0x00003d0d, + 0x00003e0d, 0x00003f0d, 0x0000400d, 0x0000410d, + 0x0000420d, 0x0000430d, 0x0000440d, 0x0000450d, + 0x0000460d, 0x0000470d, 0x0000480d, 0x0000490d, + 0x00004a0d, 0x00004b0d, 0x00004c0d, 0x00004d0d, + 0x00004e0d, 0x00004f0d, 0x0000500d, 0x0000510d, + 0x0000520d, 0x0000530d, 0x0000540d, 0x0000550d, + 0x0000560d, 0x0000570d, 0x0000580d, 0x0000590d, + 0x00005a0d, 0x00005b0d, 0x00005c0d, 0x00005d0d, + 0x00005e0d, 0x00005f0d, 0x0000600d, 0x0000610d, + 0x0000620d, 0x0000630d, 0x0000640d, 0x0000650d, + 0x0000660d, 0x0000670d, 0x0000680d, 0x0000690d, + 0x00006a0d, 0x00006b0d, 0x00006c0d, 0x00006d0d, + 0x00006e0d, 0x00006f0d, 0x0000700d, 0x0000710d, + 0x0000720d, 0x0000730d, 0x0000740d, 0x0000750d, + 0x0000760d, 0x0000770d, 0x0000780d, 0x0000790d, + 0x00007a0d, 0x00007b0d, 0x00007c0d, 0x00007d0d, + 0x00007e0d, 0x00007f0d, 0x0000800d, 0x0000810d, + 0x0000820d, 0x0000830d, 0x0000840d, 0x0000850d, + 0x0000860d, 0x0000870d, 0x0000880d, 0x0000890d, + 0x00008a0d, 0x00008b0d, 0x00008c0d, 0x00008d0d, + 0x00008e0d, 0x00008f0d, 0x0000900d, 0x0000910d, + 0x0000920d, 0x0000930d, 0x0000940d, 0x0000950d, + 0x0000960d, 0x0000970d, 0x0000980d, 0x0000990d, + 0x00009a0d, 0x00009b0d, 0x00009c0d, 0x00009d0d, + 0x00009e0d, 0x00009f0d, 0x0000a00d, 0x0000a10d, + 0x0000a20d, 0x0000a30d, 0x0000a40d, 0x0000a50d, + 0x0000a60d, 0x0000a70d, 0x0000a80d, 0x0000a90d, + 0x0000aa0d, 0x0000ab0d, 0x0000ac0d, 0x0000ad0d, + 0x0000ae0d, 0x0000af0d, 0x0000b00d, 0x0000b10d, + 0x0000b20d, 0x0000b30d, 0x0000b40d, 0x0000b50d, + 0x0000b60d, 0x0000b70d, 0x0000b80d, 0x0000b90d, + 0x0000ba0d, 0x0000bb0d, 0x0000bc0d, 0x0000bd0d, + 0x0000be0d, 0x0000bf0d, 0x0000c00d, 0x0000c10d, + 0x0000c20d, 0x0000c30d, 0x0000c40d, 0x0000c50d, + 0x0000c60d, 0x0000c70d, 0x0000c80d, 0x0000c90d, + 0x0000ca0d, 0x0000cb0d, 0x0000cc0d, 0x0000cd0d, + 0x0000ce0d, 0x0000cf0d, 0x0000d00d, 0x0000d10d, + 0x0000d20d, 0x0000d30d, 0x0000d40d, 0x0000d50d, + 0x0000d60d, 0x0000d70d, 0x0000d80d, 0x0000d90d, + 0x0000da0d, 0x0000db0d, 0x0000dc0d, 0x0000dd0d, + 0x0000de0d, 0x0000df0d, 0x0000e00d, 0x0000e10d, + 0x0000e20d, 0x0000e30d, 0x0000e40d, 0x0000e50d, + 0x0000e60d, 0x0000e70d, 0x0000e80d, 0x0000e90d, + 0x0000ea0d, 0x0000eb0d, 0x0000ec0d, 0x0000ed0d, + 0x0000ee0d, 0x0000ef0d, 0x0000f00d, 0x0000f10d, + 0x0000f20d, 0x0000f30d, 0x0000f40d, 0x0000f50d, + 0x0000f60d, 0x0000f70d, 0x0000f80d, 0x0000f90d, + 0x0000fa0d, 0x0000fb0d, 0x0000fc0d, 0x0000fd0d, + 0x0000fe0d, 0x0000ff0d, 0x0001000d, 0x0001010d, + 0x0001020d, 0x0001030d, 0x0001040d, 0x0001050d, + 0x0001060d, 0x0001070d, 0x0001080d, 0x0001090d, + 0x00010a0d, 0x00010b0d, 0x00010c0d, 0x00010d0d, + 0x00010e0d, 0x00010f0d, 0x0001100d, 0x0001110d, + 0x0001120d, 0x0001130d, 0x0001140d, 0x0001150d, + 0x0001160d, 0x0001170d, 0x0001180d, 0x0001190d, + 0x00011a0d, 0x00011b0d, 0x00011c0d, 0x00011d0d, + 0x00011e0d, 0x00011f0d, 0x0001200d, 0x0001210d, + 0x0001220d, 0x0001230d, 0x0001240d, 0x0001250d, + 0x0001260d, 0x0001270d, 0x0001280d, 0x0001290d, + 0x00012a0d, 0x00012b0d, 0x00012c0d, 0x00012d0d, + 0x00012e0d, 0x00012f0d, 0x0001300d, 0x0001310d, + 0x0001320d, 0x0001330d, 0x0001340d, 0x0001350d, + 0x0001360d, 0x0001370d, 0x0001380d, 0x0001390d, + 0x00013a0d, 0x00013b0d, 0x00013c0d, 0x00013d0d, + 0x00013e0d, 0x00013f0d, 0x0001400d, 0x0001410d, + 0x0001420d, 0x0001430d, 0x0001440d, 0x0001450d, + 0x0001460d, 0x0001470d, 0x0001480d, 0x0001490d, + 0x00014a0d, 0x00014b0d, 0x00014c0d, 0x00014d0d, + 0x00014e0d, 0x00014f0d, 0x0001500d, 0x0001510d, + 0x0001520d, 0x0001530d, 0x0001540d, 0x0001550d, + 0x0001560d, 0x0001570d, 0x0001580d, 0x0001590d, + 0x00015a0d, 0x00015b0d, 0x00015c0d, 0x00015d0d, + 0x00015e0d, 0x00015f0d, 0x0001600d, 0x0001610d, + 0x0001620d, 0x0001630d, 0x0001640d, 0x0001650d, + 0x0001660d, 0x0001670d, 0x0001680d, 0x0001690d, + 0x00016a0d, 0x00016b0d, 0x00016c0d, 0x00016d0d, + 0x00016e0d, 0x00016f0d, 0x0001700d, 0x0001710d, + 0x0001720d, 0x0001730d, 0x0001740d, 0x0001750d, + 0x0001760d, 0x0001770d, 0x0001780d, 0x0001790d, + 0x00017a0d, 0x00017b0d, 0x00017c0d, 0x00017d0d, + 0x00017e0d, 0x00017f0d, 0x0001800d, 0x0001810d, + 0x0001820d, 0x0001830d, 0x0001840d, 0x0001850d, + 0x0001860d, 0x0001870d, 0x0001880d, 0x0001890d, + 0x00018a0d, 0x00018b0d, 0x00018c0d, 0x00018d0d, + 0x00018e0d, 0x00018f0d, 0x0001900d, 0x0001910d, + 0x0001920d, 0x0001930d, 0x0001940d, 0x0001950d, + 0x0001960d, 0x0001970d, 0x0001980d, 0x0001990d, + 0x00019a0d, 0x00019b0d, 0x00019c0d, 0x00019d0d, + 0x00019e0d, 0x00019f0d, 0x0001a00d, 0x0001a10d, + 0x0001a20d, 0x0001a30d, 0x0001a40d, 0x0001a50d, + 0x0001a60d, 0x0001a70d, 0x0001a80d, 0x0001a90d, + 0x0001aa0d, 0x0001ab0d, 0x0001ac0d, 0x0001ad0d, + 0x0001ae0d, 0x0001af0d, 0x0001b00d, 0x0001b10d, + 0x0001b20d, 0x0001b30d, 0x0001b40d, 0x0001b50d, + 0x0001b60d, 0x0001b70d, 0x0001b80d, 0x0001b90d, + 0x0001ba0d, 0x0001bb0d, 0x0001bc0d, 0x0001bd0d, + 0x0001be0d, 0x0001bf0d, 0x0001c00d, 0x0001c10d, + 0x0001c20d, 0x0001c30d, 0x0001c40d, 0x0001c50d, + 0x0001c60d, 0x0001c70d, 0x0001c80d, 0x0001c90d, + 0x0001ca0d, 0x0001cb0d, 0x0001cc0d, 0x0001cd0d, + 0x0001ce0d, 0x0001cf0d, 0x0001d00d, 0x0001d10d, + 0x0001d20d, 0x0001d30d, 0x0001d40d, 0x0001d50d, + 0x0001d60d, 0x0001d70d, 0x0001d80d, 0x0001d90d, + 0x0001da0d, 0x0001db0d, 0x0001dc0d, 0x0001dd0d, + 0x0001de0d, 0x0001df0d, 0x0001e00d, 0x0001e10d, + 0x0001e20d, 0x0001e30d, 0x0001e40d, 0x0001e50d, + 0x0001e60d, 0x0001e70d, 0x0001e80d, 0x0001e90d, + 0x0001ea0d, 0x0001eb0d, 0x0001ec0d, 0x0001ed0d, + 0x0001ee0d, 0x0001ef0d, 0x0001f00d, 0x0001f10d, + 0x0001f20d, 0x0001f30d, 0x0001f40d, 0x0001f50d, + 0x0001f60d, 0x0001f70d, 0x0001f80d, 0x0001f90d, + 0x0001fa0d, 0x0001fb0d, 0x0001fc0d, 0x0001fd0d, + 0x0001fe0d, 0x0001ff0d, 0x0002000d, 0x0002010d, + 0x0002020d, 0x0002030d, 0x0002040d, 0x0002050d, + 0x0002060d, 0x0002070d, 0x0002080d, 0x0002090d, + 0x00020a0d, 0x00020b0d, 0x00020c0d, 0x00020d0d, + 0x00020e0d, 0x00020f0d, 0x0002100d, 0x0002110d, + 0x0002120d, 0x0002130d, 0x0002140d, 0x0002150d, + 0x0002160d, 0x0002170d, 0x0002180d, 0x0002190d, + 0x00021a0d, 0x00021b0d, 0x00021c0d, 0x00021d0d, + 0x00021e0d, 0x00021f0d, 0x0002200d, 0x0002210d, + 0x0002220d, 0x0002230d, 0x0002240d, 0x0002250d, + 0x0002260d, 0x0002270d, 0x0002280d, 0x0002290d, + 0x00022a0d, 0x00022b0d, 0x00022c0d, 0x00022d0d, + 0x00022e0d, 0x00022f0d, 0x0002300d, 0x0002310d, + 0x0002320d, 0x0002330d, 0x0002340d, 0x0002350d, + 0x0002360d, 0x0002370d, 0x0002380d, 0x0002390d, + 0x00023a0d, 0x00023b0d, 0x00023c0d, 0x00023d0d, + 0x00023e0d, 0x00023f0d, 0x0002400d, 0x0002410d, + 0x0002420d, 0x0002430d, 0x0002440d, 0x0002450d, + 0x0002460d, 0x0002470d, 0x0002480d, 0x0002490d, + 0x00024a0d, 0x00024b0d, 0x00024c0d, 0x00024d0d, + 0x00024e0d, 0x00024f0d, 0x0002500d, 0x0002510d, + 0x0002520d, 0x0002530d, 0x0002540d, 0x0002550d, + 0x0002560d, 0x0002570d, 0x0002580d, 0x0002590d, + 0x00025a0d, 0x00025b0d, 0x00025c0d, 0x00025d0d, + 0x00025e0d, 0x00025f0d, 0x0002600d, 0x0002610d, + 0x0002620d, 0x0002630d, 0x0002640d, 0x0002650d, + 0x0002660d, 0x0002670d, 0x0002680d, 0x0002690d, + 0x00026a0d, 0x00026b0d, 0x00026c0d, 0x00026d0d, + 0x00026e0d, 0x00026f0d, 0x0002700d, 0x0002710d, + 0x0002720d, 0x0002730d, 0x0002740d, 0x0002750d, + 0x0002760d, 0x0002770d, 0x0002780d, 0x0002790d, + 0x00027a0d, 0x00027b0d, 0x00027c0d, 0x00027d0d, + 0x00027e0d, 0x00027f0d, 0x0002800d, 0x0002810d, + 0x0002820d, 0x0002830d, 0x0002840d, 0x0002850d, + 0x0002860d, 0x0002870d, 0x0002880d, 0x0002890d, + 0x00028a0d, 0x00028b0d, 0x00028c0d, 0x00028d0d, + 0x00028e0d, 0x00028f0d, 0x0002900d, 0x0002910d, + 0x0002920d, 0x0002930d, 0x0002940d, 0x0002950d, + 0x0002960d, 0x0002970d, 0x0002980d, 0x0002990d, + 0x00029a0d, 0x00029b0d, 0x00029c0d, 0x00029d0d, + 0x00029e0d, 0x00029f0d, 0x0002a00d, 0x0002a10d, + 0x0002a20d, 0x0002a30d, 0x0002a40d, 0x0002a50d, + 0x0002a60d, 0x0002a70d, 0x0002a80d, 0x0002a90d, + 0x0002aa0d, 0x0002ab0d, 0x0002ac0d, 0x0002ad0d, + 0x0002ae0d, 0x0002af0d, 0x0002b00d, 0x0002b10d, + 0x0002b20d, 0x0002b30d, 0x0002b40d, 0x0002b50d, + 0x0002b60d, 0x0002b70d, 0x0002b80d, 0x0002b90d, + 0x0002ba0d, 0x0002bb0d, 0x0002bc0d, 0x0002bd0d, + 0x0002be0d, 0x0002bf0d, 0x0002c00d, 0x0002c10d, + 0x0002c20d, 0x0002c30d, 0x0002c40d, 0x0002c50d, + 0x0002c60d, 0x0002c70d, 0x0002c80d, 0x0002c90d, + 0x0002ca0d, 0x0002cb0d, 0x0002cc0d, 0x0002cd0d, + 0x0002ce0d, 0x0002cf0d, 0x0002d00d, 0x0002d10d, + 0x0002d20d, 0x0002d30d, 0x0002d40d, 0x0002d50d, + 0x0002d60d, 0x0002d70d, 0x0002d80d, 0x0002d90d, + 0x0002da0d, 0x0002db0d, 0x0002dc0d, 0x0002dd0d, + 0x0002de0d, 0x0002df0d, 0x0002e00d, 0x0002e10d, + 0x0002e20d, 0x0002e30d, 0x0002e40d, 0x0002e50d, + 0x0002e60d, 0x0002e70d, 0x0002e80d, 0x0002e90d, + 0x0002ea0d, 0x0002eb0d, 0x0002ec0d, 0x0002ed0d, + 0x0002ee0d, 0x0002ef0d, 0x0002f00d, 0x0002f10d, + 0x0002f20d, 0x0002f30d, 0x0002f40d, 0x0002f50d, + 0x0002f60d, 0x0002f70d, 0x0002f80d, 0x0002f90d, + 0x0002fa0d, 0x0002fb0d, 0x0002fc0d, 0x0002fd0d, + 0x0002fe0d, 0x0002ff0d, 0x0003000d, 0x0003010d, + 0x0003020d, 0x0003030d, 0x0003040d, 0x0003050d, + 0x0003060d, 0x0003070d, 0x0003080d, 0x0003090d, + 0x00030a0d, 0x00030b0d, 0x00030c0d, 0x00030d0d, + 0x00030e0d, 0x00030f0d, 0x0003100d, 0x0003110d, + 0x0003120d, 0x0003130d, 0x0003140d, 0x0003150d, + 0x0003160d, 0x0003170d, 0x0003180d, 0x0003190d, + 0x00031a0d, 0x00031b0d, 0x00031c0d, 0x00031d0d, + 0x00031e0d, 0x00031f0d, 0x0003200d, 0x0003210d, + 0x0003220d, 0x0003230d, 0x0003240d, 0x0003250d, + 0x0003260d, 0x0003270d, 0x0003280d, 0x0003290d, + 0x00032a0d, 0x00032b0d, 0x00032c0d, 0x00032d0d, + 0x00032e0d, 0x00032f0d, 0x0003300d, 0x0003310d, + 0x0003320d, 0x0003330d, 0x0003340d, 0x0003350d, + 0x0003360d, 0x0003370d, 0x0003380d, 0x0003390d, + 0x00033a0d, 0x00033b0d, 0x00033c0d, 0x00033d0d, + 0x00033e0d, 0x00033f0d, 0x0003400d, 0x0003410d, + 0x0003420d, 0x0003430d, 0x0003440d, 0x0003450d, + 0x0003460d, 0x0003470d, 0x0003480d, 0x0003490d, + 0x00034a0d, 0x00034b0d, 0x00034c0d, 0x00034d0d, + 0x00034e0d, 0x00034f0d, 0x0003500d, 0x0003510d, + 0x0003520d, 0x0003530d, 0x0003540d, 0x0003550d, + 0x0003560d, 0x0003570d, 0x0003580d, 0x0003590d, + 0x00035a0d, 0x00035b0d, 0x00035c0d, 0x00035d0d, + 0x00035e0d, 0x00035f0d, 0x0003600d, 0x0003610d, + 0x0003620d, 0x0003630d, 0x0003640d, 0x0003650d, + 0x0003660d, 0x0003670d, 0x0003680d, 0x0003690d, + 0x00036a0d, 0x00036b0d, 0x00036c0d, 0x00036d0d, + 0x00036e0d, 0x00036f0d, 0x0003700d, 0x0003710d, + 0x0003720d, 0x0003730d, 0x0003740d, 0x0003750d, + 0x0003760d, 0x0003770d, 0x0003780d, 0x0003790d, + 0x00037a0d, 0x00037b0d, 0x00037c0d, 0x00037d0d, + 0x00037e0d, 0x00037f0d, 0x0003800d, 0x0003810d, + 0x0003820d, 0x0003830d, 0x0003840d, 0x0003850d, + 0x0003860d, 0x0003870d, 0x0003880d, 0x0003890d, + 0x00038a0d, 0x00038b0d, 0x00038c0d, 0x00038d0d, + 0x00038e0d, 0x00038f0d, 0x0003900d, 0x0003910d, + 0x0003920d, 0x0003930d, 0x0003940d, 0x0003950d, + 0x0003960d, 0x0003970d, 0x0003980d, 0x0003990d, + 0x00039a0d, 0x00039b0d, 0x00039c0d, 0x00039d0d, + 0x00039e0d, 0x00039f0d, 0x0003a00d, 0x0003a10d, + 0x0003a20d, 0x0003a30d, 0x0003a40d, 0x0003a50d, + 0x0003a60d, 0x0003a70d, 0x0003a80d, 0x0003a90d, + 0x0003aa0d, 0x0003ab0d, 0x0003ac0d, 0x0003ad0d, + 0x0003ae0d, 0x0003af0d, 0x0003b00d, 0x0003b10d, + 0x0003b20d, 0x0003b30d, 0x0003b40d, 0x0003b50d, + 0x0003b60d, 0x0003b70d, 0x0003b80d, 0x0003b90d, + 0x0003ba0d, 0x0003bb0d, 0x0003bc0d, 0x0003bd0d, + 0x0003be0d, 0x0003bf0d, 0x0003c00d, 0x0003c10d, + 0x0003c20d, 0x0003c30d, 0x0003c40d, 0x0003c50d, + 0x0003c60d, 0x0003c70d, 0x0003c80d, 0x0003c90d, + 0x0003ca0d, 0x0003cb0d, 0x0003cc0d, 0x0003cd0d, + 0x0003ce0d, 0x0003cf0d, 0x0003d00d, 0x0003d10d, + 0x0003d20d, 0x0003d30d, 0x0003d40d, 0x0003d50d, + 0x0003d60d, 0x0003d70d, 0x0003d80d, 0x0003d90d, + 0x0003da0d, 0x0003db0d, 0x0003dc0d, 0x0003dd0d, + 0x0003de0d, 0x0003df0d, 0x0003e00d, 0x0003e10d, + 0x0003e20d, 0x0003e30d, 0x0003e40d, 0x0003e50d, + 0x0003e60d, 0x0003e70d, 0x0003e80d, 0x0003e90d, + 0x0003ea0d, 0x0003eb0d, 0x0003ec0d, 0x0003ed0d, + 0x0003ee0d, 0x0003ef0d, 0x0003f00d, 0x0003f10d, + 0x0003f20d, 0x0003f30d, 0x0003f40d, 0x0003f50d, + 0x0003f60d, 0x0003f70d, 0x0003f80d, 0x0003f90d, + 0x0003fa0d, 0x0003fb0d, 0x0003fc0d, 0x0003fd0d, + 0x0003fe0d, 0x0003ff0d, 0x000000ae, 0x000002ae, + 0x000004ae, 0x000006ae, 0x000008ae, 0x00000aae, + 0x00000cae, 0x00000eae, 0x000010ae, 0x000012ae, + 0x000014ae, 0x000016ae, 0x000018ae, 0x00001aae, + 0x00001cae, 0x00001eae, 0x000020ae, 0x000022ae, + 0x000024ae, 0x000026ae, 0x000028ae, 0x00002aae, + 0x00002cae, 0x00002eae, 0x000030ae, 0x000032ae, + 0x000034ae, 0x000036ae, 0x000038ae, 0x00003aae, + 0x00003cae, 0x00003eae, 0x000040ae, 0x000042ae, + 0x000044ae, 0x000046ae, 0x000048ae, 0x00004aae, + 0x00004cae, 0x00004eae, 0x000050ae, 0x000052ae, + 0x000054ae, 0x000056ae, 0x000058ae, 0x00005aae, + 0x00005cae, 0x00005eae, 0x000060ae, 0x000062ae, + 0x000064ae, 0x000066ae, 0x000068ae, 0x00006aae, + 0x00006cae, 0x00006eae, 0x000070ae, 0x000072ae, + 0x000074ae, 0x000076ae, 0x000078ae, 0x00007aae, + 0x00007cae, 0x00007eae, 0x000080ae, 0x000082ae, + 0x000084ae, 0x000086ae, 0x000088ae, 0x00008aae, + 0x00008cae, 0x00008eae, 0x000090ae, 0x000092ae, + 0x000094ae, 0x000096ae, 0x000098ae, 0x00009aae, + 0x00009cae, 0x00009eae, 0x0000a0ae, 0x0000a2ae, + 0x0000a4ae, 0x0000a6ae, 0x0000a8ae, 0x0000aaae, + 0x0000acae, 0x0000aeae, 0x0000b0ae, 0x0000b2ae, + 0x0000b4ae, 0x0000b6ae, 0x0000b8ae, 0x0000baae, + 0x0000bcae, 0x0000beae, 0x0000c0ae, 0x0000c2ae, + 0x0000c4ae, 0x0000c6ae, 0x0000c8ae, 0x0000caae, + 0x0000ccae, 0x0000ceae, 0x0000d0ae, 0x0000d2ae, + 0x0000d4ae, 0x0000d6ae, 0x0000d8ae, 0x0000daae, + 0x0000dcae, 0x0000deae, 0x0000e0ae, 0x0000e2ae, + 0x0000e4ae, 0x0000e6ae, 0x0000e8ae, 0x0000eaae, + 0x0000ecae, 0x0000eeae, 0x0000f0ae, 0x0000f2ae, + 0x0000f4ae, 0x0000f6ae, 0x0000f8ae, 0x0000faae, + 0x0000fcae, 0x0000feae, 0x000100ae, 0x000102ae, + 0x000104ae, 0x000106ae, 0x000108ae, 0x00010aae, + 0x00010cae, 0x00010eae, 0x000110ae, 0x000112ae, + 0x000114ae, 0x000116ae, 0x000118ae, 0x00011aae, + 0x00011cae, 0x00011eae, 0x000120ae, 0x000122ae, + 0x000124ae, 0x000126ae, 0x000128ae, 0x00012aae, + 0x00012cae, 0x00012eae, 0x000130ae, 0x000132ae, + 0x000134ae, 0x000136ae, 0x000138ae, 0x00013aae, + 0x00013cae, 0x00013eae, 0x000140ae, 0x000142ae, + 0x000144ae, 0x000146ae, 0x000148ae, 0x00014aae, + 0x00014cae, 0x00014eae, 0x000150ae, 0x000152ae, + 0x000154ae, 0x000156ae, 0x000158ae, 0x00015aae, + 0x00015cae, 0x00015eae, 0x000160ae, 0x000162ae, + 0x000164ae, 0x000166ae, 0x000168ae, 0x00016aae, + 0x00016cae, 0x00016eae, 0x000170ae, 0x000172ae, + 0x000174ae, 0x000176ae, 0x000178ae, 0x00017aae, + 0x00017cae, 0x00017eae, 0x000180ae, 0x000182ae, + 0x000184ae, 0x000186ae, 0x000188ae, 0x00018aae, + 0x00018cae, 0x00018eae, 0x000190ae, 0x000192ae, + 0x000194ae, 0x000196ae, 0x000198ae, 0x00019aae, + 0x00019cae, 0x00019eae, 0x0001a0ae, 0x0001a2ae, + 0x0001a4ae, 0x0001a6ae, 0x0001a8ae, 0x0001aaae, + 0x0001acae, 0x0001aeae, 0x0001b0ae, 0x0001b2ae, + 0x0001b4ae, 0x0001b6ae, 0x0001b8ae, 0x0001baae, + 0x0001bcae, 0x0001beae, 0x0001c0ae, 0x0001c2ae, + 0x0001c4ae, 0x0001c6ae, 0x0001c8ae, 0x0001caae, + 0x0001ccae, 0x0001ceae, 0x0001d0ae, 0x0001d2ae, + 0x0001d4ae, 0x0001d6ae, 0x0001d8ae, 0x0001daae, + 0x0001dcae, 0x0001deae, 0x0001e0ae, 0x0001e2ae, + 0x0001e4ae, 0x0001e6ae, 0x0001e8ae, 0x0001eaae, + 0x0001ecae, 0x0001eeae, 0x0001f0ae, 0x0001f2ae, + 0x0001f4ae, 0x0001f6ae, 0x0001f8ae, 0x0001faae, + 0x0001fcae, 0x0001feae, 0x000200ae, 0x000202ae, + 0x000204ae, 0x000206ae, 0x000208ae, 0x00020aae, + 0x00020cae, 0x00020eae, 0x000210ae, 0x000212ae, + 0x000214ae, 0x000216ae, 0x000218ae, 0x00021aae, + 0x00021cae, 0x00021eae, 0x000220ae, 0x000222ae, + 0x000224ae, 0x000226ae, 0x000228ae, 0x00022aae, + 0x00022cae, 0x00022eae, 0x000230ae, 0x000232ae, + 0x000234ae, 0x000236ae, 0x000238ae, 0x00023aae, + 0x00023cae, 0x00023eae, 0x000240ae, 0x000242ae, + 0x000244ae, 0x000246ae, 0x000248ae, 0x00024aae, + 0x00024cae, 0x00024eae, 0x000250ae, 0x000252ae, + 0x000254ae, 0x000256ae, 0x000258ae, 0x00025aae, + 0x00025cae, 0x00025eae, 0x000260ae, 0x000262ae, + 0x000264ae, 0x000266ae, 0x000268ae, 0x00026aae, + 0x00026cae, 0x00026eae, 0x000270ae, 0x000272ae, + 0x000274ae, 0x000276ae, 0x000278ae, 0x00027aae, + 0x00027cae, 0x00027eae, 0x000280ae, 0x000282ae, + 0x000284ae, 0x000286ae, 0x000288ae, 0x00028aae, + 0x00028cae, 0x00028eae, 0x000290ae, 0x000292ae, + 0x000294ae, 0x000296ae, 0x000298ae, 0x00029aae, + 0x00029cae, 0x00029eae, 0x0002a0ae, 0x0002a2ae, + 0x0002a4ae, 0x0002a6ae, 0x0002a8ae, 0x0002aaae, + 0x0002acae, 0x0002aeae, 0x0002b0ae, 0x0002b2ae, + 0x0002b4ae, 0x0002b6ae, 0x0002b8ae, 0x0002baae, + 0x0002bcae, 0x0002beae, 0x0002c0ae, 0x0002c2ae, + 0x0002c4ae, 0x0002c6ae, 0x0002c8ae, 0x0002caae, + 0x0002ccae, 0x0002ceae, 0x0002d0ae, 0x0002d2ae, + 0x0002d4ae, 0x0002d6ae, 0x0002d8ae, 0x0002daae, + 0x0002dcae, 0x0002deae, 0x0002e0ae, 0x0002e2ae, + 0x0002e4ae, 0x0002e6ae, 0x0002e8ae, 0x0002eaae, + 0x0002ecae, 0x0002eeae, 0x0002f0ae, 0x0002f2ae, + 0x0002f4ae, 0x0002f6ae, 0x0002f8ae, 0x0002faae, + 0x0002fcae, 0x0002feae, 0x000300ae, 0x000302ae, + 0x000304ae, 0x000306ae, 0x000308ae, 0x00030aae, + 0x00030cae, 0x00030eae, 0x000310ae, 0x000312ae, + 0x000314ae, 0x000316ae, 0x000318ae, 0x00031aae, + 0x00031cae, 0x00031eae, 0x000320ae, 0x000322ae, + 0x000324ae, 0x000326ae, 0x000328ae, 0x00032aae, + 0x00032cae, 0x00032eae, 0x000330ae, 0x000332ae, + 0x000334ae, 0x000336ae, 0x000338ae, 0x00033aae, + 0x00033cae, 0x00033eae, 0x000340ae, 0x000342ae, + 0x000344ae, 0x000346ae, 0x000348ae, 0x00034aae, + 0x00034cae, 0x00034eae, 0x000350ae, 0x000352ae, + 0x000354ae, 0x000356ae, 0x000358ae, 0x00035aae, + 0x00035cae, 0x00035eae, 0x000360ae, 0x000362ae, + 0x000364ae, 0x000366ae, 0x000368ae, 0x00036aae, + 0x00036cae, 0x00036eae, 0x000370ae, 0x000372ae, + 0x000374ae, 0x000376ae, 0x000378ae, 0x00037aae, + 0x00037cae, 0x00037eae, 0x000380ae, 0x000382ae, + 0x000384ae, 0x000386ae, 0x000388ae, 0x00038aae, + 0x00038cae, 0x00038eae, 0x000390ae, 0x000392ae, + 0x000394ae, 0x000396ae, 0x000398ae, 0x00039aae, + 0x00039cae, 0x00039eae, 0x0003a0ae, 0x0003a2ae, + 0x0003a4ae, 0x0003a6ae, 0x0003a8ae, 0x0003aaae, + 0x0003acae, 0x0003aeae, 0x0003b0ae, 0x0003b2ae, + 0x0003b4ae, 0x0003b6ae, 0x0003b8ae, 0x0003baae, + 0x0003bcae, 0x0003beae, 0x0003c0ae, 0x0003c2ae, + 0x0003c4ae, 0x0003c6ae, 0x0003c8ae, 0x0003caae, + 0x0003ccae, 0x0003ceae, 0x0003d0ae, 0x0003d2ae, + 0x0003d4ae, 0x0003d6ae, 0x0003d8ae, 0x0003daae, + 0x0003dcae, 0x0003deae, 0x0003e0ae, 0x0003e2ae, + 0x0003e4ae, 0x0003e6ae, 0x0003e8ae, 0x0003eaae, + 0x0003ecae, 0x0003eeae, 0x0003f0ae, 0x0003f2ae, + 0x0003f4ae, 0x0003f6ae, 0x0003f8ae, 0x0003faae, + 0x0003fcae, 0x0003feae, 0x000400ae, 0x000402ae, + 0x000404ae, 0x000406ae, 0x000408ae, 0x00040aae, + 0x00040cae, 0x00040eae, 0x000410ae, 0x000412ae, + 0x000414ae, 0x000416ae, 0x000418ae, 0x00041aae, + 0x00041cae, 0x00041eae, 0x000420ae, 0x000422ae, + 0x000424ae, 0x000426ae, 0x000428ae, 0x00042aae, + 0x00042cae, 0x00042eae, 0x000430ae, 0x000432ae, + 0x000434ae, 0x000436ae, 0x000438ae, 0x00043aae, + 0x00043cae, 0x00043eae, 0x000440ae, 0x000442ae, + 0x000444ae, 0x000446ae, 0x000448ae, 0x00044aae, + 0x00044cae, 0x00044eae, 0x000450ae, 0x000452ae, + 0x000454ae, 0x000456ae, 0x000458ae, 0x00045aae, + 0x00045cae, 0x00045eae, 0x000460ae, 0x000462ae, + 0x000464ae, 0x000466ae, 0x000468ae, 0x00046aae, + 0x00046cae, 0x00046eae, 0x000470ae, 0x000472ae, + 0x000474ae, 0x000476ae, 0x000478ae, 0x00047aae, + 0x00047cae, 0x00047eae, 0x000480ae, 0x000482ae, + 0x000484ae, 0x000486ae, 0x000488ae, 0x00048aae, + 0x00048cae, 0x00048eae, 0x000490ae, 0x000492ae, + 0x000494ae, 0x000496ae, 0x000498ae, 0x00049aae, + 0x00049cae, 0x00049eae, 0x0004a0ae, 0x0004a2ae, + 0x0004a4ae, 0x0004a6ae, 0x0004a8ae, 0x0004aaae, + 0x0004acae, 0x0004aeae, 0x0004b0ae, 0x0004b2ae, + 0x0004b4ae, 0x0004b6ae, 0x0004b8ae, 0x0004baae, + 0x0004bcae, 0x0004beae, 0x0004c0ae, 0x0004c2ae, + 0x0004c4ae, 0x0004c6ae, 0x0004c8ae, 0x0004caae, + 0x0004ccae, 0x0004ceae, 0x0004d0ae, 0x0004d2ae, + 0x0004d4ae, 0x0004d6ae, 0x0004d8ae, 0x0004daae, + 0x0004dcae, 0x0004deae, 0x0004e0ae, 0x0004e2ae, + 0x0004e4ae, 0x0004e6ae, 0x0004e8ae, 0x0004eaae, + 0x0004ecae, 0x0004eeae, 0x0004f0ae, 0x0004f2ae, + 0x0004f4ae, 0x0004f6ae, 0x0004f8ae, 0x0004faae, + 0x0004fcae, 0x0004feae, 0x000500ae, 0x000502ae, + 0x000504ae, 0x000506ae, 0x000508ae, 0x00050aae, + 0x00050cae, 0x00050eae, 0x000510ae, 0x000512ae, + 0x000514ae, 0x000516ae, 0x000518ae, 0x00051aae, + 0x00051cae, 0x00051eae, 0x000520ae, 0x000522ae, + 0x000524ae, 0x000526ae, 0x000528ae, 0x00052aae, + 0x00052cae, 0x00052eae, 0x000530ae, 0x000532ae, + 0x000534ae, 0x000536ae, 0x000538ae, 0x00053aae, + 0x00053cae, 0x00053eae, 0x000540ae, 0x000542ae, + 0x000544ae, 0x000546ae, 0x000548ae, 0x00054aae, + 0x00054cae, 0x00054eae, 0x000550ae, 0x000552ae, + 0x000554ae, 0x000556ae, 0x000558ae, 0x00055aae, + 0x00055cae, 0x00055eae, 0x000560ae, 0x000562ae, + 0x000564ae, 0x000566ae, 0x000568ae, 0x00056aae, + 0x00056cae, 0x00056eae, 0x000570ae, 0x000572ae, + 0x000574ae, 0x000576ae, 0x000578ae, 0x00057aae, + 0x00057cae, 0x00057eae, 0x000580ae, 0x000582ae, + 0x000584ae, 0x000586ae, 0x000588ae, 0x00058aae, + 0x00058cae, 0x00058eae, 0x000590ae, 0x000592ae, + 0x000594ae, 0x000596ae, 0x000598ae, 0x00059aae, + 0x00059cae, 0x00059eae, 0x0005a0ae, 0x0005a2ae, + 0x0005a4ae, 0x0005a6ae, 0x0005a8ae, 0x0005aaae, + 0x0005acae, 0x0005aeae, 0x0005b0ae, 0x0005b2ae, + 0x0005b4ae, 0x0005b6ae, 0x0005b8ae, 0x0005baae, + 0x0005bcae, 0x0005beae, 0x0005c0ae, 0x0005c2ae, + 0x0005c4ae, 0x0005c6ae, 0x0005c8ae, 0x0005caae, + 0x0005ccae, 0x0005ceae, 0x0005d0ae, 0x0005d2ae, + 0x0005d4ae, 0x0005d6ae, 0x0005d8ae, 0x0005daae, + 0x0005dcae, 0x0005deae, 0x0005e0ae, 0x0005e2ae, + 0x0005e4ae, 0x0005e6ae, 0x0005e8ae, 0x0005eaae, + 0x0005ecae, 0x0005eeae, 0x0005f0ae, 0x0005f2ae, + 0x0005f4ae, 0x0005f6ae, 0x0005f8ae, 0x0005faae, + 0x0005fcae, 0x0005feae, 0x000600ae, 0x000602ae, + 0x000604ae, 0x000606ae, 0x000608ae, 0x00060aae, + 0x00060cae, 0x00060eae, 0x000610ae, 0x000612ae, + 0x000614ae, 0x000616ae, 0x000618ae, 0x00061aae, + 0x00061cae, 0x00061eae, 0x000620ae, 0x000622ae, + 0x000624ae, 0x000626ae, 0x000628ae, 0x00062aae, + 0x00062cae, 0x00062eae, 0x000630ae, 0x000632ae, + 0x000634ae, 0x000636ae, 0x000638ae, 0x00063aae, + 0x00063cae, 0x00063eae, 0x000640ae, 0x000642ae, + 0x000644ae, 0x000646ae, 0x000648ae, 0x00064aae, + 0x00064cae, 0x00064eae, 0x000650ae, 0x000652ae, + 0x000654ae, 0x000656ae, 0x000658ae, 0x00065aae, + 0x00065cae, 0x00065eae, 0x000660ae, 0x000662ae, + 0x000664ae, 0x000666ae, 0x000668ae, 0x00066aae, + 0x00066cae, 0x00066eae, 0x000670ae, 0x000672ae, + 0x000674ae, 0x000676ae, 0x000678ae, 0x00067aae, + 0x00067cae, 0x00067eae, 0x000680ae, 0x000682ae, + 0x000684ae, 0x000686ae, 0x000688ae, 0x00068aae, + 0x00068cae, 0x00068eae, 0x000690ae, 0x000692ae, + 0x000694ae, 0x000696ae, 0x000698ae, 0x00069aae, + 0x00069cae, 0x00069eae, 0x0006a0ae, 0x0006a2ae, + 0x0006a4ae, 0x0006a6ae, 0x0006a8ae, 0x0006aaae, + 0x0006acae, 0x0006aeae, 0x0006b0ae, 0x0006b2ae, + 0x0006b4ae, 0x0006b6ae, 0x0006b8ae, 0x0006baae, + 0x0006bcae, 0x0006beae, 0x0006c0ae, 0x0006c2ae, + 0x0006c4ae, 0x0006c6ae, 0x0006c8ae, 0x0006caae, + 0x0006ccae, 0x0006ceae, 0x0006d0ae, 0x0006d2ae, + 0x0006d4ae, 0x0006d6ae, 0x0006d8ae, 0x0006daae, + 0x0006dcae, 0x0006deae, 0x0006e0ae, 0x0006e2ae, + 0x0006e4ae, 0x0006e6ae, 0x0006e8ae, 0x0006eaae, + 0x0006ecae, 0x0006eeae, 0x0006f0ae, 0x0006f2ae, + 0x0006f4ae, 0x0006f6ae, 0x0006f8ae, 0x0006faae, + 0x0006fcae, 0x0006feae, 0x000700ae, 0x000702ae, + 0x000704ae, 0x000706ae, 0x000708ae, 0x00070aae, + 0x00070cae, 0x00070eae, 0x000710ae, 0x000712ae, + 0x000714ae, 0x000716ae, 0x000718ae, 0x00071aae, + 0x00071cae, 0x00071eae, 0x000720ae, 0x000722ae, + 0x000724ae, 0x000726ae, 0x000728ae, 0x00072aae, + 0x00072cae, 0x00072eae, 0x000730ae, 0x000732ae, + 0x000734ae, 0x000736ae, 0x000738ae, 0x00073aae, + 0x00073cae, 0x00073eae, 0x000740ae, 0x000742ae, + 0x000744ae, 0x000746ae, 0x000748ae, 0x00074aae, + 0x00074cae, 0x00074eae, 0x000750ae, 0x000752ae, + 0x000754ae, 0x000756ae, 0x000758ae, 0x00075aae, + 0x00075cae, 0x00075eae, 0x000760ae, 0x000762ae, + 0x000764ae, 0x000766ae, 0x000768ae, 0x00076aae, + 0x00076cae, 0x00076eae, 0x000770ae, 0x000772ae, + 0x000774ae, 0x000776ae, 0x000778ae, 0x00077aae, + 0x00077cae, 0x00077eae, 0x000780ae, 0x000782ae, + 0x000784ae, 0x000786ae, 0x000788ae, 0x00078aae, + 0x00078cae, 0x00078eae, 0x000790ae, 0x000792ae, + 0x000794ae, 0x000796ae, 0x000798ae, 0x00079aae, + 0x00079cae, 0x00079eae, 0x0007a0ae, 0x0007a2ae, + 0x0007a4ae, 0x0007a6ae, 0x0007a8ae, 0x0007aaae, + 0x0007acae, 0x0007aeae, 0x0007b0ae, 0x0007b2ae, + 0x0007b4ae, 0x0007b6ae, 0x0007b8ae, 0x0007baae, + 0x0007bcae, 0x0007beae, 0x0007c0ae, 0x0007c2ae, + 0x0007c4ae, 0x0007c6ae, 0x0007c8ae, 0x0007caae, + 0x0007ccae, 0x0007ceae, 0x0007d0ae, 0x0007d2ae, + 0x0007d4ae, 0x0007d6ae, 0x0007d8ae, 0x0007daae, + 0x0007dcae, 0x0007deae, 0x0007e0ae, 0x0007e2ae, + 0x0007e4ae, 0x0007e6ae, 0x0007e8ae, 0x0007eaae, + 0x0007ecae, 0x0007eeae, 0x0007f0ae, 0x0007f2ae, + 0x0007f4ae, 0x0007f6ae, 0x0007f8ae, 0x0007faae, + 0x0007fcae, 0x0007feae, 0x000001af, 0x000003af, + 0x000005af, 0x000007af, 0x000009af, 0x00000baf, + 0x00000daf, 0x00000faf, 0x000011af, 0x000013af, + 0x000015af, 0x000017af, 0x000019af, 0x00001baf, + 0x00001daf, 0x00001faf, 0x000021af, 0x000023af, + 0x000025af, 0x000027af, 0x000029af, 0x00002baf, + 0x00002daf, 0x00002faf, 0x000031af, 0x000033af, + 0x000035af, 0x000037af, 0x000039af, 0x00003baf, + 0x00003daf, 0x00003faf, 0x000041af, 0x000043af, + 0x000045af, 0x000047af, 0x000049af, 0x00004baf, + 0x00004daf, 0x00004faf, 0x000051af, 0x000053af, + 0x000055af, 0x000057af, 0x000059af, 0x00005baf, + 0x00005daf, 0x00005faf, 0x000061af, 0x000063af, + 0x000065af, 0x000067af, 0x000069af, 0x00006baf, + 0x00006daf, 0x00006faf, 0x000071af, 0x000073af, + 0x000075af, 0x000077af, 0x000079af, 0x00007baf, + 0x00007daf, 0x00007faf, 0x000081af, 0x000083af, + 0x000085af, 0x000087af, 0x000089af, 0x00008baf, + 0x00008daf, 0x00008faf, 0x000091af, 0x000093af, + 0x000095af, 0x000097af, 0x000099af, 0x00009baf, + 0x00009daf, 0x00009faf, 0x0000a1af, 0x0000a3af, + 0x0000a5af, 0x0000a7af, 0x0000a9af, 0x0000abaf, + 0x0000adaf, 0x0000afaf, 0x0000b1af, 0x0000b3af, + 0x0000b5af, 0x0000b7af, 0x0000b9af, 0x0000bbaf, + 0x0000bdaf, 0x0000bfaf, 0x0000c1af, 0x0000c3af, + 0x0000c5af, 0x0000c7af, 0x0000c9af, 0x0000cbaf, + 0x0000cdaf, 0x0000cfaf, 0x0000d1af, 0x0000d3af, + 0x0000d5af, 0x0000d7af, 0x0000d9af, 0x0000dbaf, + 0x0000ddaf, 0x0000dfaf, 0x0000e1af, 0x0000e3af, + 0x0000e5af, 0x0000e7af, 0x0000e9af, 0x0000ebaf, + 0x0000edaf, 0x0000efaf, 0x0000f1af, 0x0000f3af, + 0x0000f5af, 0x0000f7af, 0x0000f9af, 0x0000fbaf, + 0x0000fdaf, 0x0000ffaf, 0x000101af, 0x000103af, + 0x000105af, 0x000107af, 0x000109af, 0x00010baf, + 0x00010daf, 0x00010faf, 0x000111af, 0x000113af, + 0x000115af, 0x000117af, 0x000119af, 0x00011baf, + 0x00011daf, 0x00011faf, 0x000121af, 0x000123af, + 0x000125af, 0x000127af, 0x000129af, 0x00012baf, + 0x00012daf, 0x00012faf, 0x000131af, 0x000133af, + 0x000135af, 0x000137af, 0x000139af, 0x00013baf, + 0x00013daf, 0x00013faf, 0x000141af, 0x000143af, + 0x000145af, 0x000147af, 0x000149af, 0x00014baf, + 0x00014daf, 0x00014faf, 0x000151af, 0x000153af, + 0x000155af, 0x000157af, 0x000159af, 0x00015baf, + 0x00015daf, 0x00015faf, 0x000161af, 0x000163af, + 0x000165af, 0x000167af, 0x000169af, 0x00016baf, + 0x00016daf, 0x00016faf, 0x000171af, 0x000173af, + 0x000175af, 0x000177af, 0x000179af, 0x00017baf, + 0x00017daf, 0x00017faf, 0x000181af, 0x000183af, + 0x000185af, 0x000187af, 0x000189af, 0x00018baf, + 0x00018daf, 0x00018faf, 0x000191af, 0x000193af, + 0x000195af, 0x000197af, 0x000199af, 0x00019baf, + 0x00019daf, 0x00019faf, 0x0001a1af, 0x0001a3af, + 0x0001a5af, 0x0001a7af, 0x0001a9af, 0x0001abaf, + 0x0001adaf, 0x0001afaf, 0x0001b1af, 0x0001b3af, + 0x0001b5af, 0x0001b7af, 0x0001b9af, 0x0001bbaf, + 0x0001bdaf, 0x0001bfaf, 0x0001c1af, 0x0001c3af, + 0x0001c5af, 0x0001c7af, 0x0001c9af, 0x0001cbaf, + 0x0001cdaf, 0x0001cfaf, 0x0001d1af, 0x0001d3af, + 0x0001d5af, 0x0001d7af, 0x0001d9af, 0x0001dbaf, + 0x0001ddaf, 0x0001dfaf, 0x0001e1af, 0x0001e3af, + 0x0001e5af, 0x0001e7af, 0x0001e9af, 0x0001ebaf, + 0x0001edaf, 0x0001efaf, 0x0001f1af, 0x0001f3af, + 0x0001f5af, 0x0001f7af, 0x0001f9af, 0x0001fbaf, + 0x0001fdaf, 0x0001ffaf, 0x000201af, 0x000203af, + 0x000205af, 0x000207af, 0x000209af, 0x00020baf, + 0x00020daf, 0x00020faf, 0x000211af, 0x000213af, + 0x000215af, 0x000217af, 0x000219af, 0x00021baf, + 0x00021daf, 0x00021faf, 0x000221af, 0x000223af, + 0x000225af, 0x000227af, 0x000229af, 0x00022baf, + 0x00022daf, 0x00022faf, 0x000231af, 0x000233af, + 0x000235af, 0x000237af, 0x000239af, 0x00023baf, + 0x00023daf, 0x00023faf, 0x000241af, 0x000243af, + 0x000245af, 0x000247af, 0x000249af, 0x00024baf, + 0x00024daf, 0x00024faf, 0x000251af, 0x000253af, + 0x000255af, 0x000257af, 0x000259af, 0x00025baf, + 0x00025daf, 0x00025faf, 0x000261af, 0x000263af, + 0x000265af, 0x000267af, 0x000269af, 0x00026baf, + 0x00026daf, 0x00026faf, 0x000271af, 0x000273af, + 0x000275af, 0x000277af, 0x000279af, 0x00027baf, + 0x00027daf, 0x00027faf, 0x000281af, 0x000283af, + 0x000285af, 0x000287af, 0x000289af, 0x00028baf, + 0x00028daf, 0x00028faf, 0x000291af, 0x000293af, + 0x000295af, 0x000297af, 0x000299af, 0x00029baf, + 0x00029daf, 0x00029faf, 0x0002a1af, 0x0002a3af, + 0x0002a5af, 0x0002a7af, 0x0002a9af, 0x0002abaf, + 0x0002adaf, 0x0002afaf, 0x0002b1af, 0x0002b3af, + 0x0002b5af, 0x0002b7af, 0x0002b9af, 0x0002bbaf, + 0x0002bdaf, 0x0002bfaf, 0x0002c1af, 0x0002c3af, + 0x0002c5af, 0x0002c7af, 0x0002c9af, 0x0002cbaf, + 0x0002cdaf, 0x0002cfaf, 0x0002d1af, 0x0002d3af, + 0x0002d5af, 0x0002d7af, 0x0002d9af, 0x0002dbaf, + 0x0002ddaf, 0x0002dfaf, 0x0002e1af, 0x0002e3af, + 0x0002e5af, 0x0002e7af, 0x0002e9af, 0x0002ebaf, + 0x0002edaf, 0x0002efaf, 0x0002f1af, 0x0002f3af, + 0x0002f5af, 0x0002f7af, 0x0002f9af, 0x0002fbaf, + 0x0002fdaf, 0x0002ffaf, 0x000301af, 0x000303af, + 0x000305af, 0x000307af, 0x000309af, 0x00030baf, + 0x00030daf, 0x00030faf, 0x000311af, 0x000313af, + 0x000315af, 0x000317af, 0x000319af, 0x00031baf, + 0x00031daf, 0x00031faf, 0x000321af, 0x000323af, + 0x000325af, 0x000327af, 0x000329af, 0x00032baf, + 0x00032daf, 0x00032faf, 0x000331af, 0x000333af, + 0x000335af, 0x000337af, 0x000339af, 0x00033baf, + 0x00033daf, 0x00033faf, 0x000341af, 0x000343af, + 0x000345af, 0x000347af, 0x000349af, 0x00034baf, + 0x00034daf, 0x00034faf, 0x000351af, 0x000353af, + 0x000355af, 0x000357af, 0x000359af, 0x00035baf, + 0x00035daf, 0x00035faf, 0x000361af, 0x000363af, + 0x000365af, 0x000367af, 0x000369af, 0x00036baf, + 0x00036daf, 0x00036faf, 0x000371af, 0x000373af, + 0x000375af, 0x000377af, 0x000379af, 0x00037baf, + 0x00037daf, 0x00037faf, 0x000381af, 0x000383af, + 0x000385af, 0x000387af, 0x000389af, 0x00038baf, + 0x00038daf, 0x00038faf, 0x000391af, 0x000393af, + 0x000395af, 0x000397af, 0x000399af, 0x00039baf, + 0x00039daf, 0x00039faf, 0x0003a1af, 0x0003a3af, + 0x0003a5af, 0x0003a7af, 0x0003a9af, 0x0003abaf, + 0x0003adaf, 0x0003afaf, 0x0003b1af, 0x0003b3af, + 0x0003b5af, 0x0003b7af, 0x0003b9af, 0x0003bbaf, + 0x0003bdaf, 0x0003bfaf, 0x0003c1af, 0x0003c3af, + 0x0003c5af, 0x0003c7af, 0x0003c9af, 0x0003cbaf, + 0x0003cdaf, 0x0003cfaf, 0x0003d1af, 0x0003d3af, + 0x0003d5af, 0x0003d7af, 0x0003d9af, 0x0003dbaf, + 0x0003ddaf, 0x0003dfaf, 0x0003e1af, 0x0003e3af, + 0x0003e5af, 0x0003e7af, 0x0003e9af, 0x0003ebaf, + 0x0003edaf, 0x0003efaf, 0x0003f1af, 0x0003f3af, + 0x0003f5af, 0x0003f7af, 0x0003f9af, 0x0003fbaf, + 0x0003fdaf, 0x0003ffaf, 0x000401af, 0x000403af, + 0x000405af, 0x000407af, 0x000409af, 0x00040baf, + 0x00040daf, 0x00040faf, 0x000411af, 0x000413af, + 0x000415af, 0x000417af, 0x000419af, 0x00041baf, + 0x00041daf, 0x00041faf, 0x000421af, 0x000423af, + 0x000425af, 0x000427af, 0x000429af, 0x00042baf, + 0x00042daf, 0x00042faf, 0x000431af, 0x000433af, + 0x000435af, 0x000437af, 0x000439af, 0x00043baf, + 0x00043daf, 0x00043faf, 0x000441af, 0x000443af, + 0x000445af, 0x000447af, 0x000449af, 0x00044baf, + 0x00044daf, 0x00044faf, 0x000451af, 0x000453af, + 0x000455af, 0x000457af, 0x000459af, 0x00045baf, + 0x00045daf, 0x00045faf, 0x000461af, 0x000463af, + 0x000465af, 0x000467af, 0x000469af, 0x00046baf, + 0x00046daf, 0x00046faf, 0x000471af, 0x000473af, + 0x000475af, 0x000477af, 0x000479af, 0x00047baf, + 0x00047daf, 0x00047faf, 0x000481af, 0x000483af, + 0x000485af, 0x000487af, 0x000489af, 0x00048baf, + 0x00048daf, 0x00048faf, 0x000491af, 0x000493af, + 0x000495af, 0x000497af, 0x000499af, 0x00049baf, + 0x00049daf, 0x00049faf, 0x0004a1af, 0x0004a3af, + 0x0004a5af, 0x0004a7af, 0x0004a9af, 0x0004abaf, + 0x0004adaf, 0x0004afaf, 0x0004b1af, 0x0004b3af, + 0x0004b5af, 0x0004b7af, 0x0004b9af, 0x0004bbaf, + 0x0004bdaf, 0x0004bfaf, 0x0004c1af, 0x0004c3af, + 0x0004c5af, 0x0004c7af, 0x0004c9af, 0x0004cbaf, + 0x0004cdaf, 0x0004cfaf, 0x0004d1af, 0x0004d3af, + 0x0004d5af, 0x0004d7af, 0x0004d9af, 0x0004dbaf, + 0x0004ddaf, 0x0004dfaf, 0x0004e1af, 0x0004e3af, + 0x0004e5af, 0x0004e7af, 0x0004e9af, 0x0004ebaf, + 0x0004edaf, 0x0004efaf, 0x0004f1af, 0x0004f3af, + 0x0004f5af, 0x0004f7af, 0x0004f9af, 0x0004fbaf, + 0x0004fdaf, 0x0004ffaf, 0x000501af, 0x000503af, + 0x000505af, 0x000507af, 0x000509af, 0x00050baf, + 0x00050daf, 0x00050faf, 0x000511af, 0x000513af, + 0x000515af, 0x000517af, 0x000519af, 0x00051baf, + 0x00051daf, 0x00051faf, 0x000521af, 0x000523af, + 0x000525af, 0x000527af, 0x000529af, 0x00052baf, + 0x00052daf, 0x00052faf, 0x000531af, 0x000533af, + 0x000535af, 0x000537af, 0x000539af, 0x00053baf, + 0x00053daf, 0x00053faf, 0x000541af, 0x000543af, + 0x000545af, 0x000547af, 0x000549af, 0x00054baf, + 0x00054daf, 0x00054faf, 0x000551af, 0x000553af, + 0x000555af, 0x000557af, 0x000559af, 0x00055baf, + 0x00055daf, 0x00055faf, 0x000561af, 0x000563af, + 0x000565af, 0x000567af, 0x000569af, 0x00056baf, + 0x00056daf, 0x00056faf, 0x000571af, 0x000573af, + 0x000575af, 0x000577af, 0x000579af, 0x00057baf, + 0x00057daf, 0x00057faf, 0x000581af, 0x000583af, + 0x000585af, 0x000587af, 0x000589af, 0x00058baf, + 0x00058daf, 0x00058faf, 0x000591af, 0x000593af, + 0x000595af, 0x000597af, 0x000599af, 0x00059baf, + 0x00059daf, 0x00059faf, 0x0005a1af, 0x0005a3af, + 0x0005a5af, 0x0005a7af, 0x0005a9af, 0x0005abaf, + 0x0005adaf, 0x0005afaf, 0x0005b1af, 0x0005b3af, + 0x0005b5af, 0x0005b7af, 0x0005b9af, 0x0005bbaf, + 0x0005bdaf, 0x0005bfaf, 0x0005c1af, 0x0005c3af, + 0x0005c5af, 0x0005c7af, 0x0005c9af, 0x0005cbaf, + 0x0005cdaf, 0x0005cfaf, 0x0005d1af, 0x0005d3af, + 0x0005d5af, 0x0005d7af, 0x0005d9af, 0x0005dbaf, + 0x0005ddaf, 0x0005dfaf, 0x0005e1af, 0x0005e3af, + 0x0005e5af, 0x0005e7af, 0x0005e9af, 0x0005ebaf, + 0x0005edaf, 0x0005efaf, 0x0005f1af, 0x0005f3af, + 0x0005f5af, 0x0005f7af, 0x0005f9af, 0x0005fbaf, + 0x0005fdaf, 0x0005ffaf, 0x000601af, 0x000603af, + 0x000605af, 0x000607af, 0x000609af, 0x00060baf, + 0x00060daf, 0x00060faf, 0x000611af, 0x000613af, + 0x000615af, 0x000617af, 0x000619af, 0x00061baf, + 0x00061daf, 0x00061faf, 0x000621af, 0x000623af, + 0x000625af, 0x000627af, 0x000629af, 0x00062baf, + 0x00062daf, 0x00062faf, 0x000631af, 0x000633af, + 0x000635af, 0x000637af, 0x000639af, 0x00063baf, + 0x00063daf, 0x00063faf, 0x000641af, 0x000643af, + 0x000645af, 0x000647af, 0x000649af, 0x00064baf, + 0x00064daf, 0x00064faf, 0x000651af, 0x000653af, + 0x000655af, 0x000657af, 0x000659af, 0x00065baf, + 0x00065daf, 0x00065faf, 0x000661af, 0x000663af, + 0x000665af, 0x000667af, 0x000669af, 0x00066baf, + 0x00066daf, 0x00066faf, 0x000671af, 0x000673af, + 0x000675af, 0x000677af, 0x000679af, 0x00067baf, + 0x00067daf, 0x00067faf, 0x000681af, 0x000683af, + 0x000685af, 0x000687af, 0x000689af, 0x00068baf, + 0x00068daf, 0x00068faf, 0x000691af, 0x000693af, + 0x000695af, 0x000697af, 0x000699af, 0x00069baf, + 0x00069daf, 0x00069faf, 0x0006a1af, 0x0006a3af, + 0x0006a5af, 0x0006a7af, 0x0006a9af, 0x0006abaf, + 0x0006adaf, 0x0006afaf, 0x0006b1af, 0x0006b3af, + 0x0006b5af, 0x0006b7af, 0x0006b9af, 0x0006bbaf, + 0x0006bdaf, 0x0006bfaf, 0x0006c1af, 0x0006c3af, + 0x0006c5af, 0x0006c7af, 0x0006c9af, 0x0006cbaf, + 0x0006cdaf, 0x0006cfaf, 0x0006d1af, 0x0006d3af, + 0x0006d5af, 0x0006d7af, 0x0006d9af, 0x0006dbaf, + 0x0006ddaf, 0x0006dfaf, 0x0006e1af, 0x0006e3af, + 0x0006e5af, 0x0006e7af, 0x0006e9af, 0x0006ebaf, + 0x0006edaf, 0x0006efaf, 0x0006f1af, 0x0006f3af, + 0x0006f5af, 0x0006f7af, 0x0006f9af, 0x0006fbaf, + 0x0006fdaf, 0x0006ffaf, 0x000701af, 0x000703af, + 0x000705af, 0x000707af, 0x000709af, 0x00070baf, + 0x00070daf, 0x00070faf, 0x000711af, 0x000713af, + 0x000715af, 0x000717af, 0x000719af, 0x00071baf, + 0x00071daf, 0x00071faf, 0x000721af, 0x000723af, + 0x000725af, 0x000727af, 0x000729af, 0x00072baf, + 0x00072daf, 0x00072faf, 0x000731af, 0x000733af, + 0x000735af, 0x000737af, 0x000739af, 0x00073baf, + 0x00073daf, 0x00073faf, 0x000741af, 0x000743af, + 0x000745af, 0x000747af, 0x000749af, 0x00074baf, + 0x00074daf, 0x00074faf, 0x000751af, 0x000753af, + 0x000755af, 0x000757af, 0x000759af, 0x00075baf, + 0x00075daf, 0x00075faf, 0x000761af, 0x000763af, + 0x000765af, 0x000767af, 0x000769af, 0x00076baf, + 0x00076daf, 0x00076faf, 0x000771af, 0x000773af, + 0x000775af, 0x000777af, 0x000779af, 0x00077baf, + 0x00077daf, 0x00077faf, 0x000781af, 0x000783af, + 0x000785af, 0x000787af, 0x000789af, 0x00078baf, + 0x00078daf, 0x00078faf, 0x000791af, 0x000793af, + 0x000795af, 0x000797af, 0x000799af, 0x00079baf, + 0x00079daf, 0x00079faf, 0x0007a1af, 0x0007a3af, + 0x0007a5af, 0x0007a7af, 0x0007a9af, 0x0007abaf, + 0x0007adaf, 0x0007afaf, 0x0007b1af, 0x0007b3af, + 0x0007b5af, 0x0007b7af, 0x0007b9af, 0x0007bbaf, + 0x0007bdaf, 0x0007bfaf, 0x0007c1af, 0x0007c3af, + 0x0007c5af, 0x0007c7af, 0x0007c9af, 0x0007cbaf, + 0x0007cdaf, 0x0007cfaf, 0x0007d1af, 0x0007d3af, + 0x0007d5af, 0x0007d7af, 0x0007d9af, 0x0007dbaf, + 0x0007ddaf, 0x0007dfaf, 0x0007e1af, 0x0007e3af, + 0x0007e5af, 0x0007e7af, 0x0007e9af, 0x0007ebaf, + 0x0007edaf, 0x0007efaf, 0x0007f1af, 0x0007f3af, + 0x0007f5af, 0x0007f7af, 0x0007f9af, 0x0007fbaf, + 0x0007fdaf, 0x0007ffaf, 0x000801af, 0x000803af, + 0x000805af, 0x000807af, 0x000809af, 0x00080baf, + 0x00080daf, 0x00080faf, 0x000811af, 0x000813af, + 0x000815af, 0x000817af, 0x000819af, 0x00081baf, + 0x00081daf, 0x00081faf, 0x000821af, 0x000823af, + 0x000825af, 0x000827af, 0x000829af, 0x00082baf, + 0x00082daf, 0x00082faf, 0x000831af, 0x000833af, + 0x000835af, 0x000837af, 0x000839af, 0x00083baf, + 0x00083daf, 0x00083faf, 0x000841af, 0x000843af, + 0x000845af, 0x000847af, 0x000849af, 0x00084baf, + 0x00084daf, 0x00084faf, 0x000851af, 0x000853af, + 0x000855af, 0x000857af, 0x000859af, 0x00085baf, + 0x00085daf, 0x00085faf, 0x000861af, 0x000863af, + 0x000865af, 0x000867af, 0x000869af, 0x00086baf, + 0x00086daf, 0x00086faf, 0x000871af, 0x000873af, + 0x000875af, 0x000877af, 0x000879af, 0x00087baf, + 0x00087daf, 0x00087faf, 0x000881af, 0x000883af, + 0x000885af, 0x000887af, 0x000889af, 0x00088baf, + 0x00088daf, 0x00088faf, 0x000891af, 0x000893af, + 0x000895af, 0x000897af, 0x000899af, 0x00089baf, + 0x00089daf, 0x00089faf, 0x0008a1af, 0x0008a3af, + 0x0008a5af, 0x0008a7af, 0x0008a9af, 0x0008abaf, + 0x0008adaf, 0x0008afaf, 0x0008b1af, 0x0008b3af, + 0x0008b5af, 0x0008b7af, 0x0008b9af, 0x0008bbaf, + 0x0008bdaf, 0x0008bfaf, 0x0008c1af, 0x0008c3af, + 0x0008c5af, 0x0008c7af, 0x0008c9af, 0x0008cbaf, + 0x0008cdaf, 0x0008cfaf, 0x0008d1af, 0x0008d3af, + 0x0008d5af, 0x0008d7af, 0x0008d9af, 0x0008dbaf, + 0x0008ddaf, 0x0008dfaf, 0x0008e1af, 0x0008e3af, + 0x0008e5af, 0x0008e7af, 0x0008e9af, 0x0008ebaf, + 0x0008edaf, 0x0008efaf, 0x0008f1af, 0x0008f3af, + 0x0008f5af, 0x0008f7af, 0x0008f9af, 0x0008fbaf, + 0x0008fdaf, 0x0008ffaf, 0x000901af, 0x000903af, + 0x000905af, 0x000907af, 0x000909af, 0x00090baf, + 0x00090daf, 0x00090faf, 0x000911af, 0x000913af, + 0x000915af, 0x000917af, 0x000919af, 0x00091baf, + 0x00091daf, 0x00091faf, 0x000921af, 0x000923af, + 0x000925af, 0x000927af, 0x000929af, 0x00092baf, + 0x00092daf, 0x00092faf, 0x000931af, 0x000933af, + 0x000935af, 0x000937af, 0x000939af, 0x00093baf, + 0x00093daf, 0x00093faf, 0x000941af, 0x000943af, + 0x000945af, 0x000947af, 0x000949af, 0x00094baf, + 0x00094daf, 0x00094faf, 0x000951af, 0x000953af, + 0x000955af, 0x000957af, 0x000959af, 0x00095baf, + 0x00095daf, 0x00095faf, 0x000961af, 0x000963af, + 0x000965af, 0x000967af, 0x000969af, 0x00096baf, + 0x00096daf, 0x00096faf, 0x000971af, 0x000973af, + 0x000975af, 0x000977af, 0x000979af, 0x00097baf, + 0x00097daf, 0x00097faf, 0x000981af, 0x000983af, + 0x000985af, 0x000987af, 0x000989af, 0x00098baf, + 0x00098daf, 0x00098faf, 0x000991af, 0x000993af, + 0x000995af, 0x000997af, 0x000999af, 0x00099baf, + 0x00099daf, 0x00099faf, 0x0009a1af, 0x0009a3af, + 0x0009a5af, 0x0009a7af, 0x0009a9af, 0x0009abaf, + 0x0009adaf, 0x0009afaf, 0x0009b1af, 0x0009b3af, + 0x0009b5af, 0x0009b7af, 0x0009b9af, 0x0009bbaf, + 0x0009bdaf, 0x0009bfaf, 0x0009c1af, 0x0009c3af, + 0x0009c5af, 0x0009c7af, 0x0009c9af, 0x0009cbaf, + 0x0009cdaf, 0x0009cfaf, 0x0009d1af, 0x0009d3af, + 0x0009d5af, 0x0009d7af, 0x0009d9af, 0x0009dbaf, + 0x0009ddaf, 0x0009dfaf, 0x0009e1af, 0x0009e3af, + 0x0009e5af, 0x0009e7af, 0x0009e9af, 0x0009ebaf, + 0x0009edaf, 0x0009efaf, 0x0009f1af, 0x0009f3af, + 0x0009f5af, 0x0009f7af, 0x0009f9af, 0x0009fbaf, + 0x0009fdaf, 0x0009ffaf, 0x000a01af, 0x000a03af, + 0x000a05af, 0x000a07af, 0x000a09af, 0x000a0baf, + 0x000a0daf, 0x000a0faf, 0x000a11af, 0x000a13af, + 0x000a15af, 0x000a17af, 0x000a19af, 0x000a1baf, + 0x000a1daf, 0x000a1faf, 0x000a21af, 0x000a23af, + 0x000a25af, 0x000a27af, 0x000a29af, 0x000a2baf, + 0x000a2daf, 0x000a2faf, 0x000a31af, 0x000a33af, + 0x000a35af, 0x000a37af, 0x000a39af, 0x000a3baf, + 0x000a3daf, 0x000a3faf, 0x000a41af, 0x000a43af, + 0x000a45af, 0x000a47af, 0x000a49af, 0x000a4baf, + 0x000a4daf, 0x000a4faf, 0x000a51af, 0x000a53af, + 0x000a55af, 0x000a57af, 0x000a59af, 0x000a5baf, + 0x000a5daf, 0x000a5faf, 0x000a61af, 0x000a63af, + 0x000a65af, 0x000a67af, 0x000a69af, 0x000a6baf, + 0x000a6daf, 0x000a6faf, 0x000a71af, 0x000a73af, + 0x000a75af, 0x000a77af, 0x000a79af, 0x000a7baf, + 0x000a7daf, 0x000a7faf, 0x000a81af, 0x000a83af, + 0x000a85af, 0x000a87af, 0x000a89af, 0x000a8baf, + 0x000a8daf, 0x000a8faf, 0x000a91af, 0x000a93af, + 0x000a95af, 0x000a97af, 0x000a99af, 0x000a9baf, + 0x000a9daf, 0x000a9faf, 0x000aa1af, 0x000aa3af, + 0x000aa5af, 0x000aa7af, 0x000aa9af, 0x000aabaf, + 0x000aadaf, 0x000aafaf, 0x000ab1af, 0x000ab3af, + 0x000ab5af, 0x000ab7af, 0x000ab9af, 0x000abbaf, + 0x000abdaf, 0x000abfaf, 0x000ac1af, 0x000ac3af, + 0x000ac5af, 0x000ac7af, 0x000ac9af, 0x000acbaf, + 0x000acdaf, 0x000acfaf, 0x000ad1af, 0x000ad3af, + 0x000ad5af, 0x000ad7af, 0x000ad9af, 0x000adbaf, + 0x000addaf, 0x000adfaf, 0x000ae1af, 0x000ae3af, + 0x000ae5af, 0x000ae7af, 0x000ae9af, 0x000aebaf, + 0x000aedaf, 0x000aefaf, 0x000af1af, 0x000af3af, + 0x000af5af, 0x000af7af, 0x000af9af, 0x000afbaf, + 0x000afdaf, 0x000affaf, 0x000b01af, 0x000b03af, + 0x000b05af, 0x000b07af, 0x000b09af, 0x000b0baf, + 0x000b0daf, 0x000b0faf, 0x000b11af, 0x000b13af, + 0x000b15af, 0x000b17af, 0x000b19af, 0x000b1baf, + 0x000b1daf, 0x000b1faf, 0x000b21af, 0x000b23af, + 0x000b25af, 0x000b27af, 0x000b29af, 0x000b2baf, + 0x000b2daf, 0x000b2faf, 0x000b31af, 0x000b33af, + 0x000b35af, 0x000b37af, 0x000b39af, 0x000b3baf, + 0x000b3daf, 0x000b3faf, 0x000b41af, 0x000b43af, + 0x000b45af, 0x000b47af, 0x000b49af, 0x000b4baf, + 0x000b4daf, 0x000b4faf, 0x000b51af, 0x000b53af, + 0x000b55af, 0x000b57af, 0x000b59af, 0x000b5baf, + 0x000b5daf, 0x000b5faf, 0x000b61af, 0x000b63af, + 0x000b65af, 0x000b67af, 0x000b69af, 0x000b6baf, + 0x000b6daf, 0x000b6faf, 0x000b71af, 0x000b73af, + 0x000b75af, 0x000b77af, 0x000b79af, 0x000b7baf, + 0x000b7daf, 0x000b7faf, 0x000b81af, 0x000b83af, + 0x000b85af, 0x000b87af, 0x000b89af, 0x000b8baf, + 0x000b8daf, 0x000b8faf, 0x000b91af, 0x000b93af, + 0x000b95af, 0x000b97af, 0x000b99af, 0x000b9baf, + 0x000b9daf, 0x000b9faf, 0x000ba1af, 0x000ba3af, + 0x000ba5af, 0x000ba7af, 0x000ba9af, 0x000babaf, + 0x000badaf, 0x000bafaf, 0x000bb1af, 0x000bb3af, + 0x000bb5af, 0x000bb7af, 0x000bb9af, 0x000bbbaf, + 0x000bbdaf, 0x000bbfaf, 0x000bc1af, 0x000bc3af, + 0x000bc5af, 0x000bc7af, 0x000bc9af, 0x000bcbaf, + 0x000bcdaf, 0x000bcfaf, 0x000bd1af, 0x000bd3af, + 0x000bd5af, 0x000bd7af, 0x000bd9af, 0x000bdbaf, + 0x000bddaf, 0x000bdfaf, 0x000be1af, 0x000be3af, + 0x000be5af, 0x000be7af, 0x000be9af, 0x000bebaf, + 0x000bedaf, 0x000befaf, 0x000bf1af, 0x000bf3af, + 0x000bf5af, 0x000bf7af, 0x000bf9af, 0x000bfbaf, + 0x000bfdaf, 0x000bffaf, 0x000c01af, 0x000c03af, + 0x000c05af, 0x000c07af, 0x000c09af, 0x000c0baf, + 0x000c0daf, 0x000c0faf, 0x000c11af, 0x000c13af, + 0x000c15af, 0x000c17af, 0x000c19af, 0x000c1baf, + 0x000c1daf, 0x000c1faf, 0x000c21af, 0x000c23af, + 0x000c25af, 0x000c27af, 0x000c29af, 0x000c2baf, + 0x000c2daf, 0x000c2faf, 0x000c31af, 0x000c33af, + 0x000c35af, 0x000c37af, 0x000c39af, 0x000c3baf, + 0x000c3daf, 0x000c3faf, 0x000c41af, 0x000c43af, + 0x000c45af, 0x000c47af, 0x000c49af, 0x000c4baf, + 0x000c4daf, 0x000c4faf, 0x000c51af, 0x000c53af, + 0x000c55af, 0x000c57af, 0x000c59af, 0x000c5baf, + 0x000c5daf, 0x000c5faf, 0x000c61af, 0x000c63af, + 0x000c65af, 0x000c67af, 0x000c69af, 0x000c6baf, + 0x000c6daf, 0x000c6faf, 0x000c71af, 0x000c73af, + 0x000c75af, 0x000c77af, 0x000c79af, 0x000c7baf, + 0x000c7daf, 0x000c7faf, 0x000c81af, 0x000c83af, + 0x000c85af, 0x000c87af, 0x000c89af, 0x000c8baf, + 0x000c8daf, 0x000c8faf, 0x000c91af, 0x000c93af, + 0x000c95af, 0x000c97af, 0x000c99af, 0x000c9baf, + 0x000c9daf, 0x000c9faf, 0x000ca1af, 0x000ca3af, + 0x000ca5af, 0x000ca7af, 0x000ca9af, 0x000cabaf, + 0x000cadaf, 0x000cafaf, 0x000cb1af, 0x000cb3af, + 0x000cb5af, 0x000cb7af, 0x000cb9af, 0x000cbbaf, + 0x000cbdaf, 0x000cbfaf, 0x000cc1af, 0x000cc3af, + 0x000cc5af, 0x000cc7af, 0x000cc9af, 0x000ccbaf, + 0x000ccdaf, 0x000ccfaf, 0x000cd1af, 0x000cd3af, + 0x000cd5af, 0x000cd7af, 0x000cd9af, 0x000cdbaf, + 0x000cddaf, 0x000cdfaf, 0x000ce1af, 0x000ce3af, + 0x000ce5af, 0x000ce7af, 0x000ce9af, 0x000cebaf, + 0x000cedaf, 0x000cefaf, 0x000cf1af, 0x000cf3af, + 0x000cf5af, 0x000cf7af, 0x000cf9af, 0x000cfbaf, + 0x000cfdaf, 0x000cffaf, 0x000d01af, 0x000d03af, + 0x000d05af, 0x000d07af, 0x000d09af, 0x000d0baf, + 0x000d0daf, 0x000d0faf, 0x000d11af, 0x000d13af, + 0x000d15af, 0x000d17af, 0x000d19af, 0x000d1baf, + 0x000d1daf, 0x000d1faf, 0x000d21af, 0x000d23af, + 0x000d25af, 0x000d27af, 0x000d29af, 0x000d2baf, + 0x000d2daf, 0x000d2faf, 0x000d31af, 0x000d33af, + 0x000d35af, 0x000d37af, 0x000d39af, 0x000d3baf, + 0x000d3daf, 0x000d3faf, 0x000d41af, 0x000d43af, + 0x000d45af, 0x000d47af, 0x000d49af, 0x000d4baf, + 0x000d4daf, 0x000d4faf, 0x000d51af, 0x000d53af, + 0x000d55af, 0x000d57af, 0x000d59af, 0x000d5baf, + 0x000d5daf, 0x000d5faf, 0x000d61af, 0x000d63af, + 0x000d65af, 0x000d67af, 0x000d69af, 0x000d6baf, + 0x000d6daf, 0x000d6faf, 0x000d71af, 0x000d73af, + 0x000d75af, 0x000d77af, 0x000d79af, 0x000d7baf, + 0x000d7daf, 0x000d7faf, 0x000d81af, 0x000d83af, + 0x000d85af, 0x000d87af, 0x000d89af, 0x000d8baf, + 0x000d8daf, 0x000d8faf, 0x000d91af, 0x000d93af, + 0x000d95af, 0x000d97af, 0x000d99af, 0x000d9baf, + 0x000d9daf, 0x000d9faf, 0x000da1af, 0x000da3af, + 0x000da5af, 0x000da7af, 0x000da9af, 0x000dabaf, + 0x000dadaf, 0x000dafaf, 0x000db1af, 0x000db3af, + 0x000db5af, 0x000db7af, 0x000db9af, 0x000dbbaf, + 0x000dbdaf, 0x000dbfaf, 0x000dc1af, 0x000dc3af, + 0x000dc5af, 0x000dc7af, 0x000dc9af, 0x000dcbaf, + 0x000dcdaf, 0x000dcfaf, 0x000dd1af, 0x000dd3af, + 0x000dd5af, 0x000dd7af, 0x000dd9af, 0x000ddbaf, + 0x000dddaf, 0x000ddfaf, 0x000de1af, 0x000de3af, + 0x000de5af, 0x000de7af, 0x000de9af, 0x000debaf, + 0x000dedaf, 0x000defaf, 0x000df1af, 0x000df3af, + 0x000df5af, 0x000df7af, 0x000df9af, 0x000dfbaf, + 0x000dfdaf, 0x000dffaf, 0x000e01af, 0x000e03af, + 0x000e05af, 0x000e07af, 0x000e09af, 0x000e0baf, + 0x000e0daf, 0x000e0faf, 0x000e11af, 0x000e13af, + 0x000e15af, 0x000e17af, 0x000e19af, 0x000e1baf, + 0x000e1daf, 0x000e1faf, 0x000e21af, 0x000e23af, + 0x000e25af, 0x000e27af, 0x000e29af, 0x000e2baf, + 0x000e2daf, 0x000e2faf, 0x000e31af, 0x000e33af, + 0x000e35af, 0x000e37af, 0x000e39af, 0x000e3baf, + 0x000e3daf, 0x000e3faf, 0x000e41af, 0x000e43af, + 0x000e45af, 0x000e47af, 0x000e49af, 0x000e4baf, + 0x000e4daf, 0x000e4faf, 0x000e51af, 0x000e53af, + 0x000e55af, 0x000e57af, 0x000e59af, 0x000e5baf, + 0x000e5daf, 0x000e5faf, 0x000e61af, 0x000e63af, + 0x000e65af, 0x000e67af, 0x000e69af, 0x000e6baf, + 0x000e6daf, 0x000e6faf, 0x000e71af, 0x000e73af, + 0x000e75af, 0x000e77af, 0x000e79af, 0x000e7baf, + 0x000e7daf, 0x000e7faf, 0x000e81af, 0x000e83af, + 0x000e85af, 0x000e87af, 0x000e89af, 0x000e8baf, + 0x000e8daf, 0x000e8faf, 0x000e91af, 0x000e93af, + 0x000e95af, 0x000e97af, 0x000e99af, 0x000e9baf, + 0x000e9daf, 0x000e9faf, 0x000ea1af, 0x000ea3af, + 0x000ea5af, 0x000ea7af, 0x000ea9af, 0x000eabaf, + 0x000eadaf, 0x000eafaf, 0x000eb1af, 0x000eb3af, + 0x000eb5af, 0x000eb7af, 0x000eb9af, 0x000ebbaf, + 0x000ebdaf, 0x000ebfaf, 0x000ec1af, 0x000ec3af, + 0x000ec5af, 0x000ec7af, 0x000ec9af, 0x000ecbaf, + 0x000ecdaf, 0x000ecfaf, 0x000ed1af, 0x000ed3af, + 0x000ed5af, 0x000ed7af, 0x000ed9af, 0x000edbaf, + 0x000eddaf, 0x000edfaf, 0x000ee1af, 0x000ee3af, + 0x000ee5af, 0x000ee7af, 0x000ee9af, 0x000eebaf, + 0x000eedaf, 0x000eefaf, 0x000ef1af, 0x000ef3af, + 0x000ef5af, 0x000ef7af, 0x000ef9af, 0x000efbaf, + 0x000efdaf, 0x000effaf, 0x000f01af, 0x000f03af, + 0x000f05af, 0x000f07af, 0x000f09af, 0x000f0baf, + 0x000f0daf, 0x000f0faf, 0x000f11af, 0x000f13af, + 0x000f15af, 0x000f17af, 0x000f19af, 0x000f1baf, + 0x000f1daf, 0x000f1faf, 0x000f21af, 0x000f23af, + 0x000f25af, 0x000f27af, 0x000f29af, 0x000f2baf, + 0x000f2daf, 0x000f2faf, 0x000f31af, 0x000f33af, + 0x000f35af, 0x000f37af, 0x000f39af, 0x000f3baf, + 0x000f3daf, 0x000f3faf, 0x000f41af, 0x000f43af, + 0x000f45af, 0x000f47af, 0x000f49af, 0x000f4baf, + 0x000f4daf, 0x000f4faf, 0x000f51af, 0x000f53af, + 0x000f55af, 0x000f57af, 0x000f59af, 0x000f5baf, + 0x000f5daf, 0x000f5faf, 0x000f61af, 0x000f63af, + 0x000f65af, 0x000f67af, 0x000f69af, 0x000f6baf, + 0x000f6daf, 0x000f6faf, 0x000f71af, 0x000f73af, + 0x000f75af, 0x000f77af, 0x000f79af, 0x000f7baf, + 0x000f7daf, 0x000f7faf, 0x000f81af, 0x000f83af, + 0x000f85af, 0x000f87af, 0x000f89af, 0x000f8baf, + 0x000f8daf, 0x000f8faf, 0x000f91af, 0x000f93af, + 0x000f95af, 0x000f97af, 0x000f99af, 0x000f9baf, + 0x000f9daf, 0x000f9faf, 0x000fa1af, 0x000fa3af, + 0x000fa5af, 0x000fa7af, 0x000fa9af, 0x000fabaf, + 0x000fadaf, 0x000fafaf, 0x000fb1af, 0x000fb3af, + 0x000fb5af, 0x000fb7af, 0x000fb9af, 0x000fbbaf, + 0x000fbdaf, 0x000fbfaf, 0x000fc1af, 0x000fc3af, + 0x000fc5af, 0x000fc7af, 0x000fc9af, 0x000fcbaf, + 0x000fcdaf, 0x000fcfaf, 0x000fd1af, 0x000fd3af, + 0x000fd5af, 0x000fd7af, 0x000fd9af, 0x000fdbaf, + 0x000fddaf, 0x000fdfaf, 0x000fe1af, 0x000fe3af, + 0x000fe5af, 0x000fe7af, 0x000fe9af, 0x000febaf, + 0x000fedaf, 0x000fefaf, 0x000ff1af, 0x000ff3af, + 0x000ff5af, 0x000ff7af, 0x000ff9af, 0x000ffbaf, + 0x000ffdaf, 0x000fffaf, 0x0000006f, 0x0000026f, + 0x0000046f, 0x0000066f, 0x0000086f, 0x00000a6f, + 0x00000c6f, 0x00000e6f, 0x0000106f, 0x0000126f, + 0x0000146f, 0x0000166f, 0x0000186f, 0x00001a6f, + 0x00001c6f, 0x00001e6f, 0x0000206f, 0x0000226f, + 0x0000246f, 0x0000266f, 0x0000286f, 0x00002a6f, + 0x00002c6f, 0x00002e6f, 0x0000306f, 0x0000326f, + 0x0000346f, 0x0000366f, 0x0000386f, 0x00003a6f, + 0x00003c6f, 0x00003e6f, 0x0000406f, 0x0000426f, + 0x0000446f, 0x0000466f, 0x0000486f, 0x00004a6f, + 0x00004c6f, 0x00004e6f, 0x0000506f, 0x0000526f, + 0x0000546f, 0x0000566f, 0x0000586f, 0x00005a6f, + 0x00005c6f, 0x00005e6f, 0x0000606f, 0x0000626f, + 0x0000646f, 0x0000666f, 0x0000686f, 0x00006a6f, + 0x00006c6f, 0x00006e6f, 0x0000706f, 0x0000726f, + 0x0000746f, 0x0000766f, 0x0000786f, 0x00007a6f, + 0x00007c6f, 0x00007e6f, 0x0000806f, 0x0000826f, + 0x0000846f, 0x0000866f, 0x0000886f, 0x00008a6f, + 0x00008c6f, 0x00008e6f, 0x0000906f, 0x0000926f, + 0x0000946f, 0x0000966f, 0x0000986f, 0x00009a6f, + 0x00009c6f, 0x00009e6f, 0x0000a06f, 0x0000a26f, + 0x0000a46f, 0x0000a66f, 0x0000a86f, 0x0000aa6f, + 0x0000ac6f, 0x0000ae6f, 0x0000b06f, 0x0000b26f, + 0x0000b46f, 0x0000b66f, 0x0000b86f, 0x0000ba6f, + 0x0000bc6f, 0x0000be6f, 0x0000c06f, 0x0000c26f, + 0x0000c46f, 0x0000c66f, 0x0000c86f, 0x0000ca6f, + 0x0000cc6f, 0x0000ce6f, 0x0000d06f, 0x0000d26f, + 0x0000d46f, 0x0000d66f, 0x0000d86f, 0x0000da6f, + 0x0000dc6f, 0x0000de6f, 0x0000e06f, 0x0000e26f, + 0x0000e46f, 0x0000e66f, 0x0000e86f, 0x0000ea6f, + 0x0000ec6f, 0x0000ee6f, 0x0000f06f, 0x0000f26f, + 0x0000f46f, 0x0000f66f, 0x0000f86f, 0x0000fa6f, + 0x0000fc6f, 0x0000fe6f, 0x0001006f, 0x0001026f, + 0x0001046f, 0x0001066f, 0x0001086f, 0x00010a6f, + 0x00010c6f, 0x00010e6f, 0x0001106f, 0x0001126f, + 0x0001146f, 0x0001166f, 0x0001186f, 0x00011a6f, + 0x00011c6f, 0x00011e6f, 0x0001206f, 0x0001226f, + 0x0001246f, 0x0001266f, 0x0001286f, 0x00012a6f, + 0x00012c6f, 0x00012e6f, 0x0001306f, 0x0001326f, + 0x0001346f, 0x0001366f, 0x0001386f, 0x00013a6f, + 0x00013c6f, 0x00013e6f, 0x0001406f, 0x0001426f, + 0x0001446f, 0x0001466f, 0x0001486f, 0x00014a6f, + 0x00014c6f, 0x00014e6f, 0x0001506f, 0x0001526f, + 0x0001546f, 0x0001566f, 0x0001586f, 0x00015a6f, + 0x00015c6f, 0x00015e6f, 0x0001606f, 0x0001626f, + 0x0001646f, 0x0001666f, 0x0001686f, 0x00016a6f, + 0x00016c6f, 0x00016e6f, 0x0001706f, 0x0001726f, + 0x0001746f, 0x0001766f, 0x0001786f, 0x00017a6f, + 0x00017c6f, 0x00017e6f, 0x0001806f, 0x0001826f, + 0x0001846f, 0x0001866f, 0x0001886f, 0x00018a6f, + 0x00018c6f, 0x00018e6f, 0x0001906f, 0x0001926f, + 0x0001946f, 0x0001966f, 0x0001986f, 0x00019a6f, + 0x00019c6f, 0x00019e6f, 0x0001a06f, 0x0001a26f, + 0x0001a46f, 0x0001a66f, 0x0001a86f, 0x0001aa6f, + 0x0001ac6f, 0x0001ae6f, 0x0001b06f, 0x0001b26f, + 0x0001b46f, 0x0001b66f, 0x0001b86f, 0x0001ba6f, + 0x0001bc6f, 0x0001be6f, 0x0001c06f, 0x0001c26f, + 0x0001c46f, 0x0001c66f, 0x0001c86f, 0x0001ca6f, + 0x0001cc6f, 0x0001ce6f, 0x0001d06f, 0x0001d26f, + 0x0001d46f, 0x0001d66f, 0x0001d86f, 0x0001da6f, + 0x0001dc6f, 0x0001de6f, 0x0001e06f, 0x0001e26f, + 0x0001e46f, 0x0001e66f, 0x0001e86f, 0x0001ea6f, + 0x0001ec6f, 0x0001ee6f, 0x0001f06f, 0x0001f26f, + 0x0001f46f, 0x0001f66f, 0x0001f86f, 0x0001fa6f, + 0x0001fc6f, 0x0001fe6f, 0x0002006f, 0x0002026f, + 0x0002046f, 0x0002066f, 0x0002086f, 0x00020a6f, + 0x00020c6f, 0x00020e6f, 0x0002106f, 0x0002126f, + 0x0002146f, 0x0002166f, 0x0002186f, 0x00021a6f, + 0x00021c6f, 0x00021e6f, 0x0002206f, 0x0002226f, + 0x0002246f, 0x0002266f, 0x0002286f, 0x00022a6f, + 0x00022c6f, 0x00022e6f, 0x0002306f, 0x0002326f, + 0x0002346f, 0x0002366f, 0x0002386f, 0x00023a6f, + 0x00023c6f, 0x00023e6f, 0x0002406f, 0x0002426f, + 0x0002446f, 0x0002466f, 0x0002486f, 0x00024a6f, + 0x00024c6f, 0x00024e6f, 0x0002506f, 0x0002526f, + 0x0002546f, 0x0002566f, 0x0002586f, 0x00025a6f, + 0x00025c6f, 0x00025e6f, 0x0002606f, 0x0002626f, + 0x0002646f, 0x0002666f, 0x0002686f, 0x00026a6f, + 0x00026c6f, 0x00026e6f, 0x0002706f, 0x0002726f, + 0x0002746f, 0x0002766f, 0x0002786f, 0x00027a6f, + 0x00027c6f, 0x00027e6f, 0x0002806f, 0x0002826f, + 0x0002846f, 0x0002866f, 0x0002886f, 0x00028a6f, + 0x00028c6f, 0x00028e6f, 0x0002906f, 0x0002926f, + 0x0002946f, 0x0002966f, 0x0002986f, 0x00029a6f, + 0x00029c6f, 0x00029e6f, 0x0002a06f, 0x0002a26f, + 0x0002a46f, 0x0002a66f, 0x0002a86f, 0x0002aa6f, + 0x0002ac6f, 0x0002ae6f, 0x0002b06f, 0x0002b26f, + 0x0002b46f, 0x0002b66f, 0x0002b86f, 0x0002ba6f, + 0x0002bc6f, 0x0002be6f, 0x0002c06f, 0x0002c26f, + 0x0002c46f, 0x0002c66f, 0x0002c86f, 0x0002ca6f, + 0x0002cc6f, 0x0002ce6f, 0x0002d06f, 0x0002d26f, + 0x0002d46f, 0x0002d66f, 0x0002d86f, 0x0002da6f, + 0x0002dc6f, 0x0002de6f, 0x0002e06f, 0x0002e26f, + 0x0002e46f, 0x0002e66f, 0x0002e86f, 0x0002ea6f, + 0x0002ec6f, 0x0002ee6f, 0x0002f06f, 0x0002f26f, + 0x0002f46f, 0x0002f66f, 0x0002f86f, 0x0002fa6f, + 0x0002fc6f, 0x0002fe6f, 0x0003006f, 0x0003026f, + 0x0003046f, 0x0003066f, 0x0003086f, 0x00030a6f, + 0x00030c6f, 0x00030e6f, 0x0003106f, 0x0003126f, + 0x0003146f, 0x0003166f, 0x0003186f, 0x00031a6f, + 0x00031c6f, 0x00031e6f, 0x0003206f, 0x0003226f, + 0x0003246f, 0x0003266f, 0x0003286f, 0x00032a6f, + 0x00032c6f, 0x00032e6f, 0x0003306f, 0x0003326f, + 0x0003346f, 0x0003366f, 0x0003386f, 0x00033a6f, + 0x00033c6f, 0x00033e6f, 0x0003406f, 0x0003426f, + 0x0003446f, 0x0003466f, 0x0003486f, 0x00034a6f, + 0x00034c6f, 0x00034e6f, 0x0003506f, 0x0003526f, + 0x0003546f, 0x0003566f, 0x0003586f, 0x00035a6f, + 0x00035c6f, 0x00035e6f, 0x0003606f, 0x0003626f, + 0x0003646f, 0x0003666f, 0x0003686f, 0x00036a6f, + 0x00036c6f, 0x00036e6f, 0x0003706f, 0x0003726f, + 0x0003746f, 0x0003766f, 0x0003786f, 0x00037a6f, + 0x00037c6f, 0x00037e6f, 0x0003806f, 0x0003826f, + 0x0003846f, 0x0003866f, 0x0003886f, 0x00038a6f, + 0x00038c6f, 0x00038e6f, 0x0003906f, 0x0003926f, + 0x0003946f, 0x0003966f, 0x0003986f, 0x00039a6f, + 0x00039c6f, 0x00039e6f, 0x0003a06f, 0x0003a26f, + 0x0003a46f, 0x0003a66f, 0x0003a86f, 0x0003aa6f, + 0x0003ac6f, 0x0003ae6f, 0x0003b06f, 0x0003b26f, + 0x0003b46f, 0x0003b66f, 0x0003b86f, 0x0003ba6f, + 0x0003bc6f, 0x0003be6f, 0x0003c06f, 0x0003c26f, + 0x0003c46f, 0x0003c66f, 0x0003c86f, 0x0003ca6f, + 0x0003cc6f, 0x0003ce6f, 0x0003d06f, 0x0003d26f, + 0x0003d46f, 0x0003d66f, 0x0003d86f, 0x0003da6f, + 0x0003dc6f, 0x0003de6f, 0x0003e06f, 0x0003e26f, + 0x0003e46f, 0x0003e66f, 0x0003e86f, 0x0003ea6f, + 0x0003ec6f, 0x0003ee6f, 0x0003f06f, 0x0003f26f, + 0x0003f46f, 0x0003f66f, 0x0003f86f, 0x0003fa6f, + 0x0003fc6f, 0x0003fe6f, 0x0004006f, 0x0004026f, + 0x0004046f, 0x0004066f, 0x0004086f, 0x00040a6f, + 0x00040c6f, 0x00040e6f, 0x0004106f, 0x0004126f, + 0x0004146f, 0x0004166f, 0x0004186f, 0x00041a6f, + 0x00041c6f, 0x00041e6f, 0x0004206f, 0x0004226f, + 0x0004246f, 0x0004266f, 0x0004286f, 0x00042a6f, + 0x00042c6f, 0x00042e6f, 0x0004306f, 0x0004326f, + 0x0004346f, 0x0004366f, 0x0004386f, 0x00043a6f, + 0x00043c6f, 0x00043e6f, 0x0004406f, 0x0004426f, + 0x0004446f, 0x0004466f, 0x0004486f, 0x00044a6f, + 0x00044c6f, 0x00044e6f, 0x0004506f, 0x0004526f, + 0x0004546f, 0x0004566f, 0x0004586f, 0x00045a6f, + 0x00045c6f, 0x00045e6f, 0x0004606f, 0x0004626f, + 0x0004646f, 0x0004666f, 0x0004686f, 0x00046a6f, + 0x00046c6f, 0x00046e6f, 0x0004706f, 0x0004726f, + 0x0004746f, 0x0004766f, 0x0004786f, 0x00047a6f, + 0x00047c6f, 0x00047e6f, 0x0004806f, 0x0004826f, + 0x0004846f, 0x0004866f, 0x0004886f, 0x00048a6f, + 0x00048c6f, 0x00048e6f, 0x0004906f, 0x0004926f, + 0x0004946f, 0x0004966f, 0x0004986f, 0x00049a6f, + 0x00049c6f, 0x00049e6f, 0x0004a06f, 0x0004a26f, + 0x0004a46f, 0x0004a66f, 0x0004a86f, 0x0004aa6f, + 0x0004ac6f, 0x0004ae6f, 0x0004b06f, 0x0004b26f, + 0x0004b46f, 0x0004b66f, 0x0004b86f, 0x0004ba6f, + 0x0004bc6f, 0x0004be6f, 0x0004c06f, 0x0004c26f, + 0x0004c46f, 0x0004c66f, 0x0004c86f, 0x0004ca6f, + 0x0004cc6f, 0x0004ce6f, 0x0004d06f, 0x0004d26f, + 0x0004d46f, 0x0004d66f, 0x0004d86f, 0x0004da6f, + 0x0004dc6f, 0x0004de6f, 0x0004e06f, 0x0004e26f, + 0x0004e46f, 0x0004e66f, 0x0004e86f, 0x0004ea6f, + 0x0004ec6f, 0x0004ee6f, 0x0004f06f, 0x0004f26f, + 0x0004f46f, 0x0004f66f, 0x0004f86f, 0x0004fa6f, + 0x0004fc6f, 0x0004fe6f, 0x0005006f, 0x0005026f, + 0x0005046f, 0x0005066f, 0x0005086f, 0x00050a6f, + 0x00050c6f, 0x00050e6f, 0x0005106f, 0x0005126f, + 0x0005146f, 0x0005166f, 0x0005186f, 0x00051a6f, + 0x00051c6f, 0x00051e6f, 0x0005206f, 0x0005226f, + 0x0005246f, 0x0005266f, 0x0005286f, 0x00052a6f, + 0x00052c6f, 0x00052e6f, 0x0005306f, 0x0005326f, + 0x0005346f, 0x0005366f, 0x0005386f, 0x00053a6f, + 0x00053c6f, 0x00053e6f, 0x0005406f, 0x0005426f, + 0x0005446f, 0x0005466f, 0x0005486f, 0x00054a6f, + 0x00054c6f, 0x00054e6f, 0x0005506f, 0x0005526f, + 0x0005546f, 0x0005566f, 0x0005586f, 0x00055a6f, + 0x00055c6f, 0x00055e6f, 0x0005606f, 0x0005626f, + 0x0005646f, 0x0005666f, 0x0005686f, 0x00056a6f, + 0x00056c6f, 0x00056e6f, 0x0005706f, 0x0005726f, + 0x0005746f, 0x0005766f, 0x0005786f, 0x00057a6f, + 0x00057c6f, 0x00057e6f, 0x0005806f, 0x0005826f, + 0x0005846f, 0x0005866f, 0x0005886f, 0x00058a6f, + 0x00058c6f, 0x00058e6f, 0x0005906f, 0x0005926f, + 0x0005946f, 0x0005966f, 0x0005986f, 0x00059a6f, + 0x00059c6f, 0x00059e6f, 0x0005a06f, 0x0005a26f, + 0x0005a46f, 0x0005a66f, 0x0005a86f, 0x0005aa6f, + 0x0005ac6f, 0x0005ae6f, 0x0005b06f, 0x0005b26f, + 0x0005b46f, 0x0005b66f, 0x0005b86f, 0x0005ba6f, + 0x0005bc6f, 0x0005be6f, 0x0005c06f, 0x0005c26f, + 0x0005c46f, 0x0005c66f, 0x0005c86f, 0x0005ca6f, + 0x0005cc6f, 0x0005ce6f, 0x0005d06f, 0x0005d26f, + 0x0005d46f, 0x0005d66f, 0x0005d86f, 0x0005da6f, + 0x0005dc6f, 0x0005de6f, 0x0005e06f, 0x0005e26f, + 0x0005e46f, 0x0005e66f, 0x0005e86f, 0x0005ea6f, + 0x0005ec6f, 0x0005ee6f, 0x0005f06f, 0x0005f26f, + 0x0005f46f, 0x0005f66f, 0x0005f86f, 0x0005fa6f, + 0x0005fc6f, 0x0005fe6f, 0x0006006f, 0x0006026f, + 0x0006046f, 0x0006066f, 0x0006086f, 0x00060a6f, + 0x00060c6f, 0x00060e6f, 0x0006106f, 0x0006126f, + 0x0006146f, 0x0006166f, 0x0006186f, 0x00061a6f, + 0x00061c6f, 0x00061e6f, 0x0006206f, 0x0006226f, + 0x0006246f, 0x0006266f, 0x0006286f, 0x00062a6f, + 0x00062c6f, 0x00062e6f, 0x0006306f, 0x0006326f, + 0x0006346f, 0x0006366f, 0x0006386f, 0x00063a6f, + 0x00063c6f, 0x00063e6f, 0x0006406f, 0x0006426f, + 0x0006446f, 0x0006466f, 0x0006486f, 0x00064a6f, + 0x00064c6f, 0x00064e6f, 0x0006506f, 0x0006526f, + 0x0006546f, 0x0006566f, 0x0006586f, 0x00065a6f, + 0x00065c6f, 0x00065e6f, 0x0006606f, 0x0006626f, + 0x0006646f, 0x0006666f, 0x0006686f, 0x00066a6f, + 0x00066c6f, 0x00066e6f, 0x0006706f, 0x0006726f, + 0x0006746f, 0x0006766f, 0x0006786f, 0x00067a6f, + 0x00067c6f, 0x00067e6f, 0x0006806f, 0x0006826f, + 0x0006846f, 0x0006866f, 0x0006886f, 0x00068a6f, + 0x00068c6f, 0x00068e6f, 0x0006906f, 0x0006926f, + 0x0006946f, 0x0006966f, 0x0006986f, 0x00069a6f, + 0x00069c6f, 0x00069e6f, 0x0006a06f, 0x0006a26f, + 0x0006a46f, 0x0006a66f, 0x0006a86f, 0x0006aa6f, + 0x0006ac6f, 0x0006ae6f, 0x0006b06f, 0x0006b26f, + 0x0006b46f, 0x0006b66f, 0x0006b86f, 0x0006ba6f, + 0x0006bc6f, 0x0006be6f, 0x0006c06f, 0x0006c26f, + 0x0006c46f, 0x0006c66f, 0x0006c86f, 0x0006ca6f, + 0x0006cc6f, 0x0006ce6f, 0x0006d06f, 0x0006d26f, + 0x0006d46f, 0x0006d66f, 0x0006d86f, 0x0006da6f, + 0x0006dc6f, 0x0006de6f, 0x0006e06f, 0x0006e26f, + 0x0006e46f, 0x0006e66f, 0x0006e86f, 0x0006ea6f, + 0x0006ec6f, 0x0006ee6f, 0x0006f06f, 0x0006f26f, + 0x0006f46f, 0x0006f66f, 0x0006f86f, 0x0006fa6f, + 0x0006fc6f, 0x0006fe6f, 0x0007006f, 0x0007026f, + 0x0007046f, 0x0007066f, 0x0007086f, 0x00070a6f, + 0x00070c6f, 0x00070e6f, 0x0007106f, 0x0007126f, + 0x0007146f, 0x0007166f, 0x0007186f, 0x00071a6f, + 0x00071c6f, 0x00071e6f, 0x0007206f, 0x0007226f, + 0x0007246f, 0x0007266f, 0x0007286f, 0x00072a6f, + 0x00072c6f, 0x00072e6f, 0x0007306f, 0x0007326f, + 0x0007346f, 0x0007366f, 0x0007386f, 0x00073a6f, + 0x00073c6f, 0x00073e6f, 0x0007406f, 0x0007426f, + 0x0007446f, 0x0007466f, 0x0007486f, 0x00074a6f, + 0x00074c6f, 0x00074e6f, 0x0007506f, 0x0007526f, + 0x0007546f, 0x0007566f, 0x0007586f, 0x00075a6f, + 0x00075c6f, 0x00075e6f, 0x0007606f, 0x0007626f, + 0x0007646f, 0x0007666f, 0x0007686f, 0x00076a6f, + 0x00076c6f, 0x00076e6f, 0x0007706f, 0x0007726f, + 0x0007746f, 0x0007766f, 0x0007786f, 0x00077a6f, + 0x00077c6f, 0x00077e6f, 0x0007806f, 0x0007826f, + 0x0007846f, 0x0007866f, 0x0007886f, 0x00078a6f, + 0x00078c6f, 0x00078e6f, 0x0007906f, 0x0007926f, + 0x0007946f, 0x0007966f, 0x0007986f, 0x00079a6f, + 0x00079c6f, 0x00079e6f, 0x0007a06f, 0x0007a26f, + 0x0007a46f, 0x0007a66f, 0x0007a86f, 0x0007aa6f, + 0x0007ac6f, 0x0007ae6f, 0x0007b06f, 0x0007b26f, + 0x0007b46f, 0x0007b66f, 0x0007b86f, 0x0007ba6f, + 0x0007bc6f, 0x0007be6f, 0x0007c06f, 0x0007c26f, + 0x0007c46f, 0x0007c66f, 0x0007c86f, 0x0007ca6f, + 0x0007cc6f, 0x0007ce6f, 0x0007d06f, 0x0007d26f, + 0x0007d46f, 0x0007d66f, 0x0007d86f, 0x0007da6f, + 0x0007dc6f, 0x0007de6f, 0x0007e06f, 0x0007e26f, + 0x0007e46f, 0x0007e66f, 0x0007e86f, 0x0007ea6f, + 0x0007ec6f, 0x0007ee6f, 0x0007f06f, 0x0007f26f, + 0x0007f46f, 0x0007f66f, 0x0007f86f, 0x0007fa6f, + 0x0007fc6f, 0x0007fe6f, 0x0008006f, 0x0008026f, + 0x0008046f, 0x0008066f, 0x0008086f, 0x00080a6f, + 0x00080c6f, 0x00080e6f, 0x0008106f, 0x0008126f, + 0x0008146f, 0x0008166f, 0x0008186f, 0x00081a6f, + 0x00081c6f, 0x00081e6f, 0x0008206f, 0x0008226f, + 0x0008246f, 0x0008266f, 0x0008286f, 0x00082a6f, + 0x00082c6f, 0x00082e6f, 0x0008306f, 0x0008326f, + 0x0008346f, 0x0008366f, 0x0008386f, 0x00083a6f, + 0x00083c6f, 0x00083e6f, 0x0008406f, 0x0008426f, + 0x0008446f, 0x0008466f, 0x0008486f, 0x00084a6f, + 0x00084c6f, 0x00084e6f, 0x0008506f, 0x0008526f, + 0x0008546f, 0x0008566f, 0x0008586f, 0x00085a6f, + 0x00085c6f, 0x00085e6f, 0x0008606f, 0x0008626f, + 0x0008646f, 0x0008666f, 0x0008686f, 0x00086a6f, + 0x00086c6f, 0x00086e6f, 0x0008706f, 0x0008726f, + 0x0008746f, 0x0008766f, 0x0008786f, 0x00087a6f, + 0x00087c6f, 0x00087e6f, 0x0008806f, 0x0008826f, + 0x0008846f, 0x0008866f, 0x0008886f, 0x00088a6f, + 0x00088c6f, 0x00088e6f, 0x0008906f, 0x0008926f, + 0x0008946f, 0x0008966f, 0x0008986f, 0x00089a6f, + 0x00089c6f, 0x00089e6f, 0x0008a06f, 0x0008a26f, + 0x0008a46f, 0x0008a66f, 0x0008a86f, 0x0008aa6f, + 0x0008ac6f, 0x0008ae6f, 0x0008b06f, 0x0008b26f, + 0x0008b46f, 0x0008b66f, 0x0008b86f, 0x0008ba6f, + 0x0008bc6f, 0x0008be6f, 0x0008c06f, 0x0008c26f, + 0x0008c46f, 0x0008c66f, 0x0008c86f, 0x0008ca6f, + 0x0008cc6f, 0x0008ce6f, 0x0008d06f, 0x0008d26f, + 0x0008d46f, 0x0008d66f, 0x0008d86f, 0x0008da6f, + 0x0008dc6f, 0x0008de6f, 0x0008e06f, 0x0008e26f, + 0x0008e46f, 0x0008e66f, 0x0008e86f, 0x0008ea6f, + 0x0008ec6f, 0x0008ee6f, 0x0008f06f, 0x0008f26f, + 0x0008f46f, 0x0008f66f, 0x0008f86f, 0x0008fa6f, + 0x0008fc6f, 0x0008fe6f, 0x0009006f, 0x0009026f, + 0x0009046f, 0x0009066f, 0x0009086f, 0x00090a6f, + 0x00090c6f, 0x00090e6f, 0x0009106f, 0x0009126f, + 0x0009146f, 0x0009166f, 0x0009186f, 0x00091a6f, + 0x00091c6f, 0x00091e6f, 0x0009206f, 0x0009226f, + 0x0009246f, 0x0009266f, 0x0009286f, 0x00092a6f, + 0x00092c6f, 0x00092e6f, 0x0009306f, 0x0009326f, + 0x0009346f, 0x0009366f, 0x0009386f, 0x00093a6f, + 0x00093c6f, 0x00093e6f, 0x0009406f, 0x0009426f, + 0x0009446f, 0x0009466f, 0x0009486f, 0x00094a6f, + 0x00094c6f, 0x00094e6f, 0x0009506f, 0x0009526f, + 0x0009546f, 0x0009566f, 0x0009586f, 0x00095a6f, + 0x00095c6f, 0x00095e6f, 0x0009606f, 0x0009626f, + 0x0009646f, 0x0009666f, 0x0009686f, 0x00096a6f, + 0x00096c6f, 0x00096e6f, 0x0009706f, 0x0009726f, + 0x0009746f, 0x0009766f, 0x0009786f, 0x00097a6f, + 0x00097c6f, 0x00097e6f, 0x0009806f, 0x0009826f, + 0x0009846f, 0x0009866f, 0x0009886f, 0x00098a6f, + 0x00098c6f, 0x00098e6f, 0x0009906f, 0x0009926f, + 0x0009946f, 0x0009966f, 0x0009986f, 0x00099a6f, + 0x00099c6f, 0x00099e6f, 0x0009a06f, 0x0009a26f, + 0x0009a46f, 0x0009a66f, 0x0009a86f, 0x0009aa6f, + 0x0009ac6f, 0x0009ae6f, 0x0009b06f, 0x0009b26f, + 0x0009b46f, 0x0009b66f, 0x0009b86f, 0x0009ba6f, + 0x0009bc6f, 0x0009be6f, 0x0009c06f, 0x0009c26f, + 0x0009c46f, 0x0009c66f, 0x0009c86f, 0x0009ca6f, + 0x0009cc6f, 0x0009ce6f, 0x0009d06f, 0x0009d26f, + 0x0009d46f, 0x0009d66f, 0x0009d86f, 0x0009da6f, + 0x0009dc6f, 0x0009de6f, 0x0009e06f, 0x0009e26f, + 0x0009e46f, 0x0009e66f, 0x0009e86f, 0x0009ea6f, + 0x0009ec6f, 0x0009ee6f, 0x0009f06f, 0x0009f26f, + 0x0009f46f, 0x0009f66f, 0x0009f86f, 0x0009fa6f, + 0x0009fc6f, 0x0009fe6f, 0x000a006f, 0x000a026f, + 0x000a046f, 0x000a066f, 0x000a086f, 0x000a0a6f, + 0x000a0c6f, 0x000a0e6f, 0x000a106f, 0x000a126f, + 0x000a146f, 0x000a166f, 0x000a186f, 0x000a1a6f, + 0x000a1c6f, 0x000a1e6f, 0x000a206f, 0x000a226f, + 0x000a246f, 0x000a266f, 0x000a286f, 0x000a2a6f, + 0x000a2c6f, 0x000a2e6f, 0x000a306f, 0x000a326f, + 0x000a346f, 0x000a366f, 0x000a386f, 0x000a3a6f, + 0x000a3c6f, 0x000a3e6f, 0x000a406f, 0x000a426f, + 0x000a446f, 0x000a466f, 0x000a486f, 0x000a4a6f, + 0x000a4c6f, 0x000a4e6f, 0x000a506f, 0x000a526f, + 0x000a546f, 0x000a566f, 0x000a586f, 0x000a5a6f, + 0x000a5c6f, 0x000a5e6f, 0x000a606f, 0x000a626f, + 0x000a646f, 0x000a666f, 0x000a686f, 0x000a6a6f, + 0x000a6c6f, 0x000a6e6f, 0x000a706f, 0x000a726f, + 0x000a746f, 0x000a766f, 0x000a786f, 0x000a7a6f, + 0x000a7c6f, 0x000a7e6f, 0x000a806f, 0x000a826f, + 0x000a846f, 0x000a866f, 0x000a886f, 0x000a8a6f, + 0x000a8c6f, 0x000a8e6f, 0x000a906f, 0x000a926f, + 0x000a946f, 0x000a966f, 0x000a986f, 0x000a9a6f, + 0x000a9c6f, 0x000a9e6f, 0x000aa06f, 0x000aa26f, + 0x000aa46f, 0x000aa66f, 0x000aa86f, 0x000aaa6f, + 0x000aac6f, 0x000aae6f, 0x000ab06f, 0x000ab26f, + 0x000ab46f, 0x000ab66f, 0x000ab86f, 0x000aba6f, + 0x000abc6f, 0x000abe6f, 0x000ac06f, 0x000ac26f, + 0x000ac46f, 0x000ac66f, 0x000ac86f, 0x000aca6f, + 0x000acc6f, 0x000ace6f, 0x000ad06f, 0x000ad26f, + 0x000ad46f, 0x000ad66f, 0x000ad86f, 0x000ada6f, + 0x000adc6f, 0x000ade6f, 0x000ae06f, 0x000ae26f, + 0x000ae46f, 0x000ae66f, 0x000ae86f, 0x000aea6f, + 0x000aec6f, 0x000aee6f, 0x000af06f, 0x000af26f, + 0x000af46f, 0x000af66f, 0x000af86f, 0x000afa6f, + 0x000afc6f, 0x000afe6f, 0x000b006f, 0x000b026f, + 0x000b046f, 0x000b066f, 0x000b086f, 0x000b0a6f, + 0x000b0c6f, 0x000b0e6f, 0x000b106f, 0x000b126f, + 0x000b146f, 0x000b166f, 0x000b186f, 0x000b1a6f, + 0x000b1c6f, 0x000b1e6f, 0x000b206f, 0x000b226f, + 0x000b246f, 0x000b266f, 0x000b286f, 0x000b2a6f, + 0x000b2c6f, 0x000b2e6f, 0x000b306f, 0x000b326f, + 0x000b346f, 0x000b366f, 0x000b386f, 0x000b3a6f, + 0x000b3c6f, 0x000b3e6f, 0x000b406f, 0x000b426f, + 0x000b446f, 0x000b466f, 0x000b486f, 0x000b4a6f, + 0x000b4c6f, 0x000b4e6f, 0x000b506f, 0x000b526f, + 0x000b546f, 0x000b566f, 0x000b586f, 0x000b5a6f, + 0x000b5c6f, 0x000b5e6f, 0x000b606f, 0x000b626f, + 0x000b646f, 0x000b666f, 0x000b686f, 0x000b6a6f, + 0x000b6c6f, 0x000b6e6f, 0x000b706f, 0x000b726f, + 0x000b746f, 0x000b766f, 0x000b786f, 0x000b7a6f, + 0x000b7c6f, 0x000b7e6f, 0x000b806f, 0x000b826f, + 0x000b846f, 0x000b866f, 0x000b886f, 0x000b8a6f, + 0x000b8c6f, 0x000b8e6f, 0x000b906f, 0x000b926f, + 0x000b946f, 0x000b966f, 0x000b986f, 0x000b9a6f, + 0x000b9c6f, 0x000b9e6f, 0x000ba06f, 0x000ba26f, + 0x000ba46f, 0x000ba66f, 0x000ba86f, 0x000baa6f, + 0x000bac6f, 0x000bae6f, 0x000bb06f, 0x000bb26f, + 0x000bb46f, 0x000bb66f, 0x000bb86f, 0x000bba6f, + 0x000bbc6f, 0x000bbe6f, 0x000bc06f, 0x000bc26f, + 0x000bc46f, 0x000bc66f, 0x000bc86f, 0x000bca6f, + 0x000bcc6f, 0x000bce6f, 0x000bd06f, 0x000bd26f, + 0x000bd46f, 0x000bd66f, 0x000bd86f, 0x000bda6f, + 0x000bdc6f, 0x000bde6f, 0x000be06f, 0x000be26f, + 0x000be46f, 0x000be66f, 0x000be86f, 0x000bea6f, + 0x000bec6f, 0x000bee6f, 0x000bf06f, 0x000bf26f, + 0x000bf46f, 0x000bf66f, 0x000bf86f, 0x000bfa6f, + 0x000bfc6f, 0x000bfe6f, 0x000c006f, 0x000c026f, + 0x000c046f, 0x000c066f, 0x000c086f, 0x000c0a6f, + 0x000c0c6f, 0x000c0e6f, 0x000c106f, 0x000c126f, + 0x000c146f, 0x000c166f, 0x000c186f, 0x000c1a6f, + 0x000c1c6f, 0x000c1e6f, 0x000c206f, 0x000c226f, + 0x000c246f, 0x000c266f, 0x000c286f, 0x000c2a6f, + 0x000c2c6f, 0x000c2e6f, 0x000c306f, 0x000c326f, + 0x000c346f, 0x000c366f, 0x000c386f, 0x000c3a6f, + 0x000c3c6f, 0x000c3e6f, 0x000c406f, 0x000c426f, + 0x000c446f, 0x000c466f, 0x000c486f, 0x000c4a6f, + 0x000c4c6f, 0x000c4e6f, 0x000c506f, 0x000c526f, + 0x000c546f, 0x000c566f, 0x000c586f, 0x000c5a6f, + 0x000c5c6f, 0x000c5e6f, 0x000c606f, 0x000c626f, + 0x000c646f, 0x000c666f, 0x000c686f, 0x000c6a6f, + 0x000c6c6f, 0x000c6e6f, 0x000c706f, 0x000c726f, + 0x000c746f, 0x000c766f, 0x000c786f, 0x000c7a6f, + 0x000c7c6f, 0x000c7e6f, 0x000c806f, 0x000c826f, + 0x000c846f, 0x000c866f, 0x000c886f, 0x000c8a6f, + 0x000c8c6f, 0x000c8e6f, 0x000c906f, 0x000c926f, + 0x000c946f, 0x000c966f, 0x000c986f, 0x000c9a6f, + 0x000c9c6f, 0x000c9e6f, 0x000ca06f, 0x000ca26f, + 0x000ca46f, 0x000ca66f, 0x000ca86f, 0x000caa6f, + 0x000cac6f, 0x000cae6f, 0x000cb06f, 0x000cb26f, + 0x000cb46f, 0x000cb66f, 0x000cb86f, 0x000cba6f, + 0x000cbc6f, 0x000cbe6f, 0x000cc06f, 0x000cc26f, + 0x000cc46f, 0x000cc66f, 0x000cc86f, 0x000cca6f, + 0x000ccc6f, 0x000cce6f, 0x000cd06f, 0x000cd26f, + 0x000cd46f, 0x000cd66f, 0x000cd86f, 0x000cda6f, + 0x000cdc6f, 0x000cde6f, 0x000ce06f, 0x000ce26f, + 0x000ce46f, 0x000ce66f, 0x000ce86f, 0x000cea6f, + 0x000cec6f, 0x000cee6f, 0x000cf06f, 0x000cf26f, + 0x000cf46f, 0x000cf66f, 0x000cf86f, 0x000cfa6f, + 0x000cfc6f, 0x000cfe6f, 0x000d006f, 0x000d026f, + 0x000d046f, 0x000d066f, 0x000d086f, 0x000d0a6f, + 0x000d0c6f, 0x000d0e6f, 0x000d106f, 0x000d126f, + 0x000d146f, 0x000d166f, 0x000d186f, 0x000d1a6f, + 0x000d1c6f, 0x000d1e6f, 0x000d206f, 0x000d226f, + 0x000d246f, 0x000d266f, 0x000d286f, 0x000d2a6f, + 0x000d2c6f, 0x000d2e6f, 0x000d306f, 0x000d326f, + 0x000d346f, 0x000d366f, 0x000d386f, 0x000d3a6f, + 0x000d3c6f, 0x000d3e6f, 0x000d406f, 0x000d426f, + 0x000d446f, 0x000d466f, 0x000d486f, 0x000d4a6f, + 0x000d4c6f, 0x000d4e6f, 0x000d506f, 0x000d526f, + 0x000d546f, 0x000d566f, 0x000d586f, 0x000d5a6f, + 0x000d5c6f, 0x000d5e6f, 0x000d606f, 0x000d626f, + 0x000d646f, 0x000d666f, 0x000d686f, 0x000d6a6f, + 0x000d6c6f, 0x000d6e6f, 0x000d706f, 0x000d726f, + 0x000d746f, 0x000d766f, 0x000d786f, 0x000d7a6f, + 0x000d7c6f, 0x000d7e6f, 0x000d806f, 0x000d826f, + 0x000d846f, 0x000d866f, 0x000d886f, 0x000d8a6f, + 0x000d8c6f, 0x000d8e6f, 0x000d906f, 0x000d926f, + 0x000d946f, 0x000d966f, 0x000d986f, 0x000d9a6f, + 0x000d9c6f, 0x000d9e6f, 0x000da06f, 0x000da26f, + 0x000da46f, 0x000da66f, 0x000da86f, 0x000daa6f, + 0x000dac6f, 0x000dae6f, 0x000db06f, 0x000db26f, + 0x000db46f, 0x000db66f, 0x000db86f, 0x000dba6f, + 0x000dbc6f, 0x000dbe6f, 0x000dc06f, 0x000dc26f, + 0x000dc46f, 0x000dc66f, 0x000dc86f, 0x000dca6f, + 0x000dcc6f, 0x000dce6f, 0x000dd06f, 0x000dd26f, + 0x000dd46f, 0x000dd66f, 0x000dd86f, 0x000dda6f, + 0x000ddc6f, 0x000dde6f, 0x000de06f, 0x000de26f, + 0x000de46f, 0x000de66f, 0x000de86f, 0x000dea6f, + 0x000dec6f, 0x000dee6f, 0x000df06f, 0x000df26f, + 0x000df46f, 0x000df66f, 0x000df86f, 0x000dfa6f, + 0x000dfc6f, 0x000dfe6f, 0x000e006f, 0x000e026f, + 0x000e046f, 0x000e066f, 0x000e086f, 0x000e0a6f, + 0x000e0c6f, 0x000e0e6f, 0x000e106f, 0x000e126f, + 0x000e146f, 0x000e166f, 0x000e186f, 0x000e1a6f, + 0x000e1c6f, 0x000e1e6f, 0x000e206f, 0x000e226f, + 0x000e246f, 0x000e266f, 0x000e286f, 0x000e2a6f, + 0x000e2c6f, 0x000e2e6f, 0x000e306f, 0x000e326f, + 0x000e346f, 0x000e366f, 0x000e386f, 0x000e3a6f, + 0x000e3c6f, 0x000e3e6f, 0x000e406f, 0x000e426f, + 0x000e446f, 0x000e466f, 0x000e486f, 0x000e4a6f, + 0x000e4c6f, 0x000e4e6f, 0x000e506f, 0x000e526f, + 0x000e546f, 0x000e566f, 0x000e586f, 0x000e5a6f, + 0x000e5c6f, 0x000e5e6f, 0x000e606f, 0x000e626f, + 0x000e646f, 0x000e666f, 0x000e686f, 0x000e6a6f, + 0x000e6c6f, 0x000e6e6f, 0x000e706f, 0x000e726f, + 0x000e746f, 0x000e766f, 0x000e786f, 0x000e7a6f, + 0x000e7c6f, 0x000e7e6f, 0x000e806f, 0x000e826f, + 0x000e846f, 0x000e866f, 0x000e886f, 0x000e8a6f, + 0x000e8c6f, 0x000e8e6f, 0x000e906f, 0x000e926f, + 0x000e946f, 0x000e966f, 0x000e986f, 0x000e9a6f, + 0x000e9c6f, 0x000e9e6f, 0x000ea06f, 0x000ea26f, + 0x000ea46f, 0x000ea66f, 0x000ea86f, 0x000eaa6f, + 0x000eac6f, 0x000eae6f, 0x000eb06f, 0x000eb26f, + 0x000eb46f, 0x000eb66f, 0x000eb86f, 0x000eba6f, + 0x000ebc6f, 0x000ebe6f, 0x000ec06f, 0x000ec26f, + 0x000ec46f, 0x000ec66f, 0x000ec86f, 0x000eca6f, + 0x000ecc6f, 0x000ece6f, 0x000ed06f, 0x000ed26f, + 0x000ed46f, 0x000ed66f, 0x000ed86f, 0x000eda6f, + 0x000edc6f, 0x000ede6f, 0x000ee06f, 0x000ee26f, + 0x000ee46f, 0x000ee66f, 0x000ee86f, 0x000eea6f, + 0x000eec6f, 0x000eee6f, 0x000ef06f, 0x000ef26f, + 0x000ef46f, 0x000ef66f, 0x000ef86f, 0x000efa6f, + 0x000efc6f, 0x000efe6f, 0x000f006f, 0x000f026f, + 0x000f046f, 0x000f066f, 0x000f086f, 0x000f0a6f, + 0x000f0c6f, 0x000f0e6f, 0x000f106f, 0x000f126f, + 0x000f146f, 0x000f166f, 0x000f186f, 0x000f1a6f, + 0x000f1c6f, 0x000f1e6f, 0x000f206f, 0x000f226f, + 0x000f246f, 0x000f266f, 0x000f286f, 0x000f2a6f, + 0x000f2c6f, 0x000f2e6f, 0x000f306f, 0x000f326f, + 0x000f346f, 0x000f366f, 0x000f386f, 0x000f3a6f, + 0x000f3c6f, 0x000f3e6f, 0x000f406f, 0x000f426f, + 0x000f446f, 0x000f466f, 0x000f486f, 0x000f4a6f, + 0x000f4c6f, 0x000f4e6f, 0x000f506f, 0x000f526f, + 0x000f546f, 0x000f566f, 0x000f586f, 0x000f5a6f, + 0x000f5c6f, 0x000f5e6f, 0x000f606f, 0x000f626f, + 0x000f646f, 0x000f666f, 0x000f686f, 0x000f6a6f, + 0x000f6c6f, 0x000f6e6f, 0x000f706f, 0x000f726f, + 0x000f746f, 0x000f766f, 0x000f786f, 0x000f7a6f, + 0x000f7c6f, 0x000f7e6f, 0x000f806f, 0x000f826f, + 0x000f846f, 0x000f866f, 0x000f886f, 0x000f8a6f, + 0x000f8c6f, 0x000f8e6f, 0x000f906f, 0x000f926f, + 0x000f946f, 0x000f966f, 0x000f986f, 0x000f9a6f, + 0x000f9c6f, 0x000f9e6f, 0x000fa06f, 0x000fa26f, + 0x000fa46f, 0x000fa66f, 0x000fa86f, 0x000faa6f, + 0x000fac6f, 0x000fae6f, 0x000fb06f, 0x000fb26f, + 0x000fb46f, 0x000fb66f, 0x000fb86f, 0x000fba6f, + 0x000fbc6f, 0x000fbe6f, 0x000fc06f, 0x000fc26f, + 0x000fc46f, 0x000fc66f, 0x000fc86f, 0x000fca6f, + 0x000fcc6f, 0x000fce6f, 0x000fd06f, 0x000fd26f, + 0x000fd46f, 0x000fd66f, 0x000fd86f, 0x000fda6f, + 0x000fdc6f, 0x000fde6f, 0x000fe06f, 0x000fe26f, + 0x000fe46f, 0x000fe66f, 0x000fe86f, 0x000fea6f, + 0x000fec6f, 0x000fee6f, 0x000ff06f, 0x000ff26f, + 0x000ff46f, 0x000ff66f, 0x000ff86f, 0x000ffa6f, + 0x000ffc6f, 0x000ffe6f +#endif /* LONGER_HUFFTABLE */ + }, + + .len_table = { + 0x000bffef, 0x00000003, 0x00000084, 0x00000145, + 0x00000345, 0x00000626, 0x000002a7, 0x00000aa7, + 0x000000c6, 0x000004c6, 0x00001469, 0x00003469, + 0x00000c69, 0x00002c69, 0x00001c69, 0x00003c69, + 0x0000026a, 0x0000226a, 0x0000426a, 0x0000626a, + 0x000008eb, 0x000048eb, 0x000088eb, 0x0000c8eb, + 0x000029ec, 0x0000a9ec, 0x000129ec, 0x0001a9ec, + 0x000069ec, 0x0000e9ec, 0x000169ec, 0x0001e9ec, + 0x000019ed, 0x000099ed, 0x000119ed, 0x000199ed, + 0x000219ed, 0x000299ed, 0x000319ed, 0x000399ed, + 0x000059ed, 0x0000d9ed, 0x000159ed, 0x0001d9ed, + 0x000259ed, 0x0002d9ed, 0x000359ed, 0x0003d9ed, + 0x000039ed, 0x0000b9ed, 0x000139ed, 0x0001b9ed, + 0x000239ed, 0x0002b9ed, 0x000339ed, 0x0003b9ed, + 0x000079ed, 0x0000f9ed, 0x000179ed, 0x0001f9ed, + 0x000279ed, 0x0002f9ed, 0x000379ed, 0x0003f9ed, + 0x00003fef, 0x00013fef, 0x00023fef, 0x00033fef, + 0x00043fef, 0x00053fef, 0x00063fef, 0x00073fef, + 0x00083fef, 0x00093fef, 0x000a3fef, 0x000b3fef, + 0x000c3fef, 0x000d3fef, 0x000e3fef, 0x000f3fef, + 0x00007ff0, 0x00027ff0, 0x00047ff0, 0x00067ff0, + 0x00087ff0, 0x000a7ff0, 0x000c7ff0, 0x000e7ff0, + 0x00107ff0, 0x00127ff0, 0x00147ff0, 0x00167ff0, + 0x00187ff0, 0x001a7ff0, 0x001c7ff0, 0x001e7ff0, + 0x0000fff1, 0x0004fff1, 0x0008fff1, 0x000cfff1, + 0x0010fff1, 0x0014fff1, 0x0018fff1, 0x001cfff1, + 0x0020fff1, 0x0024fff1, 0x0028fff1, 0x002cfff1, + 0x0030fff1, 0x0034fff1, 0x0038fff1, 0x003cfff1, + 0x0002fff1, 0x0006fff1, 0x000afff1, 0x000efff1, + 0x0012fff1, 0x0016fff1, 0x001afff1, 0x001efff1, + 0x0022fff1, 0x0026fff1, 0x002afff1, 0x002efff1, + 0x0032fff1, 0x0036fff1, 0x003afff1, 0x003efff1, + 0x00017ff1, 0x00037ff1, 0x00057ff1, 0x00077ff1, + 0x00097ff1, 0x000b7ff1, 0x000d7ff1, 0x000f7ff1, + 0x00117ff1, 0x00137ff1, 0x00157ff1, 0x00177ff1, + 0x00197ff1, 0x001b7ff1, 0x001d7ff1, 0x001f7ff1, + 0x00217ff1, 0x00237ff1, 0x00257ff1, 0x00277ff1, + 0x00297ff1, 0x002b7ff1, 0x002d7ff1, 0x002f7ff1, + 0x00317ff1, 0x00337ff1, 0x00357ff1, 0x00377ff1, + 0x00397ff1, 0x003b7ff1, 0x003d7ff1, 0x003f7ff1, + 0x0001fff2, 0x0005fff2, 0x0009fff2, 0x000dfff2, + 0x0011fff2, 0x0015fff2, 0x0019fff2, 0x001dfff2, + 0x0021fff2, 0x0025fff2, 0x0029fff2, 0x002dfff2, + 0x0031fff2, 0x0035fff2, 0x0039fff2, 0x003dfff2, + 0x0041fff2, 0x0045fff2, 0x0049fff2, 0x004dfff2, + 0x0051fff2, 0x0055fff2, 0x0059fff2, 0x005dfff2, + 0x0061fff2, 0x0065fff2, 0x0069fff2, 0x006dfff2, + 0x0071fff2, 0x0075fff2, 0x0079fff2, 0x007dfff2, + 0x0007fff4, 0x0017fff4, 0x0027fff4, 0x0037fff4, + 0x0047fff4, 0x0057fff4, 0x0067fff4, 0x0077fff4, + 0x0087fff4, 0x0097fff4, 0x00a7fff4, 0x00b7fff4, + 0x00c7fff4, 0x00d7fff4, 0x00e7fff4, 0x00f7fff4, + 0x0107fff4, 0x0117fff4, 0x0127fff4, 0x0137fff4, + 0x0147fff4, 0x0157fff4, 0x0167fff4, 0x0177fff4, + 0x0187fff4, 0x0197fff4, 0x01a7fff4, 0x01b7fff4, + 0x01c7fff4, 0x01d7fff4, 0x01e7fff4, 0x01f7fff4, + 0x000ffff4, 0x001ffff4, 0x002ffff4, 0x003ffff4, + 0x004ffff4, 0x005ffff4, 0x006ffff4, 0x007ffff4, + 0x008ffff4, 0x009ffff4, 0x00affff4, 0x00bffff4, + 0x00cffff4, 0x00dffff4, 0x00effff4, 0x00fffff4, + 0x010ffff4, 0x011ffff4, 0x012ffff4, 0x013ffff4, + 0x014ffff4, 0x015ffff4, 0x016ffff4, 0x017ffff4, + 0x018ffff4, 0x019ffff4, 0x01affff4, 0x01bffff4, + 0x01cffff4, 0x01dffff4, 0x01effff4, 0x0000bfeb}, + + .lit_table = { + 0x000c, 0x0035, 0x0093, 0x00b5, 0x0075, 0x00f5, 0x0193, 0x0053, + 0x0153, 0x000d, 0x0009, 0x00d3, 0x01d3, 0x008d, 0x0033, 0x0133, + 0x00b3, 0x0147, 0x0347, 0x00c7, 0x02c7, 0x01c7, 0x03c7, 0x0027, + 0x0227, 0x002f, 0x042f, 0x022f, 0x0127, 0x062f, 0x01b3, 0x0073, + 0x001c, 0x0327, 0x0173, 0x00a7, 0x00f3, 0x02a7, 0x01a7, 0x01f3, + 0x004d, 0x000b, 0x03a7, 0x0067, 0x0049, 0x00cd, 0x0029, 0x0267, + 0x002d, 0x00ad, 0x006d, 0x00ed, 0x001d, 0x009d, 0x010b, 0x008b, + 0x005d, 0x018b, 0x004b, 0x014b, 0x00cb, 0x0167, 0x01cb, 0x002b, + 0x00dd, 0x003d, 0x00bd, 0x007d, 0x012b, 0x00ab, 0x01ab, 0x006b, + 0x016b, 0x00fd, 0x00eb, 0x0367, 0x01eb, 0x001b, 0x011b, 0x009b, + 0x0003, 0x00e7, 0x019b, 0x0083, 0x005b, 0x015b, 0x02e7, 0x00db, + 0x01e7, 0x03e7, 0x0017, 0x0217, 0x0117, 0x0317, 0x0097, 0x0297, + 0x01db, 0x0002, 0x0069, 0x0019, 0x0016, 0x0012, 0x0059, 0x0039, + 0x0079, 0x0036, 0x003b, 0x0043, 0x000e, 0x0005, 0x002e, 0x001e, + 0x0045, 0x0197, 0x003e, 0x0001, 0x0021, 0x0011, 0x00c3, 0x0025, + 0x013b, 0x0065, 0x00bb, 0x012f, 0x0397, 0x0057, 0x0257, 0x0157, + 0x01bb, 0x052f, 0x032f, 0x0357, 0x00d7, 0x072f, 0x00af, 0x02d7, + 0x01d7, 0x04af, 0x02af, 0x03d7, 0x06af, 0x01af, 0x05af, 0x0037, + 0x0237, 0x03af, 0x07af, 0x006f, 0x046f, 0x026f, 0x066f, 0x016f, + 0x056f, 0x036f, 0x076f, 0x00ef, 0x04ef, 0x02ef, 0x06ef, 0x01ef, + 0x0137, 0x05ef, 0x03ef, 0x07ef, 0x0337, 0x001f, 0x00b7, 0x041f, + 0x02b7, 0x021f, 0x061f, 0x011f, 0x051f, 0x031f, 0x071f, 0x009f, + 0x01b7, 0x049f, 0x029f, 0x069f, 0x03b7, 0x019f, 0x059f, 0x039f, + 0x079f, 0x005f, 0x045f, 0x025f, 0x065f, 0x0077, 0x015f, 0x0277, + 0x007b, 0x0177, 0x017b, 0x00fb, 0x055f, 0x035f, 0x075f, 0x0377, + 0x00f7, 0x00df, 0x04df, 0x02df, 0x06df, 0x01df, 0x05df, 0x02f7, + 0x01f7, 0x03df, 0x07df, 0x003f, 0x043f, 0x023f, 0x063f, 0x013f, + 0x053f, 0x033f, 0x073f, 0x00bf, 0x04bf, 0x02bf, 0x06bf, 0x01bf, + 0x01fb, 0x03f7, 0x05bf, 0x000f, 0x020f, 0x03bf, 0x07bf, 0x010f, + 0x030f, 0x007f, 0x047f, 0x027f, 0x067f, 0x017f, 0x057f, 0x008f, + 0x0007, 0x028f, 0x037f, 0x018f, 0x038f, 0x077f, 0x00ff, 0x04ff, + 0x0107, 0x004f, 0x02ff, 0x06ff, 0x0087, 0x024f, 0x0187, 0x0023, + 0x1fff}, + + .lit_table_sizes = { + 0x05, 0x08, 0x09, 0x08, 0x08, 0x08, 0x09, 0x09, + 0x09, 0x08, 0x07, 0x09, 0x09, 0x08, 0x09, 0x09, + 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, + 0x0a, 0x0b, 0x0b, 0x0b, 0x0a, 0x0b, 0x09, 0x09, + 0x05, 0x0a, 0x09, 0x0a, 0x09, 0x0a, 0x0a, 0x09, + 0x08, 0x09, 0x0a, 0x0a, 0x07, 0x08, 0x07, 0x0a, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, + 0x08, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, + 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x08, 0x09, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x08, 0x0a, 0x09, 0x08, 0x09, 0x09, 0x0a, 0x09, + 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, + 0x09, 0x05, 0x07, 0x07, 0x06, 0x05, 0x07, 0x07, + 0x07, 0x06, 0x09, 0x08, 0x06, 0x07, 0x06, 0x06, + 0x07, 0x0a, 0x06, 0x06, 0x06, 0x06, 0x08, 0x07, + 0x09, 0x07, 0x09, 0x0b, 0x0a, 0x0a, 0x0a, 0x0a, + 0x09, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b, 0x0a, + 0x0a, 0x0b, 0x0b, 0x0a, 0x0b, 0x0b, 0x0b, 0x0a, + 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0a, 0x0b, 0x0b, 0x0b, 0x0a, 0x0b, 0x0a, 0x0b, + 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0a, 0x0b, 0x0b, 0x0b, 0x0a, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0b, 0x0a, + 0x09, 0x0a, 0x09, 0x09, 0x0b, 0x0b, 0x0b, 0x0a, + 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, + 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x09, 0x0a, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b, 0x0a, + 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, + 0x09, 0x0a, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, + 0x09, 0x0a, 0x0b, 0x0b, 0x09, 0x0a, 0x09, 0x08, + 0x0f}, + +#ifndef LONGER_HUFFTABLE + .dcodes = { + 0x007f, 0x01ff, 0x017f, 0x03ff, 0x00ff, 0x003f, 0x00bf, 0x000f, + 0x002f, 0x001f, 0x000b, 0x001b, 0x0004, 0x0007, 0x000c, 0x0002, + 0x000a, 0x0006, 0x000e, 0x0001, 0x0009, 0x0017, 0x0000, 0x0005, + 0x000d, 0x0003, 0x0000, 0x0000, 0x0000, 0x0000}, + + .dcodes_sizes = { + 0x09, 0x0a, 0x09, 0x0a, 0x09, 0x08, 0x08, 0x06, + 0x06, 0x06, 0x05, 0x05, 0x04, 0x05, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x03, 0x04, + 0x04, 0x04, 0x00, 0x00, 0x00, 0x00} #else + .dcodes = { + 0x0000, 0x0000, 0x0000, 0x0000}, + + .dcodes_sizes = { + 0x00, 0x00, 0x00, 0x00} +#endif +}; + +#else // LARGE_WINDOW + +const uint8_t gzip_hdr[] = { + 0x1f, 0x8b, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff +}; + +const uint32_t gzip_hdr_bytes = 10; +const uint32_t gzip_trl_bytes = 8; + +struct isal_hufftables hufftables_default = { + + .deflate_hdr = { + 0xed, 0xfd, 0x09, 0x80, 0x1c, 0x45, 0xf9, 0xbf, + 0x81, 0xf7, 0x66, 0x37, 0xd7, 0x24, 0x9b, 0x04, + 0x40, 0x45, 0x45, 0x52, 0x04, 0x20, 0x09, 0xcc, + 0x2e, 0xbb, 0x9b, 0x3b, 0x81, 0x24, 0xbb, 0xb9, + 0x21, 0x17, 0x49, 0xb8, 0x04, 0x85, 0xde, 0x99, + 0xde, 0x9d, 0x26, 0x33, 0xd3, 0x43, 0xf7, 0x4c, + 0x36, 0x8b, 0x08, 0xf1, 0x56, 0x51, 0xc1, 0xfb, + 0x56, 0x54, 0xc4, 0x5b, 0x51, 0xf1, 0x16, 0x0d, + 0x89, 0x8a, 0x37, 0x78, 0xdf, 0x1a, 0x45, 0x05, + 0xef, 0x20, 0xaa, 0xa0, 0x90, 0xfd, 0xff, 0x9f, + 0xf7, 0xad, 0x9e, 0xa9, 0xdd, 0xdd, 0x70, 0xfa, + 0xfd, 0xfd, 0xbe, 0xbf, 0xff, 0xdf, 0xcd, 0x66, + 0x67, 0xba, 0xbb, 0xaa, 0xea, 0x7d, 0xdf, 0x7a, + 0xeb, 0xad, 0x4f, 0xbd, 0xf5, 0x56, 0x35}, + + .deflate_hdr_count = 110, + .deflate_hdr_extra_bits = 6, + .dist_table = { - 0x00001be9, 0x00003be9, 0x00000be8, 0x000007e9, - 0x000001e7, 0x000009e7, 0x000027ea, 0x000067ea, - 0x000003e9, 0x000013e9, 0x000023e9, 0x000033e9, - 0x000005e8, 0x00000de8, 0x000015e8, 0x00001de8, - 0x00000068, 0x00000468, 0x00000868, 0x00000c68, - 0x00001068, 0x00001468, 0x00001868, 0x00001c68, - 0x00000268, 0x00000668, 0x00000a68, 0x00000e68, - 0x00001268, 0x00001668, 0x00001a68, 0x00001e68, - 0x00000048, 0x00000248, 0x00000448, 0x00000648, - 0x00000848, 0x00000a48, 0x00000c48, 0x00000e48, - 0x00001048, 0x00001248, 0x00001448, 0x00001648, - 0x00001848, 0x00001a48, 0x00001c48, 0x00001e48, - 0x00000148, 0x00000348, 0x00000548, 0x00000748, - 0x00000948, 0x00000b48, 0x00000d48, 0x00000f48, - 0x00001148, 0x00001348, 0x00001548, 0x00001748, - 0x00001948, 0x00001b48, 0x00001d48, 0x00001f48, - 0x000000c9, 0x000002c9, 0x000004c9, 0x000006c9, - 0x000008c9, 0x00000ac9, 0x00000cc9, 0x00000ec9, - 0x000010c9, 0x000012c9, 0x000014c9, 0x000016c9, - 0x000018c9, 0x00001ac9, 0x00001cc9, 0x00001ec9, - 0x000020c9, 0x000022c9, 0x000024c9, 0x000026c9, - 0x000028c9, 0x00002ac9, 0x00002cc9, 0x00002ec9, - 0x000030c9, 0x000032c9, 0x000034c9, 0x000036c9, - 0x000038c9, 0x00003ac9, 0x00003cc9, 0x00003ec9, - 0x0000016a, 0x0000056a, 0x0000096a, 0x00000d6a, - 0x0000116a, 0x0000156a, 0x0000196a, 0x00001d6a, - 0x0000216a, 0x0000256a, 0x0000296a, 0x00002d6a, - 0x0000316a, 0x0000356a, 0x0000396a, 0x00003d6a, - 0x0000416a, 0x0000456a, 0x0000496a, 0x00004d6a, - 0x0000516a, 0x0000556a, 0x0000596a, 0x00005d6a, - 0x0000616a, 0x0000656a, 0x0000696a, 0x00006d6a, - 0x0000716a, 0x0000756a, 0x0000796a, 0x00007d6a, - 0x000001ca, 0x000003ca, 0x000005ca, 0x000007ca, - 0x000009ca, 0x00000bca, 0x00000dca, 0x00000fca, - 0x000011ca, 0x000013ca, 0x000015ca, 0x000017ca, - 0x000019ca, 0x00001bca, 0x00001dca, 0x00001fca, - 0x000021ca, 0x000023ca, 0x000025ca, 0x000027ca, - 0x000029ca, 0x00002bca, 0x00002dca, 0x00002fca, - 0x000031ca, 0x000033ca, 0x000035ca, 0x000037ca, - 0x000039ca, 0x00003bca, 0x00003dca, 0x00003fca, - 0x000041ca, 0x000043ca, 0x000045ca, 0x000047ca, - 0x000049ca, 0x00004bca, 0x00004dca, 0x00004fca, - 0x000051ca, 0x000053ca, 0x000055ca, 0x000057ca, - 0x000059ca, 0x00005bca, 0x00005dca, 0x00005fca, - 0x000061ca, 0x000063ca, 0x000065ca, 0x000067ca, - 0x000069ca, 0x00006bca, 0x00006dca, 0x00006fca, - 0x000071ca, 0x000073ca, 0x000075ca, 0x000077ca, - 0x000079ca, 0x00007bca, 0x00007dca, 0x00007fca, - 0x0000002a, 0x0000022a, 0x0000042a, 0x0000062a, - 0x0000082a, 0x00000a2a, 0x00000c2a, 0x00000e2a, - 0x0000102a, 0x0000122a, 0x0000142a, 0x0000162a, - 0x0000182a, 0x00001a2a, 0x00001c2a, 0x00001e2a, - 0x0000202a, 0x0000222a, 0x0000242a, 0x0000262a, - 0x0000282a, 0x00002a2a, 0x00002c2a, 0x00002e2a, - 0x0000302a, 0x0000322a, 0x0000342a, 0x0000362a, - 0x0000382a, 0x00003a2a, 0x00003c2a, 0x00003e2a, - 0x0000402a, 0x0000422a, 0x0000442a, 0x0000462a, - 0x0000482a, 0x00004a2a, 0x00004c2a, 0x00004e2a, - 0x0000502a, 0x0000522a, 0x0000542a, 0x0000562a, - 0x0000582a, 0x00005a2a, 0x00005c2a, 0x00005e2a, - 0x0000602a, 0x0000622a, 0x0000642a, 0x0000662a, - 0x0000682a, 0x00006a2a, 0x00006c2a, 0x00006e2a, - 0x0000702a, 0x0000722a, 0x0000742a, 0x0000762a, - 0x0000782a, 0x00007a2a, 0x00007c2a, 0x00007e2a, - 0x0000000a, 0x0000010a, 0x0000020a, 0x0000030a, - 0x0000040a, 0x0000050a, 0x0000060a, 0x0000070a, - 0x0000080a, 0x0000090a, 0x00000a0a, 0x00000b0a, - 0x00000c0a, 0x00000d0a, 0x00000e0a, 0x00000f0a, - 0x0000100a, 0x0000110a, 0x0000120a, 0x0000130a, - 0x0000140a, 0x0000150a, 0x0000160a, 0x0000170a, - 0x0000180a, 0x0000190a, 0x00001a0a, 0x00001b0a, - 0x00001c0a, 0x00001d0a, 0x00001e0a, 0x00001f0a, - 0x0000200a, 0x0000210a, 0x0000220a, 0x0000230a, - 0x0000240a, 0x0000250a, 0x0000260a, 0x0000270a, - 0x0000280a, 0x0000290a, 0x00002a0a, 0x00002b0a, - 0x00002c0a, 0x00002d0a, 0x00002e0a, 0x00002f0a, - 0x0000300a, 0x0000310a, 0x0000320a, 0x0000330a, - 0x0000340a, 0x0000350a, 0x0000360a, 0x0000370a, - 0x0000380a, 0x0000390a, 0x00003a0a, 0x00003b0a, - 0x00003c0a, 0x00003d0a, 0x00003e0a, 0x00003f0a, - 0x0000400a, 0x0000410a, 0x0000420a, 0x0000430a, - 0x0000440a, 0x0000450a, 0x0000460a, 0x0000470a, - 0x0000480a, 0x0000490a, 0x00004a0a, 0x00004b0a, - 0x00004c0a, 0x00004d0a, 0x00004e0a, 0x00004f0a, - 0x0000500a, 0x0000510a, 0x0000520a, 0x0000530a, - 0x0000540a, 0x0000550a, 0x0000560a, 0x0000570a, - 0x0000580a, 0x0000590a, 0x00005a0a, 0x00005b0a, - 0x00005c0a, 0x00005d0a, 0x00005e0a, 0x00005f0a, - 0x0000600a, 0x0000610a, 0x0000620a, 0x0000630a, - 0x0000640a, 0x0000650a, 0x0000660a, 0x0000670a, - 0x0000680a, 0x0000690a, 0x00006a0a, 0x00006b0a, - 0x00006c0a, 0x00006d0a, 0x00006e0a, 0x00006f0a, - 0x0000700a, 0x0000710a, 0x0000720a, 0x0000730a, - 0x0000740a, 0x0000750a, 0x0000760a, 0x0000770a, - 0x0000780a, 0x0000790a, 0x00007a0a, 0x00007b0a, - 0x00007c0a, 0x00007d0a, 0x00007e0a, 0x00007f0a, - 0x0000012b, 0x0000032b, 0x0000052b, 0x0000072b, - 0x0000092b, 0x00000b2b, 0x00000d2b, 0x00000f2b, - 0x0000112b, 0x0000132b, 0x0000152b, 0x0000172b, - 0x0000192b, 0x00001b2b, 0x00001d2b, 0x00001f2b, - 0x0000212b, 0x0000232b, 0x0000252b, 0x0000272b, - 0x0000292b, 0x00002b2b, 0x00002d2b, 0x00002f2b, - 0x0000312b, 0x0000332b, 0x0000352b, 0x0000372b, - 0x0000392b, 0x00003b2b, 0x00003d2b, 0x00003f2b, - 0x0000412b, 0x0000432b, 0x0000452b, 0x0000472b, - 0x0000492b, 0x00004b2b, 0x00004d2b, 0x00004f2b, - 0x0000512b, 0x0000532b, 0x0000552b, 0x0000572b, - 0x0000592b, 0x00005b2b, 0x00005d2b, 0x00005f2b, - 0x0000612b, 0x0000632b, 0x0000652b, 0x0000672b, - 0x0000692b, 0x00006b2b, 0x00006d2b, 0x00006f2b, - 0x0000712b, 0x0000732b, 0x0000752b, 0x0000772b, - 0x0000792b, 0x00007b2b, 0x00007d2b, 0x00007f2b, - 0x0000812b, 0x0000832b, 0x0000852b, 0x0000872b, - 0x0000892b, 0x00008b2b, 0x00008d2b, 0x00008f2b, - 0x0000912b, 0x0000932b, 0x0000952b, 0x0000972b, - 0x0000992b, 0x00009b2b, 0x00009d2b, 0x00009f2b, - 0x0000a12b, 0x0000a32b, 0x0000a52b, 0x0000a72b, - 0x0000a92b, 0x0000ab2b, 0x0000ad2b, 0x0000af2b, - 0x0000b12b, 0x0000b32b, 0x0000b52b, 0x0000b72b, - 0x0000b92b, 0x0000bb2b, 0x0000bd2b, 0x0000bf2b, - 0x0000c12b, 0x0000c32b, 0x0000c52b, 0x0000c72b, - 0x0000c92b, 0x0000cb2b, 0x0000cd2b, 0x0000cf2b, - 0x0000d12b, 0x0000d32b, 0x0000d52b, 0x0000d72b, - 0x0000d92b, 0x0000db2b, 0x0000dd2b, 0x0000df2b, - 0x0000e12b, 0x0000e32b, 0x0000e52b, 0x0000e72b, - 0x0000e92b, 0x0000eb2b, 0x0000ed2b, 0x0000ef2b, - 0x0000f12b, 0x0000f32b, 0x0000f52b, 0x0000f72b, - 0x0000f92b, 0x0000fb2b, 0x0000fd2b, 0x0000ff2b, - 0x0000008b, 0x0000018b, 0x0000028b, 0x0000038b, - 0x0000048b, 0x0000058b, 0x0000068b, 0x0000078b, - 0x0000088b, 0x0000098b, 0x00000a8b, 0x00000b8b, - 0x00000c8b, 0x00000d8b, 0x00000e8b, 0x00000f8b, - 0x0000108b, 0x0000118b, 0x0000128b, 0x0000138b, - 0x0000148b, 0x0000158b, 0x0000168b, 0x0000178b, - 0x0000188b, 0x0000198b, 0x00001a8b, 0x00001b8b, - 0x00001c8b, 0x00001d8b, 0x00001e8b, 0x00001f8b, - 0x0000208b, 0x0000218b, 0x0000228b, 0x0000238b, - 0x0000248b, 0x0000258b, 0x0000268b, 0x0000278b, - 0x0000288b, 0x0000298b, 0x00002a8b, 0x00002b8b, - 0x00002c8b, 0x00002d8b, 0x00002e8b, 0x00002f8b, - 0x0000308b, 0x0000318b, 0x0000328b, 0x0000338b, - 0x0000348b, 0x0000358b, 0x0000368b, 0x0000378b, - 0x0000388b, 0x0000398b, 0x00003a8b, 0x00003b8b, - 0x00003c8b, 0x00003d8b, 0x00003e8b, 0x00003f8b, - 0x0000408b, 0x0000418b, 0x0000428b, 0x0000438b, - 0x0000448b, 0x0000458b, 0x0000468b, 0x0000478b, - 0x0000488b, 0x0000498b, 0x00004a8b, 0x00004b8b, - 0x00004c8b, 0x00004d8b, 0x00004e8b, 0x00004f8b, - 0x0000508b, 0x0000518b, 0x0000528b, 0x0000538b, - 0x0000548b, 0x0000558b, 0x0000568b, 0x0000578b, - 0x0000588b, 0x0000598b, 0x00005a8b, 0x00005b8b, - 0x00005c8b, 0x00005d8b, 0x00005e8b, 0x00005f8b, - 0x0000608b, 0x0000618b, 0x0000628b, 0x0000638b, - 0x0000648b, 0x0000658b, 0x0000668b, 0x0000678b, - 0x0000688b, 0x0000698b, 0x00006a8b, 0x00006b8b, - 0x00006c8b, 0x00006d8b, 0x00006e8b, 0x00006f8b, - 0x0000708b, 0x0000718b, 0x0000728b, 0x0000738b, - 0x0000748b, 0x0000758b, 0x0000768b, 0x0000778b, - 0x0000788b, 0x0000798b, 0x00007a8b, 0x00007b8b, - 0x00007c8b, 0x00007d8b, 0x00007e8b, 0x00007f8b, - 0x0000808b, 0x0000818b, 0x0000828b, 0x0000838b, - 0x0000848b, 0x0000858b, 0x0000868b, 0x0000878b, - 0x0000888b, 0x0000898b, 0x00008a8b, 0x00008b8b, - 0x00008c8b, 0x00008d8b, 0x00008e8b, 0x00008f8b, - 0x0000908b, 0x0000918b, 0x0000928b, 0x0000938b, - 0x0000948b, 0x0000958b, 0x0000968b, 0x0000978b, - 0x0000988b, 0x0000998b, 0x00009a8b, 0x00009b8b, - 0x00009c8b, 0x00009d8b, 0x00009e8b, 0x00009f8b, - 0x0000a08b, 0x0000a18b, 0x0000a28b, 0x0000a38b, - 0x0000a48b, 0x0000a58b, 0x0000a68b, 0x0000a78b, - 0x0000a88b, 0x0000a98b, 0x0000aa8b, 0x0000ab8b, - 0x0000ac8b, 0x0000ad8b, 0x0000ae8b, 0x0000af8b, - 0x0000b08b, 0x0000b18b, 0x0000b28b, 0x0000b38b, - 0x0000b48b, 0x0000b58b, 0x0000b68b, 0x0000b78b, - 0x0000b88b, 0x0000b98b, 0x0000ba8b, 0x0000bb8b, - 0x0000bc8b, 0x0000bd8b, 0x0000be8b, 0x0000bf8b, - 0x0000c08b, 0x0000c18b, 0x0000c28b, 0x0000c38b, - 0x0000c48b, 0x0000c58b, 0x0000c68b, 0x0000c78b, - 0x0000c88b, 0x0000c98b, 0x0000ca8b, 0x0000cb8b, - 0x0000cc8b, 0x0000cd8b, 0x0000ce8b, 0x0000cf8b, - 0x0000d08b, 0x0000d18b, 0x0000d28b, 0x0000d38b, - 0x0000d48b, 0x0000d58b, 0x0000d68b, 0x0000d78b, - 0x0000d88b, 0x0000d98b, 0x0000da8b, 0x0000db8b, - 0x0000dc8b, 0x0000dd8b, 0x0000de8b, 0x0000df8b, - 0x0000e08b, 0x0000e18b, 0x0000e28b, 0x0000e38b, - 0x0000e48b, 0x0000e58b, 0x0000e68b, 0x0000e78b, - 0x0000e88b, 0x0000e98b, 0x0000ea8b, 0x0000eb8b, - 0x0000ec8b, 0x0000ed8b, 0x0000ee8b, 0x0000ef8b, - 0x0000f08b, 0x0000f18b, 0x0000f28b, 0x0000f38b, - 0x0000f48b, 0x0000f58b, 0x0000f68b, 0x0000f78b, - 0x0000f88b, 0x0000f98b, 0x0000fa8b, 0x0000fb8b, - 0x0000fc8b, 0x0000fd8b, 0x0000fe8b, 0x0000ff8b, - 0x000000ac, 0x000002ac, 0x000004ac, 0x000006ac, - 0x000008ac, 0x00000aac, 0x00000cac, 0x00000eac, - 0x000010ac, 0x000012ac, 0x000014ac, 0x000016ac, - 0x000018ac, 0x00001aac, 0x00001cac, 0x00001eac, - 0x000020ac, 0x000022ac, 0x000024ac, 0x000026ac, - 0x000028ac, 0x00002aac, 0x00002cac, 0x00002eac, - 0x000030ac, 0x000032ac, 0x000034ac, 0x000036ac, - 0x000038ac, 0x00003aac, 0x00003cac, 0x00003eac, - 0x000040ac, 0x000042ac, 0x000044ac, 0x000046ac, - 0x000048ac, 0x00004aac, 0x00004cac, 0x00004eac, - 0x000050ac, 0x000052ac, 0x000054ac, 0x000056ac, - 0x000058ac, 0x00005aac, 0x00005cac, 0x00005eac, - 0x000060ac, 0x000062ac, 0x000064ac, 0x000066ac, - 0x000068ac, 0x00006aac, 0x00006cac, 0x00006eac, - 0x000070ac, 0x000072ac, 0x000074ac, 0x000076ac, - 0x000078ac, 0x00007aac, 0x00007cac, 0x00007eac, - 0x000080ac, 0x000082ac, 0x000084ac, 0x000086ac, - 0x000088ac, 0x00008aac, 0x00008cac, 0x00008eac, - 0x000090ac, 0x000092ac, 0x000094ac, 0x000096ac, - 0x000098ac, 0x00009aac, 0x00009cac, 0x00009eac, - 0x0000a0ac, 0x0000a2ac, 0x0000a4ac, 0x0000a6ac, - 0x0000a8ac, 0x0000aaac, 0x0000acac, 0x0000aeac, - 0x0000b0ac, 0x0000b2ac, 0x0000b4ac, 0x0000b6ac, - 0x0000b8ac, 0x0000baac, 0x0000bcac, 0x0000beac, - 0x0000c0ac, 0x0000c2ac, 0x0000c4ac, 0x0000c6ac, - 0x0000c8ac, 0x0000caac, 0x0000ccac, 0x0000ceac, - 0x0000d0ac, 0x0000d2ac, 0x0000d4ac, 0x0000d6ac, - 0x0000d8ac, 0x0000daac, 0x0000dcac, 0x0000deac, - 0x0000e0ac, 0x0000e2ac, 0x0000e4ac, 0x0000e6ac, - 0x0000e8ac, 0x0000eaac, 0x0000ecac, 0x0000eeac, - 0x0000f0ac, 0x0000f2ac, 0x0000f4ac, 0x0000f6ac, - 0x0000f8ac, 0x0000faac, 0x0000fcac, 0x0000feac, - 0x000100ac, 0x000102ac, 0x000104ac, 0x000106ac, - 0x000108ac, 0x00010aac, 0x00010cac, 0x00010eac, - 0x000110ac, 0x000112ac, 0x000114ac, 0x000116ac, - 0x000118ac, 0x00011aac, 0x00011cac, 0x00011eac, - 0x000120ac, 0x000122ac, 0x000124ac, 0x000126ac, - 0x000128ac, 0x00012aac, 0x00012cac, 0x00012eac, - 0x000130ac, 0x000132ac, 0x000134ac, 0x000136ac, - 0x000138ac, 0x00013aac, 0x00013cac, 0x00013eac, - 0x000140ac, 0x000142ac, 0x000144ac, 0x000146ac, - 0x000148ac, 0x00014aac, 0x00014cac, 0x00014eac, - 0x000150ac, 0x000152ac, 0x000154ac, 0x000156ac, - 0x000158ac, 0x00015aac, 0x00015cac, 0x00015eac, - 0x000160ac, 0x000162ac, 0x000164ac, 0x000166ac, - 0x000168ac, 0x00016aac, 0x00016cac, 0x00016eac, - 0x000170ac, 0x000172ac, 0x000174ac, 0x000176ac, - 0x000178ac, 0x00017aac, 0x00017cac, 0x00017eac, - 0x000180ac, 0x000182ac, 0x000184ac, 0x000186ac, - 0x000188ac, 0x00018aac, 0x00018cac, 0x00018eac, - 0x000190ac, 0x000192ac, 0x000194ac, 0x000196ac, - 0x000198ac, 0x00019aac, 0x00019cac, 0x00019eac, - 0x0001a0ac, 0x0001a2ac, 0x0001a4ac, 0x0001a6ac, - 0x0001a8ac, 0x0001aaac, 0x0001acac, 0x0001aeac, - 0x0001b0ac, 0x0001b2ac, 0x0001b4ac, 0x0001b6ac, - 0x0001b8ac, 0x0001baac, 0x0001bcac, 0x0001beac, - 0x0001c0ac, 0x0001c2ac, 0x0001c4ac, 0x0001c6ac, - 0x0001c8ac, 0x0001caac, 0x0001ccac, 0x0001ceac, - 0x0001d0ac, 0x0001d2ac, 0x0001d4ac, 0x0001d6ac, - 0x0001d8ac, 0x0001daac, 0x0001dcac, 0x0001deac, - 0x0001e0ac, 0x0001e2ac, 0x0001e4ac, 0x0001e6ac, - 0x0001e8ac, 0x0001eaac, 0x0001ecac, 0x0001eeac, - 0x0001f0ac, 0x0001f2ac, 0x0001f4ac, 0x0001f6ac, - 0x0001f8ac, 0x0001faac, 0x0001fcac, 0x0001feac }, + 0x000007e8, 0x00001fe9, +#ifdef LONGER_HUFFTABLE + 0x000017e8, 0x00003fe9, 0x00000fe9, 0x00002fe9, + 0x000003e8, 0x000013e8, 0x00000be9, 0x00001be9, + 0x00002be9, 0x00003be9, 0x000002e8, 0x00000ae8, + 0x000012e8, 0x00001ae8, 0x000006e9, 0x00000ee9, + 0x000016e9, 0x00001ee9, 0x000026e9, 0x00002ee9, + 0x000036e9, 0x00003ee9, 0x000001e9, 0x000009e9, + 0x000011e9, 0x000019e9, 0x000021e9, 0x000029e9, + 0x000031e9, 0x000039e9, 0x00000129, 0x00000529, + 0x00000929, 0x00000d29, 0x00001129, 0x00001529, + 0x00001929, 0x00001d29, 0x00002129, 0x00002529, + 0x00002929, 0x00002d29, 0x00003129, 0x00003529, + 0x00003929, 0x00003d29, 0x00000329, 0x00000729, + 0x00000b29, 0x00000f29, 0x00001329, 0x00001729, + 0x00001b29, 0x00001f29, 0x00002329, 0x00002729, + 0x00002b29, 0x00002f29, 0x00003329, 0x00003729, + 0x00003b29, 0x00003f29, 0x000000aa, 0x000004aa, + 0x000008aa, 0x00000caa, 0x000010aa, 0x000014aa, + 0x000018aa, 0x00001caa, 0x000020aa, 0x000024aa, + 0x000028aa, 0x00002caa, 0x000030aa, 0x000034aa, + 0x000038aa, 0x00003caa, 0x000040aa, 0x000044aa, + 0x000048aa, 0x00004caa, 0x000050aa, 0x000054aa, + 0x000058aa, 0x00005caa, 0x000060aa, 0x000064aa, + 0x000068aa, 0x00006caa, 0x000070aa, 0x000074aa, + 0x000078aa, 0x00007caa, 0x000002aa, 0x000006aa, + 0x00000aaa, 0x00000eaa, 0x000012aa, 0x000016aa, + 0x00001aaa, 0x00001eaa, 0x000022aa, 0x000026aa, + 0x00002aaa, 0x00002eaa, 0x000032aa, 0x000036aa, + 0x00003aaa, 0x00003eaa, 0x000042aa, 0x000046aa, + 0x00004aaa, 0x00004eaa, 0x000052aa, 0x000056aa, + 0x00005aaa, 0x00005eaa, 0x000062aa, 0x000066aa, + 0x00006aaa, 0x00006eaa, 0x000072aa, 0x000076aa, + 0x00007aaa, 0x00007eaa, 0x0000008a, 0x0000028a, + 0x0000048a, 0x0000068a, 0x0000088a, 0x00000a8a, + 0x00000c8a, 0x00000e8a, 0x0000108a, 0x0000128a, + 0x0000148a, 0x0000168a, 0x0000188a, 0x00001a8a, + 0x00001c8a, 0x00001e8a, 0x0000208a, 0x0000228a, + 0x0000248a, 0x0000268a, 0x0000288a, 0x00002a8a, + 0x00002c8a, 0x00002e8a, 0x0000308a, 0x0000328a, + 0x0000348a, 0x0000368a, 0x0000388a, 0x00003a8a, + 0x00003c8a, 0x00003e8a, 0x0000408a, 0x0000428a, + 0x0000448a, 0x0000468a, 0x0000488a, 0x00004a8a, + 0x00004c8a, 0x00004e8a, 0x0000508a, 0x0000528a, + 0x0000548a, 0x0000568a, 0x0000588a, 0x00005a8a, + 0x00005c8a, 0x00005e8a, 0x0000608a, 0x0000628a, + 0x0000648a, 0x0000668a, 0x0000688a, 0x00006a8a, + 0x00006c8a, 0x00006e8a, 0x0000708a, 0x0000728a, + 0x0000748a, 0x0000768a, 0x0000788a, 0x00007a8a, + 0x00007c8a, 0x00007e8a, 0x0000018a, 0x0000038a, + 0x0000058a, 0x0000078a, 0x0000098a, 0x00000b8a, + 0x00000d8a, 0x00000f8a, 0x0000118a, 0x0000138a, + 0x0000158a, 0x0000178a, 0x0000198a, 0x00001b8a, + 0x00001d8a, 0x00001f8a, 0x0000218a, 0x0000238a, + 0x0000258a, 0x0000278a, 0x0000298a, 0x00002b8a, + 0x00002d8a, 0x00002f8a, 0x0000318a, 0x0000338a, + 0x0000358a, 0x0000378a, 0x0000398a, 0x00003b8a, + 0x00003d8a, 0x00003f8a, 0x0000418a, 0x0000438a, + 0x0000458a, 0x0000478a, 0x0000498a, 0x00004b8a, + 0x00004d8a, 0x00004f8a, 0x0000518a, 0x0000538a, + 0x0000558a, 0x0000578a, 0x0000598a, 0x00005b8a, + 0x00005d8a, 0x00005f8a, 0x0000618a, 0x0000638a, + 0x0000658a, 0x0000678a, 0x0000698a, 0x00006b8a, + 0x00006d8a, 0x00006f8a, 0x0000718a, 0x0000738a, + 0x0000758a, 0x0000778a, 0x0000798a, 0x00007b8a, + 0x00007d8a, 0x00007f8a, 0x0000004b, 0x0000024b, + 0x0000044b, 0x0000064b, 0x0000084b, 0x00000a4b, + 0x00000c4b, 0x00000e4b, 0x0000104b, 0x0000124b, + 0x0000144b, 0x0000164b, 0x0000184b, 0x00001a4b, + 0x00001c4b, 0x00001e4b, 0x0000204b, 0x0000224b, + 0x0000244b, 0x0000264b, 0x0000284b, 0x00002a4b, + 0x00002c4b, 0x00002e4b, 0x0000304b, 0x0000324b, + 0x0000344b, 0x0000364b, 0x0000384b, 0x00003a4b, + 0x00003c4b, 0x00003e4b, 0x0000404b, 0x0000424b, + 0x0000444b, 0x0000464b, 0x0000484b, 0x00004a4b, + 0x00004c4b, 0x00004e4b, 0x0000504b, 0x0000524b, + 0x0000544b, 0x0000564b, 0x0000584b, 0x00005a4b, + 0x00005c4b, 0x00005e4b, 0x0000604b, 0x0000624b, + 0x0000644b, 0x0000664b, 0x0000684b, 0x00006a4b, + 0x00006c4b, 0x00006e4b, 0x0000704b, 0x0000724b, + 0x0000744b, 0x0000764b, 0x0000784b, 0x00007a4b, + 0x00007c4b, 0x00007e4b, 0x0000804b, 0x0000824b, + 0x0000844b, 0x0000864b, 0x0000884b, 0x00008a4b, + 0x00008c4b, 0x00008e4b, 0x0000904b, 0x0000924b, + 0x0000944b, 0x0000964b, 0x0000984b, 0x00009a4b, + 0x00009c4b, 0x00009e4b, 0x0000a04b, 0x0000a24b, + 0x0000a44b, 0x0000a64b, 0x0000a84b, 0x0000aa4b, + 0x0000ac4b, 0x0000ae4b, 0x0000b04b, 0x0000b24b, + 0x0000b44b, 0x0000b64b, 0x0000b84b, 0x0000ba4b, + 0x0000bc4b, 0x0000be4b, 0x0000c04b, 0x0000c24b, + 0x0000c44b, 0x0000c64b, 0x0000c84b, 0x0000ca4b, + 0x0000cc4b, 0x0000ce4b, 0x0000d04b, 0x0000d24b, + 0x0000d44b, 0x0000d64b, 0x0000d84b, 0x0000da4b, + 0x0000dc4b, 0x0000de4b, 0x0000e04b, 0x0000e24b, + 0x0000e44b, 0x0000e64b, 0x0000e84b, 0x0000ea4b, + 0x0000ec4b, 0x0000ee4b, 0x0000f04b, 0x0000f24b, + 0x0000f44b, 0x0000f64b, 0x0000f84b, 0x0000fa4b, + 0x0000fc4b, 0x0000fe4b, 0x000001ac, 0x000005ac, + 0x000009ac, 0x00000dac, 0x000011ac, 0x000015ac, + 0x000019ac, 0x00001dac, 0x000021ac, 0x000025ac, + 0x000029ac, 0x00002dac, 0x000031ac, 0x000035ac, + 0x000039ac, 0x00003dac, 0x000041ac, 0x000045ac, + 0x000049ac, 0x00004dac, 0x000051ac, 0x000055ac, + 0x000059ac, 0x00005dac, 0x000061ac, 0x000065ac, + 0x000069ac, 0x00006dac, 0x000071ac, 0x000075ac, + 0x000079ac, 0x00007dac, 0x000081ac, 0x000085ac, + 0x000089ac, 0x00008dac, 0x000091ac, 0x000095ac, + 0x000099ac, 0x00009dac, 0x0000a1ac, 0x0000a5ac, + 0x0000a9ac, 0x0000adac, 0x0000b1ac, 0x0000b5ac, + 0x0000b9ac, 0x0000bdac, 0x0000c1ac, 0x0000c5ac, + 0x0000c9ac, 0x0000cdac, 0x0000d1ac, 0x0000d5ac, + 0x0000d9ac, 0x0000ddac, 0x0000e1ac, 0x0000e5ac, + 0x0000e9ac, 0x0000edac, 0x0000f1ac, 0x0000f5ac, + 0x0000f9ac, 0x0000fdac, 0x000101ac, 0x000105ac, + 0x000109ac, 0x00010dac, 0x000111ac, 0x000115ac, + 0x000119ac, 0x00011dac, 0x000121ac, 0x000125ac, + 0x000129ac, 0x00012dac, 0x000131ac, 0x000135ac, + 0x000139ac, 0x00013dac, 0x000141ac, 0x000145ac, + 0x000149ac, 0x00014dac, 0x000151ac, 0x000155ac, + 0x000159ac, 0x00015dac, 0x000161ac, 0x000165ac, + 0x000169ac, 0x00016dac, 0x000171ac, 0x000175ac, + 0x000179ac, 0x00017dac, 0x000181ac, 0x000185ac, + 0x000189ac, 0x00018dac, 0x000191ac, 0x000195ac, + 0x000199ac, 0x00019dac, 0x0001a1ac, 0x0001a5ac, + 0x0001a9ac, 0x0001adac, 0x0001b1ac, 0x0001b5ac, + 0x0001b9ac, 0x0001bdac, 0x0001c1ac, 0x0001c5ac, + 0x0001c9ac, 0x0001cdac, 0x0001d1ac, 0x0001d5ac, + 0x0001d9ac, 0x0001ddac, 0x0001e1ac, 0x0001e5ac, + 0x0001e9ac, 0x0001edac, 0x0001f1ac, 0x0001f5ac, + 0x0001f9ac, 0x0001fdac, 0x0000014c, 0x0000034c, + 0x0000054c, 0x0000074c, 0x0000094c, 0x00000b4c, + 0x00000d4c, 0x00000f4c, 0x0000114c, 0x0000134c, + 0x0000154c, 0x0000174c, 0x0000194c, 0x00001b4c, + 0x00001d4c, 0x00001f4c, 0x0000214c, 0x0000234c, + 0x0000254c, 0x0000274c, 0x0000294c, 0x00002b4c, + 0x00002d4c, 0x00002f4c, 0x0000314c, 0x0000334c, + 0x0000354c, 0x0000374c, 0x0000394c, 0x00003b4c, + 0x00003d4c, 0x00003f4c, 0x0000414c, 0x0000434c, + 0x0000454c, 0x0000474c, 0x0000494c, 0x00004b4c, + 0x00004d4c, 0x00004f4c, 0x0000514c, 0x0000534c, + 0x0000554c, 0x0000574c, 0x0000594c, 0x00005b4c, + 0x00005d4c, 0x00005f4c, 0x0000614c, 0x0000634c, + 0x0000654c, 0x0000674c, 0x0000694c, 0x00006b4c, + 0x00006d4c, 0x00006f4c, 0x0000714c, 0x0000734c, + 0x0000754c, 0x0000774c, 0x0000794c, 0x00007b4c, + 0x00007d4c, 0x00007f4c, 0x0000814c, 0x0000834c, + 0x0000854c, 0x0000874c, 0x0000894c, 0x00008b4c, + 0x00008d4c, 0x00008f4c, 0x0000914c, 0x0000934c, + 0x0000954c, 0x0000974c, 0x0000994c, 0x00009b4c, + 0x00009d4c, 0x00009f4c, 0x0000a14c, 0x0000a34c, + 0x0000a54c, 0x0000a74c, 0x0000a94c, 0x0000ab4c, + 0x0000ad4c, 0x0000af4c, 0x0000b14c, 0x0000b34c, + 0x0000b54c, 0x0000b74c, 0x0000b94c, 0x0000bb4c, + 0x0000bd4c, 0x0000bf4c, 0x0000c14c, 0x0000c34c, + 0x0000c54c, 0x0000c74c, 0x0000c94c, 0x0000cb4c, + 0x0000cd4c, 0x0000cf4c, 0x0000d14c, 0x0000d34c, + 0x0000d54c, 0x0000d74c, 0x0000d94c, 0x0000db4c, + 0x0000dd4c, 0x0000df4c, 0x0000e14c, 0x0000e34c, + 0x0000e54c, 0x0000e74c, 0x0000e94c, 0x0000eb4c, + 0x0000ed4c, 0x0000ef4c, 0x0000f14c, 0x0000f34c, + 0x0000f54c, 0x0000f74c, 0x0000f94c, 0x0000fb4c, + 0x0000fd4c, 0x0000ff4c, 0x0001014c, 0x0001034c, + 0x0001054c, 0x0001074c, 0x0001094c, 0x00010b4c, + 0x00010d4c, 0x00010f4c, 0x0001114c, 0x0001134c, + 0x0001154c, 0x0001174c, 0x0001194c, 0x00011b4c, + 0x00011d4c, 0x00011f4c, 0x0001214c, 0x0001234c, + 0x0001254c, 0x0001274c, 0x0001294c, 0x00012b4c, + 0x00012d4c, 0x00012f4c, 0x0001314c, 0x0001334c, + 0x0001354c, 0x0001374c, 0x0001394c, 0x00013b4c, + 0x00013d4c, 0x00013f4c, 0x0001414c, 0x0001434c, + 0x0001454c, 0x0001474c, 0x0001494c, 0x00014b4c, + 0x00014d4c, 0x00014f4c, 0x0001514c, 0x0001534c, + 0x0001554c, 0x0001574c, 0x0001594c, 0x00015b4c, + 0x00015d4c, 0x00015f4c, 0x0001614c, 0x0001634c, + 0x0001654c, 0x0001674c, 0x0001694c, 0x00016b4c, + 0x00016d4c, 0x00016f4c, 0x0001714c, 0x0001734c, + 0x0001754c, 0x0001774c, 0x0001794c, 0x00017b4c, + 0x00017d4c, 0x00017f4c, 0x0001814c, 0x0001834c, + 0x0001854c, 0x0001874c, 0x0001894c, 0x00018b4c, + 0x00018d4c, 0x00018f4c, 0x0001914c, 0x0001934c, + 0x0001954c, 0x0001974c, 0x0001994c, 0x00019b4c, + 0x00019d4c, 0x00019f4c, 0x0001a14c, 0x0001a34c, + 0x0001a54c, 0x0001a74c, 0x0001a94c, 0x0001ab4c, + 0x0001ad4c, 0x0001af4c, 0x0001b14c, 0x0001b34c, + 0x0001b54c, 0x0001b74c, 0x0001b94c, 0x0001bb4c, + 0x0001bd4c, 0x0001bf4c, 0x0001c14c, 0x0001c34c, + 0x0001c54c, 0x0001c74c, 0x0001c94c, 0x0001cb4c, + 0x0001cd4c, 0x0001cf4c, 0x0001d14c, 0x0001d34c, + 0x0001d54c, 0x0001d74c, 0x0001d94c, 0x0001db4c, + 0x0001dd4c, 0x0001df4c, 0x0001e14c, 0x0001e34c, + 0x0001e54c, 0x0001e74c, 0x0001e94c, 0x0001eb4c, + 0x0001ed4c, 0x0001ef4c, 0x0001f14c, 0x0001f34c, + 0x0001f54c, 0x0001f74c, 0x0001f94c, 0x0001fb4c, + 0x0001fd4c, 0x0001ff4c, 0x000003ad, 0x000007ad, + 0x00000bad, 0x00000fad, 0x000013ad, 0x000017ad, + 0x00001bad, 0x00001fad, 0x000023ad, 0x000027ad, + 0x00002bad, 0x00002fad, 0x000033ad, 0x000037ad, + 0x00003bad, 0x00003fad, 0x000043ad, 0x000047ad, + 0x00004bad, 0x00004fad, 0x000053ad, 0x000057ad, + 0x00005bad, 0x00005fad, 0x000063ad, 0x000067ad, + 0x00006bad, 0x00006fad, 0x000073ad, 0x000077ad, + 0x00007bad, 0x00007fad, 0x000083ad, 0x000087ad, + 0x00008bad, 0x00008fad, 0x000093ad, 0x000097ad, + 0x00009bad, 0x00009fad, 0x0000a3ad, 0x0000a7ad, + 0x0000abad, 0x0000afad, 0x0000b3ad, 0x0000b7ad, + 0x0000bbad, 0x0000bfad, 0x0000c3ad, 0x0000c7ad, + 0x0000cbad, 0x0000cfad, 0x0000d3ad, 0x0000d7ad, + 0x0000dbad, 0x0000dfad, 0x0000e3ad, 0x0000e7ad, + 0x0000ebad, 0x0000efad, 0x0000f3ad, 0x0000f7ad, + 0x0000fbad, 0x0000ffad, 0x000103ad, 0x000107ad, + 0x00010bad, 0x00010fad, 0x000113ad, 0x000117ad, + 0x00011bad, 0x00011fad, 0x000123ad, 0x000127ad, + 0x00012bad, 0x00012fad, 0x000133ad, 0x000137ad, + 0x00013bad, 0x00013fad, 0x000143ad, 0x000147ad, + 0x00014bad, 0x00014fad, 0x000153ad, 0x000157ad, + 0x00015bad, 0x00015fad, 0x000163ad, 0x000167ad, + 0x00016bad, 0x00016fad, 0x000173ad, 0x000177ad, + 0x00017bad, 0x00017fad, 0x000183ad, 0x000187ad, + 0x00018bad, 0x00018fad, 0x000193ad, 0x000197ad, + 0x00019bad, 0x00019fad, 0x0001a3ad, 0x0001a7ad, + 0x0001abad, 0x0001afad, 0x0001b3ad, 0x0001b7ad, + 0x0001bbad, 0x0001bfad, 0x0001c3ad, 0x0001c7ad, + 0x0001cbad, 0x0001cfad, 0x0001d3ad, 0x0001d7ad, + 0x0001dbad, 0x0001dfad, 0x0001e3ad, 0x0001e7ad, + 0x0001ebad, 0x0001efad, 0x0001f3ad, 0x0001f7ad, + 0x0001fbad, 0x0001ffad, 0x000203ad, 0x000207ad, + 0x00020bad, 0x00020fad, 0x000213ad, 0x000217ad, + 0x00021bad, 0x00021fad, 0x000223ad, 0x000227ad, + 0x00022bad, 0x00022fad, 0x000233ad, 0x000237ad, + 0x00023bad, 0x00023fad, 0x000243ad, 0x000247ad, + 0x00024bad, 0x00024fad, 0x000253ad, 0x000257ad, + 0x00025bad, 0x00025fad, 0x000263ad, 0x000267ad, + 0x00026bad, 0x00026fad, 0x000273ad, 0x000277ad, + 0x00027bad, 0x00027fad, 0x000283ad, 0x000287ad, + 0x00028bad, 0x00028fad, 0x000293ad, 0x000297ad, + 0x00029bad, 0x00029fad, 0x0002a3ad, 0x0002a7ad, + 0x0002abad, 0x0002afad, 0x0002b3ad, 0x0002b7ad, + 0x0002bbad, 0x0002bfad, 0x0002c3ad, 0x0002c7ad, + 0x0002cbad, 0x0002cfad, 0x0002d3ad, 0x0002d7ad, + 0x0002dbad, 0x0002dfad, 0x0002e3ad, 0x0002e7ad, + 0x0002ebad, 0x0002efad, 0x0002f3ad, 0x0002f7ad, + 0x0002fbad, 0x0002ffad, 0x000303ad, 0x000307ad, + 0x00030bad, 0x00030fad, 0x000313ad, 0x000317ad, + 0x00031bad, 0x00031fad, 0x000323ad, 0x000327ad, + 0x00032bad, 0x00032fad, 0x000333ad, 0x000337ad, + 0x00033bad, 0x00033fad, 0x000343ad, 0x000347ad, + 0x00034bad, 0x00034fad, 0x000353ad, 0x000357ad, + 0x00035bad, 0x00035fad, 0x000363ad, 0x000367ad, + 0x00036bad, 0x00036fad, 0x000373ad, 0x000377ad, + 0x00037bad, 0x00037fad, 0x000383ad, 0x000387ad, + 0x00038bad, 0x00038fad, 0x000393ad, 0x000397ad, + 0x00039bad, 0x00039fad, 0x0003a3ad, 0x0003a7ad, + 0x0003abad, 0x0003afad, 0x0003b3ad, 0x0003b7ad, + 0x0003bbad, 0x0003bfad, 0x0003c3ad, 0x0003c7ad, + 0x0003cbad, 0x0003cfad, 0x0003d3ad, 0x0003d7ad, + 0x0003dbad, 0x0003dfad, 0x0003e3ad, 0x0003e7ad, + 0x0003ebad, 0x0003efad, 0x0003f3ad, 0x0003f7ad, + 0x0003fbad, 0x0003ffad, 0x000000cd, 0x000002cd, + 0x000004cd, 0x000006cd, 0x000008cd, 0x00000acd, + 0x00000ccd, 0x00000ecd, 0x000010cd, 0x000012cd, + 0x000014cd, 0x000016cd, 0x000018cd, 0x00001acd, + 0x00001ccd, 0x00001ecd, 0x000020cd, 0x000022cd, + 0x000024cd, 0x000026cd, 0x000028cd, 0x00002acd, + 0x00002ccd, 0x00002ecd, 0x000030cd, 0x000032cd, + 0x000034cd, 0x000036cd, 0x000038cd, 0x00003acd, + 0x00003ccd, 0x00003ecd, 0x000040cd, 0x000042cd, + 0x000044cd, 0x000046cd, 0x000048cd, 0x00004acd, + 0x00004ccd, 0x00004ecd, 0x000050cd, 0x000052cd, + 0x000054cd, 0x000056cd, 0x000058cd, 0x00005acd, + 0x00005ccd, 0x00005ecd, 0x000060cd, 0x000062cd, + 0x000064cd, 0x000066cd, 0x000068cd, 0x00006acd, + 0x00006ccd, 0x00006ecd, 0x000070cd, 0x000072cd, + 0x000074cd, 0x000076cd, 0x000078cd, 0x00007acd, + 0x00007ccd, 0x00007ecd, 0x000080cd, 0x000082cd, + 0x000084cd, 0x000086cd, 0x000088cd, 0x00008acd, + 0x00008ccd, 0x00008ecd, 0x000090cd, 0x000092cd, + 0x000094cd, 0x000096cd, 0x000098cd, 0x00009acd, + 0x00009ccd, 0x00009ecd, 0x0000a0cd, 0x0000a2cd, + 0x0000a4cd, 0x0000a6cd, 0x0000a8cd, 0x0000aacd, + 0x0000accd, 0x0000aecd, 0x0000b0cd, 0x0000b2cd, + 0x0000b4cd, 0x0000b6cd, 0x0000b8cd, 0x0000bacd, + 0x0000bccd, 0x0000becd, 0x0000c0cd, 0x0000c2cd, + 0x0000c4cd, 0x0000c6cd, 0x0000c8cd, 0x0000cacd, + 0x0000cccd, 0x0000cecd, 0x0000d0cd, 0x0000d2cd, + 0x0000d4cd, 0x0000d6cd, 0x0000d8cd, 0x0000dacd, + 0x0000dccd, 0x0000decd, 0x0000e0cd, 0x0000e2cd, + 0x0000e4cd, 0x0000e6cd, 0x0000e8cd, 0x0000eacd, + 0x0000eccd, 0x0000eecd, 0x0000f0cd, 0x0000f2cd, + 0x0000f4cd, 0x0000f6cd, 0x0000f8cd, 0x0000facd, + 0x0000fccd, 0x0000fecd, 0x000100cd, 0x000102cd, + 0x000104cd, 0x000106cd, 0x000108cd, 0x00010acd, + 0x00010ccd, 0x00010ecd, 0x000110cd, 0x000112cd, + 0x000114cd, 0x000116cd, 0x000118cd, 0x00011acd, + 0x00011ccd, 0x00011ecd, 0x000120cd, 0x000122cd, + 0x000124cd, 0x000126cd, 0x000128cd, 0x00012acd, + 0x00012ccd, 0x00012ecd, 0x000130cd, 0x000132cd, + 0x000134cd, 0x000136cd, 0x000138cd, 0x00013acd, + 0x00013ccd, 0x00013ecd, 0x000140cd, 0x000142cd, + 0x000144cd, 0x000146cd, 0x000148cd, 0x00014acd, + 0x00014ccd, 0x00014ecd, 0x000150cd, 0x000152cd, + 0x000154cd, 0x000156cd, 0x000158cd, 0x00015acd, + 0x00015ccd, 0x00015ecd, 0x000160cd, 0x000162cd, + 0x000164cd, 0x000166cd, 0x000168cd, 0x00016acd, + 0x00016ccd, 0x00016ecd, 0x000170cd, 0x000172cd, + 0x000174cd, 0x000176cd, 0x000178cd, 0x00017acd, + 0x00017ccd, 0x00017ecd, 0x000180cd, 0x000182cd, + 0x000184cd, 0x000186cd, 0x000188cd, 0x00018acd, + 0x00018ccd, 0x00018ecd, 0x000190cd, 0x000192cd, + 0x000194cd, 0x000196cd, 0x000198cd, 0x00019acd, + 0x00019ccd, 0x00019ecd, 0x0001a0cd, 0x0001a2cd, + 0x0001a4cd, 0x0001a6cd, 0x0001a8cd, 0x0001aacd, + 0x0001accd, 0x0001aecd, 0x0001b0cd, 0x0001b2cd, + 0x0001b4cd, 0x0001b6cd, 0x0001b8cd, 0x0001bacd, + 0x0001bccd, 0x0001becd, 0x0001c0cd, 0x0001c2cd, + 0x0001c4cd, 0x0001c6cd, 0x0001c8cd, 0x0001cacd, + 0x0001cccd, 0x0001cecd, 0x0001d0cd, 0x0001d2cd, + 0x0001d4cd, 0x0001d6cd, 0x0001d8cd, 0x0001dacd, + 0x0001dccd, 0x0001decd, 0x0001e0cd, 0x0001e2cd, + 0x0001e4cd, 0x0001e6cd, 0x0001e8cd, 0x0001eacd, + 0x0001eccd, 0x0001eecd, 0x0001f0cd, 0x0001f2cd, + 0x0001f4cd, 0x0001f6cd, 0x0001f8cd, 0x0001facd, + 0x0001fccd, 0x0001fecd, 0x000200cd, 0x000202cd, + 0x000204cd, 0x000206cd, 0x000208cd, 0x00020acd, + 0x00020ccd, 0x00020ecd, 0x000210cd, 0x000212cd, + 0x000214cd, 0x000216cd, 0x000218cd, 0x00021acd, + 0x00021ccd, 0x00021ecd, 0x000220cd, 0x000222cd, + 0x000224cd, 0x000226cd, 0x000228cd, 0x00022acd, + 0x00022ccd, 0x00022ecd, 0x000230cd, 0x000232cd, + 0x000234cd, 0x000236cd, 0x000238cd, 0x00023acd, + 0x00023ccd, 0x00023ecd, 0x000240cd, 0x000242cd, + 0x000244cd, 0x000246cd, 0x000248cd, 0x00024acd, + 0x00024ccd, 0x00024ecd, 0x000250cd, 0x000252cd, + 0x000254cd, 0x000256cd, 0x000258cd, 0x00025acd, + 0x00025ccd, 0x00025ecd, 0x000260cd, 0x000262cd, + 0x000264cd, 0x000266cd, 0x000268cd, 0x00026acd, + 0x00026ccd, 0x00026ecd, 0x000270cd, 0x000272cd, + 0x000274cd, 0x000276cd, 0x000278cd, 0x00027acd, + 0x00027ccd, 0x00027ecd, 0x000280cd, 0x000282cd, + 0x000284cd, 0x000286cd, 0x000288cd, 0x00028acd, + 0x00028ccd, 0x00028ecd, 0x000290cd, 0x000292cd, + 0x000294cd, 0x000296cd, 0x000298cd, 0x00029acd, + 0x00029ccd, 0x00029ecd, 0x0002a0cd, 0x0002a2cd, + 0x0002a4cd, 0x0002a6cd, 0x0002a8cd, 0x0002aacd, + 0x0002accd, 0x0002aecd, 0x0002b0cd, 0x0002b2cd, + 0x0002b4cd, 0x0002b6cd, 0x0002b8cd, 0x0002bacd, + 0x0002bccd, 0x0002becd, 0x0002c0cd, 0x0002c2cd, + 0x0002c4cd, 0x0002c6cd, 0x0002c8cd, 0x0002cacd, + 0x0002cccd, 0x0002cecd, 0x0002d0cd, 0x0002d2cd, + 0x0002d4cd, 0x0002d6cd, 0x0002d8cd, 0x0002dacd, + 0x0002dccd, 0x0002decd, 0x0002e0cd, 0x0002e2cd, + 0x0002e4cd, 0x0002e6cd, 0x0002e8cd, 0x0002eacd, + 0x0002eccd, 0x0002eecd, 0x0002f0cd, 0x0002f2cd, + 0x0002f4cd, 0x0002f6cd, 0x0002f8cd, 0x0002facd, + 0x0002fccd, 0x0002fecd, 0x000300cd, 0x000302cd, + 0x000304cd, 0x000306cd, 0x000308cd, 0x00030acd, + 0x00030ccd, 0x00030ecd, 0x000310cd, 0x000312cd, + 0x000314cd, 0x000316cd, 0x000318cd, 0x00031acd, + 0x00031ccd, 0x00031ecd, 0x000320cd, 0x000322cd, + 0x000324cd, 0x000326cd, 0x000328cd, 0x00032acd, + 0x00032ccd, 0x00032ecd, 0x000330cd, 0x000332cd, + 0x000334cd, 0x000336cd, 0x000338cd, 0x00033acd, + 0x00033ccd, 0x00033ecd, 0x000340cd, 0x000342cd, + 0x000344cd, 0x000346cd, 0x000348cd, 0x00034acd, + 0x00034ccd, 0x00034ecd, 0x000350cd, 0x000352cd, + 0x000354cd, 0x000356cd, 0x000358cd, 0x00035acd, + 0x00035ccd, 0x00035ecd, 0x000360cd, 0x000362cd, + 0x000364cd, 0x000366cd, 0x000368cd, 0x00036acd, + 0x00036ccd, 0x00036ecd, 0x000370cd, 0x000372cd, + 0x000374cd, 0x000376cd, 0x000378cd, 0x00037acd, + 0x00037ccd, 0x00037ecd, 0x000380cd, 0x000382cd, + 0x000384cd, 0x000386cd, 0x000388cd, 0x00038acd, + 0x00038ccd, 0x00038ecd, 0x000390cd, 0x000392cd, + 0x000394cd, 0x000396cd, 0x000398cd, 0x00039acd, + 0x00039ccd, 0x00039ecd, 0x0003a0cd, 0x0003a2cd, + 0x0003a4cd, 0x0003a6cd, 0x0003a8cd, 0x0003aacd, + 0x0003accd, 0x0003aecd, 0x0003b0cd, 0x0003b2cd, + 0x0003b4cd, 0x0003b6cd, 0x0003b8cd, 0x0003bacd, + 0x0003bccd, 0x0003becd, 0x0003c0cd, 0x0003c2cd, + 0x0003c4cd, 0x0003c6cd, 0x0003c8cd, 0x0003cacd, + 0x0003cccd, 0x0003cecd, 0x0003d0cd, 0x0003d2cd, + 0x0003d4cd, 0x0003d6cd, 0x0003d8cd, 0x0003dacd, + 0x0003dccd, 0x0003decd, 0x0003e0cd, 0x0003e2cd, + 0x0003e4cd, 0x0003e6cd, 0x0003e8cd, 0x0003eacd, + 0x0003eccd, 0x0003eecd, 0x0003f0cd, 0x0003f2cd, + 0x0003f4cd, 0x0003f6cd, 0x0003f8cd, 0x0003facd, + 0x0003fccd, 0x0003fecd, 0x0000006e, 0x0000046e, + 0x0000086e, 0x00000c6e, 0x0000106e, 0x0000146e, + 0x0000186e, 0x00001c6e, 0x0000206e, 0x0000246e, + 0x0000286e, 0x00002c6e, 0x0000306e, 0x0000346e, + 0x0000386e, 0x00003c6e, 0x0000406e, 0x0000446e, + 0x0000486e, 0x00004c6e, 0x0000506e, 0x0000546e, + 0x0000586e, 0x00005c6e, 0x0000606e, 0x0000646e, + 0x0000686e, 0x00006c6e, 0x0000706e, 0x0000746e, + 0x0000786e, 0x00007c6e, 0x0000806e, 0x0000846e, + 0x0000886e, 0x00008c6e, 0x0000906e, 0x0000946e, + 0x0000986e, 0x00009c6e, 0x0000a06e, 0x0000a46e, + 0x0000a86e, 0x0000ac6e, 0x0000b06e, 0x0000b46e, + 0x0000b86e, 0x0000bc6e, 0x0000c06e, 0x0000c46e, + 0x0000c86e, 0x0000cc6e, 0x0000d06e, 0x0000d46e, + 0x0000d86e, 0x0000dc6e, 0x0000e06e, 0x0000e46e, + 0x0000e86e, 0x0000ec6e, 0x0000f06e, 0x0000f46e, + 0x0000f86e, 0x0000fc6e, 0x0001006e, 0x0001046e, + 0x0001086e, 0x00010c6e, 0x0001106e, 0x0001146e, + 0x0001186e, 0x00011c6e, 0x0001206e, 0x0001246e, + 0x0001286e, 0x00012c6e, 0x0001306e, 0x0001346e, + 0x0001386e, 0x00013c6e, 0x0001406e, 0x0001446e, + 0x0001486e, 0x00014c6e, 0x0001506e, 0x0001546e, + 0x0001586e, 0x00015c6e, 0x0001606e, 0x0001646e, + 0x0001686e, 0x00016c6e, 0x0001706e, 0x0001746e, + 0x0001786e, 0x00017c6e, 0x0001806e, 0x0001846e, + 0x0001886e, 0x00018c6e, 0x0001906e, 0x0001946e, + 0x0001986e, 0x00019c6e, 0x0001a06e, 0x0001a46e, + 0x0001a86e, 0x0001ac6e, 0x0001b06e, 0x0001b46e, + 0x0001b86e, 0x0001bc6e, 0x0001c06e, 0x0001c46e, + 0x0001c86e, 0x0001cc6e, 0x0001d06e, 0x0001d46e, + 0x0001d86e, 0x0001dc6e, 0x0001e06e, 0x0001e46e, + 0x0001e86e, 0x0001ec6e, 0x0001f06e, 0x0001f46e, + 0x0001f86e, 0x0001fc6e, 0x0002006e, 0x0002046e, + 0x0002086e, 0x00020c6e, 0x0002106e, 0x0002146e, + 0x0002186e, 0x00021c6e, 0x0002206e, 0x0002246e, + 0x0002286e, 0x00022c6e, 0x0002306e, 0x0002346e, + 0x0002386e, 0x00023c6e, 0x0002406e, 0x0002446e, + 0x0002486e, 0x00024c6e, 0x0002506e, 0x0002546e, + 0x0002586e, 0x00025c6e, 0x0002606e, 0x0002646e, + 0x0002686e, 0x00026c6e, 0x0002706e, 0x0002746e, + 0x0002786e, 0x00027c6e, 0x0002806e, 0x0002846e, + 0x0002886e, 0x00028c6e, 0x0002906e, 0x0002946e, + 0x0002986e, 0x00029c6e, 0x0002a06e, 0x0002a46e, + 0x0002a86e, 0x0002ac6e, 0x0002b06e, 0x0002b46e, + 0x0002b86e, 0x0002bc6e, 0x0002c06e, 0x0002c46e, + 0x0002c86e, 0x0002cc6e, 0x0002d06e, 0x0002d46e, + 0x0002d86e, 0x0002dc6e, 0x0002e06e, 0x0002e46e, + 0x0002e86e, 0x0002ec6e, 0x0002f06e, 0x0002f46e, + 0x0002f86e, 0x0002fc6e, 0x0003006e, 0x0003046e, + 0x0003086e, 0x00030c6e, 0x0003106e, 0x0003146e, + 0x0003186e, 0x00031c6e, 0x0003206e, 0x0003246e, + 0x0003286e, 0x00032c6e, 0x0003306e, 0x0003346e, + 0x0003386e, 0x00033c6e, 0x0003406e, 0x0003446e, + 0x0003486e, 0x00034c6e, 0x0003506e, 0x0003546e, + 0x0003586e, 0x00035c6e, 0x0003606e, 0x0003646e, + 0x0003686e, 0x00036c6e, 0x0003706e, 0x0003746e, + 0x0003786e, 0x00037c6e, 0x0003806e, 0x0003846e, + 0x0003886e, 0x00038c6e, 0x0003906e, 0x0003946e, + 0x0003986e, 0x00039c6e, 0x0003a06e, 0x0003a46e, + 0x0003a86e, 0x0003ac6e, 0x0003b06e, 0x0003b46e, + 0x0003b86e, 0x0003bc6e, 0x0003c06e, 0x0003c46e, + 0x0003c86e, 0x0003cc6e, 0x0003d06e, 0x0003d46e, + 0x0003d86e, 0x0003dc6e, 0x0003e06e, 0x0003e46e, + 0x0003e86e, 0x0003ec6e, 0x0003f06e, 0x0003f46e, + 0x0003f86e, 0x0003fc6e, 0x0004006e, 0x0004046e, + 0x0004086e, 0x00040c6e, 0x0004106e, 0x0004146e, + 0x0004186e, 0x00041c6e, 0x0004206e, 0x0004246e, + 0x0004286e, 0x00042c6e, 0x0004306e, 0x0004346e, + 0x0004386e, 0x00043c6e, 0x0004406e, 0x0004446e, + 0x0004486e, 0x00044c6e, 0x0004506e, 0x0004546e, + 0x0004586e, 0x00045c6e, 0x0004606e, 0x0004646e, + 0x0004686e, 0x00046c6e, 0x0004706e, 0x0004746e, + 0x0004786e, 0x00047c6e, 0x0004806e, 0x0004846e, + 0x0004886e, 0x00048c6e, 0x0004906e, 0x0004946e, + 0x0004986e, 0x00049c6e, 0x0004a06e, 0x0004a46e, + 0x0004a86e, 0x0004ac6e, 0x0004b06e, 0x0004b46e, + 0x0004b86e, 0x0004bc6e, 0x0004c06e, 0x0004c46e, + 0x0004c86e, 0x0004cc6e, 0x0004d06e, 0x0004d46e, + 0x0004d86e, 0x0004dc6e, 0x0004e06e, 0x0004e46e, + 0x0004e86e, 0x0004ec6e, 0x0004f06e, 0x0004f46e, + 0x0004f86e, 0x0004fc6e, 0x0005006e, 0x0005046e, + 0x0005086e, 0x00050c6e, 0x0005106e, 0x0005146e, + 0x0005186e, 0x00051c6e, 0x0005206e, 0x0005246e, + 0x0005286e, 0x00052c6e, 0x0005306e, 0x0005346e, + 0x0005386e, 0x00053c6e, 0x0005406e, 0x0005446e, + 0x0005486e, 0x00054c6e, 0x0005506e, 0x0005546e, + 0x0005586e, 0x00055c6e, 0x0005606e, 0x0005646e, + 0x0005686e, 0x00056c6e, 0x0005706e, 0x0005746e, + 0x0005786e, 0x00057c6e, 0x0005806e, 0x0005846e, + 0x0005886e, 0x00058c6e, 0x0005906e, 0x0005946e, + 0x0005986e, 0x00059c6e, 0x0005a06e, 0x0005a46e, + 0x0005a86e, 0x0005ac6e, 0x0005b06e, 0x0005b46e, + 0x0005b86e, 0x0005bc6e, 0x0005c06e, 0x0005c46e, + 0x0005c86e, 0x0005cc6e, 0x0005d06e, 0x0005d46e, + 0x0005d86e, 0x0005dc6e, 0x0005e06e, 0x0005e46e, + 0x0005e86e, 0x0005ec6e, 0x0005f06e, 0x0005f46e, + 0x0005f86e, 0x0005fc6e, 0x0006006e, 0x0006046e, + 0x0006086e, 0x00060c6e, 0x0006106e, 0x0006146e, + 0x0006186e, 0x00061c6e, 0x0006206e, 0x0006246e, + 0x0006286e, 0x00062c6e, 0x0006306e, 0x0006346e, + 0x0006386e, 0x00063c6e, 0x0006406e, 0x0006446e, + 0x0006486e, 0x00064c6e, 0x0006506e, 0x0006546e, + 0x0006586e, 0x00065c6e, 0x0006606e, 0x0006646e, + 0x0006686e, 0x00066c6e, 0x0006706e, 0x0006746e, + 0x0006786e, 0x00067c6e, 0x0006806e, 0x0006846e, + 0x0006886e, 0x00068c6e, 0x0006906e, 0x0006946e, + 0x0006986e, 0x00069c6e, 0x0006a06e, 0x0006a46e, + 0x0006a86e, 0x0006ac6e, 0x0006b06e, 0x0006b46e, + 0x0006b86e, 0x0006bc6e, 0x0006c06e, 0x0006c46e, + 0x0006c86e, 0x0006cc6e, 0x0006d06e, 0x0006d46e, + 0x0006d86e, 0x0006dc6e, 0x0006e06e, 0x0006e46e, + 0x0006e86e, 0x0006ec6e, 0x0006f06e, 0x0006f46e, + 0x0006f86e, 0x0006fc6e, 0x0007006e, 0x0007046e, + 0x0007086e, 0x00070c6e, 0x0007106e, 0x0007146e, + 0x0007186e, 0x00071c6e, 0x0007206e, 0x0007246e, + 0x0007286e, 0x00072c6e, 0x0007306e, 0x0007346e, + 0x0007386e, 0x00073c6e, 0x0007406e, 0x0007446e, + 0x0007486e, 0x00074c6e, 0x0007506e, 0x0007546e, + 0x0007586e, 0x00075c6e, 0x0007606e, 0x0007646e, + 0x0007686e, 0x00076c6e, 0x0007706e, 0x0007746e, + 0x0007786e, 0x00077c6e, 0x0007806e, 0x0007846e, + 0x0007886e, 0x00078c6e, 0x0007906e, 0x0007946e, + 0x0007986e, 0x00079c6e, 0x0007a06e, 0x0007a46e, + 0x0007a86e, 0x0007ac6e, 0x0007b06e, 0x0007b46e, + 0x0007b86e, 0x0007bc6e, 0x0007c06e, 0x0007c46e, + 0x0007c86e, 0x0007cc6e, 0x0007d06e, 0x0007d46e, + 0x0007d86e, 0x0007dc6e, 0x0007e06e, 0x0007e46e, + 0x0007e86e, 0x0007ec6e, 0x0007f06e, 0x0007f46e, + 0x0007f86e, 0x0007fc6e, 0x0000000d, 0x0000010d, + 0x0000020d, 0x0000030d, 0x0000040d, 0x0000050d, + 0x0000060d, 0x0000070d, 0x0000080d, 0x0000090d, + 0x00000a0d, 0x00000b0d, 0x00000c0d, 0x00000d0d, + 0x00000e0d, 0x00000f0d, 0x0000100d, 0x0000110d, + 0x0000120d, 0x0000130d, 0x0000140d, 0x0000150d, + 0x0000160d, 0x0000170d, 0x0000180d, 0x0000190d, + 0x00001a0d, 0x00001b0d, 0x00001c0d, 0x00001d0d, + 0x00001e0d, 0x00001f0d, 0x0000200d, 0x0000210d, + 0x0000220d, 0x0000230d, 0x0000240d, 0x0000250d, + 0x0000260d, 0x0000270d, 0x0000280d, 0x0000290d, + 0x00002a0d, 0x00002b0d, 0x00002c0d, 0x00002d0d, + 0x00002e0d, 0x00002f0d, 0x0000300d, 0x0000310d, + 0x0000320d, 0x0000330d, 0x0000340d, 0x0000350d, + 0x0000360d, 0x0000370d, 0x0000380d, 0x0000390d, + 0x00003a0d, 0x00003b0d, 0x00003c0d, 0x00003d0d, + 0x00003e0d, 0x00003f0d, 0x0000400d, 0x0000410d, + 0x0000420d, 0x0000430d, 0x0000440d, 0x0000450d, + 0x0000460d, 0x0000470d, 0x0000480d, 0x0000490d, + 0x00004a0d, 0x00004b0d, 0x00004c0d, 0x00004d0d, + 0x00004e0d, 0x00004f0d, 0x0000500d, 0x0000510d, + 0x0000520d, 0x0000530d, 0x0000540d, 0x0000550d, + 0x0000560d, 0x0000570d, 0x0000580d, 0x0000590d, + 0x00005a0d, 0x00005b0d, 0x00005c0d, 0x00005d0d, + 0x00005e0d, 0x00005f0d, 0x0000600d, 0x0000610d, + 0x0000620d, 0x0000630d, 0x0000640d, 0x0000650d, + 0x0000660d, 0x0000670d, 0x0000680d, 0x0000690d, + 0x00006a0d, 0x00006b0d, 0x00006c0d, 0x00006d0d, + 0x00006e0d, 0x00006f0d, 0x0000700d, 0x0000710d, + 0x0000720d, 0x0000730d, 0x0000740d, 0x0000750d, + 0x0000760d, 0x0000770d, 0x0000780d, 0x0000790d, + 0x00007a0d, 0x00007b0d, 0x00007c0d, 0x00007d0d, + 0x00007e0d, 0x00007f0d, 0x0000800d, 0x0000810d, + 0x0000820d, 0x0000830d, 0x0000840d, 0x0000850d, + 0x0000860d, 0x0000870d, 0x0000880d, 0x0000890d, + 0x00008a0d, 0x00008b0d, 0x00008c0d, 0x00008d0d, + 0x00008e0d, 0x00008f0d, 0x0000900d, 0x0000910d, + 0x0000920d, 0x0000930d, 0x0000940d, 0x0000950d, + 0x0000960d, 0x0000970d, 0x0000980d, 0x0000990d, + 0x00009a0d, 0x00009b0d, 0x00009c0d, 0x00009d0d, + 0x00009e0d, 0x00009f0d, 0x0000a00d, 0x0000a10d, + 0x0000a20d, 0x0000a30d, 0x0000a40d, 0x0000a50d, + 0x0000a60d, 0x0000a70d, 0x0000a80d, 0x0000a90d, + 0x0000aa0d, 0x0000ab0d, 0x0000ac0d, 0x0000ad0d, + 0x0000ae0d, 0x0000af0d, 0x0000b00d, 0x0000b10d, + 0x0000b20d, 0x0000b30d, 0x0000b40d, 0x0000b50d, + 0x0000b60d, 0x0000b70d, 0x0000b80d, 0x0000b90d, + 0x0000ba0d, 0x0000bb0d, 0x0000bc0d, 0x0000bd0d, + 0x0000be0d, 0x0000bf0d, 0x0000c00d, 0x0000c10d, + 0x0000c20d, 0x0000c30d, 0x0000c40d, 0x0000c50d, + 0x0000c60d, 0x0000c70d, 0x0000c80d, 0x0000c90d, + 0x0000ca0d, 0x0000cb0d, 0x0000cc0d, 0x0000cd0d, + 0x0000ce0d, 0x0000cf0d, 0x0000d00d, 0x0000d10d, + 0x0000d20d, 0x0000d30d, 0x0000d40d, 0x0000d50d, + 0x0000d60d, 0x0000d70d, 0x0000d80d, 0x0000d90d, + 0x0000da0d, 0x0000db0d, 0x0000dc0d, 0x0000dd0d, + 0x0000de0d, 0x0000df0d, 0x0000e00d, 0x0000e10d, + 0x0000e20d, 0x0000e30d, 0x0000e40d, 0x0000e50d, + 0x0000e60d, 0x0000e70d, 0x0000e80d, 0x0000e90d, + 0x0000ea0d, 0x0000eb0d, 0x0000ec0d, 0x0000ed0d, + 0x0000ee0d, 0x0000ef0d, 0x0000f00d, 0x0000f10d, + 0x0000f20d, 0x0000f30d, 0x0000f40d, 0x0000f50d, + 0x0000f60d, 0x0000f70d, 0x0000f80d, 0x0000f90d, + 0x0000fa0d, 0x0000fb0d, 0x0000fc0d, 0x0000fd0d, + 0x0000fe0d, 0x0000ff0d, 0x0001000d, 0x0001010d, + 0x0001020d, 0x0001030d, 0x0001040d, 0x0001050d, + 0x0001060d, 0x0001070d, 0x0001080d, 0x0001090d, + 0x00010a0d, 0x00010b0d, 0x00010c0d, 0x00010d0d, + 0x00010e0d, 0x00010f0d, 0x0001100d, 0x0001110d, + 0x0001120d, 0x0001130d, 0x0001140d, 0x0001150d, + 0x0001160d, 0x0001170d, 0x0001180d, 0x0001190d, + 0x00011a0d, 0x00011b0d, 0x00011c0d, 0x00011d0d, + 0x00011e0d, 0x00011f0d, 0x0001200d, 0x0001210d, + 0x0001220d, 0x0001230d, 0x0001240d, 0x0001250d, + 0x0001260d, 0x0001270d, 0x0001280d, 0x0001290d, + 0x00012a0d, 0x00012b0d, 0x00012c0d, 0x00012d0d, + 0x00012e0d, 0x00012f0d, 0x0001300d, 0x0001310d, + 0x0001320d, 0x0001330d, 0x0001340d, 0x0001350d, + 0x0001360d, 0x0001370d, 0x0001380d, 0x0001390d, + 0x00013a0d, 0x00013b0d, 0x00013c0d, 0x00013d0d, + 0x00013e0d, 0x00013f0d, 0x0001400d, 0x0001410d, + 0x0001420d, 0x0001430d, 0x0001440d, 0x0001450d, + 0x0001460d, 0x0001470d, 0x0001480d, 0x0001490d, + 0x00014a0d, 0x00014b0d, 0x00014c0d, 0x00014d0d, + 0x00014e0d, 0x00014f0d, 0x0001500d, 0x0001510d, + 0x0001520d, 0x0001530d, 0x0001540d, 0x0001550d, + 0x0001560d, 0x0001570d, 0x0001580d, 0x0001590d, + 0x00015a0d, 0x00015b0d, 0x00015c0d, 0x00015d0d, + 0x00015e0d, 0x00015f0d, 0x0001600d, 0x0001610d, + 0x0001620d, 0x0001630d, 0x0001640d, 0x0001650d, + 0x0001660d, 0x0001670d, 0x0001680d, 0x0001690d, + 0x00016a0d, 0x00016b0d, 0x00016c0d, 0x00016d0d, + 0x00016e0d, 0x00016f0d, 0x0001700d, 0x0001710d, + 0x0001720d, 0x0001730d, 0x0001740d, 0x0001750d, + 0x0001760d, 0x0001770d, 0x0001780d, 0x0001790d, + 0x00017a0d, 0x00017b0d, 0x00017c0d, 0x00017d0d, + 0x00017e0d, 0x00017f0d, 0x0001800d, 0x0001810d, + 0x0001820d, 0x0001830d, 0x0001840d, 0x0001850d, + 0x0001860d, 0x0001870d, 0x0001880d, 0x0001890d, + 0x00018a0d, 0x00018b0d, 0x00018c0d, 0x00018d0d, + 0x00018e0d, 0x00018f0d, 0x0001900d, 0x0001910d, + 0x0001920d, 0x0001930d, 0x0001940d, 0x0001950d, + 0x0001960d, 0x0001970d, 0x0001980d, 0x0001990d, + 0x00019a0d, 0x00019b0d, 0x00019c0d, 0x00019d0d, + 0x00019e0d, 0x00019f0d, 0x0001a00d, 0x0001a10d, + 0x0001a20d, 0x0001a30d, 0x0001a40d, 0x0001a50d, + 0x0001a60d, 0x0001a70d, 0x0001a80d, 0x0001a90d, + 0x0001aa0d, 0x0001ab0d, 0x0001ac0d, 0x0001ad0d, + 0x0001ae0d, 0x0001af0d, 0x0001b00d, 0x0001b10d, + 0x0001b20d, 0x0001b30d, 0x0001b40d, 0x0001b50d, + 0x0001b60d, 0x0001b70d, 0x0001b80d, 0x0001b90d, + 0x0001ba0d, 0x0001bb0d, 0x0001bc0d, 0x0001bd0d, + 0x0001be0d, 0x0001bf0d, 0x0001c00d, 0x0001c10d, + 0x0001c20d, 0x0001c30d, 0x0001c40d, 0x0001c50d, + 0x0001c60d, 0x0001c70d, 0x0001c80d, 0x0001c90d, + 0x0001ca0d, 0x0001cb0d, 0x0001cc0d, 0x0001cd0d, + 0x0001ce0d, 0x0001cf0d, 0x0001d00d, 0x0001d10d, + 0x0001d20d, 0x0001d30d, 0x0001d40d, 0x0001d50d, + 0x0001d60d, 0x0001d70d, 0x0001d80d, 0x0001d90d, + 0x0001da0d, 0x0001db0d, 0x0001dc0d, 0x0001dd0d, + 0x0001de0d, 0x0001df0d, 0x0001e00d, 0x0001e10d, + 0x0001e20d, 0x0001e30d, 0x0001e40d, 0x0001e50d, + 0x0001e60d, 0x0001e70d, 0x0001e80d, 0x0001e90d, + 0x0001ea0d, 0x0001eb0d, 0x0001ec0d, 0x0001ed0d, + 0x0001ee0d, 0x0001ef0d, 0x0001f00d, 0x0001f10d, + 0x0001f20d, 0x0001f30d, 0x0001f40d, 0x0001f50d, + 0x0001f60d, 0x0001f70d, 0x0001f80d, 0x0001f90d, + 0x0001fa0d, 0x0001fb0d, 0x0001fc0d, 0x0001fd0d, + 0x0001fe0d, 0x0001ff0d, 0x0002000d, 0x0002010d, + 0x0002020d, 0x0002030d, 0x0002040d, 0x0002050d, + 0x0002060d, 0x0002070d, 0x0002080d, 0x0002090d, + 0x00020a0d, 0x00020b0d, 0x00020c0d, 0x00020d0d, + 0x00020e0d, 0x00020f0d, 0x0002100d, 0x0002110d, + 0x0002120d, 0x0002130d, 0x0002140d, 0x0002150d, + 0x0002160d, 0x0002170d, 0x0002180d, 0x0002190d, + 0x00021a0d, 0x00021b0d, 0x00021c0d, 0x00021d0d, + 0x00021e0d, 0x00021f0d, 0x0002200d, 0x0002210d, + 0x0002220d, 0x0002230d, 0x0002240d, 0x0002250d, + 0x0002260d, 0x0002270d, 0x0002280d, 0x0002290d, + 0x00022a0d, 0x00022b0d, 0x00022c0d, 0x00022d0d, + 0x00022e0d, 0x00022f0d, 0x0002300d, 0x0002310d, + 0x0002320d, 0x0002330d, 0x0002340d, 0x0002350d, + 0x0002360d, 0x0002370d, 0x0002380d, 0x0002390d, + 0x00023a0d, 0x00023b0d, 0x00023c0d, 0x00023d0d, + 0x00023e0d, 0x00023f0d, 0x0002400d, 0x0002410d, + 0x0002420d, 0x0002430d, 0x0002440d, 0x0002450d, + 0x0002460d, 0x0002470d, 0x0002480d, 0x0002490d, + 0x00024a0d, 0x00024b0d, 0x00024c0d, 0x00024d0d, + 0x00024e0d, 0x00024f0d, 0x0002500d, 0x0002510d, + 0x0002520d, 0x0002530d, 0x0002540d, 0x0002550d, + 0x0002560d, 0x0002570d, 0x0002580d, 0x0002590d, + 0x00025a0d, 0x00025b0d, 0x00025c0d, 0x00025d0d, + 0x00025e0d, 0x00025f0d, 0x0002600d, 0x0002610d, + 0x0002620d, 0x0002630d, 0x0002640d, 0x0002650d, + 0x0002660d, 0x0002670d, 0x0002680d, 0x0002690d, + 0x00026a0d, 0x00026b0d, 0x00026c0d, 0x00026d0d, + 0x00026e0d, 0x00026f0d, 0x0002700d, 0x0002710d, + 0x0002720d, 0x0002730d, 0x0002740d, 0x0002750d, + 0x0002760d, 0x0002770d, 0x0002780d, 0x0002790d, + 0x00027a0d, 0x00027b0d, 0x00027c0d, 0x00027d0d, + 0x00027e0d, 0x00027f0d, 0x0002800d, 0x0002810d, + 0x0002820d, 0x0002830d, 0x0002840d, 0x0002850d, + 0x0002860d, 0x0002870d, 0x0002880d, 0x0002890d, + 0x00028a0d, 0x00028b0d, 0x00028c0d, 0x00028d0d, + 0x00028e0d, 0x00028f0d, 0x0002900d, 0x0002910d, + 0x0002920d, 0x0002930d, 0x0002940d, 0x0002950d, + 0x0002960d, 0x0002970d, 0x0002980d, 0x0002990d, + 0x00029a0d, 0x00029b0d, 0x00029c0d, 0x00029d0d, + 0x00029e0d, 0x00029f0d, 0x0002a00d, 0x0002a10d, + 0x0002a20d, 0x0002a30d, 0x0002a40d, 0x0002a50d, + 0x0002a60d, 0x0002a70d, 0x0002a80d, 0x0002a90d, + 0x0002aa0d, 0x0002ab0d, 0x0002ac0d, 0x0002ad0d, + 0x0002ae0d, 0x0002af0d, 0x0002b00d, 0x0002b10d, + 0x0002b20d, 0x0002b30d, 0x0002b40d, 0x0002b50d, + 0x0002b60d, 0x0002b70d, 0x0002b80d, 0x0002b90d, + 0x0002ba0d, 0x0002bb0d, 0x0002bc0d, 0x0002bd0d, + 0x0002be0d, 0x0002bf0d, 0x0002c00d, 0x0002c10d, + 0x0002c20d, 0x0002c30d, 0x0002c40d, 0x0002c50d, + 0x0002c60d, 0x0002c70d, 0x0002c80d, 0x0002c90d, + 0x0002ca0d, 0x0002cb0d, 0x0002cc0d, 0x0002cd0d, + 0x0002ce0d, 0x0002cf0d, 0x0002d00d, 0x0002d10d, + 0x0002d20d, 0x0002d30d, 0x0002d40d, 0x0002d50d, + 0x0002d60d, 0x0002d70d, 0x0002d80d, 0x0002d90d, + 0x0002da0d, 0x0002db0d, 0x0002dc0d, 0x0002dd0d, + 0x0002de0d, 0x0002df0d, 0x0002e00d, 0x0002e10d, + 0x0002e20d, 0x0002e30d, 0x0002e40d, 0x0002e50d, + 0x0002e60d, 0x0002e70d, 0x0002e80d, 0x0002e90d, + 0x0002ea0d, 0x0002eb0d, 0x0002ec0d, 0x0002ed0d, + 0x0002ee0d, 0x0002ef0d, 0x0002f00d, 0x0002f10d, + 0x0002f20d, 0x0002f30d, 0x0002f40d, 0x0002f50d, + 0x0002f60d, 0x0002f70d, 0x0002f80d, 0x0002f90d, + 0x0002fa0d, 0x0002fb0d, 0x0002fc0d, 0x0002fd0d, + 0x0002fe0d, 0x0002ff0d, 0x0003000d, 0x0003010d, + 0x0003020d, 0x0003030d, 0x0003040d, 0x0003050d, + 0x0003060d, 0x0003070d, 0x0003080d, 0x0003090d, + 0x00030a0d, 0x00030b0d, 0x00030c0d, 0x00030d0d, + 0x00030e0d, 0x00030f0d, 0x0003100d, 0x0003110d, + 0x0003120d, 0x0003130d, 0x0003140d, 0x0003150d, + 0x0003160d, 0x0003170d, 0x0003180d, 0x0003190d, + 0x00031a0d, 0x00031b0d, 0x00031c0d, 0x00031d0d, + 0x00031e0d, 0x00031f0d, 0x0003200d, 0x0003210d, + 0x0003220d, 0x0003230d, 0x0003240d, 0x0003250d, + 0x0003260d, 0x0003270d, 0x0003280d, 0x0003290d, + 0x00032a0d, 0x00032b0d, 0x00032c0d, 0x00032d0d, + 0x00032e0d, 0x00032f0d, 0x0003300d, 0x0003310d, + 0x0003320d, 0x0003330d, 0x0003340d, 0x0003350d, + 0x0003360d, 0x0003370d, 0x0003380d, 0x0003390d, + 0x00033a0d, 0x00033b0d, 0x00033c0d, 0x00033d0d, + 0x00033e0d, 0x00033f0d, 0x0003400d, 0x0003410d, + 0x0003420d, 0x0003430d, 0x0003440d, 0x0003450d, + 0x0003460d, 0x0003470d, 0x0003480d, 0x0003490d, + 0x00034a0d, 0x00034b0d, 0x00034c0d, 0x00034d0d, + 0x00034e0d, 0x00034f0d, 0x0003500d, 0x0003510d, + 0x0003520d, 0x0003530d, 0x0003540d, 0x0003550d, + 0x0003560d, 0x0003570d, 0x0003580d, 0x0003590d, + 0x00035a0d, 0x00035b0d, 0x00035c0d, 0x00035d0d, + 0x00035e0d, 0x00035f0d, 0x0003600d, 0x0003610d, + 0x0003620d, 0x0003630d, 0x0003640d, 0x0003650d, + 0x0003660d, 0x0003670d, 0x0003680d, 0x0003690d, + 0x00036a0d, 0x00036b0d, 0x00036c0d, 0x00036d0d, + 0x00036e0d, 0x00036f0d, 0x0003700d, 0x0003710d, + 0x0003720d, 0x0003730d, 0x0003740d, 0x0003750d, + 0x0003760d, 0x0003770d, 0x0003780d, 0x0003790d, + 0x00037a0d, 0x00037b0d, 0x00037c0d, 0x00037d0d, + 0x00037e0d, 0x00037f0d, 0x0003800d, 0x0003810d, + 0x0003820d, 0x0003830d, 0x0003840d, 0x0003850d, + 0x0003860d, 0x0003870d, 0x0003880d, 0x0003890d, + 0x00038a0d, 0x00038b0d, 0x00038c0d, 0x00038d0d, + 0x00038e0d, 0x00038f0d, 0x0003900d, 0x0003910d, + 0x0003920d, 0x0003930d, 0x0003940d, 0x0003950d, + 0x0003960d, 0x0003970d, 0x0003980d, 0x0003990d, + 0x00039a0d, 0x00039b0d, 0x00039c0d, 0x00039d0d, + 0x00039e0d, 0x00039f0d, 0x0003a00d, 0x0003a10d, + 0x0003a20d, 0x0003a30d, 0x0003a40d, 0x0003a50d, + 0x0003a60d, 0x0003a70d, 0x0003a80d, 0x0003a90d, + 0x0003aa0d, 0x0003ab0d, 0x0003ac0d, 0x0003ad0d, + 0x0003ae0d, 0x0003af0d, 0x0003b00d, 0x0003b10d, + 0x0003b20d, 0x0003b30d, 0x0003b40d, 0x0003b50d, + 0x0003b60d, 0x0003b70d, 0x0003b80d, 0x0003b90d, + 0x0003ba0d, 0x0003bb0d, 0x0003bc0d, 0x0003bd0d, + 0x0003be0d, 0x0003bf0d, 0x0003c00d, 0x0003c10d, + 0x0003c20d, 0x0003c30d, 0x0003c40d, 0x0003c50d, + 0x0003c60d, 0x0003c70d, 0x0003c80d, 0x0003c90d, + 0x0003ca0d, 0x0003cb0d, 0x0003cc0d, 0x0003cd0d, + 0x0003ce0d, 0x0003cf0d, 0x0003d00d, 0x0003d10d, + 0x0003d20d, 0x0003d30d, 0x0003d40d, 0x0003d50d, + 0x0003d60d, 0x0003d70d, 0x0003d80d, 0x0003d90d, + 0x0003da0d, 0x0003db0d, 0x0003dc0d, 0x0003dd0d, + 0x0003de0d, 0x0003df0d, 0x0003e00d, 0x0003e10d, + 0x0003e20d, 0x0003e30d, 0x0003e40d, 0x0003e50d, + 0x0003e60d, 0x0003e70d, 0x0003e80d, 0x0003e90d, + 0x0003ea0d, 0x0003eb0d, 0x0003ec0d, 0x0003ed0d, + 0x0003ee0d, 0x0003ef0d, 0x0003f00d, 0x0003f10d, + 0x0003f20d, 0x0003f30d, 0x0003f40d, 0x0003f50d, + 0x0003f60d, 0x0003f70d, 0x0003f80d, 0x0003f90d, + 0x0003fa0d, 0x0003fb0d, 0x0003fc0d, 0x0003fd0d, + 0x0003fe0d, 0x0003ff0d, 0x0000026f, 0x0000066f, + 0x00000a6f, 0x00000e6f, 0x0000126f, 0x0000166f, + 0x00001a6f, 0x00001e6f, 0x0000226f, 0x0000266f, + 0x00002a6f, 0x00002e6f, 0x0000326f, 0x0000366f, + 0x00003a6f, 0x00003e6f, 0x0000426f, 0x0000466f, + 0x00004a6f, 0x00004e6f, 0x0000526f, 0x0000566f, + 0x00005a6f, 0x00005e6f, 0x0000626f, 0x0000666f, + 0x00006a6f, 0x00006e6f, 0x0000726f, 0x0000766f, + 0x00007a6f, 0x00007e6f, 0x0000826f, 0x0000866f, + 0x00008a6f, 0x00008e6f, 0x0000926f, 0x0000966f, + 0x00009a6f, 0x00009e6f, 0x0000a26f, 0x0000a66f, + 0x0000aa6f, 0x0000ae6f, 0x0000b26f, 0x0000b66f, + 0x0000ba6f, 0x0000be6f, 0x0000c26f, 0x0000c66f, + 0x0000ca6f, 0x0000ce6f, 0x0000d26f, 0x0000d66f, + 0x0000da6f, 0x0000de6f, 0x0000e26f, 0x0000e66f, + 0x0000ea6f, 0x0000ee6f, 0x0000f26f, 0x0000f66f, + 0x0000fa6f, 0x0000fe6f, 0x0001026f, 0x0001066f, + 0x00010a6f, 0x00010e6f, 0x0001126f, 0x0001166f, + 0x00011a6f, 0x00011e6f, 0x0001226f, 0x0001266f, + 0x00012a6f, 0x00012e6f, 0x0001326f, 0x0001366f, + 0x00013a6f, 0x00013e6f, 0x0001426f, 0x0001466f, + 0x00014a6f, 0x00014e6f, 0x0001526f, 0x0001566f, + 0x00015a6f, 0x00015e6f, 0x0001626f, 0x0001666f, + 0x00016a6f, 0x00016e6f, 0x0001726f, 0x0001766f, + 0x00017a6f, 0x00017e6f, 0x0001826f, 0x0001866f, + 0x00018a6f, 0x00018e6f, 0x0001926f, 0x0001966f, + 0x00019a6f, 0x00019e6f, 0x0001a26f, 0x0001a66f, + 0x0001aa6f, 0x0001ae6f, 0x0001b26f, 0x0001b66f, + 0x0001ba6f, 0x0001be6f, 0x0001c26f, 0x0001c66f, + 0x0001ca6f, 0x0001ce6f, 0x0001d26f, 0x0001d66f, + 0x0001da6f, 0x0001de6f, 0x0001e26f, 0x0001e66f, + 0x0001ea6f, 0x0001ee6f, 0x0001f26f, 0x0001f66f, + 0x0001fa6f, 0x0001fe6f, 0x0002026f, 0x0002066f, + 0x00020a6f, 0x00020e6f, 0x0002126f, 0x0002166f, + 0x00021a6f, 0x00021e6f, 0x0002226f, 0x0002266f, + 0x00022a6f, 0x00022e6f, 0x0002326f, 0x0002366f, + 0x00023a6f, 0x00023e6f, 0x0002426f, 0x0002466f, + 0x00024a6f, 0x00024e6f, 0x0002526f, 0x0002566f, + 0x00025a6f, 0x00025e6f, 0x0002626f, 0x0002666f, + 0x00026a6f, 0x00026e6f, 0x0002726f, 0x0002766f, + 0x00027a6f, 0x00027e6f, 0x0002826f, 0x0002866f, + 0x00028a6f, 0x00028e6f, 0x0002926f, 0x0002966f, + 0x00029a6f, 0x00029e6f, 0x0002a26f, 0x0002a66f, + 0x0002aa6f, 0x0002ae6f, 0x0002b26f, 0x0002b66f, + 0x0002ba6f, 0x0002be6f, 0x0002c26f, 0x0002c66f, + 0x0002ca6f, 0x0002ce6f, 0x0002d26f, 0x0002d66f, + 0x0002da6f, 0x0002de6f, 0x0002e26f, 0x0002e66f, + 0x0002ea6f, 0x0002ee6f, 0x0002f26f, 0x0002f66f, + 0x0002fa6f, 0x0002fe6f, 0x0003026f, 0x0003066f, + 0x00030a6f, 0x00030e6f, 0x0003126f, 0x0003166f, + 0x00031a6f, 0x00031e6f, 0x0003226f, 0x0003266f, + 0x00032a6f, 0x00032e6f, 0x0003326f, 0x0003366f, + 0x00033a6f, 0x00033e6f, 0x0003426f, 0x0003466f, + 0x00034a6f, 0x00034e6f, 0x0003526f, 0x0003566f, + 0x00035a6f, 0x00035e6f, 0x0003626f, 0x0003666f, + 0x00036a6f, 0x00036e6f, 0x0003726f, 0x0003766f, + 0x00037a6f, 0x00037e6f, 0x0003826f, 0x0003866f, + 0x00038a6f, 0x00038e6f, 0x0003926f, 0x0003966f, + 0x00039a6f, 0x00039e6f, 0x0003a26f, 0x0003a66f, + 0x0003aa6f, 0x0003ae6f, 0x0003b26f, 0x0003b66f, + 0x0003ba6f, 0x0003be6f, 0x0003c26f, 0x0003c66f, + 0x0003ca6f, 0x0003ce6f, 0x0003d26f, 0x0003d66f, + 0x0003da6f, 0x0003de6f, 0x0003e26f, 0x0003e66f, + 0x0003ea6f, 0x0003ee6f, 0x0003f26f, 0x0003f66f, + 0x0003fa6f, 0x0003fe6f, 0x0004026f, 0x0004066f, + 0x00040a6f, 0x00040e6f, 0x0004126f, 0x0004166f, + 0x00041a6f, 0x00041e6f, 0x0004226f, 0x0004266f, + 0x00042a6f, 0x00042e6f, 0x0004326f, 0x0004366f, + 0x00043a6f, 0x00043e6f, 0x0004426f, 0x0004466f, + 0x00044a6f, 0x00044e6f, 0x0004526f, 0x0004566f, + 0x00045a6f, 0x00045e6f, 0x0004626f, 0x0004666f, + 0x00046a6f, 0x00046e6f, 0x0004726f, 0x0004766f, + 0x00047a6f, 0x00047e6f, 0x0004826f, 0x0004866f, + 0x00048a6f, 0x00048e6f, 0x0004926f, 0x0004966f, + 0x00049a6f, 0x00049e6f, 0x0004a26f, 0x0004a66f, + 0x0004aa6f, 0x0004ae6f, 0x0004b26f, 0x0004b66f, + 0x0004ba6f, 0x0004be6f, 0x0004c26f, 0x0004c66f, + 0x0004ca6f, 0x0004ce6f, 0x0004d26f, 0x0004d66f, + 0x0004da6f, 0x0004de6f, 0x0004e26f, 0x0004e66f, + 0x0004ea6f, 0x0004ee6f, 0x0004f26f, 0x0004f66f, + 0x0004fa6f, 0x0004fe6f, 0x0005026f, 0x0005066f, + 0x00050a6f, 0x00050e6f, 0x0005126f, 0x0005166f, + 0x00051a6f, 0x00051e6f, 0x0005226f, 0x0005266f, + 0x00052a6f, 0x00052e6f, 0x0005326f, 0x0005366f, + 0x00053a6f, 0x00053e6f, 0x0005426f, 0x0005466f, + 0x00054a6f, 0x00054e6f, 0x0005526f, 0x0005566f, + 0x00055a6f, 0x00055e6f, 0x0005626f, 0x0005666f, + 0x00056a6f, 0x00056e6f, 0x0005726f, 0x0005766f, + 0x00057a6f, 0x00057e6f, 0x0005826f, 0x0005866f, + 0x00058a6f, 0x00058e6f, 0x0005926f, 0x0005966f, + 0x00059a6f, 0x00059e6f, 0x0005a26f, 0x0005a66f, + 0x0005aa6f, 0x0005ae6f, 0x0005b26f, 0x0005b66f, + 0x0005ba6f, 0x0005be6f, 0x0005c26f, 0x0005c66f, + 0x0005ca6f, 0x0005ce6f, 0x0005d26f, 0x0005d66f, + 0x0005da6f, 0x0005de6f, 0x0005e26f, 0x0005e66f, + 0x0005ea6f, 0x0005ee6f, 0x0005f26f, 0x0005f66f, + 0x0005fa6f, 0x0005fe6f, 0x0006026f, 0x0006066f, + 0x00060a6f, 0x00060e6f, 0x0006126f, 0x0006166f, + 0x00061a6f, 0x00061e6f, 0x0006226f, 0x0006266f, + 0x00062a6f, 0x00062e6f, 0x0006326f, 0x0006366f, + 0x00063a6f, 0x00063e6f, 0x0006426f, 0x0006466f, + 0x00064a6f, 0x00064e6f, 0x0006526f, 0x0006566f, + 0x00065a6f, 0x00065e6f, 0x0006626f, 0x0006666f, + 0x00066a6f, 0x00066e6f, 0x0006726f, 0x0006766f, + 0x00067a6f, 0x00067e6f, 0x0006826f, 0x0006866f, + 0x00068a6f, 0x00068e6f, 0x0006926f, 0x0006966f, + 0x00069a6f, 0x00069e6f, 0x0006a26f, 0x0006a66f, + 0x0006aa6f, 0x0006ae6f, 0x0006b26f, 0x0006b66f, + 0x0006ba6f, 0x0006be6f, 0x0006c26f, 0x0006c66f, + 0x0006ca6f, 0x0006ce6f, 0x0006d26f, 0x0006d66f, + 0x0006da6f, 0x0006de6f, 0x0006e26f, 0x0006e66f, + 0x0006ea6f, 0x0006ee6f, 0x0006f26f, 0x0006f66f, + 0x0006fa6f, 0x0006fe6f, 0x0007026f, 0x0007066f, + 0x00070a6f, 0x00070e6f, 0x0007126f, 0x0007166f, + 0x00071a6f, 0x00071e6f, 0x0007226f, 0x0007266f, + 0x00072a6f, 0x00072e6f, 0x0007326f, 0x0007366f, + 0x00073a6f, 0x00073e6f, 0x0007426f, 0x0007466f, + 0x00074a6f, 0x00074e6f, 0x0007526f, 0x0007566f, + 0x00075a6f, 0x00075e6f, 0x0007626f, 0x0007666f, + 0x00076a6f, 0x00076e6f, 0x0007726f, 0x0007766f, + 0x00077a6f, 0x00077e6f, 0x0007826f, 0x0007866f, + 0x00078a6f, 0x00078e6f, 0x0007926f, 0x0007966f, + 0x00079a6f, 0x00079e6f, 0x0007a26f, 0x0007a66f, + 0x0007aa6f, 0x0007ae6f, 0x0007b26f, 0x0007b66f, + 0x0007ba6f, 0x0007be6f, 0x0007c26f, 0x0007c66f, + 0x0007ca6f, 0x0007ce6f, 0x0007d26f, 0x0007d66f, + 0x0007da6f, 0x0007de6f, 0x0007e26f, 0x0007e66f, + 0x0007ea6f, 0x0007ee6f, 0x0007f26f, 0x0007f66f, + 0x0007fa6f, 0x0007fe6f, 0x0008026f, 0x0008066f, + 0x00080a6f, 0x00080e6f, 0x0008126f, 0x0008166f, + 0x00081a6f, 0x00081e6f, 0x0008226f, 0x0008266f, + 0x00082a6f, 0x00082e6f, 0x0008326f, 0x0008366f, + 0x00083a6f, 0x00083e6f, 0x0008426f, 0x0008466f, + 0x00084a6f, 0x00084e6f, 0x0008526f, 0x0008566f, + 0x00085a6f, 0x00085e6f, 0x0008626f, 0x0008666f, + 0x00086a6f, 0x00086e6f, 0x0008726f, 0x0008766f, + 0x00087a6f, 0x00087e6f, 0x0008826f, 0x0008866f, + 0x00088a6f, 0x00088e6f, 0x0008926f, 0x0008966f, + 0x00089a6f, 0x00089e6f, 0x0008a26f, 0x0008a66f, + 0x0008aa6f, 0x0008ae6f, 0x0008b26f, 0x0008b66f, + 0x0008ba6f, 0x0008be6f, 0x0008c26f, 0x0008c66f, + 0x0008ca6f, 0x0008ce6f, 0x0008d26f, 0x0008d66f, + 0x0008da6f, 0x0008de6f, 0x0008e26f, 0x0008e66f, + 0x0008ea6f, 0x0008ee6f, 0x0008f26f, 0x0008f66f, + 0x0008fa6f, 0x0008fe6f, 0x0009026f, 0x0009066f, + 0x00090a6f, 0x00090e6f, 0x0009126f, 0x0009166f, + 0x00091a6f, 0x00091e6f, 0x0009226f, 0x0009266f, + 0x00092a6f, 0x00092e6f, 0x0009326f, 0x0009366f, + 0x00093a6f, 0x00093e6f, 0x0009426f, 0x0009466f, + 0x00094a6f, 0x00094e6f, 0x0009526f, 0x0009566f, + 0x00095a6f, 0x00095e6f, 0x0009626f, 0x0009666f, + 0x00096a6f, 0x00096e6f, 0x0009726f, 0x0009766f, + 0x00097a6f, 0x00097e6f, 0x0009826f, 0x0009866f, + 0x00098a6f, 0x00098e6f, 0x0009926f, 0x0009966f, + 0x00099a6f, 0x00099e6f, 0x0009a26f, 0x0009a66f, + 0x0009aa6f, 0x0009ae6f, 0x0009b26f, 0x0009b66f, + 0x0009ba6f, 0x0009be6f, 0x0009c26f, 0x0009c66f, + 0x0009ca6f, 0x0009ce6f, 0x0009d26f, 0x0009d66f, + 0x0009da6f, 0x0009de6f, 0x0009e26f, 0x0009e66f, + 0x0009ea6f, 0x0009ee6f, 0x0009f26f, 0x0009f66f, + 0x0009fa6f, 0x0009fe6f, 0x000a026f, 0x000a066f, + 0x000a0a6f, 0x000a0e6f, 0x000a126f, 0x000a166f, + 0x000a1a6f, 0x000a1e6f, 0x000a226f, 0x000a266f, + 0x000a2a6f, 0x000a2e6f, 0x000a326f, 0x000a366f, + 0x000a3a6f, 0x000a3e6f, 0x000a426f, 0x000a466f, + 0x000a4a6f, 0x000a4e6f, 0x000a526f, 0x000a566f, + 0x000a5a6f, 0x000a5e6f, 0x000a626f, 0x000a666f, + 0x000a6a6f, 0x000a6e6f, 0x000a726f, 0x000a766f, + 0x000a7a6f, 0x000a7e6f, 0x000a826f, 0x000a866f, + 0x000a8a6f, 0x000a8e6f, 0x000a926f, 0x000a966f, + 0x000a9a6f, 0x000a9e6f, 0x000aa26f, 0x000aa66f, + 0x000aaa6f, 0x000aae6f, 0x000ab26f, 0x000ab66f, + 0x000aba6f, 0x000abe6f, 0x000ac26f, 0x000ac66f, + 0x000aca6f, 0x000ace6f, 0x000ad26f, 0x000ad66f, + 0x000ada6f, 0x000ade6f, 0x000ae26f, 0x000ae66f, + 0x000aea6f, 0x000aee6f, 0x000af26f, 0x000af66f, + 0x000afa6f, 0x000afe6f, 0x000b026f, 0x000b066f, + 0x000b0a6f, 0x000b0e6f, 0x000b126f, 0x000b166f, + 0x000b1a6f, 0x000b1e6f, 0x000b226f, 0x000b266f, + 0x000b2a6f, 0x000b2e6f, 0x000b326f, 0x000b366f, + 0x000b3a6f, 0x000b3e6f, 0x000b426f, 0x000b466f, + 0x000b4a6f, 0x000b4e6f, 0x000b526f, 0x000b566f, + 0x000b5a6f, 0x000b5e6f, 0x000b626f, 0x000b666f, + 0x000b6a6f, 0x000b6e6f, 0x000b726f, 0x000b766f, + 0x000b7a6f, 0x000b7e6f, 0x000b826f, 0x000b866f, + 0x000b8a6f, 0x000b8e6f, 0x000b926f, 0x000b966f, + 0x000b9a6f, 0x000b9e6f, 0x000ba26f, 0x000ba66f, + 0x000baa6f, 0x000bae6f, 0x000bb26f, 0x000bb66f, + 0x000bba6f, 0x000bbe6f, 0x000bc26f, 0x000bc66f, + 0x000bca6f, 0x000bce6f, 0x000bd26f, 0x000bd66f, + 0x000bda6f, 0x000bde6f, 0x000be26f, 0x000be66f, + 0x000bea6f, 0x000bee6f, 0x000bf26f, 0x000bf66f, + 0x000bfa6f, 0x000bfe6f, 0x000c026f, 0x000c066f, + 0x000c0a6f, 0x000c0e6f, 0x000c126f, 0x000c166f, + 0x000c1a6f, 0x000c1e6f, 0x000c226f, 0x000c266f, + 0x000c2a6f, 0x000c2e6f, 0x000c326f, 0x000c366f, + 0x000c3a6f, 0x000c3e6f, 0x000c426f, 0x000c466f, + 0x000c4a6f, 0x000c4e6f, 0x000c526f, 0x000c566f, + 0x000c5a6f, 0x000c5e6f, 0x000c626f, 0x000c666f, + 0x000c6a6f, 0x000c6e6f, 0x000c726f, 0x000c766f, + 0x000c7a6f, 0x000c7e6f, 0x000c826f, 0x000c866f, + 0x000c8a6f, 0x000c8e6f, 0x000c926f, 0x000c966f, + 0x000c9a6f, 0x000c9e6f, 0x000ca26f, 0x000ca66f, + 0x000caa6f, 0x000cae6f, 0x000cb26f, 0x000cb66f, + 0x000cba6f, 0x000cbe6f, 0x000cc26f, 0x000cc66f, + 0x000cca6f, 0x000cce6f, 0x000cd26f, 0x000cd66f, + 0x000cda6f, 0x000cde6f, 0x000ce26f, 0x000ce66f, + 0x000cea6f, 0x000cee6f, 0x000cf26f, 0x000cf66f, + 0x000cfa6f, 0x000cfe6f, 0x000d026f, 0x000d066f, + 0x000d0a6f, 0x000d0e6f, 0x000d126f, 0x000d166f, + 0x000d1a6f, 0x000d1e6f, 0x000d226f, 0x000d266f, + 0x000d2a6f, 0x000d2e6f, 0x000d326f, 0x000d366f, + 0x000d3a6f, 0x000d3e6f, 0x000d426f, 0x000d466f, + 0x000d4a6f, 0x000d4e6f, 0x000d526f, 0x000d566f, + 0x000d5a6f, 0x000d5e6f, 0x000d626f, 0x000d666f, + 0x000d6a6f, 0x000d6e6f, 0x000d726f, 0x000d766f, + 0x000d7a6f, 0x000d7e6f, 0x000d826f, 0x000d866f, + 0x000d8a6f, 0x000d8e6f, 0x000d926f, 0x000d966f, + 0x000d9a6f, 0x000d9e6f, 0x000da26f, 0x000da66f, + 0x000daa6f, 0x000dae6f, 0x000db26f, 0x000db66f, + 0x000dba6f, 0x000dbe6f, 0x000dc26f, 0x000dc66f, + 0x000dca6f, 0x000dce6f, 0x000dd26f, 0x000dd66f, + 0x000dda6f, 0x000dde6f, 0x000de26f, 0x000de66f, + 0x000dea6f, 0x000dee6f, 0x000df26f, 0x000df66f, + 0x000dfa6f, 0x000dfe6f, 0x000e026f, 0x000e066f, + 0x000e0a6f, 0x000e0e6f, 0x000e126f, 0x000e166f, + 0x000e1a6f, 0x000e1e6f, 0x000e226f, 0x000e266f, + 0x000e2a6f, 0x000e2e6f, 0x000e326f, 0x000e366f, + 0x000e3a6f, 0x000e3e6f, 0x000e426f, 0x000e466f, + 0x000e4a6f, 0x000e4e6f, 0x000e526f, 0x000e566f, + 0x000e5a6f, 0x000e5e6f, 0x000e626f, 0x000e666f, + 0x000e6a6f, 0x000e6e6f, 0x000e726f, 0x000e766f, + 0x000e7a6f, 0x000e7e6f, 0x000e826f, 0x000e866f, + 0x000e8a6f, 0x000e8e6f, 0x000e926f, 0x000e966f, + 0x000e9a6f, 0x000e9e6f, 0x000ea26f, 0x000ea66f, + 0x000eaa6f, 0x000eae6f, 0x000eb26f, 0x000eb66f, + 0x000eba6f, 0x000ebe6f, 0x000ec26f, 0x000ec66f, + 0x000eca6f, 0x000ece6f, 0x000ed26f, 0x000ed66f, + 0x000eda6f, 0x000ede6f, 0x000ee26f, 0x000ee66f, + 0x000eea6f, 0x000eee6f, 0x000ef26f, 0x000ef66f, + 0x000efa6f, 0x000efe6f, 0x000f026f, 0x000f066f, + 0x000f0a6f, 0x000f0e6f, 0x000f126f, 0x000f166f, + 0x000f1a6f, 0x000f1e6f, 0x000f226f, 0x000f266f, + 0x000f2a6f, 0x000f2e6f, 0x000f326f, 0x000f366f, + 0x000f3a6f, 0x000f3e6f, 0x000f426f, 0x000f466f, + 0x000f4a6f, 0x000f4e6f, 0x000f526f, 0x000f566f, + 0x000f5a6f, 0x000f5e6f, 0x000f626f, 0x000f666f, + 0x000f6a6f, 0x000f6e6f, 0x000f726f, 0x000f766f, + 0x000f7a6f, 0x000f7e6f, 0x000f826f, 0x000f866f, + 0x000f8a6f, 0x000f8e6f, 0x000f926f, 0x000f966f, + 0x000f9a6f, 0x000f9e6f, 0x000fa26f, 0x000fa66f, + 0x000faa6f, 0x000fae6f, 0x000fb26f, 0x000fb66f, + 0x000fba6f, 0x000fbe6f, 0x000fc26f, 0x000fc66f, + 0x000fca6f, 0x000fce6f, 0x000fd26f, 0x000fd66f, + 0x000fda6f, 0x000fde6f, 0x000fe26f, 0x000fe66f, + 0x000fea6f, 0x000fee6f, 0x000ff26f, 0x000ff66f, + 0x000ffa6f, 0x000ffe6f, 0x000001cf, 0x000003cf, + 0x000005cf, 0x000007cf, 0x000009cf, 0x00000bcf, + 0x00000dcf, 0x00000fcf, 0x000011cf, 0x000013cf, + 0x000015cf, 0x000017cf, 0x000019cf, 0x00001bcf, + 0x00001dcf, 0x00001fcf, 0x000021cf, 0x000023cf, + 0x000025cf, 0x000027cf, 0x000029cf, 0x00002bcf, + 0x00002dcf, 0x00002fcf, 0x000031cf, 0x000033cf, + 0x000035cf, 0x000037cf, 0x000039cf, 0x00003bcf, + 0x00003dcf, 0x00003fcf, 0x000041cf, 0x000043cf, + 0x000045cf, 0x000047cf, 0x000049cf, 0x00004bcf, + 0x00004dcf, 0x00004fcf, 0x000051cf, 0x000053cf, + 0x000055cf, 0x000057cf, 0x000059cf, 0x00005bcf, + 0x00005dcf, 0x00005fcf, 0x000061cf, 0x000063cf, + 0x000065cf, 0x000067cf, 0x000069cf, 0x00006bcf, + 0x00006dcf, 0x00006fcf, 0x000071cf, 0x000073cf, + 0x000075cf, 0x000077cf, 0x000079cf, 0x00007bcf, + 0x00007dcf, 0x00007fcf, 0x000081cf, 0x000083cf, + 0x000085cf, 0x000087cf, 0x000089cf, 0x00008bcf, + 0x00008dcf, 0x00008fcf, 0x000091cf, 0x000093cf, + 0x000095cf, 0x000097cf, 0x000099cf, 0x00009bcf, + 0x00009dcf, 0x00009fcf, 0x0000a1cf, 0x0000a3cf, + 0x0000a5cf, 0x0000a7cf, 0x0000a9cf, 0x0000abcf, + 0x0000adcf, 0x0000afcf, 0x0000b1cf, 0x0000b3cf, + 0x0000b5cf, 0x0000b7cf, 0x0000b9cf, 0x0000bbcf, + 0x0000bdcf, 0x0000bfcf, 0x0000c1cf, 0x0000c3cf, + 0x0000c5cf, 0x0000c7cf, 0x0000c9cf, 0x0000cbcf, + 0x0000cdcf, 0x0000cfcf, 0x0000d1cf, 0x0000d3cf, + 0x0000d5cf, 0x0000d7cf, 0x0000d9cf, 0x0000dbcf, + 0x0000ddcf, 0x0000dfcf, 0x0000e1cf, 0x0000e3cf, + 0x0000e5cf, 0x0000e7cf, 0x0000e9cf, 0x0000ebcf, + 0x0000edcf, 0x0000efcf, 0x0000f1cf, 0x0000f3cf, + 0x0000f5cf, 0x0000f7cf, 0x0000f9cf, 0x0000fbcf, + 0x0000fdcf, 0x0000ffcf, 0x000101cf, 0x000103cf, + 0x000105cf, 0x000107cf, 0x000109cf, 0x00010bcf, + 0x00010dcf, 0x00010fcf, 0x000111cf, 0x000113cf, + 0x000115cf, 0x000117cf, 0x000119cf, 0x00011bcf, + 0x00011dcf, 0x00011fcf, 0x000121cf, 0x000123cf, + 0x000125cf, 0x000127cf, 0x000129cf, 0x00012bcf, + 0x00012dcf, 0x00012fcf, 0x000131cf, 0x000133cf, + 0x000135cf, 0x000137cf, 0x000139cf, 0x00013bcf, + 0x00013dcf, 0x00013fcf, 0x000141cf, 0x000143cf, + 0x000145cf, 0x000147cf, 0x000149cf, 0x00014bcf, + 0x00014dcf, 0x00014fcf, 0x000151cf, 0x000153cf, + 0x000155cf, 0x000157cf, 0x000159cf, 0x00015bcf, + 0x00015dcf, 0x00015fcf, 0x000161cf, 0x000163cf, + 0x000165cf, 0x000167cf, 0x000169cf, 0x00016bcf, + 0x00016dcf, 0x00016fcf, 0x000171cf, 0x000173cf, + 0x000175cf, 0x000177cf, 0x000179cf, 0x00017bcf, + 0x00017dcf, 0x00017fcf, 0x000181cf, 0x000183cf, + 0x000185cf, 0x000187cf, 0x000189cf, 0x00018bcf, + 0x00018dcf, 0x00018fcf, 0x000191cf, 0x000193cf, + 0x000195cf, 0x000197cf, 0x000199cf, 0x00019bcf, + 0x00019dcf, 0x00019fcf, 0x0001a1cf, 0x0001a3cf, + 0x0001a5cf, 0x0001a7cf, 0x0001a9cf, 0x0001abcf, + 0x0001adcf, 0x0001afcf, 0x0001b1cf, 0x0001b3cf, + 0x0001b5cf, 0x0001b7cf, 0x0001b9cf, 0x0001bbcf, + 0x0001bdcf, 0x0001bfcf, 0x0001c1cf, 0x0001c3cf, + 0x0001c5cf, 0x0001c7cf, 0x0001c9cf, 0x0001cbcf, + 0x0001cdcf, 0x0001cfcf, 0x0001d1cf, 0x0001d3cf, + 0x0001d5cf, 0x0001d7cf, 0x0001d9cf, 0x0001dbcf, + 0x0001ddcf, 0x0001dfcf, 0x0001e1cf, 0x0001e3cf, + 0x0001e5cf, 0x0001e7cf, 0x0001e9cf, 0x0001ebcf, + 0x0001edcf, 0x0001efcf, 0x0001f1cf, 0x0001f3cf, + 0x0001f5cf, 0x0001f7cf, 0x0001f9cf, 0x0001fbcf, + 0x0001fdcf, 0x0001ffcf, 0x000201cf, 0x000203cf, + 0x000205cf, 0x000207cf, 0x000209cf, 0x00020bcf, + 0x00020dcf, 0x00020fcf, 0x000211cf, 0x000213cf, + 0x000215cf, 0x000217cf, 0x000219cf, 0x00021bcf, + 0x00021dcf, 0x00021fcf, 0x000221cf, 0x000223cf, + 0x000225cf, 0x000227cf, 0x000229cf, 0x00022bcf, + 0x00022dcf, 0x00022fcf, 0x000231cf, 0x000233cf, + 0x000235cf, 0x000237cf, 0x000239cf, 0x00023bcf, + 0x00023dcf, 0x00023fcf, 0x000241cf, 0x000243cf, + 0x000245cf, 0x000247cf, 0x000249cf, 0x00024bcf, + 0x00024dcf, 0x00024fcf, 0x000251cf, 0x000253cf, + 0x000255cf, 0x000257cf, 0x000259cf, 0x00025bcf, + 0x00025dcf, 0x00025fcf, 0x000261cf, 0x000263cf, + 0x000265cf, 0x000267cf, 0x000269cf, 0x00026bcf, + 0x00026dcf, 0x00026fcf, 0x000271cf, 0x000273cf, + 0x000275cf, 0x000277cf, 0x000279cf, 0x00027bcf, + 0x00027dcf, 0x00027fcf, 0x000281cf, 0x000283cf, + 0x000285cf, 0x000287cf, 0x000289cf, 0x00028bcf, + 0x00028dcf, 0x00028fcf, 0x000291cf, 0x000293cf, + 0x000295cf, 0x000297cf, 0x000299cf, 0x00029bcf, + 0x00029dcf, 0x00029fcf, 0x0002a1cf, 0x0002a3cf, + 0x0002a5cf, 0x0002a7cf, 0x0002a9cf, 0x0002abcf, + 0x0002adcf, 0x0002afcf, 0x0002b1cf, 0x0002b3cf, + 0x0002b5cf, 0x0002b7cf, 0x0002b9cf, 0x0002bbcf, + 0x0002bdcf, 0x0002bfcf, 0x0002c1cf, 0x0002c3cf, + 0x0002c5cf, 0x0002c7cf, 0x0002c9cf, 0x0002cbcf, + 0x0002cdcf, 0x0002cfcf, 0x0002d1cf, 0x0002d3cf, + 0x0002d5cf, 0x0002d7cf, 0x0002d9cf, 0x0002dbcf, + 0x0002ddcf, 0x0002dfcf, 0x0002e1cf, 0x0002e3cf, + 0x0002e5cf, 0x0002e7cf, 0x0002e9cf, 0x0002ebcf, + 0x0002edcf, 0x0002efcf, 0x0002f1cf, 0x0002f3cf, + 0x0002f5cf, 0x0002f7cf, 0x0002f9cf, 0x0002fbcf, + 0x0002fdcf, 0x0002ffcf, 0x000301cf, 0x000303cf, + 0x000305cf, 0x000307cf, 0x000309cf, 0x00030bcf, + 0x00030dcf, 0x00030fcf, 0x000311cf, 0x000313cf, + 0x000315cf, 0x000317cf, 0x000319cf, 0x00031bcf, + 0x00031dcf, 0x00031fcf, 0x000321cf, 0x000323cf, + 0x000325cf, 0x000327cf, 0x000329cf, 0x00032bcf, + 0x00032dcf, 0x00032fcf, 0x000331cf, 0x000333cf, + 0x000335cf, 0x000337cf, 0x000339cf, 0x00033bcf, + 0x00033dcf, 0x00033fcf, 0x000341cf, 0x000343cf, + 0x000345cf, 0x000347cf, 0x000349cf, 0x00034bcf, + 0x00034dcf, 0x00034fcf, 0x000351cf, 0x000353cf, + 0x000355cf, 0x000357cf, 0x000359cf, 0x00035bcf, + 0x00035dcf, 0x00035fcf, 0x000361cf, 0x000363cf, + 0x000365cf, 0x000367cf, 0x000369cf, 0x00036bcf, + 0x00036dcf, 0x00036fcf, 0x000371cf, 0x000373cf, + 0x000375cf, 0x000377cf, 0x000379cf, 0x00037bcf, + 0x00037dcf, 0x00037fcf, 0x000381cf, 0x000383cf, + 0x000385cf, 0x000387cf, 0x000389cf, 0x00038bcf, + 0x00038dcf, 0x00038fcf, 0x000391cf, 0x000393cf, + 0x000395cf, 0x000397cf, 0x000399cf, 0x00039bcf, + 0x00039dcf, 0x00039fcf, 0x0003a1cf, 0x0003a3cf, + 0x0003a5cf, 0x0003a7cf, 0x0003a9cf, 0x0003abcf, + 0x0003adcf, 0x0003afcf, 0x0003b1cf, 0x0003b3cf, + 0x0003b5cf, 0x0003b7cf, 0x0003b9cf, 0x0003bbcf, + 0x0003bdcf, 0x0003bfcf, 0x0003c1cf, 0x0003c3cf, + 0x0003c5cf, 0x0003c7cf, 0x0003c9cf, 0x0003cbcf, + 0x0003cdcf, 0x0003cfcf, 0x0003d1cf, 0x0003d3cf, + 0x0003d5cf, 0x0003d7cf, 0x0003d9cf, 0x0003dbcf, + 0x0003ddcf, 0x0003dfcf, 0x0003e1cf, 0x0003e3cf, + 0x0003e5cf, 0x0003e7cf, 0x0003e9cf, 0x0003ebcf, + 0x0003edcf, 0x0003efcf, 0x0003f1cf, 0x0003f3cf, + 0x0003f5cf, 0x0003f7cf, 0x0003f9cf, 0x0003fbcf, + 0x0003fdcf, 0x0003ffcf, 0x000401cf, 0x000403cf, + 0x000405cf, 0x000407cf, 0x000409cf, 0x00040bcf, + 0x00040dcf, 0x00040fcf, 0x000411cf, 0x000413cf, + 0x000415cf, 0x000417cf, 0x000419cf, 0x00041bcf, + 0x00041dcf, 0x00041fcf, 0x000421cf, 0x000423cf, + 0x000425cf, 0x000427cf, 0x000429cf, 0x00042bcf, + 0x00042dcf, 0x00042fcf, 0x000431cf, 0x000433cf, + 0x000435cf, 0x000437cf, 0x000439cf, 0x00043bcf, + 0x00043dcf, 0x00043fcf, 0x000441cf, 0x000443cf, + 0x000445cf, 0x000447cf, 0x000449cf, 0x00044bcf, + 0x00044dcf, 0x00044fcf, 0x000451cf, 0x000453cf, + 0x000455cf, 0x000457cf, 0x000459cf, 0x00045bcf, + 0x00045dcf, 0x00045fcf, 0x000461cf, 0x000463cf, + 0x000465cf, 0x000467cf, 0x000469cf, 0x00046bcf, + 0x00046dcf, 0x00046fcf, 0x000471cf, 0x000473cf, + 0x000475cf, 0x000477cf, 0x000479cf, 0x00047bcf, + 0x00047dcf, 0x00047fcf, 0x000481cf, 0x000483cf, + 0x000485cf, 0x000487cf, 0x000489cf, 0x00048bcf, + 0x00048dcf, 0x00048fcf, 0x000491cf, 0x000493cf, + 0x000495cf, 0x000497cf, 0x000499cf, 0x00049bcf, + 0x00049dcf, 0x00049fcf, 0x0004a1cf, 0x0004a3cf, + 0x0004a5cf, 0x0004a7cf, 0x0004a9cf, 0x0004abcf, + 0x0004adcf, 0x0004afcf, 0x0004b1cf, 0x0004b3cf, + 0x0004b5cf, 0x0004b7cf, 0x0004b9cf, 0x0004bbcf, + 0x0004bdcf, 0x0004bfcf, 0x0004c1cf, 0x0004c3cf, + 0x0004c5cf, 0x0004c7cf, 0x0004c9cf, 0x0004cbcf, + 0x0004cdcf, 0x0004cfcf, 0x0004d1cf, 0x0004d3cf, + 0x0004d5cf, 0x0004d7cf, 0x0004d9cf, 0x0004dbcf, + 0x0004ddcf, 0x0004dfcf, 0x0004e1cf, 0x0004e3cf, + 0x0004e5cf, 0x0004e7cf, 0x0004e9cf, 0x0004ebcf, + 0x0004edcf, 0x0004efcf, 0x0004f1cf, 0x0004f3cf, + 0x0004f5cf, 0x0004f7cf, 0x0004f9cf, 0x0004fbcf, + 0x0004fdcf, 0x0004ffcf, 0x000501cf, 0x000503cf, + 0x000505cf, 0x000507cf, 0x000509cf, 0x00050bcf, + 0x00050dcf, 0x00050fcf, 0x000511cf, 0x000513cf, + 0x000515cf, 0x000517cf, 0x000519cf, 0x00051bcf, + 0x00051dcf, 0x00051fcf, 0x000521cf, 0x000523cf, + 0x000525cf, 0x000527cf, 0x000529cf, 0x00052bcf, + 0x00052dcf, 0x00052fcf, 0x000531cf, 0x000533cf, + 0x000535cf, 0x000537cf, 0x000539cf, 0x00053bcf, + 0x00053dcf, 0x00053fcf, 0x000541cf, 0x000543cf, + 0x000545cf, 0x000547cf, 0x000549cf, 0x00054bcf, + 0x00054dcf, 0x00054fcf, 0x000551cf, 0x000553cf, + 0x000555cf, 0x000557cf, 0x000559cf, 0x00055bcf, + 0x00055dcf, 0x00055fcf, 0x000561cf, 0x000563cf, + 0x000565cf, 0x000567cf, 0x000569cf, 0x00056bcf, + 0x00056dcf, 0x00056fcf, 0x000571cf, 0x000573cf, + 0x000575cf, 0x000577cf, 0x000579cf, 0x00057bcf, + 0x00057dcf, 0x00057fcf, 0x000581cf, 0x000583cf, + 0x000585cf, 0x000587cf, 0x000589cf, 0x00058bcf, + 0x00058dcf, 0x00058fcf, 0x000591cf, 0x000593cf, + 0x000595cf, 0x000597cf, 0x000599cf, 0x00059bcf, + 0x00059dcf, 0x00059fcf, 0x0005a1cf, 0x0005a3cf, + 0x0005a5cf, 0x0005a7cf, 0x0005a9cf, 0x0005abcf, + 0x0005adcf, 0x0005afcf, 0x0005b1cf, 0x0005b3cf, + 0x0005b5cf, 0x0005b7cf, 0x0005b9cf, 0x0005bbcf, + 0x0005bdcf, 0x0005bfcf, 0x0005c1cf, 0x0005c3cf, + 0x0005c5cf, 0x0005c7cf, 0x0005c9cf, 0x0005cbcf, + 0x0005cdcf, 0x0005cfcf, 0x0005d1cf, 0x0005d3cf, + 0x0005d5cf, 0x0005d7cf, 0x0005d9cf, 0x0005dbcf, + 0x0005ddcf, 0x0005dfcf, 0x0005e1cf, 0x0005e3cf, + 0x0005e5cf, 0x0005e7cf, 0x0005e9cf, 0x0005ebcf, + 0x0005edcf, 0x0005efcf, 0x0005f1cf, 0x0005f3cf, + 0x0005f5cf, 0x0005f7cf, 0x0005f9cf, 0x0005fbcf, + 0x0005fdcf, 0x0005ffcf, 0x000601cf, 0x000603cf, + 0x000605cf, 0x000607cf, 0x000609cf, 0x00060bcf, + 0x00060dcf, 0x00060fcf, 0x000611cf, 0x000613cf, + 0x000615cf, 0x000617cf, 0x000619cf, 0x00061bcf, + 0x00061dcf, 0x00061fcf, 0x000621cf, 0x000623cf, + 0x000625cf, 0x000627cf, 0x000629cf, 0x00062bcf, + 0x00062dcf, 0x00062fcf, 0x000631cf, 0x000633cf, + 0x000635cf, 0x000637cf, 0x000639cf, 0x00063bcf, + 0x00063dcf, 0x00063fcf, 0x000641cf, 0x000643cf, + 0x000645cf, 0x000647cf, 0x000649cf, 0x00064bcf, + 0x00064dcf, 0x00064fcf, 0x000651cf, 0x000653cf, + 0x000655cf, 0x000657cf, 0x000659cf, 0x00065bcf, + 0x00065dcf, 0x00065fcf, 0x000661cf, 0x000663cf, + 0x000665cf, 0x000667cf, 0x000669cf, 0x00066bcf, + 0x00066dcf, 0x00066fcf, 0x000671cf, 0x000673cf, + 0x000675cf, 0x000677cf, 0x000679cf, 0x00067bcf, + 0x00067dcf, 0x00067fcf, 0x000681cf, 0x000683cf, + 0x000685cf, 0x000687cf, 0x000689cf, 0x00068bcf, + 0x00068dcf, 0x00068fcf, 0x000691cf, 0x000693cf, + 0x000695cf, 0x000697cf, 0x000699cf, 0x00069bcf, + 0x00069dcf, 0x00069fcf, 0x0006a1cf, 0x0006a3cf, + 0x0006a5cf, 0x0006a7cf, 0x0006a9cf, 0x0006abcf, + 0x0006adcf, 0x0006afcf, 0x0006b1cf, 0x0006b3cf, + 0x0006b5cf, 0x0006b7cf, 0x0006b9cf, 0x0006bbcf, + 0x0006bdcf, 0x0006bfcf, 0x0006c1cf, 0x0006c3cf, + 0x0006c5cf, 0x0006c7cf, 0x0006c9cf, 0x0006cbcf, + 0x0006cdcf, 0x0006cfcf, 0x0006d1cf, 0x0006d3cf, + 0x0006d5cf, 0x0006d7cf, 0x0006d9cf, 0x0006dbcf, + 0x0006ddcf, 0x0006dfcf, 0x0006e1cf, 0x0006e3cf, + 0x0006e5cf, 0x0006e7cf, 0x0006e9cf, 0x0006ebcf, + 0x0006edcf, 0x0006efcf, 0x0006f1cf, 0x0006f3cf, + 0x0006f5cf, 0x0006f7cf, 0x0006f9cf, 0x0006fbcf, + 0x0006fdcf, 0x0006ffcf, 0x000701cf, 0x000703cf, + 0x000705cf, 0x000707cf, 0x000709cf, 0x00070bcf, + 0x00070dcf, 0x00070fcf, 0x000711cf, 0x000713cf, + 0x000715cf, 0x000717cf, 0x000719cf, 0x00071bcf, + 0x00071dcf, 0x00071fcf, 0x000721cf, 0x000723cf, + 0x000725cf, 0x000727cf, 0x000729cf, 0x00072bcf, + 0x00072dcf, 0x00072fcf, 0x000731cf, 0x000733cf, + 0x000735cf, 0x000737cf, 0x000739cf, 0x00073bcf, + 0x00073dcf, 0x00073fcf, 0x000741cf, 0x000743cf, + 0x000745cf, 0x000747cf, 0x000749cf, 0x00074bcf, + 0x00074dcf, 0x00074fcf, 0x000751cf, 0x000753cf, + 0x000755cf, 0x000757cf, 0x000759cf, 0x00075bcf, + 0x00075dcf, 0x00075fcf, 0x000761cf, 0x000763cf, + 0x000765cf, 0x000767cf, 0x000769cf, 0x00076bcf, + 0x00076dcf, 0x00076fcf, 0x000771cf, 0x000773cf, + 0x000775cf, 0x000777cf, 0x000779cf, 0x00077bcf, + 0x00077dcf, 0x00077fcf, 0x000781cf, 0x000783cf, + 0x000785cf, 0x000787cf, 0x000789cf, 0x00078bcf, + 0x00078dcf, 0x00078fcf, 0x000791cf, 0x000793cf, + 0x000795cf, 0x000797cf, 0x000799cf, 0x00079bcf, + 0x00079dcf, 0x00079fcf, 0x0007a1cf, 0x0007a3cf, + 0x0007a5cf, 0x0007a7cf, 0x0007a9cf, 0x0007abcf, + 0x0007adcf, 0x0007afcf, 0x0007b1cf, 0x0007b3cf, + 0x0007b5cf, 0x0007b7cf, 0x0007b9cf, 0x0007bbcf, + 0x0007bdcf, 0x0007bfcf, 0x0007c1cf, 0x0007c3cf, + 0x0007c5cf, 0x0007c7cf, 0x0007c9cf, 0x0007cbcf, + 0x0007cdcf, 0x0007cfcf, 0x0007d1cf, 0x0007d3cf, + 0x0007d5cf, 0x0007d7cf, 0x0007d9cf, 0x0007dbcf, + 0x0007ddcf, 0x0007dfcf, 0x0007e1cf, 0x0007e3cf, + 0x0007e5cf, 0x0007e7cf, 0x0007e9cf, 0x0007ebcf, + 0x0007edcf, 0x0007efcf, 0x0007f1cf, 0x0007f3cf, + 0x0007f5cf, 0x0007f7cf, 0x0007f9cf, 0x0007fbcf, + 0x0007fdcf, 0x0007ffcf, 0x000801cf, 0x000803cf, + 0x000805cf, 0x000807cf, 0x000809cf, 0x00080bcf, + 0x00080dcf, 0x00080fcf, 0x000811cf, 0x000813cf, + 0x000815cf, 0x000817cf, 0x000819cf, 0x00081bcf, + 0x00081dcf, 0x00081fcf, 0x000821cf, 0x000823cf, + 0x000825cf, 0x000827cf, 0x000829cf, 0x00082bcf, + 0x00082dcf, 0x00082fcf, 0x000831cf, 0x000833cf, + 0x000835cf, 0x000837cf, 0x000839cf, 0x00083bcf, + 0x00083dcf, 0x00083fcf, 0x000841cf, 0x000843cf, + 0x000845cf, 0x000847cf, 0x000849cf, 0x00084bcf, + 0x00084dcf, 0x00084fcf, 0x000851cf, 0x000853cf, + 0x000855cf, 0x000857cf, 0x000859cf, 0x00085bcf, + 0x00085dcf, 0x00085fcf, 0x000861cf, 0x000863cf, + 0x000865cf, 0x000867cf, 0x000869cf, 0x00086bcf, + 0x00086dcf, 0x00086fcf, 0x000871cf, 0x000873cf, + 0x000875cf, 0x000877cf, 0x000879cf, 0x00087bcf, + 0x00087dcf, 0x00087fcf, 0x000881cf, 0x000883cf, + 0x000885cf, 0x000887cf, 0x000889cf, 0x00088bcf, + 0x00088dcf, 0x00088fcf, 0x000891cf, 0x000893cf, + 0x000895cf, 0x000897cf, 0x000899cf, 0x00089bcf, + 0x00089dcf, 0x00089fcf, 0x0008a1cf, 0x0008a3cf, + 0x0008a5cf, 0x0008a7cf, 0x0008a9cf, 0x0008abcf, + 0x0008adcf, 0x0008afcf, 0x0008b1cf, 0x0008b3cf, + 0x0008b5cf, 0x0008b7cf, 0x0008b9cf, 0x0008bbcf, + 0x0008bdcf, 0x0008bfcf, 0x0008c1cf, 0x0008c3cf, + 0x0008c5cf, 0x0008c7cf, 0x0008c9cf, 0x0008cbcf, + 0x0008cdcf, 0x0008cfcf, 0x0008d1cf, 0x0008d3cf, + 0x0008d5cf, 0x0008d7cf, 0x0008d9cf, 0x0008dbcf, + 0x0008ddcf, 0x0008dfcf, 0x0008e1cf, 0x0008e3cf, + 0x0008e5cf, 0x0008e7cf, 0x0008e9cf, 0x0008ebcf, + 0x0008edcf, 0x0008efcf, 0x0008f1cf, 0x0008f3cf, + 0x0008f5cf, 0x0008f7cf, 0x0008f9cf, 0x0008fbcf, + 0x0008fdcf, 0x0008ffcf, 0x000901cf, 0x000903cf, + 0x000905cf, 0x000907cf, 0x000909cf, 0x00090bcf, + 0x00090dcf, 0x00090fcf, 0x000911cf, 0x000913cf, + 0x000915cf, 0x000917cf, 0x000919cf, 0x00091bcf, + 0x00091dcf, 0x00091fcf, 0x000921cf, 0x000923cf, + 0x000925cf, 0x000927cf, 0x000929cf, 0x00092bcf, + 0x00092dcf, 0x00092fcf, 0x000931cf, 0x000933cf, + 0x000935cf, 0x000937cf, 0x000939cf, 0x00093bcf, + 0x00093dcf, 0x00093fcf, 0x000941cf, 0x000943cf, + 0x000945cf, 0x000947cf, 0x000949cf, 0x00094bcf, + 0x00094dcf, 0x00094fcf, 0x000951cf, 0x000953cf, + 0x000955cf, 0x000957cf, 0x000959cf, 0x00095bcf, + 0x00095dcf, 0x00095fcf, 0x000961cf, 0x000963cf, + 0x000965cf, 0x000967cf, 0x000969cf, 0x00096bcf, + 0x00096dcf, 0x00096fcf, 0x000971cf, 0x000973cf, + 0x000975cf, 0x000977cf, 0x000979cf, 0x00097bcf, + 0x00097dcf, 0x00097fcf, 0x000981cf, 0x000983cf, + 0x000985cf, 0x000987cf, 0x000989cf, 0x00098bcf, + 0x00098dcf, 0x00098fcf, 0x000991cf, 0x000993cf, + 0x000995cf, 0x000997cf, 0x000999cf, 0x00099bcf, + 0x00099dcf, 0x00099fcf, 0x0009a1cf, 0x0009a3cf, + 0x0009a5cf, 0x0009a7cf, 0x0009a9cf, 0x0009abcf, + 0x0009adcf, 0x0009afcf, 0x0009b1cf, 0x0009b3cf, + 0x0009b5cf, 0x0009b7cf, 0x0009b9cf, 0x0009bbcf, + 0x0009bdcf, 0x0009bfcf, 0x0009c1cf, 0x0009c3cf, + 0x0009c5cf, 0x0009c7cf, 0x0009c9cf, 0x0009cbcf, + 0x0009cdcf, 0x0009cfcf, 0x0009d1cf, 0x0009d3cf, + 0x0009d5cf, 0x0009d7cf, 0x0009d9cf, 0x0009dbcf, + 0x0009ddcf, 0x0009dfcf, 0x0009e1cf, 0x0009e3cf, + 0x0009e5cf, 0x0009e7cf, 0x0009e9cf, 0x0009ebcf, + 0x0009edcf, 0x0009efcf, 0x0009f1cf, 0x0009f3cf, + 0x0009f5cf, 0x0009f7cf, 0x0009f9cf, 0x0009fbcf, + 0x0009fdcf, 0x0009ffcf, 0x000a01cf, 0x000a03cf, + 0x000a05cf, 0x000a07cf, 0x000a09cf, 0x000a0bcf, + 0x000a0dcf, 0x000a0fcf, 0x000a11cf, 0x000a13cf, + 0x000a15cf, 0x000a17cf, 0x000a19cf, 0x000a1bcf, + 0x000a1dcf, 0x000a1fcf, 0x000a21cf, 0x000a23cf, + 0x000a25cf, 0x000a27cf, 0x000a29cf, 0x000a2bcf, + 0x000a2dcf, 0x000a2fcf, 0x000a31cf, 0x000a33cf, + 0x000a35cf, 0x000a37cf, 0x000a39cf, 0x000a3bcf, + 0x000a3dcf, 0x000a3fcf, 0x000a41cf, 0x000a43cf, + 0x000a45cf, 0x000a47cf, 0x000a49cf, 0x000a4bcf, + 0x000a4dcf, 0x000a4fcf, 0x000a51cf, 0x000a53cf, + 0x000a55cf, 0x000a57cf, 0x000a59cf, 0x000a5bcf, + 0x000a5dcf, 0x000a5fcf, 0x000a61cf, 0x000a63cf, + 0x000a65cf, 0x000a67cf, 0x000a69cf, 0x000a6bcf, + 0x000a6dcf, 0x000a6fcf, 0x000a71cf, 0x000a73cf, + 0x000a75cf, 0x000a77cf, 0x000a79cf, 0x000a7bcf, + 0x000a7dcf, 0x000a7fcf, 0x000a81cf, 0x000a83cf, + 0x000a85cf, 0x000a87cf, 0x000a89cf, 0x000a8bcf, + 0x000a8dcf, 0x000a8fcf, 0x000a91cf, 0x000a93cf, + 0x000a95cf, 0x000a97cf, 0x000a99cf, 0x000a9bcf, + 0x000a9dcf, 0x000a9fcf, 0x000aa1cf, 0x000aa3cf, + 0x000aa5cf, 0x000aa7cf, 0x000aa9cf, 0x000aabcf, + 0x000aadcf, 0x000aafcf, 0x000ab1cf, 0x000ab3cf, + 0x000ab5cf, 0x000ab7cf, 0x000ab9cf, 0x000abbcf, + 0x000abdcf, 0x000abfcf, 0x000ac1cf, 0x000ac3cf, + 0x000ac5cf, 0x000ac7cf, 0x000ac9cf, 0x000acbcf, + 0x000acdcf, 0x000acfcf, 0x000ad1cf, 0x000ad3cf, + 0x000ad5cf, 0x000ad7cf, 0x000ad9cf, 0x000adbcf, + 0x000addcf, 0x000adfcf, 0x000ae1cf, 0x000ae3cf, + 0x000ae5cf, 0x000ae7cf, 0x000ae9cf, 0x000aebcf, + 0x000aedcf, 0x000aefcf, 0x000af1cf, 0x000af3cf, + 0x000af5cf, 0x000af7cf, 0x000af9cf, 0x000afbcf, + 0x000afdcf, 0x000affcf, 0x000b01cf, 0x000b03cf, + 0x000b05cf, 0x000b07cf, 0x000b09cf, 0x000b0bcf, + 0x000b0dcf, 0x000b0fcf, 0x000b11cf, 0x000b13cf, + 0x000b15cf, 0x000b17cf, 0x000b19cf, 0x000b1bcf, + 0x000b1dcf, 0x000b1fcf, 0x000b21cf, 0x000b23cf, + 0x000b25cf, 0x000b27cf, 0x000b29cf, 0x000b2bcf, + 0x000b2dcf, 0x000b2fcf, 0x000b31cf, 0x000b33cf, + 0x000b35cf, 0x000b37cf, 0x000b39cf, 0x000b3bcf, + 0x000b3dcf, 0x000b3fcf, 0x000b41cf, 0x000b43cf, + 0x000b45cf, 0x000b47cf, 0x000b49cf, 0x000b4bcf, + 0x000b4dcf, 0x000b4fcf, 0x000b51cf, 0x000b53cf, + 0x000b55cf, 0x000b57cf, 0x000b59cf, 0x000b5bcf, + 0x000b5dcf, 0x000b5fcf, 0x000b61cf, 0x000b63cf, + 0x000b65cf, 0x000b67cf, 0x000b69cf, 0x000b6bcf, + 0x000b6dcf, 0x000b6fcf, 0x000b71cf, 0x000b73cf, + 0x000b75cf, 0x000b77cf, 0x000b79cf, 0x000b7bcf, + 0x000b7dcf, 0x000b7fcf, 0x000b81cf, 0x000b83cf, + 0x000b85cf, 0x000b87cf, 0x000b89cf, 0x000b8bcf, + 0x000b8dcf, 0x000b8fcf, 0x000b91cf, 0x000b93cf, + 0x000b95cf, 0x000b97cf, 0x000b99cf, 0x000b9bcf, + 0x000b9dcf, 0x000b9fcf, 0x000ba1cf, 0x000ba3cf, + 0x000ba5cf, 0x000ba7cf, 0x000ba9cf, 0x000babcf, + 0x000badcf, 0x000bafcf, 0x000bb1cf, 0x000bb3cf, + 0x000bb5cf, 0x000bb7cf, 0x000bb9cf, 0x000bbbcf, + 0x000bbdcf, 0x000bbfcf, 0x000bc1cf, 0x000bc3cf, + 0x000bc5cf, 0x000bc7cf, 0x000bc9cf, 0x000bcbcf, + 0x000bcdcf, 0x000bcfcf, 0x000bd1cf, 0x000bd3cf, + 0x000bd5cf, 0x000bd7cf, 0x000bd9cf, 0x000bdbcf, + 0x000bddcf, 0x000bdfcf, 0x000be1cf, 0x000be3cf, + 0x000be5cf, 0x000be7cf, 0x000be9cf, 0x000bebcf, + 0x000bedcf, 0x000befcf, 0x000bf1cf, 0x000bf3cf, + 0x000bf5cf, 0x000bf7cf, 0x000bf9cf, 0x000bfbcf, + 0x000bfdcf, 0x000bffcf, 0x000c01cf, 0x000c03cf, + 0x000c05cf, 0x000c07cf, 0x000c09cf, 0x000c0bcf, + 0x000c0dcf, 0x000c0fcf, 0x000c11cf, 0x000c13cf, + 0x000c15cf, 0x000c17cf, 0x000c19cf, 0x000c1bcf, + 0x000c1dcf, 0x000c1fcf, 0x000c21cf, 0x000c23cf, + 0x000c25cf, 0x000c27cf, 0x000c29cf, 0x000c2bcf, + 0x000c2dcf, 0x000c2fcf, 0x000c31cf, 0x000c33cf, + 0x000c35cf, 0x000c37cf, 0x000c39cf, 0x000c3bcf, + 0x000c3dcf, 0x000c3fcf, 0x000c41cf, 0x000c43cf, + 0x000c45cf, 0x000c47cf, 0x000c49cf, 0x000c4bcf, + 0x000c4dcf, 0x000c4fcf, 0x000c51cf, 0x000c53cf, + 0x000c55cf, 0x000c57cf, 0x000c59cf, 0x000c5bcf, + 0x000c5dcf, 0x000c5fcf, 0x000c61cf, 0x000c63cf, + 0x000c65cf, 0x000c67cf, 0x000c69cf, 0x000c6bcf, + 0x000c6dcf, 0x000c6fcf, 0x000c71cf, 0x000c73cf, + 0x000c75cf, 0x000c77cf, 0x000c79cf, 0x000c7bcf, + 0x000c7dcf, 0x000c7fcf, 0x000c81cf, 0x000c83cf, + 0x000c85cf, 0x000c87cf, 0x000c89cf, 0x000c8bcf, + 0x000c8dcf, 0x000c8fcf, 0x000c91cf, 0x000c93cf, + 0x000c95cf, 0x000c97cf, 0x000c99cf, 0x000c9bcf, + 0x000c9dcf, 0x000c9fcf, 0x000ca1cf, 0x000ca3cf, + 0x000ca5cf, 0x000ca7cf, 0x000ca9cf, 0x000cabcf, + 0x000cadcf, 0x000cafcf, 0x000cb1cf, 0x000cb3cf, + 0x000cb5cf, 0x000cb7cf, 0x000cb9cf, 0x000cbbcf, + 0x000cbdcf, 0x000cbfcf, 0x000cc1cf, 0x000cc3cf, + 0x000cc5cf, 0x000cc7cf, 0x000cc9cf, 0x000ccbcf, + 0x000ccdcf, 0x000ccfcf, 0x000cd1cf, 0x000cd3cf, + 0x000cd5cf, 0x000cd7cf, 0x000cd9cf, 0x000cdbcf, + 0x000cddcf, 0x000cdfcf, 0x000ce1cf, 0x000ce3cf, + 0x000ce5cf, 0x000ce7cf, 0x000ce9cf, 0x000cebcf, + 0x000cedcf, 0x000cefcf, 0x000cf1cf, 0x000cf3cf, + 0x000cf5cf, 0x000cf7cf, 0x000cf9cf, 0x000cfbcf, + 0x000cfdcf, 0x000cffcf, 0x000d01cf, 0x000d03cf, + 0x000d05cf, 0x000d07cf, 0x000d09cf, 0x000d0bcf, + 0x000d0dcf, 0x000d0fcf, 0x000d11cf, 0x000d13cf, + 0x000d15cf, 0x000d17cf, 0x000d19cf, 0x000d1bcf, + 0x000d1dcf, 0x000d1fcf, 0x000d21cf, 0x000d23cf, + 0x000d25cf, 0x000d27cf, 0x000d29cf, 0x000d2bcf, + 0x000d2dcf, 0x000d2fcf, 0x000d31cf, 0x000d33cf, + 0x000d35cf, 0x000d37cf, 0x000d39cf, 0x000d3bcf, + 0x000d3dcf, 0x000d3fcf, 0x000d41cf, 0x000d43cf, + 0x000d45cf, 0x000d47cf, 0x000d49cf, 0x000d4bcf, + 0x000d4dcf, 0x000d4fcf, 0x000d51cf, 0x000d53cf, + 0x000d55cf, 0x000d57cf, 0x000d59cf, 0x000d5bcf, + 0x000d5dcf, 0x000d5fcf, 0x000d61cf, 0x000d63cf, + 0x000d65cf, 0x000d67cf, 0x000d69cf, 0x000d6bcf, + 0x000d6dcf, 0x000d6fcf, 0x000d71cf, 0x000d73cf, + 0x000d75cf, 0x000d77cf, 0x000d79cf, 0x000d7bcf, + 0x000d7dcf, 0x000d7fcf, 0x000d81cf, 0x000d83cf, + 0x000d85cf, 0x000d87cf, 0x000d89cf, 0x000d8bcf, + 0x000d8dcf, 0x000d8fcf, 0x000d91cf, 0x000d93cf, + 0x000d95cf, 0x000d97cf, 0x000d99cf, 0x000d9bcf, + 0x000d9dcf, 0x000d9fcf, 0x000da1cf, 0x000da3cf, + 0x000da5cf, 0x000da7cf, 0x000da9cf, 0x000dabcf, + 0x000dadcf, 0x000dafcf, 0x000db1cf, 0x000db3cf, + 0x000db5cf, 0x000db7cf, 0x000db9cf, 0x000dbbcf, + 0x000dbdcf, 0x000dbfcf, 0x000dc1cf, 0x000dc3cf, + 0x000dc5cf, 0x000dc7cf, 0x000dc9cf, 0x000dcbcf, + 0x000dcdcf, 0x000dcfcf, 0x000dd1cf, 0x000dd3cf, + 0x000dd5cf, 0x000dd7cf, 0x000dd9cf, 0x000ddbcf, + 0x000dddcf, 0x000ddfcf, 0x000de1cf, 0x000de3cf, + 0x000de5cf, 0x000de7cf, 0x000de9cf, 0x000debcf, + 0x000dedcf, 0x000defcf, 0x000df1cf, 0x000df3cf, + 0x000df5cf, 0x000df7cf, 0x000df9cf, 0x000dfbcf, + 0x000dfdcf, 0x000dffcf, 0x000e01cf, 0x000e03cf, + 0x000e05cf, 0x000e07cf, 0x000e09cf, 0x000e0bcf, + 0x000e0dcf, 0x000e0fcf, 0x000e11cf, 0x000e13cf, + 0x000e15cf, 0x000e17cf, 0x000e19cf, 0x000e1bcf, + 0x000e1dcf, 0x000e1fcf, 0x000e21cf, 0x000e23cf, + 0x000e25cf, 0x000e27cf, 0x000e29cf, 0x000e2bcf, + 0x000e2dcf, 0x000e2fcf, 0x000e31cf, 0x000e33cf, + 0x000e35cf, 0x000e37cf, 0x000e39cf, 0x000e3bcf, + 0x000e3dcf, 0x000e3fcf, 0x000e41cf, 0x000e43cf, + 0x000e45cf, 0x000e47cf, 0x000e49cf, 0x000e4bcf, + 0x000e4dcf, 0x000e4fcf, 0x000e51cf, 0x000e53cf, + 0x000e55cf, 0x000e57cf, 0x000e59cf, 0x000e5bcf, + 0x000e5dcf, 0x000e5fcf, 0x000e61cf, 0x000e63cf, + 0x000e65cf, 0x000e67cf, 0x000e69cf, 0x000e6bcf, + 0x000e6dcf, 0x000e6fcf, 0x000e71cf, 0x000e73cf, + 0x000e75cf, 0x000e77cf, 0x000e79cf, 0x000e7bcf, + 0x000e7dcf, 0x000e7fcf, 0x000e81cf, 0x000e83cf, + 0x000e85cf, 0x000e87cf, 0x000e89cf, 0x000e8bcf, + 0x000e8dcf, 0x000e8fcf, 0x000e91cf, 0x000e93cf, + 0x000e95cf, 0x000e97cf, 0x000e99cf, 0x000e9bcf, + 0x000e9dcf, 0x000e9fcf, 0x000ea1cf, 0x000ea3cf, + 0x000ea5cf, 0x000ea7cf, 0x000ea9cf, 0x000eabcf, + 0x000eadcf, 0x000eafcf, 0x000eb1cf, 0x000eb3cf, + 0x000eb5cf, 0x000eb7cf, 0x000eb9cf, 0x000ebbcf, + 0x000ebdcf, 0x000ebfcf, 0x000ec1cf, 0x000ec3cf, + 0x000ec5cf, 0x000ec7cf, 0x000ec9cf, 0x000ecbcf, + 0x000ecdcf, 0x000ecfcf, 0x000ed1cf, 0x000ed3cf, + 0x000ed5cf, 0x000ed7cf, 0x000ed9cf, 0x000edbcf, + 0x000eddcf, 0x000edfcf, 0x000ee1cf, 0x000ee3cf, + 0x000ee5cf, 0x000ee7cf, 0x000ee9cf, 0x000eebcf, + 0x000eedcf, 0x000eefcf, 0x000ef1cf, 0x000ef3cf, + 0x000ef5cf, 0x000ef7cf, 0x000ef9cf, 0x000efbcf, + 0x000efdcf, 0x000effcf, 0x000f01cf, 0x000f03cf, + 0x000f05cf, 0x000f07cf, 0x000f09cf, 0x000f0bcf, + 0x000f0dcf, 0x000f0fcf, 0x000f11cf, 0x000f13cf, + 0x000f15cf, 0x000f17cf, 0x000f19cf, 0x000f1bcf, + 0x000f1dcf, 0x000f1fcf, 0x000f21cf, 0x000f23cf, + 0x000f25cf, 0x000f27cf, 0x000f29cf, 0x000f2bcf, + 0x000f2dcf, 0x000f2fcf, 0x000f31cf, 0x000f33cf, + 0x000f35cf, 0x000f37cf, 0x000f39cf, 0x000f3bcf, + 0x000f3dcf, 0x000f3fcf, 0x000f41cf, 0x000f43cf, + 0x000f45cf, 0x000f47cf, 0x000f49cf, 0x000f4bcf, + 0x000f4dcf, 0x000f4fcf, 0x000f51cf, 0x000f53cf, + 0x000f55cf, 0x000f57cf, 0x000f59cf, 0x000f5bcf, + 0x000f5dcf, 0x000f5fcf, 0x000f61cf, 0x000f63cf, + 0x000f65cf, 0x000f67cf, 0x000f69cf, 0x000f6bcf, + 0x000f6dcf, 0x000f6fcf, 0x000f71cf, 0x000f73cf, + 0x000f75cf, 0x000f77cf, 0x000f79cf, 0x000f7bcf, + 0x000f7dcf, 0x000f7fcf, 0x000f81cf, 0x000f83cf, + 0x000f85cf, 0x000f87cf, 0x000f89cf, 0x000f8bcf, + 0x000f8dcf, 0x000f8fcf, 0x000f91cf, 0x000f93cf, + 0x000f95cf, 0x000f97cf, 0x000f99cf, 0x000f9bcf, + 0x000f9dcf, 0x000f9fcf, 0x000fa1cf, 0x000fa3cf, + 0x000fa5cf, 0x000fa7cf, 0x000fa9cf, 0x000fabcf, + 0x000fadcf, 0x000fafcf, 0x000fb1cf, 0x000fb3cf, + 0x000fb5cf, 0x000fb7cf, 0x000fb9cf, 0x000fbbcf, + 0x000fbdcf, 0x000fbfcf, 0x000fc1cf, 0x000fc3cf, + 0x000fc5cf, 0x000fc7cf, 0x000fc9cf, 0x000fcbcf, + 0x000fcdcf, 0x000fcfcf, 0x000fd1cf, 0x000fd3cf, + 0x000fd5cf, 0x000fd7cf, 0x000fd9cf, 0x000fdbcf, + 0x000fddcf, 0x000fdfcf, 0x000fe1cf, 0x000fe3cf, + 0x000fe5cf, 0x000fe7cf, 0x000fe9cf, 0x000febcf, + 0x000fedcf, 0x000fefcf, 0x000ff1cf, 0x000ff3cf, + 0x000ff5cf, 0x000ff7cf, 0x000ff9cf, 0x000ffbcf, + 0x000ffdcf, 0x000fffcf, 0x00000170, 0x00000570, + 0x00000970, 0x00000d70, 0x00001170, 0x00001570, + 0x00001970, 0x00001d70, 0x00002170, 0x00002570, + 0x00002970, 0x00002d70, 0x00003170, 0x00003570, + 0x00003970, 0x00003d70, 0x00004170, 0x00004570, + 0x00004970, 0x00004d70, 0x00005170, 0x00005570, + 0x00005970, 0x00005d70, 0x00006170, 0x00006570, + 0x00006970, 0x00006d70, 0x00007170, 0x00007570, + 0x00007970, 0x00007d70, 0x00008170, 0x00008570, + 0x00008970, 0x00008d70, 0x00009170, 0x00009570, + 0x00009970, 0x00009d70, 0x0000a170, 0x0000a570, + 0x0000a970, 0x0000ad70, 0x0000b170, 0x0000b570, + 0x0000b970, 0x0000bd70, 0x0000c170, 0x0000c570, + 0x0000c970, 0x0000cd70, 0x0000d170, 0x0000d570, + 0x0000d970, 0x0000dd70, 0x0000e170, 0x0000e570, + 0x0000e970, 0x0000ed70, 0x0000f170, 0x0000f570, + 0x0000f970, 0x0000fd70, 0x00010170, 0x00010570, + 0x00010970, 0x00010d70, 0x00011170, 0x00011570, + 0x00011970, 0x00011d70, 0x00012170, 0x00012570, + 0x00012970, 0x00012d70, 0x00013170, 0x00013570, + 0x00013970, 0x00013d70, 0x00014170, 0x00014570, + 0x00014970, 0x00014d70, 0x00015170, 0x00015570, + 0x00015970, 0x00015d70, 0x00016170, 0x00016570, + 0x00016970, 0x00016d70, 0x00017170, 0x00017570, + 0x00017970, 0x00017d70, 0x00018170, 0x00018570, + 0x00018970, 0x00018d70, 0x00019170, 0x00019570, + 0x00019970, 0x00019d70, 0x0001a170, 0x0001a570, + 0x0001a970, 0x0001ad70, 0x0001b170, 0x0001b570, + 0x0001b970, 0x0001bd70, 0x0001c170, 0x0001c570, + 0x0001c970, 0x0001cd70, 0x0001d170, 0x0001d570, + 0x0001d970, 0x0001dd70, 0x0001e170, 0x0001e570, + 0x0001e970, 0x0001ed70, 0x0001f170, 0x0001f570, + 0x0001f970, 0x0001fd70, 0x00020170, 0x00020570, + 0x00020970, 0x00020d70, 0x00021170, 0x00021570, + 0x00021970, 0x00021d70, 0x00022170, 0x00022570, + 0x00022970, 0x00022d70, 0x00023170, 0x00023570, + 0x00023970, 0x00023d70, 0x00024170, 0x00024570, + 0x00024970, 0x00024d70, 0x00025170, 0x00025570, + 0x00025970, 0x00025d70, 0x00026170, 0x00026570, + 0x00026970, 0x00026d70, 0x00027170, 0x00027570, + 0x00027970, 0x00027d70, 0x00028170, 0x00028570, + 0x00028970, 0x00028d70, 0x00029170, 0x00029570, + 0x00029970, 0x00029d70, 0x0002a170, 0x0002a570, + 0x0002a970, 0x0002ad70, 0x0002b170, 0x0002b570, + 0x0002b970, 0x0002bd70, 0x0002c170, 0x0002c570, + 0x0002c970, 0x0002cd70, 0x0002d170, 0x0002d570, + 0x0002d970, 0x0002dd70, 0x0002e170, 0x0002e570, + 0x0002e970, 0x0002ed70, 0x0002f170, 0x0002f570, + 0x0002f970, 0x0002fd70, 0x00030170, 0x00030570, + 0x00030970, 0x00030d70, 0x00031170, 0x00031570, + 0x00031970, 0x00031d70, 0x00032170, 0x00032570, + 0x00032970, 0x00032d70, 0x00033170, 0x00033570, + 0x00033970, 0x00033d70, 0x00034170, 0x00034570, + 0x00034970, 0x00034d70, 0x00035170, 0x00035570, + 0x00035970, 0x00035d70, 0x00036170, 0x00036570, + 0x00036970, 0x00036d70, 0x00037170, 0x00037570, + 0x00037970, 0x00037d70, 0x00038170, 0x00038570, + 0x00038970, 0x00038d70, 0x00039170, 0x00039570, + 0x00039970, 0x00039d70, 0x0003a170, 0x0003a570, + 0x0003a970, 0x0003ad70, 0x0003b170, 0x0003b570, + 0x0003b970, 0x0003bd70, 0x0003c170, 0x0003c570, + 0x0003c970, 0x0003cd70, 0x0003d170, 0x0003d570, + 0x0003d970, 0x0003dd70, 0x0003e170, 0x0003e570, + 0x0003e970, 0x0003ed70, 0x0003f170, 0x0003f570, + 0x0003f970, 0x0003fd70, 0x00040170, 0x00040570, + 0x00040970, 0x00040d70, 0x00041170, 0x00041570, + 0x00041970, 0x00041d70, 0x00042170, 0x00042570, + 0x00042970, 0x00042d70, 0x00043170, 0x00043570, + 0x00043970, 0x00043d70, 0x00044170, 0x00044570, + 0x00044970, 0x00044d70, 0x00045170, 0x00045570, + 0x00045970, 0x00045d70, 0x00046170, 0x00046570, + 0x00046970, 0x00046d70, 0x00047170, 0x00047570, + 0x00047970, 0x00047d70, 0x00048170, 0x00048570, + 0x00048970, 0x00048d70, 0x00049170, 0x00049570, + 0x00049970, 0x00049d70, 0x0004a170, 0x0004a570, + 0x0004a970, 0x0004ad70, 0x0004b170, 0x0004b570, + 0x0004b970, 0x0004bd70, 0x0004c170, 0x0004c570, + 0x0004c970, 0x0004cd70, 0x0004d170, 0x0004d570, + 0x0004d970, 0x0004dd70, 0x0004e170, 0x0004e570, + 0x0004e970, 0x0004ed70, 0x0004f170, 0x0004f570, + 0x0004f970, 0x0004fd70, 0x00050170, 0x00050570, + 0x00050970, 0x00050d70, 0x00051170, 0x00051570, + 0x00051970, 0x00051d70, 0x00052170, 0x00052570, + 0x00052970, 0x00052d70, 0x00053170, 0x00053570, + 0x00053970, 0x00053d70, 0x00054170, 0x00054570, + 0x00054970, 0x00054d70, 0x00055170, 0x00055570, + 0x00055970, 0x00055d70, 0x00056170, 0x00056570, + 0x00056970, 0x00056d70, 0x00057170, 0x00057570, + 0x00057970, 0x00057d70, 0x00058170, 0x00058570, + 0x00058970, 0x00058d70, 0x00059170, 0x00059570, + 0x00059970, 0x00059d70, 0x0005a170, 0x0005a570, + 0x0005a970, 0x0005ad70, 0x0005b170, 0x0005b570, + 0x0005b970, 0x0005bd70, 0x0005c170, 0x0005c570, + 0x0005c970, 0x0005cd70, 0x0005d170, 0x0005d570, + 0x0005d970, 0x0005dd70, 0x0005e170, 0x0005e570, + 0x0005e970, 0x0005ed70, 0x0005f170, 0x0005f570, + 0x0005f970, 0x0005fd70, 0x00060170, 0x00060570, + 0x00060970, 0x00060d70, 0x00061170, 0x00061570, + 0x00061970, 0x00061d70, 0x00062170, 0x00062570, + 0x00062970, 0x00062d70, 0x00063170, 0x00063570, + 0x00063970, 0x00063d70, 0x00064170, 0x00064570, + 0x00064970, 0x00064d70, 0x00065170, 0x00065570, + 0x00065970, 0x00065d70, 0x00066170, 0x00066570, + 0x00066970, 0x00066d70, 0x00067170, 0x00067570, + 0x00067970, 0x00067d70, 0x00068170, 0x00068570, + 0x00068970, 0x00068d70, 0x00069170, 0x00069570, + 0x00069970, 0x00069d70, 0x0006a170, 0x0006a570, + 0x0006a970, 0x0006ad70, 0x0006b170, 0x0006b570, + 0x0006b970, 0x0006bd70, 0x0006c170, 0x0006c570, + 0x0006c970, 0x0006cd70, 0x0006d170, 0x0006d570, + 0x0006d970, 0x0006dd70, 0x0006e170, 0x0006e570, + 0x0006e970, 0x0006ed70, 0x0006f170, 0x0006f570, + 0x0006f970, 0x0006fd70, 0x00070170, 0x00070570, + 0x00070970, 0x00070d70, 0x00071170, 0x00071570, + 0x00071970, 0x00071d70, 0x00072170, 0x00072570, + 0x00072970, 0x00072d70, 0x00073170, 0x00073570, + 0x00073970, 0x00073d70, 0x00074170, 0x00074570, + 0x00074970, 0x00074d70, 0x00075170, 0x00075570, + 0x00075970, 0x00075d70, 0x00076170, 0x00076570, + 0x00076970, 0x00076d70, 0x00077170, 0x00077570, + 0x00077970, 0x00077d70, 0x00078170, 0x00078570, + 0x00078970, 0x00078d70, 0x00079170, 0x00079570, + 0x00079970, 0x00079d70, 0x0007a170, 0x0007a570, + 0x0007a970, 0x0007ad70, 0x0007b170, 0x0007b570, + 0x0007b970, 0x0007bd70, 0x0007c170, 0x0007c570, + 0x0007c970, 0x0007cd70, 0x0007d170, 0x0007d570, + 0x0007d970, 0x0007dd70, 0x0007e170, 0x0007e570, + 0x0007e970, 0x0007ed70, 0x0007f170, 0x0007f570, + 0x0007f970, 0x0007fd70, 0x00080170, 0x00080570, + 0x00080970, 0x00080d70, 0x00081170, 0x00081570, + 0x00081970, 0x00081d70, 0x00082170, 0x00082570, + 0x00082970, 0x00082d70, 0x00083170, 0x00083570, + 0x00083970, 0x00083d70, 0x00084170, 0x00084570, + 0x00084970, 0x00084d70, 0x00085170, 0x00085570, + 0x00085970, 0x00085d70, 0x00086170, 0x00086570, + 0x00086970, 0x00086d70, 0x00087170, 0x00087570, + 0x00087970, 0x00087d70, 0x00088170, 0x00088570, + 0x00088970, 0x00088d70, 0x00089170, 0x00089570, + 0x00089970, 0x00089d70, 0x0008a170, 0x0008a570, + 0x0008a970, 0x0008ad70, 0x0008b170, 0x0008b570, + 0x0008b970, 0x0008bd70, 0x0008c170, 0x0008c570, + 0x0008c970, 0x0008cd70, 0x0008d170, 0x0008d570, + 0x0008d970, 0x0008dd70, 0x0008e170, 0x0008e570, + 0x0008e970, 0x0008ed70, 0x0008f170, 0x0008f570, + 0x0008f970, 0x0008fd70, 0x00090170, 0x00090570, + 0x00090970, 0x00090d70, 0x00091170, 0x00091570, + 0x00091970, 0x00091d70, 0x00092170, 0x00092570, + 0x00092970, 0x00092d70, 0x00093170, 0x00093570, + 0x00093970, 0x00093d70, 0x00094170, 0x00094570, + 0x00094970, 0x00094d70, 0x00095170, 0x00095570, + 0x00095970, 0x00095d70, 0x00096170, 0x00096570, + 0x00096970, 0x00096d70, 0x00097170, 0x00097570, + 0x00097970, 0x00097d70, 0x00098170, 0x00098570, + 0x00098970, 0x00098d70, 0x00099170, 0x00099570, + 0x00099970, 0x00099d70, 0x0009a170, 0x0009a570, + 0x0009a970, 0x0009ad70, 0x0009b170, 0x0009b570, + 0x0009b970, 0x0009bd70, 0x0009c170, 0x0009c570, + 0x0009c970, 0x0009cd70, 0x0009d170, 0x0009d570, + 0x0009d970, 0x0009dd70, 0x0009e170, 0x0009e570, + 0x0009e970, 0x0009ed70, 0x0009f170, 0x0009f570, + 0x0009f970, 0x0009fd70, 0x000a0170, 0x000a0570, + 0x000a0970, 0x000a0d70, 0x000a1170, 0x000a1570, + 0x000a1970, 0x000a1d70, 0x000a2170, 0x000a2570, + 0x000a2970, 0x000a2d70, 0x000a3170, 0x000a3570, + 0x000a3970, 0x000a3d70, 0x000a4170, 0x000a4570, + 0x000a4970, 0x000a4d70, 0x000a5170, 0x000a5570, + 0x000a5970, 0x000a5d70, 0x000a6170, 0x000a6570, + 0x000a6970, 0x000a6d70, 0x000a7170, 0x000a7570, + 0x000a7970, 0x000a7d70, 0x000a8170, 0x000a8570, + 0x000a8970, 0x000a8d70, 0x000a9170, 0x000a9570, + 0x000a9970, 0x000a9d70, 0x000aa170, 0x000aa570, + 0x000aa970, 0x000aad70, 0x000ab170, 0x000ab570, + 0x000ab970, 0x000abd70, 0x000ac170, 0x000ac570, + 0x000ac970, 0x000acd70, 0x000ad170, 0x000ad570, + 0x000ad970, 0x000add70, 0x000ae170, 0x000ae570, + 0x000ae970, 0x000aed70, 0x000af170, 0x000af570, + 0x000af970, 0x000afd70, 0x000b0170, 0x000b0570, + 0x000b0970, 0x000b0d70, 0x000b1170, 0x000b1570, + 0x000b1970, 0x000b1d70, 0x000b2170, 0x000b2570, + 0x000b2970, 0x000b2d70, 0x000b3170, 0x000b3570, + 0x000b3970, 0x000b3d70, 0x000b4170, 0x000b4570, + 0x000b4970, 0x000b4d70, 0x000b5170, 0x000b5570, + 0x000b5970, 0x000b5d70, 0x000b6170, 0x000b6570, + 0x000b6970, 0x000b6d70, 0x000b7170, 0x000b7570, + 0x000b7970, 0x000b7d70, 0x000b8170, 0x000b8570, + 0x000b8970, 0x000b8d70, 0x000b9170, 0x000b9570, + 0x000b9970, 0x000b9d70, 0x000ba170, 0x000ba570, + 0x000ba970, 0x000bad70, 0x000bb170, 0x000bb570, + 0x000bb970, 0x000bbd70, 0x000bc170, 0x000bc570, + 0x000bc970, 0x000bcd70, 0x000bd170, 0x000bd570, + 0x000bd970, 0x000bdd70, 0x000be170, 0x000be570, + 0x000be970, 0x000bed70, 0x000bf170, 0x000bf570, + 0x000bf970, 0x000bfd70, 0x000c0170, 0x000c0570, + 0x000c0970, 0x000c0d70, 0x000c1170, 0x000c1570, + 0x000c1970, 0x000c1d70, 0x000c2170, 0x000c2570, + 0x000c2970, 0x000c2d70, 0x000c3170, 0x000c3570, + 0x000c3970, 0x000c3d70, 0x000c4170, 0x000c4570, + 0x000c4970, 0x000c4d70, 0x000c5170, 0x000c5570, + 0x000c5970, 0x000c5d70, 0x000c6170, 0x000c6570, + 0x000c6970, 0x000c6d70, 0x000c7170, 0x000c7570, + 0x000c7970, 0x000c7d70, 0x000c8170, 0x000c8570, + 0x000c8970, 0x000c8d70, 0x000c9170, 0x000c9570, + 0x000c9970, 0x000c9d70, 0x000ca170, 0x000ca570, + 0x000ca970, 0x000cad70, 0x000cb170, 0x000cb570, + 0x000cb970, 0x000cbd70, 0x000cc170, 0x000cc570, + 0x000cc970, 0x000ccd70, 0x000cd170, 0x000cd570, + 0x000cd970, 0x000cdd70, 0x000ce170, 0x000ce570, + 0x000ce970, 0x000ced70, 0x000cf170, 0x000cf570, + 0x000cf970, 0x000cfd70, 0x000d0170, 0x000d0570, + 0x000d0970, 0x000d0d70, 0x000d1170, 0x000d1570, + 0x000d1970, 0x000d1d70, 0x000d2170, 0x000d2570, + 0x000d2970, 0x000d2d70, 0x000d3170, 0x000d3570, + 0x000d3970, 0x000d3d70, 0x000d4170, 0x000d4570, + 0x000d4970, 0x000d4d70, 0x000d5170, 0x000d5570, + 0x000d5970, 0x000d5d70, 0x000d6170, 0x000d6570, + 0x000d6970, 0x000d6d70, 0x000d7170, 0x000d7570, + 0x000d7970, 0x000d7d70, 0x000d8170, 0x000d8570, + 0x000d8970, 0x000d8d70, 0x000d9170, 0x000d9570, + 0x000d9970, 0x000d9d70, 0x000da170, 0x000da570, + 0x000da970, 0x000dad70, 0x000db170, 0x000db570, + 0x000db970, 0x000dbd70, 0x000dc170, 0x000dc570, + 0x000dc970, 0x000dcd70, 0x000dd170, 0x000dd570, + 0x000dd970, 0x000ddd70, 0x000de170, 0x000de570, + 0x000de970, 0x000ded70, 0x000df170, 0x000df570, + 0x000df970, 0x000dfd70, 0x000e0170, 0x000e0570, + 0x000e0970, 0x000e0d70, 0x000e1170, 0x000e1570, + 0x000e1970, 0x000e1d70, 0x000e2170, 0x000e2570, + 0x000e2970, 0x000e2d70, 0x000e3170, 0x000e3570, + 0x000e3970, 0x000e3d70, 0x000e4170, 0x000e4570, + 0x000e4970, 0x000e4d70, 0x000e5170, 0x000e5570, + 0x000e5970, 0x000e5d70, 0x000e6170, 0x000e6570, + 0x000e6970, 0x000e6d70, 0x000e7170, 0x000e7570, + 0x000e7970, 0x000e7d70, 0x000e8170, 0x000e8570, + 0x000e8970, 0x000e8d70, 0x000e9170, 0x000e9570, + 0x000e9970, 0x000e9d70, 0x000ea170, 0x000ea570, + 0x000ea970, 0x000ead70, 0x000eb170, 0x000eb570, + 0x000eb970, 0x000ebd70, 0x000ec170, 0x000ec570, + 0x000ec970, 0x000ecd70, 0x000ed170, 0x000ed570, + 0x000ed970, 0x000edd70, 0x000ee170, 0x000ee570, + 0x000ee970, 0x000eed70, 0x000ef170, 0x000ef570, + 0x000ef970, 0x000efd70, 0x000f0170, 0x000f0570, + 0x000f0970, 0x000f0d70, 0x000f1170, 0x000f1570, + 0x000f1970, 0x000f1d70, 0x000f2170, 0x000f2570, + 0x000f2970, 0x000f2d70, 0x000f3170, 0x000f3570, + 0x000f3970, 0x000f3d70, 0x000f4170, 0x000f4570, + 0x000f4970, 0x000f4d70, 0x000f5170, 0x000f5570, + 0x000f5970, 0x000f5d70, 0x000f6170, 0x000f6570, + 0x000f6970, 0x000f6d70, 0x000f7170, 0x000f7570, + 0x000f7970, 0x000f7d70, 0x000f8170, 0x000f8570, + 0x000f8970, 0x000f8d70, 0x000f9170, 0x000f9570, + 0x000f9970, 0x000f9d70, 0x000fa170, 0x000fa570, + 0x000fa970, 0x000fad70, 0x000fb170, 0x000fb570, + 0x000fb970, 0x000fbd70, 0x000fc170, 0x000fc570, + 0x000fc970, 0x000fcd70, 0x000fd170, 0x000fd570, + 0x000fd970, 0x000fdd70, 0x000fe170, 0x000fe570, + 0x000fe970, 0x000fed70, 0x000ff170, 0x000ff570, + 0x000ff970, 0x000ffd70, 0x00100170, 0x00100570, + 0x00100970, 0x00100d70, 0x00101170, 0x00101570, + 0x00101970, 0x00101d70, 0x00102170, 0x00102570, + 0x00102970, 0x00102d70, 0x00103170, 0x00103570, + 0x00103970, 0x00103d70, 0x00104170, 0x00104570, + 0x00104970, 0x00104d70, 0x00105170, 0x00105570, + 0x00105970, 0x00105d70, 0x00106170, 0x00106570, + 0x00106970, 0x00106d70, 0x00107170, 0x00107570, + 0x00107970, 0x00107d70, 0x00108170, 0x00108570, + 0x00108970, 0x00108d70, 0x00109170, 0x00109570, + 0x00109970, 0x00109d70, 0x0010a170, 0x0010a570, + 0x0010a970, 0x0010ad70, 0x0010b170, 0x0010b570, + 0x0010b970, 0x0010bd70, 0x0010c170, 0x0010c570, + 0x0010c970, 0x0010cd70, 0x0010d170, 0x0010d570, + 0x0010d970, 0x0010dd70, 0x0010e170, 0x0010e570, + 0x0010e970, 0x0010ed70, 0x0010f170, 0x0010f570, + 0x0010f970, 0x0010fd70, 0x00110170, 0x00110570, + 0x00110970, 0x00110d70, 0x00111170, 0x00111570, + 0x00111970, 0x00111d70, 0x00112170, 0x00112570, + 0x00112970, 0x00112d70, 0x00113170, 0x00113570, + 0x00113970, 0x00113d70, 0x00114170, 0x00114570, + 0x00114970, 0x00114d70, 0x00115170, 0x00115570, + 0x00115970, 0x00115d70, 0x00116170, 0x00116570, + 0x00116970, 0x00116d70, 0x00117170, 0x00117570, + 0x00117970, 0x00117d70, 0x00118170, 0x00118570, + 0x00118970, 0x00118d70, 0x00119170, 0x00119570, + 0x00119970, 0x00119d70, 0x0011a170, 0x0011a570, + 0x0011a970, 0x0011ad70, 0x0011b170, 0x0011b570, + 0x0011b970, 0x0011bd70, 0x0011c170, 0x0011c570, + 0x0011c970, 0x0011cd70, 0x0011d170, 0x0011d570, + 0x0011d970, 0x0011dd70, 0x0011e170, 0x0011e570, + 0x0011e970, 0x0011ed70, 0x0011f170, 0x0011f570, + 0x0011f970, 0x0011fd70, 0x00120170, 0x00120570, + 0x00120970, 0x00120d70, 0x00121170, 0x00121570, + 0x00121970, 0x00121d70, 0x00122170, 0x00122570, + 0x00122970, 0x00122d70, 0x00123170, 0x00123570, + 0x00123970, 0x00123d70, 0x00124170, 0x00124570, + 0x00124970, 0x00124d70, 0x00125170, 0x00125570, + 0x00125970, 0x00125d70, 0x00126170, 0x00126570, + 0x00126970, 0x00126d70, 0x00127170, 0x00127570, + 0x00127970, 0x00127d70, 0x00128170, 0x00128570, + 0x00128970, 0x00128d70, 0x00129170, 0x00129570, + 0x00129970, 0x00129d70, 0x0012a170, 0x0012a570, + 0x0012a970, 0x0012ad70, 0x0012b170, 0x0012b570, + 0x0012b970, 0x0012bd70, 0x0012c170, 0x0012c570, + 0x0012c970, 0x0012cd70, 0x0012d170, 0x0012d570, + 0x0012d970, 0x0012dd70, 0x0012e170, 0x0012e570, + 0x0012e970, 0x0012ed70, 0x0012f170, 0x0012f570, + 0x0012f970, 0x0012fd70, 0x00130170, 0x00130570, + 0x00130970, 0x00130d70, 0x00131170, 0x00131570, + 0x00131970, 0x00131d70, 0x00132170, 0x00132570, + 0x00132970, 0x00132d70, 0x00133170, 0x00133570, + 0x00133970, 0x00133d70, 0x00134170, 0x00134570, + 0x00134970, 0x00134d70, 0x00135170, 0x00135570, + 0x00135970, 0x00135d70, 0x00136170, 0x00136570, + 0x00136970, 0x00136d70, 0x00137170, 0x00137570, + 0x00137970, 0x00137d70, 0x00138170, 0x00138570, + 0x00138970, 0x00138d70, 0x00139170, 0x00139570, + 0x00139970, 0x00139d70, 0x0013a170, 0x0013a570, + 0x0013a970, 0x0013ad70, 0x0013b170, 0x0013b570, + 0x0013b970, 0x0013bd70, 0x0013c170, 0x0013c570, + 0x0013c970, 0x0013cd70, 0x0013d170, 0x0013d570, + 0x0013d970, 0x0013dd70, 0x0013e170, 0x0013e570, + 0x0013e970, 0x0013ed70, 0x0013f170, 0x0013f570, + 0x0013f970, 0x0013fd70, 0x00140170, 0x00140570, + 0x00140970, 0x00140d70, 0x00141170, 0x00141570, + 0x00141970, 0x00141d70, 0x00142170, 0x00142570, + 0x00142970, 0x00142d70, 0x00143170, 0x00143570, + 0x00143970, 0x00143d70, 0x00144170, 0x00144570, + 0x00144970, 0x00144d70, 0x00145170, 0x00145570, + 0x00145970, 0x00145d70, 0x00146170, 0x00146570, + 0x00146970, 0x00146d70, 0x00147170, 0x00147570, + 0x00147970, 0x00147d70, 0x00148170, 0x00148570, + 0x00148970, 0x00148d70, 0x00149170, 0x00149570, + 0x00149970, 0x00149d70, 0x0014a170, 0x0014a570, + 0x0014a970, 0x0014ad70, 0x0014b170, 0x0014b570, + 0x0014b970, 0x0014bd70, 0x0014c170, 0x0014c570, + 0x0014c970, 0x0014cd70, 0x0014d170, 0x0014d570, + 0x0014d970, 0x0014dd70, 0x0014e170, 0x0014e570, + 0x0014e970, 0x0014ed70, 0x0014f170, 0x0014f570, + 0x0014f970, 0x0014fd70, 0x00150170, 0x00150570, + 0x00150970, 0x00150d70, 0x00151170, 0x00151570, + 0x00151970, 0x00151d70, 0x00152170, 0x00152570, + 0x00152970, 0x00152d70, 0x00153170, 0x00153570, + 0x00153970, 0x00153d70, 0x00154170, 0x00154570, + 0x00154970, 0x00154d70, 0x00155170, 0x00155570, + 0x00155970, 0x00155d70, 0x00156170, 0x00156570, + 0x00156970, 0x00156d70, 0x00157170, 0x00157570, + 0x00157970, 0x00157d70, 0x00158170, 0x00158570, + 0x00158970, 0x00158d70, 0x00159170, 0x00159570, + 0x00159970, 0x00159d70, 0x0015a170, 0x0015a570, + 0x0015a970, 0x0015ad70, 0x0015b170, 0x0015b570, + 0x0015b970, 0x0015bd70, 0x0015c170, 0x0015c570, + 0x0015c970, 0x0015cd70, 0x0015d170, 0x0015d570, + 0x0015d970, 0x0015dd70, 0x0015e170, 0x0015e570, + 0x0015e970, 0x0015ed70, 0x0015f170, 0x0015f570, + 0x0015f970, 0x0015fd70, 0x00160170, 0x00160570, + 0x00160970, 0x00160d70, 0x00161170, 0x00161570, + 0x00161970, 0x00161d70, 0x00162170, 0x00162570, + 0x00162970, 0x00162d70, 0x00163170, 0x00163570, + 0x00163970, 0x00163d70, 0x00164170, 0x00164570, + 0x00164970, 0x00164d70, 0x00165170, 0x00165570, + 0x00165970, 0x00165d70, 0x00166170, 0x00166570, + 0x00166970, 0x00166d70, 0x00167170, 0x00167570, + 0x00167970, 0x00167d70, 0x00168170, 0x00168570, + 0x00168970, 0x00168d70, 0x00169170, 0x00169570, + 0x00169970, 0x00169d70, 0x0016a170, 0x0016a570, + 0x0016a970, 0x0016ad70, 0x0016b170, 0x0016b570, + 0x0016b970, 0x0016bd70, 0x0016c170, 0x0016c570, + 0x0016c970, 0x0016cd70, 0x0016d170, 0x0016d570, + 0x0016d970, 0x0016dd70, 0x0016e170, 0x0016e570, + 0x0016e970, 0x0016ed70, 0x0016f170, 0x0016f570, + 0x0016f970, 0x0016fd70, 0x00170170, 0x00170570, + 0x00170970, 0x00170d70, 0x00171170, 0x00171570, + 0x00171970, 0x00171d70, 0x00172170, 0x00172570, + 0x00172970, 0x00172d70, 0x00173170, 0x00173570, + 0x00173970, 0x00173d70, 0x00174170, 0x00174570, + 0x00174970, 0x00174d70, 0x00175170, 0x00175570, + 0x00175970, 0x00175d70, 0x00176170, 0x00176570, + 0x00176970, 0x00176d70, 0x00177170, 0x00177570, + 0x00177970, 0x00177d70, 0x00178170, 0x00178570, + 0x00178970, 0x00178d70, 0x00179170, 0x00179570, + 0x00179970, 0x00179d70, 0x0017a170, 0x0017a570, + 0x0017a970, 0x0017ad70, 0x0017b170, 0x0017b570, + 0x0017b970, 0x0017bd70, 0x0017c170, 0x0017c570, + 0x0017c970, 0x0017cd70, 0x0017d170, 0x0017d570, + 0x0017d970, 0x0017dd70, 0x0017e170, 0x0017e570, + 0x0017e970, 0x0017ed70, 0x0017f170, 0x0017f570, + 0x0017f970, 0x0017fd70, 0x00180170, 0x00180570, + 0x00180970, 0x00180d70, 0x00181170, 0x00181570, + 0x00181970, 0x00181d70, 0x00182170, 0x00182570, + 0x00182970, 0x00182d70, 0x00183170, 0x00183570, + 0x00183970, 0x00183d70, 0x00184170, 0x00184570, + 0x00184970, 0x00184d70, 0x00185170, 0x00185570, + 0x00185970, 0x00185d70, 0x00186170, 0x00186570, + 0x00186970, 0x00186d70, 0x00187170, 0x00187570, + 0x00187970, 0x00187d70, 0x00188170, 0x00188570, + 0x00188970, 0x00188d70, 0x00189170, 0x00189570, + 0x00189970, 0x00189d70, 0x0018a170, 0x0018a570, + 0x0018a970, 0x0018ad70, 0x0018b170, 0x0018b570, + 0x0018b970, 0x0018bd70, 0x0018c170, 0x0018c570, + 0x0018c970, 0x0018cd70, 0x0018d170, 0x0018d570, + 0x0018d970, 0x0018dd70, 0x0018e170, 0x0018e570, + 0x0018e970, 0x0018ed70, 0x0018f170, 0x0018f570, + 0x0018f970, 0x0018fd70, 0x00190170, 0x00190570, + 0x00190970, 0x00190d70, 0x00191170, 0x00191570, + 0x00191970, 0x00191d70, 0x00192170, 0x00192570, + 0x00192970, 0x00192d70, 0x00193170, 0x00193570, + 0x00193970, 0x00193d70, 0x00194170, 0x00194570, + 0x00194970, 0x00194d70, 0x00195170, 0x00195570, + 0x00195970, 0x00195d70, 0x00196170, 0x00196570, + 0x00196970, 0x00196d70, 0x00197170, 0x00197570, + 0x00197970, 0x00197d70, 0x00198170, 0x00198570, + 0x00198970, 0x00198d70, 0x00199170, 0x00199570, + 0x00199970, 0x00199d70, 0x0019a170, 0x0019a570, + 0x0019a970, 0x0019ad70, 0x0019b170, 0x0019b570, + 0x0019b970, 0x0019bd70, 0x0019c170, 0x0019c570, + 0x0019c970, 0x0019cd70, 0x0019d170, 0x0019d570, + 0x0019d970, 0x0019dd70, 0x0019e170, 0x0019e570, + 0x0019e970, 0x0019ed70, 0x0019f170, 0x0019f570, + 0x0019f970, 0x0019fd70, 0x001a0170, 0x001a0570, + 0x001a0970, 0x001a0d70, 0x001a1170, 0x001a1570, + 0x001a1970, 0x001a1d70, 0x001a2170, 0x001a2570, + 0x001a2970, 0x001a2d70, 0x001a3170, 0x001a3570, + 0x001a3970, 0x001a3d70, 0x001a4170, 0x001a4570, + 0x001a4970, 0x001a4d70, 0x001a5170, 0x001a5570, + 0x001a5970, 0x001a5d70, 0x001a6170, 0x001a6570, + 0x001a6970, 0x001a6d70, 0x001a7170, 0x001a7570, + 0x001a7970, 0x001a7d70, 0x001a8170, 0x001a8570, + 0x001a8970, 0x001a8d70, 0x001a9170, 0x001a9570, + 0x001a9970, 0x001a9d70, 0x001aa170, 0x001aa570, + 0x001aa970, 0x001aad70, 0x001ab170, 0x001ab570, + 0x001ab970, 0x001abd70, 0x001ac170, 0x001ac570, + 0x001ac970, 0x001acd70, 0x001ad170, 0x001ad570, + 0x001ad970, 0x001add70, 0x001ae170, 0x001ae570, + 0x001ae970, 0x001aed70, 0x001af170, 0x001af570, + 0x001af970, 0x001afd70, 0x001b0170, 0x001b0570, + 0x001b0970, 0x001b0d70, 0x001b1170, 0x001b1570, + 0x001b1970, 0x001b1d70, 0x001b2170, 0x001b2570, + 0x001b2970, 0x001b2d70, 0x001b3170, 0x001b3570, + 0x001b3970, 0x001b3d70, 0x001b4170, 0x001b4570, + 0x001b4970, 0x001b4d70, 0x001b5170, 0x001b5570, + 0x001b5970, 0x001b5d70, 0x001b6170, 0x001b6570, + 0x001b6970, 0x001b6d70, 0x001b7170, 0x001b7570, + 0x001b7970, 0x001b7d70, 0x001b8170, 0x001b8570, + 0x001b8970, 0x001b8d70, 0x001b9170, 0x001b9570, + 0x001b9970, 0x001b9d70, 0x001ba170, 0x001ba570, + 0x001ba970, 0x001bad70, 0x001bb170, 0x001bb570, + 0x001bb970, 0x001bbd70, 0x001bc170, 0x001bc570, + 0x001bc970, 0x001bcd70, 0x001bd170, 0x001bd570, + 0x001bd970, 0x001bdd70, 0x001be170, 0x001be570, + 0x001be970, 0x001bed70, 0x001bf170, 0x001bf570, + 0x001bf970, 0x001bfd70, 0x001c0170, 0x001c0570, + 0x001c0970, 0x001c0d70, 0x001c1170, 0x001c1570, + 0x001c1970, 0x001c1d70, 0x001c2170, 0x001c2570, + 0x001c2970, 0x001c2d70, 0x001c3170, 0x001c3570, + 0x001c3970, 0x001c3d70, 0x001c4170, 0x001c4570, + 0x001c4970, 0x001c4d70, 0x001c5170, 0x001c5570, + 0x001c5970, 0x001c5d70, 0x001c6170, 0x001c6570, + 0x001c6970, 0x001c6d70, 0x001c7170, 0x001c7570, + 0x001c7970, 0x001c7d70, 0x001c8170, 0x001c8570, + 0x001c8970, 0x001c8d70, 0x001c9170, 0x001c9570, + 0x001c9970, 0x001c9d70, 0x001ca170, 0x001ca570, + 0x001ca970, 0x001cad70, 0x001cb170, 0x001cb570, + 0x001cb970, 0x001cbd70, 0x001cc170, 0x001cc570, + 0x001cc970, 0x001ccd70, 0x001cd170, 0x001cd570, + 0x001cd970, 0x001cdd70, 0x001ce170, 0x001ce570, + 0x001ce970, 0x001ced70, 0x001cf170, 0x001cf570, + 0x001cf970, 0x001cfd70, 0x001d0170, 0x001d0570, + 0x001d0970, 0x001d0d70, 0x001d1170, 0x001d1570, + 0x001d1970, 0x001d1d70, 0x001d2170, 0x001d2570, + 0x001d2970, 0x001d2d70, 0x001d3170, 0x001d3570, + 0x001d3970, 0x001d3d70, 0x001d4170, 0x001d4570, + 0x001d4970, 0x001d4d70, 0x001d5170, 0x001d5570, + 0x001d5970, 0x001d5d70, 0x001d6170, 0x001d6570, + 0x001d6970, 0x001d6d70, 0x001d7170, 0x001d7570, + 0x001d7970, 0x001d7d70, 0x001d8170, 0x001d8570, + 0x001d8970, 0x001d8d70, 0x001d9170, 0x001d9570, + 0x001d9970, 0x001d9d70, 0x001da170, 0x001da570, + 0x001da970, 0x001dad70, 0x001db170, 0x001db570, + 0x001db970, 0x001dbd70, 0x001dc170, 0x001dc570, + 0x001dc970, 0x001dcd70, 0x001dd170, 0x001dd570, + 0x001dd970, 0x001ddd70, 0x001de170, 0x001de570, + 0x001de970, 0x001ded70, 0x001df170, 0x001df570, + 0x001df970, 0x001dfd70, 0x001e0170, 0x001e0570, + 0x001e0970, 0x001e0d70, 0x001e1170, 0x001e1570, + 0x001e1970, 0x001e1d70, 0x001e2170, 0x001e2570, + 0x001e2970, 0x001e2d70, 0x001e3170, 0x001e3570, + 0x001e3970, 0x001e3d70, 0x001e4170, 0x001e4570, + 0x001e4970, 0x001e4d70, 0x001e5170, 0x001e5570, + 0x001e5970, 0x001e5d70, 0x001e6170, 0x001e6570, + 0x001e6970, 0x001e6d70, 0x001e7170, 0x001e7570, + 0x001e7970, 0x001e7d70, 0x001e8170, 0x001e8570, + 0x001e8970, 0x001e8d70, 0x001e9170, 0x001e9570, + 0x001e9970, 0x001e9d70, 0x001ea170, 0x001ea570, + 0x001ea970, 0x001ead70, 0x001eb170, 0x001eb570, + 0x001eb970, 0x001ebd70, 0x001ec170, 0x001ec570, + 0x001ec970, 0x001ecd70, 0x001ed170, 0x001ed570, + 0x001ed970, 0x001edd70, 0x001ee170, 0x001ee570, + 0x001ee970, 0x001eed70, 0x001ef170, 0x001ef570, + 0x001ef970, 0x001efd70, 0x001f0170, 0x001f0570, + 0x001f0970, 0x001f0d70, 0x001f1170, 0x001f1570, + 0x001f1970, 0x001f1d70, 0x001f2170, 0x001f2570, + 0x001f2970, 0x001f2d70, 0x001f3170, 0x001f3570, + 0x001f3970, 0x001f3d70, 0x001f4170, 0x001f4570, + 0x001f4970, 0x001f4d70, 0x001f5170, 0x001f5570, + 0x001f5970, 0x001f5d70, 0x001f6170, 0x001f6570, + 0x001f6970, 0x001f6d70, 0x001f7170, 0x001f7570, + 0x001f7970, 0x001f7d70, 0x001f8170, 0x001f8570, + 0x001f8970, 0x001f8d70, 0x001f9170, 0x001f9570, + 0x001f9970, 0x001f9d70, 0x001fa170, 0x001fa570, + 0x001fa970, 0x001fad70, 0x001fb170, 0x001fb570, + 0x001fb970, 0x001fbd70, 0x001fc170, 0x001fc570, + 0x001fc970, 0x001fcd70, 0x001fd170, 0x001fd570, + 0x001fd970, 0x001fdd70, 0x001fe170, 0x001fe570, + 0x001fe970, 0x001fed70, 0x001ff170, 0x001ff570, + 0x001ff970, 0x001ffd70 +#endif /* LONGER_HUFFTABLE */ + }, + + .len_table = { + 0x000bffef, 0x00000002, 0x00000044, 0x00000144, + 0x000002c5, 0x00000526, 0x00000ea7, 0x000001a7, + 0x000001c6, 0x000005c6, 0x00001869, 0x00003869, + 0x00000469, 0x00002469, 0x00001469, 0x00003469, + 0x00000c6a, 0x00002c6a, 0x00004c6a, 0x00006c6a, + 0x000030eb, 0x000070eb, 0x0000b0eb, 0x0000f0eb, + 0x000041ec, 0x0000c1ec, 0x000141ec, 0x0001c1ec, + 0x000021ec, 0x0000a1ec, 0x000121ec, 0x0001a1ec, + 0x000061ed, 0x0000e1ed, 0x000161ed, 0x0001e1ed, + 0x000261ed, 0x0002e1ed, 0x000361ed, 0x0003e1ed, + 0x000011ed, 0x000091ed, 0x000111ed, 0x000191ed, + 0x000211ed, 0x000291ed, 0x000311ed, 0x000391ed, + 0x000051ed, 0x0000d1ed, 0x000151ed, 0x0001d1ed, + 0x000251ed, 0x0002d1ed, 0x000351ed, 0x0003d1ed, + 0x000031ed, 0x0000b1ed, 0x000131ed, 0x0001b1ed, + 0x000231ed, 0x0002b1ed, 0x000331ed, 0x0003b1ed, + 0x00003fef, 0x00013fef, 0x00023fef, 0x00033fef, + 0x00043fef, 0x00053fef, 0x00063fef, 0x00073fef, + 0x00083fef, 0x00093fef, 0x000a3fef, 0x000b3fef, + 0x000c3fef, 0x000d3fef, 0x000e3fef, 0x000f3fef, + 0x00007ff0, 0x00027ff0, 0x00047ff0, 0x00067ff0, + 0x00087ff0, 0x000a7ff0, 0x000c7ff0, 0x000e7ff0, + 0x00107ff0, 0x00127ff0, 0x00147ff0, 0x00167ff0, + 0x00187ff0, 0x001a7ff0, 0x001c7ff0, 0x001e7ff0, + 0x0000fff1, 0x0004fff1, 0x0008fff1, 0x000cfff1, + 0x0010fff1, 0x0014fff1, 0x0018fff1, 0x001cfff1, + 0x0020fff1, 0x0024fff1, 0x0028fff1, 0x002cfff1, + 0x0030fff1, 0x0034fff1, 0x0038fff1, 0x003cfff1, + 0x0002fff1, 0x0006fff1, 0x000afff1, 0x000efff1, + 0x0012fff1, 0x0016fff1, 0x001afff1, 0x001efff1, + 0x0022fff1, 0x0026fff1, 0x002afff1, 0x002efff1, + 0x0032fff1, 0x0036fff1, 0x003afff1, 0x003efff1, + 0x00017ff1, 0x00037ff1, 0x00057ff1, 0x00077ff1, + 0x00097ff1, 0x000b7ff1, 0x000d7ff1, 0x000f7ff1, + 0x00117ff1, 0x00137ff1, 0x00157ff1, 0x00177ff1, + 0x00197ff1, 0x001b7ff1, 0x001d7ff1, 0x001f7ff1, + 0x00217ff1, 0x00237ff1, 0x00257ff1, 0x00277ff1, + 0x00297ff1, 0x002b7ff1, 0x002d7ff1, 0x002f7ff1, + 0x00317ff1, 0x00337ff1, 0x00357ff1, 0x00377ff1, + 0x00397ff1, 0x003b7ff1, 0x003d7ff1, 0x003f7ff1, + 0x0001fff2, 0x0005fff2, 0x0009fff2, 0x000dfff2, + 0x0011fff2, 0x0015fff2, 0x0019fff2, 0x001dfff2, + 0x0021fff2, 0x0025fff2, 0x0029fff2, 0x002dfff2, + 0x0031fff2, 0x0035fff2, 0x0039fff2, 0x003dfff2, + 0x0041fff2, 0x0045fff2, 0x0049fff2, 0x004dfff2, + 0x0051fff2, 0x0055fff2, 0x0059fff2, 0x005dfff2, + 0x0061fff2, 0x0065fff2, 0x0069fff2, 0x006dfff2, + 0x0071fff2, 0x0075fff2, 0x0079fff2, 0x007dfff2, + 0x0007fff4, 0x0017fff4, 0x0027fff4, 0x0037fff4, + 0x0047fff4, 0x0057fff4, 0x0067fff4, 0x0077fff4, + 0x0087fff4, 0x0097fff4, 0x00a7fff4, 0x00b7fff4, + 0x00c7fff4, 0x00d7fff4, 0x00e7fff4, 0x00f7fff4, + 0x0107fff4, 0x0117fff4, 0x0127fff4, 0x0137fff4, + 0x0147fff4, 0x0157fff4, 0x0167fff4, 0x0177fff4, + 0x0187fff4, 0x0197fff4, 0x01a7fff4, 0x01b7fff4, + 0x01c7fff4, 0x01d7fff4, 0x01e7fff4, 0x01f7fff4, + 0x000ffff4, 0x001ffff4, 0x002ffff4, 0x003ffff4, + 0x004ffff4, 0x005ffff4, 0x006ffff4, 0x007ffff4, + 0x008ffff4, 0x009ffff4, 0x00affff4, 0x00bffff4, + 0x00cffff4, 0x00dffff4, 0x00effff4, 0x00fffff4, + 0x010ffff4, 0x011ffff4, 0x012ffff4, 0x013ffff4, + 0x014ffff4, 0x015ffff4, 0x016ffff4, 0x017ffff4, + 0x018ffff4, 0x019ffff4, 0x01affff4, 0x01bffff4, + 0x01cffff4, 0x01dffff4, 0x01effff4, 0x0000bfeb}, + + .lit_table = { + 0x001e, 0x004d, 0x00e3, 0x00cd, 0x002d, 0x01e3, 0x0013, 0x0113, + 0x0093, 0x0193, 0x0019, 0x0053, 0x0153, 0x00ad, 0x00d3, 0x01d3, + 0x0033, 0x0047, 0x0247, 0x0147, 0x0347, 0x038f, 0x078f, 0x004f, + 0x00c7, 0x044f, 0x024f, 0x064f, 0x02c7, 0x014f, 0x01c7, 0x0133, + 0x0006, 0x03c7, 0x00b3, 0x0027, 0x0227, 0x0127, 0x0327, 0x01b3, + 0x0073, 0x0173, 0x00a7, 0x02a7, 0x0059, 0x006d, 0x00ed, 0x01a7, + 0x001d, 0x009d, 0x005d, 0x00f3, 0x01f3, 0x000b, 0x010b, 0x008b, + 0x018b, 0x004b, 0x014b, 0x00cb, 0x03a7, 0x0067, 0x01cb, 0x002b, + 0x012b, 0x00dd, 0x003d, 0x00ab, 0x01ab, 0x006b, 0x016b, 0x00eb, + 0x01eb, 0x001b, 0x0267, 0x0167, 0x011b, 0x009b, 0x019b, 0x005b, + 0x015b, 0x0367, 0x00db, 0x01db, 0x003b, 0x00e7, 0x02e7, 0x01e7, + 0x03e7, 0x0017, 0x054f, 0x0217, 0x0117, 0x034f, 0x074f, 0x0317, + 0x0097, 0x003e, 0x00bd, 0x0039, 0x0079, 0x0001, 0x007d, 0x00fd, + 0x0005, 0x0021, 0x0297, 0x013b, 0x0045, 0x0025, 0x0065, 0x0011, + 0x0015, 0x0197, 0x0031, 0x0009, 0x0055, 0x0035, 0x00bb, 0x0003, + 0x01bb, 0x0083, 0x0397, 0x00cf, 0x0057, 0x04cf, 0x0257, 0x0157, + 0x007b, 0x02cf, 0x06cf, 0x01cf, 0x05cf, 0x03cf, 0x07cf, 0x002f, + 0x042f, 0x022f, 0x062f, 0x0357, 0x012f, 0x052f, 0x032f, 0x00d7, + 0x02d7, 0x072f, 0x00af, 0x04af, 0x02af, 0x06af, 0x01af, 0x05af, + 0x03af, 0x07af, 0x006f, 0x046f, 0x026f, 0x066f, 0x016f, 0x056f, + 0x01d7, 0x036f, 0x076f, 0x00ef, 0x03d7, 0x04ef, 0x0037, 0x02ef, + 0x06ef, 0x01ef, 0x05ef, 0x03ef, 0x07ef, 0x001f, 0x041f, 0x021f, + 0x0237, 0x061f, 0x011f, 0x051f, 0x0137, 0x031f, 0x071f, 0x009f, + 0x049f, 0x029f, 0x069f, 0x019f, 0x059f, 0x0337, 0x039f, 0x079f, + 0x017b, 0x00b7, 0x00fb, 0x01fb, 0x005f, 0x045f, 0x025f, 0x02b7, + 0x065f, 0x015f, 0x055f, 0x035f, 0x075f, 0x00df, 0x04df, 0x01b7, + 0x03b7, 0x02df, 0x06df, 0x01df, 0x05df, 0x03df, 0x07df, 0x003f, + 0x043f, 0x023f, 0x063f, 0x013f, 0x053f, 0x033f, 0x073f, 0x00bf, + 0x0007, 0x04bf, 0x02bf, 0x0077, 0x06bf, 0x01bf, 0x05bf, 0x0277, + 0x0177, 0x03bf, 0x07bf, 0x007f, 0x047f, 0x027f, 0x067f, 0x017f, + 0x0107, 0x0377, 0x057f, 0x00f7, 0x037f, 0x077f, 0x00ff, 0x04ff, + 0x02f7, 0x01f7, 0x02ff, 0x06ff, 0x03f7, 0x000f, 0x0087, 0x0043, + 0x1fff}, + + .lit_table_sizes = { + 0x06, 0x08, 0x09, 0x08, 0x08, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x07, 0x09, 0x09, 0x08, 0x09, 0x09, + 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, + 0x0a, 0x0b, 0x0b, 0x0b, 0x0a, 0x0b, 0x0a, 0x09, + 0x05, 0x0a, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, + 0x09, 0x09, 0x0a, 0x0a, 0x07, 0x08, 0x08, 0x0a, + 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x09, 0x09, + 0x09, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x0a, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, + 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b, 0x0a, + 0x0a, 0x06, 0x08, 0x07, 0x07, 0x06, 0x08, 0x08, + 0x07, 0x06, 0x0a, 0x09, 0x07, 0x07, 0x07, 0x06, + 0x07, 0x0a, 0x06, 0x06, 0x07, 0x07, 0x09, 0x08, + 0x09, 0x08, 0x0a, 0x0b, 0x0a, 0x0b, 0x0a, 0x0a, + 0x09, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0a, 0x0b, 0x0b, 0x0b, 0x0a, + 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0a, 0x0b, 0x0b, 0x0b, 0x0a, 0x0b, 0x0a, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0a, 0x0b, 0x0b, 0x0b, 0x0a, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0b, 0x0b, + 0x09, 0x0a, 0x09, 0x09, 0x0b, 0x0b, 0x0b, 0x0a, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, + 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x09, 0x0b, 0x0b, 0x0a, 0x0b, 0x0b, 0x0b, 0x0a, + 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x09, 0x0a, 0x0b, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x09, 0x08, + 0x0f}, + +#ifndef LONGER_HUFFTABLE + .dcodes = { + 0x003f, 0x00ff, 0x00bf, 0x01ff, 0x007f, 0x001f, 0x005f, 0x0017, + 0x0037, 0x000f, 0x0009, 0x0019, 0x0005, 0x0015, 0x0004, 0x000c, + 0x0002, 0x000d, 0x000a, 0x001d, 0x0006, 0x0003, 0x0000, 0x0013, + 0x000e, 0x000b, 0x0001, 0x001b, 0x0007, 0x002f}, + + .dcodes_sizes = { + 0x08, 0x09, 0x08, 0x09, 0x08, 0x07, 0x07, 0x06, + 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x04, 0x04, + 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x03, 0x05, + 0x04, 0x05, 0x04, 0x05, 0x05, 0x06} +#else + .dcodes = { + 0x0001, 0x001b, 0x0007, 0x002f}, + + .dcodes_sizes = { + 0x04, 0x05, 0x05, 0x06} #endif +}; +#endif // LARGE_WINDOW + +struct isal_hufftables hufftables_static = { + + .deflate_hdr = {0x03}, + .deflate_hdr_count = 0, + .deflate_hdr_extra_bits = 3, + + .dist_table = { + 0x00000005, 0x00000205, +#ifdef LONGER_HUFFTABLE + 0x00000105, 0x00000305, 0x00000086, 0x00000486, + 0x00000286, 0x00000686, 0x00000187, 0x00000587, + 0x00000987, 0x00000d87, 0x00000387, 0x00000787, + 0x00000b87, 0x00000f87, 0x00000048, 0x00000448, + 0x00000848, 0x00000c48, 0x00001048, 0x00001448, + 0x00001848, 0x00001c48, 0x00000248, 0x00000648, + 0x00000a48, 0x00000e48, 0x00001248, 0x00001648, + 0x00001a48, 0x00001e48, 0x00000149, 0x00000549, + 0x00000949, 0x00000d49, 0x00001149, 0x00001549, + 0x00001949, 0x00001d49, 0x00002149, 0x00002549, + 0x00002949, 0x00002d49, 0x00003149, 0x00003549, + 0x00003949, 0x00003d49, 0x00000349, 0x00000749, + 0x00000b49, 0x00000f49, 0x00001349, 0x00001749, + 0x00001b49, 0x00001f49, 0x00002349, 0x00002749, + 0x00002b49, 0x00002f49, 0x00003349, 0x00003749, + 0x00003b49, 0x00003f49, 0x000000ca, 0x000004ca, + 0x000008ca, 0x00000cca, 0x000010ca, 0x000014ca, + 0x000018ca, 0x00001cca, 0x000020ca, 0x000024ca, + 0x000028ca, 0x00002cca, 0x000030ca, 0x000034ca, + 0x000038ca, 0x00003cca, 0x000040ca, 0x000044ca, + 0x000048ca, 0x00004cca, 0x000050ca, 0x000054ca, + 0x000058ca, 0x00005cca, 0x000060ca, 0x000064ca, + 0x000068ca, 0x00006cca, 0x000070ca, 0x000074ca, + 0x000078ca, 0x00007cca, 0x000002ca, 0x000006ca, + 0x00000aca, 0x00000eca, 0x000012ca, 0x000016ca, + 0x00001aca, 0x00001eca, 0x000022ca, 0x000026ca, + 0x00002aca, 0x00002eca, 0x000032ca, 0x000036ca, + 0x00003aca, 0x00003eca, 0x000042ca, 0x000046ca, + 0x00004aca, 0x00004eca, 0x000052ca, 0x000056ca, + 0x00005aca, 0x00005eca, 0x000062ca, 0x000066ca, + 0x00006aca, 0x00006eca, 0x000072ca, 0x000076ca, + 0x00007aca, 0x00007eca, 0x000001cb, 0x000005cb, + 0x000009cb, 0x00000dcb, 0x000011cb, 0x000015cb, + 0x000019cb, 0x00001dcb, 0x000021cb, 0x000025cb, + 0x000029cb, 0x00002dcb, 0x000031cb, 0x000035cb, + 0x000039cb, 0x00003dcb, 0x000041cb, 0x000045cb, + 0x000049cb, 0x00004dcb, 0x000051cb, 0x000055cb, + 0x000059cb, 0x00005dcb, 0x000061cb, 0x000065cb, + 0x000069cb, 0x00006dcb, 0x000071cb, 0x000075cb, + 0x000079cb, 0x00007dcb, 0x000081cb, 0x000085cb, + 0x000089cb, 0x00008dcb, 0x000091cb, 0x000095cb, + 0x000099cb, 0x00009dcb, 0x0000a1cb, 0x0000a5cb, + 0x0000a9cb, 0x0000adcb, 0x0000b1cb, 0x0000b5cb, + 0x0000b9cb, 0x0000bdcb, 0x0000c1cb, 0x0000c5cb, + 0x0000c9cb, 0x0000cdcb, 0x0000d1cb, 0x0000d5cb, + 0x0000d9cb, 0x0000ddcb, 0x0000e1cb, 0x0000e5cb, + 0x0000e9cb, 0x0000edcb, 0x0000f1cb, 0x0000f5cb, + 0x0000f9cb, 0x0000fdcb, 0x000003cb, 0x000007cb, + 0x00000bcb, 0x00000fcb, 0x000013cb, 0x000017cb, + 0x00001bcb, 0x00001fcb, 0x000023cb, 0x000027cb, + 0x00002bcb, 0x00002fcb, 0x000033cb, 0x000037cb, + 0x00003bcb, 0x00003fcb, 0x000043cb, 0x000047cb, + 0x00004bcb, 0x00004fcb, 0x000053cb, 0x000057cb, + 0x00005bcb, 0x00005fcb, 0x000063cb, 0x000067cb, + 0x00006bcb, 0x00006fcb, 0x000073cb, 0x000077cb, + 0x00007bcb, 0x00007fcb, 0x000083cb, 0x000087cb, + 0x00008bcb, 0x00008fcb, 0x000093cb, 0x000097cb, + 0x00009bcb, 0x00009fcb, 0x0000a3cb, 0x0000a7cb, + 0x0000abcb, 0x0000afcb, 0x0000b3cb, 0x0000b7cb, + 0x0000bbcb, 0x0000bfcb, 0x0000c3cb, 0x0000c7cb, + 0x0000cbcb, 0x0000cfcb, 0x0000d3cb, 0x0000d7cb, + 0x0000dbcb, 0x0000dfcb, 0x0000e3cb, 0x0000e7cb, + 0x0000ebcb, 0x0000efcb, 0x0000f3cb, 0x0000f7cb, + 0x0000fbcb, 0x0000ffcb, 0x0000002c, 0x0000042c, + 0x0000082c, 0x00000c2c, 0x0000102c, 0x0000142c, + 0x0000182c, 0x00001c2c, 0x0000202c, 0x0000242c, + 0x0000282c, 0x00002c2c, 0x0000302c, 0x0000342c, + 0x0000382c, 0x00003c2c, 0x0000402c, 0x0000442c, + 0x0000482c, 0x00004c2c, 0x0000502c, 0x0000542c, + 0x0000582c, 0x00005c2c, 0x0000602c, 0x0000642c, + 0x0000682c, 0x00006c2c, 0x0000702c, 0x0000742c, + 0x0000782c, 0x00007c2c, 0x0000802c, 0x0000842c, + 0x0000882c, 0x00008c2c, 0x0000902c, 0x0000942c, + 0x0000982c, 0x00009c2c, 0x0000a02c, 0x0000a42c, + 0x0000a82c, 0x0000ac2c, 0x0000b02c, 0x0000b42c, + 0x0000b82c, 0x0000bc2c, 0x0000c02c, 0x0000c42c, + 0x0000c82c, 0x0000cc2c, 0x0000d02c, 0x0000d42c, + 0x0000d82c, 0x0000dc2c, 0x0000e02c, 0x0000e42c, + 0x0000e82c, 0x0000ec2c, 0x0000f02c, 0x0000f42c, + 0x0000f82c, 0x0000fc2c, 0x0001002c, 0x0001042c, + 0x0001082c, 0x00010c2c, 0x0001102c, 0x0001142c, + 0x0001182c, 0x00011c2c, 0x0001202c, 0x0001242c, + 0x0001282c, 0x00012c2c, 0x0001302c, 0x0001342c, + 0x0001382c, 0x00013c2c, 0x0001402c, 0x0001442c, + 0x0001482c, 0x00014c2c, 0x0001502c, 0x0001542c, + 0x0001582c, 0x00015c2c, 0x0001602c, 0x0001642c, + 0x0001682c, 0x00016c2c, 0x0001702c, 0x0001742c, + 0x0001782c, 0x00017c2c, 0x0001802c, 0x0001842c, + 0x0001882c, 0x00018c2c, 0x0001902c, 0x0001942c, + 0x0001982c, 0x00019c2c, 0x0001a02c, 0x0001a42c, + 0x0001a82c, 0x0001ac2c, 0x0001b02c, 0x0001b42c, + 0x0001b82c, 0x0001bc2c, 0x0001c02c, 0x0001c42c, + 0x0001c82c, 0x0001cc2c, 0x0001d02c, 0x0001d42c, + 0x0001d82c, 0x0001dc2c, 0x0001e02c, 0x0001e42c, + 0x0001e82c, 0x0001ec2c, 0x0001f02c, 0x0001f42c, + 0x0001f82c, 0x0001fc2c, 0x0000022c, 0x0000062c, + 0x00000a2c, 0x00000e2c, 0x0000122c, 0x0000162c, + 0x00001a2c, 0x00001e2c, 0x0000222c, 0x0000262c, + 0x00002a2c, 0x00002e2c, 0x0000322c, 0x0000362c, + 0x00003a2c, 0x00003e2c, 0x0000422c, 0x0000462c, + 0x00004a2c, 0x00004e2c, 0x0000522c, 0x0000562c, + 0x00005a2c, 0x00005e2c, 0x0000622c, 0x0000662c, + 0x00006a2c, 0x00006e2c, 0x0000722c, 0x0000762c, + 0x00007a2c, 0x00007e2c, 0x0000822c, 0x0000862c, + 0x00008a2c, 0x00008e2c, 0x0000922c, 0x0000962c, + 0x00009a2c, 0x00009e2c, 0x0000a22c, 0x0000a62c, + 0x0000aa2c, 0x0000ae2c, 0x0000b22c, 0x0000b62c, + 0x0000ba2c, 0x0000be2c, 0x0000c22c, 0x0000c62c, + 0x0000ca2c, 0x0000ce2c, 0x0000d22c, 0x0000d62c, + 0x0000da2c, 0x0000de2c, 0x0000e22c, 0x0000e62c, + 0x0000ea2c, 0x0000ee2c, 0x0000f22c, 0x0000f62c, + 0x0000fa2c, 0x0000fe2c, 0x0001022c, 0x0001062c, + 0x00010a2c, 0x00010e2c, 0x0001122c, 0x0001162c, + 0x00011a2c, 0x00011e2c, 0x0001222c, 0x0001262c, + 0x00012a2c, 0x00012e2c, 0x0001322c, 0x0001362c, + 0x00013a2c, 0x00013e2c, 0x0001422c, 0x0001462c, + 0x00014a2c, 0x00014e2c, 0x0001522c, 0x0001562c, + 0x00015a2c, 0x00015e2c, 0x0001622c, 0x0001662c, + 0x00016a2c, 0x00016e2c, 0x0001722c, 0x0001762c, + 0x00017a2c, 0x00017e2c, 0x0001822c, 0x0001862c, + 0x00018a2c, 0x00018e2c, 0x0001922c, 0x0001962c, + 0x00019a2c, 0x00019e2c, 0x0001a22c, 0x0001a62c, + 0x0001aa2c, 0x0001ae2c, 0x0001b22c, 0x0001b62c, + 0x0001ba2c, 0x0001be2c, 0x0001c22c, 0x0001c62c, + 0x0001ca2c, 0x0001ce2c, 0x0001d22c, 0x0001d62c, + 0x0001da2c, 0x0001de2c, 0x0001e22c, 0x0001e62c, + 0x0001ea2c, 0x0001ee2c, 0x0001f22c, 0x0001f62c, + 0x0001fa2c, 0x0001fe2c, 0x0000012d, 0x0000052d, + 0x0000092d, 0x00000d2d, 0x0000112d, 0x0000152d, + 0x0000192d, 0x00001d2d, 0x0000212d, 0x0000252d, + 0x0000292d, 0x00002d2d, 0x0000312d, 0x0000352d, + 0x0000392d, 0x00003d2d, 0x0000412d, 0x0000452d, + 0x0000492d, 0x00004d2d, 0x0000512d, 0x0000552d, + 0x0000592d, 0x00005d2d, 0x0000612d, 0x0000652d, + 0x0000692d, 0x00006d2d, 0x0000712d, 0x0000752d, + 0x0000792d, 0x00007d2d, 0x0000812d, 0x0000852d, + 0x0000892d, 0x00008d2d, 0x0000912d, 0x0000952d, + 0x0000992d, 0x00009d2d, 0x0000a12d, 0x0000a52d, + 0x0000a92d, 0x0000ad2d, 0x0000b12d, 0x0000b52d, + 0x0000b92d, 0x0000bd2d, 0x0000c12d, 0x0000c52d, + 0x0000c92d, 0x0000cd2d, 0x0000d12d, 0x0000d52d, + 0x0000d92d, 0x0000dd2d, 0x0000e12d, 0x0000e52d, + 0x0000e92d, 0x0000ed2d, 0x0000f12d, 0x0000f52d, + 0x0000f92d, 0x0000fd2d, 0x0001012d, 0x0001052d, + 0x0001092d, 0x00010d2d, 0x0001112d, 0x0001152d, + 0x0001192d, 0x00011d2d, 0x0001212d, 0x0001252d, + 0x0001292d, 0x00012d2d, 0x0001312d, 0x0001352d, + 0x0001392d, 0x00013d2d, 0x0001412d, 0x0001452d, + 0x0001492d, 0x00014d2d, 0x0001512d, 0x0001552d, + 0x0001592d, 0x00015d2d, 0x0001612d, 0x0001652d, + 0x0001692d, 0x00016d2d, 0x0001712d, 0x0001752d, + 0x0001792d, 0x00017d2d, 0x0001812d, 0x0001852d, + 0x0001892d, 0x00018d2d, 0x0001912d, 0x0001952d, + 0x0001992d, 0x00019d2d, 0x0001a12d, 0x0001a52d, + 0x0001a92d, 0x0001ad2d, 0x0001b12d, 0x0001b52d, + 0x0001b92d, 0x0001bd2d, 0x0001c12d, 0x0001c52d, + 0x0001c92d, 0x0001cd2d, 0x0001d12d, 0x0001d52d, + 0x0001d92d, 0x0001dd2d, 0x0001e12d, 0x0001e52d, + 0x0001e92d, 0x0001ed2d, 0x0001f12d, 0x0001f52d, + 0x0001f92d, 0x0001fd2d, 0x0002012d, 0x0002052d, + 0x0002092d, 0x00020d2d, 0x0002112d, 0x0002152d, + 0x0002192d, 0x00021d2d, 0x0002212d, 0x0002252d, + 0x0002292d, 0x00022d2d, 0x0002312d, 0x0002352d, + 0x0002392d, 0x00023d2d, 0x0002412d, 0x0002452d, + 0x0002492d, 0x00024d2d, 0x0002512d, 0x0002552d, + 0x0002592d, 0x00025d2d, 0x0002612d, 0x0002652d, + 0x0002692d, 0x00026d2d, 0x0002712d, 0x0002752d, + 0x0002792d, 0x00027d2d, 0x0002812d, 0x0002852d, + 0x0002892d, 0x00028d2d, 0x0002912d, 0x0002952d, + 0x0002992d, 0x00029d2d, 0x0002a12d, 0x0002a52d, + 0x0002a92d, 0x0002ad2d, 0x0002b12d, 0x0002b52d, + 0x0002b92d, 0x0002bd2d, 0x0002c12d, 0x0002c52d, + 0x0002c92d, 0x0002cd2d, 0x0002d12d, 0x0002d52d, + 0x0002d92d, 0x0002dd2d, 0x0002e12d, 0x0002e52d, + 0x0002e92d, 0x0002ed2d, 0x0002f12d, 0x0002f52d, + 0x0002f92d, 0x0002fd2d, 0x0003012d, 0x0003052d, + 0x0003092d, 0x00030d2d, 0x0003112d, 0x0003152d, + 0x0003192d, 0x00031d2d, 0x0003212d, 0x0003252d, + 0x0003292d, 0x00032d2d, 0x0003312d, 0x0003352d, + 0x0003392d, 0x00033d2d, 0x0003412d, 0x0003452d, + 0x0003492d, 0x00034d2d, 0x0003512d, 0x0003552d, + 0x0003592d, 0x00035d2d, 0x0003612d, 0x0003652d, + 0x0003692d, 0x00036d2d, 0x0003712d, 0x0003752d, + 0x0003792d, 0x00037d2d, 0x0003812d, 0x0003852d, + 0x0003892d, 0x00038d2d, 0x0003912d, 0x0003952d, + 0x0003992d, 0x00039d2d, 0x0003a12d, 0x0003a52d, + 0x0003a92d, 0x0003ad2d, 0x0003b12d, 0x0003b52d, + 0x0003b92d, 0x0003bd2d, 0x0003c12d, 0x0003c52d, + 0x0003c92d, 0x0003cd2d, 0x0003d12d, 0x0003d52d, + 0x0003d92d, 0x0003dd2d, 0x0003e12d, 0x0003e52d, + 0x0003e92d, 0x0003ed2d, 0x0003f12d, 0x0003f52d, + 0x0003f92d, 0x0003fd2d, 0x0000032d, 0x0000072d, + 0x00000b2d, 0x00000f2d, 0x0000132d, 0x0000172d, + 0x00001b2d, 0x00001f2d, 0x0000232d, 0x0000272d, + 0x00002b2d, 0x00002f2d, 0x0000332d, 0x0000372d, + 0x00003b2d, 0x00003f2d, 0x0000432d, 0x0000472d, + 0x00004b2d, 0x00004f2d, 0x0000532d, 0x0000572d, + 0x00005b2d, 0x00005f2d, 0x0000632d, 0x0000672d, + 0x00006b2d, 0x00006f2d, 0x0000732d, 0x0000772d, + 0x00007b2d, 0x00007f2d, 0x0000832d, 0x0000872d, + 0x00008b2d, 0x00008f2d, 0x0000932d, 0x0000972d, + 0x00009b2d, 0x00009f2d, 0x0000a32d, 0x0000a72d, + 0x0000ab2d, 0x0000af2d, 0x0000b32d, 0x0000b72d, + 0x0000bb2d, 0x0000bf2d, 0x0000c32d, 0x0000c72d, + 0x0000cb2d, 0x0000cf2d, 0x0000d32d, 0x0000d72d, + 0x0000db2d, 0x0000df2d, 0x0000e32d, 0x0000e72d, + 0x0000eb2d, 0x0000ef2d, 0x0000f32d, 0x0000f72d, + 0x0000fb2d, 0x0000ff2d, 0x0001032d, 0x0001072d, + 0x00010b2d, 0x00010f2d, 0x0001132d, 0x0001172d, + 0x00011b2d, 0x00011f2d, 0x0001232d, 0x0001272d, + 0x00012b2d, 0x00012f2d, 0x0001332d, 0x0001372d, + 0x00013b2d, 0x00013f2d, 0x0001432d, 0x0001472d, + 0x00014b2d, 0x00014f2d, 0x0001532d, 0x0001572d, + 0x00015b2d, 0x00015f2d, 0x0001632d, 0x0001672d, + 0x00016b2d, 0x00016f2d, 0x0001732d, 0x0001772d, + 0x00017b2d, 0x00017f2d, 0x0001832d, 0x0001872d, + 0x00018b2d, 0x00018f2d, 0x0001932d, 0x0001972d, + 0x00019b2d, 0x00019f2d, 0x0001a32d, 0x0001a72d, + 0x0001ab2d, 0x0001af2d, 0x0001b32d, 0x0001b72d, + 0x0001bb2d, 0x0001bf2d, 0x0001c32d, 0x0001c72d, + 0x0001cb2d, 0x0001cf2d, 0x0001d32d, 0x0001d72d, + 0x0001db2d, 0x0001df2d, 0x0001e32d, 0x0001e72d, + 0x0001eb2d, 0x0001ef2d, 0x0001f32d, 0x0001f72d, + 0x0001fb2d, 0x0001ff2d, 0x0002032d, 0x0002072d, + 0x00020b2d, 0x00020f2d, 0x0002132d, 0x0002172d, + 0x00021b2d, 0x00021f2d, 0x0002232d, 0x0002272d, + 0x00022b2d, 0x00022f2d, 0x0002332d, 0x0002372d, + 0x00023b2d, 0x00023f2d, 0x0002432d, 0x0002472d, + 0x00024b2d, 0x00024f2d, 0x0002532d, 0x0002572d, + 0x00025b2d, 0x00025f2d, 0x0002632d, 0x0002672d, + 0x00026b2d, 0x00026f2d, 0x0002732d, 0x0002772d, + 0x00027b2d, 0x00027f2d, 0x0002832d, 0x0002872d, + 0x00028b2d, 0x00028f2d, 0x0002932d, 0x0002972d, + 0x00029b2d, 0x00029f2d, 0x0002a32d, 0x0002a72d, + 0x0002ab2d, 0x0002af2d, 0x0002b32d, 0x0002b72d, + 0x0002bb2d, 0x0002bf2d, 0x0002c32d, 0x0002c72d, + 0x0002cb2d, 0x0002cf2d, 0x0002d32d, 0x0002d72d, + 0x0002db2d, 0x0002df2d, 0x0002e32d, 0x0002e72d, + 0x0002eb2d, 0x0002ef2d, 0x0002f32d, 0x0002f72d, + 0x0002fb2d, 0x0002ff2d, 0x0003032d, 0x0003072d, + 0x00030b2d, 0x00030f2d, 0x0003132d, 0x0003172d, + 0x00031b2d, 0x00031f2d, 0x0003232d, 0x0003272d, + 0x00032b2d, 0x00032f2d, 0x0003332d, 0x0003372d, + 0x00033b2d, 0x00033f2d, 0x0003432d, 0x0003472d, + 0x00034b2d, 0x00034f2d, 0x0003532d, 0x0003572d, + 0x00035b2d, 0x00035f2d, 0x0003632d, 0x0003672d, + 0x00036b2d, 0x00036f2d, 0x0003732d, 0x0003772d, + 0x00037b2d, 0x00037f2d, 0x0003832d, 0x0003872d, + 0x00038b2d, 0x00038f2d, 0x0003932d, 0x0003972d, + 0x00039b2d, 0x00039f2d, 0x0003a32d, 0x0003a72d, + 0x0003ab2d, 0x0003af2d, 0x0003b32d, 0x0003b72d, + 0x0003bb2d, 0x0003bf2d, 0x0003c32d, 0x0003c72d, + 0x0003cb2d, 0x0003cf2d, 0x0003d32d, 0x0003d72d, + 0x0003db2d, 0x0003df2d, 0x0003e32d, 0x0003e72d, + 0x0003eb2d, 0x0003ef2d, 0x0003f32d, 0x0003f72d, + 0x0003fb2d, 0x0003ff2d, 0x000000ae, 0x000004ae, + 0x000008ae, 0x00000cae, 0x000010ae, 0x000014ae, + 0x000018ae, 0x00001cae, 0x000020ae, 0x000024ae, + 0x000028ae, 0x00002cae, 0x000030ae, 0x000034ae, + 0x000038ae, 0x00003cae, 0x000040ae, 0x000044ae, + 0x000048ae, 0x00004cae, 0x000050ae, 0x000054ae, + 0x000058ae, 0x00005cae, 0x000060ae, 0x000064ae, + 0x000068ae, 0x00006cae, 0x000070ae, 0x000074ae, + 0x000078ae, 0x00007cae, 0x000080ae, 0x000084ae, + 0x000088ae, 0x00008cae, 0x000090ae, 0x000094ae, + 0x000098ae, 0x00009cae, 0x0000a0ae, 0x0000a4ae, + 0x0000a8ae, 0x0000acae, 0x0000b0ae, 0x0000b4ae, + 0x0000b8ae, 0x0000bcae, 0x0000c0ae, 0x0000c4ae, + 0x0000c8ae, 0x0000ccae, 0x0000d0ae, 0x0000d4ae, + 0x0000d8ae, 0x0000dcae, 0x0000e0ae, 0x0000e4ae, + 0x0000e8ae, 0x0000ecae, 0x0000f0ae, 0x0000f4ae, + 0x0000f8ae, 0x0000fcae, 0x000100ae, 0x000104ae, + 0x000108ae, 0x00010cae, 0x000110ae, 0x000114ae, + 0x000118ae, 0x00011cae, 0x000120ae, 0x000124ae, + 0x000128ae, 0x00012cae, 0x000130ae, 0x000134ae, + 0x000138ae, 0x00013cae, 0x000140ae, 0x000144ae, + 0x000148ae, 0x00014cae, 0x000150ae, 0x000154ae, + 0x000158ae, 0x00015cae, 0x000160ae, 0x000164ae, + 0x000168ae, 0x00016cae, 0x000170ae, 0x000174ae, + 0x000178ae, 0x00017cae, 0x000180ae, 0x000184ae, + 0x000188ae, 0x00018cae, 0x000190ae, 0x000194ae, + 0x000198ae, 0x00019cae, 0x0001a0ae, 0x0001a4ae, + 0x0001a8ae, 0x0001acae, 0x0001b0ae, 0x0001b4ae, + 0x0001b8ae, 0x0001bcae, 0x0001c0ae, 0x0001c4ae, + 0x0001c8ae, 0x0001ccae, 0x0001d0ae, 0x0001d4ae, + 0x0001d8ae, 0x0001dcae, 0x0001e0ae, 0x0001e4ae, + 0x0001e8ae, 0x0001ecae, 0x0001f0ae, 0x0001f4ae, + 0x0001f8ae, 0x0001fcae, 0x000200ae, 0x000204ae, + 0x000208ae, 0x00020cae, 0x000210ae, 0x000214ae, + 0x000218ae, 0x00021cae, 0x000220ae, 0x000224ae, + 0x000228ae, 0x00022cae, 0x000230ae, 0x000234ae, + 0x000238ae, 0x00023cae, 0x000240ae, 0x000244ae, + 0x000248ae, 0x00024cae, 0x000250ae, 0x000254ae, + 0x000258ae, 0x00025cae, 0x000260ae, 0x000264ae, + 0x000268ae, 0x00026cae, 0x000270ae, 0x000274ae, + 0x000278ae, 0x00027cae, 0x000280ae, 0x000284ae, + 0x000288ae, 0x00028cae, 0x000290ae, 0x000294ae, + 0x000298ae, 0x00029cae, 0x0002a0ae, 0x0002a4ae, + 0x0002a8ae, 0x0002acae, 0x0002b0ae, 0x0002b4ae, + 0x0002b8ae, 0x0002bcae, 0x0002c0ae, 0x0002c4ae, + 0x0002c8ae, 0x0002ccae, 0x0002d0ae, 0x0002d4ae, + 0x0002d8ae, 0x0002dcae, 0x0002e0ae, 0x0002e4ae, + 0x0002e8ae, 0x0002ecae, 0x0002f0ae, 0x0002f4ae, + 0x0002f8ae, 0x0002fcae, 0x000300ae, 0x000304ae, + 0x000308ae, 0x00030cae, 0x000310ae, 0x000314ae, + 0x000318ae, 0x00031cae, 0x000320ae, 0x000324ae, + 0x000328ae, 0x00032cae, 0x000330ae, 0x000334ae, + 0x000338ae, 0x00033cae, 0x000340ae, 0x000344ae, + 0x000348ae, 0x00034cae, 0x000350ae, 0x000354ae, + 0x000358ae, 0x00035cae, 0x000360ae, 0x000364ae, + 0x000368ae, 0x00036cae, 0x000370ae, 0x000374ae, + 0x000378ae, 0x00037cae, 0x000380ae, 0x000384ae, + 0x000388ae, 0x00038cae, 0x000390ae, 0x000394ae, + 0x000398ae, 0x00039cae, 0x0003a0ae, 0x0003a4ae, + 0x0003a8ae, 0x0003acae, 0x0003b0ae, 0x0003b4ae, + 0x0003b8ae, 0x0003bcae, 0x0003c0ae, 0x0003c4ae, + 0x0003c8ae, 0x0003ccae, 0x0003d0ae, 0x0003d4ae, + 0x0003d8ae, 0x0003dcae, 0x0003e0ae, 0x0003e4ae, + 0x0003e8ae, 0x0003ecae, 0x0003f0ae, 0x0003f4ae, + 0x0003f8ae, 0x0003fcae, 0x000400ae, 0x000404ae, + 0x000408ae, 0x00040cae, 0x000410ae, 0x000414ae, + 0x000418ae, 0x00041cae, 0x000420ae, 0x000424ae, + 0x000428ae, 0x00042cae, 0x000430ae, 0x000434ae, + 0x000438ae, 0x00043cae, 0x000440ae, 0x000444ae, + 0x000448ae, 0x00044cae, 0x000450ae, 0x000454ae, + 0x000458ae, 0x00045cae, 0x000460ae, 0x000464ae, + 0x000468ae, 0x00046cae, 0x000470ae, 0x000474ae, + 0x000478ae, 0x00047cae, 0x000480ae, 0x000484ae, + 0x000488ae, 0x00048cae, 0x000490ae, 0x000494ae, + 0x000498ae, 0x00049cae, 0x0004a0ae, 0x0004a4ae, + 0x0004a8ae, 0x0004acae, 0x0004b0ae, 0x0004b4ae, + 0x0004b8ae, 0x0004bcae, 0x0004c0ae, 0x0004c4ae, + 0x0004c8ae, 0x0004ccae, 0x0004d0ae, 0x0004d4ae, + 0x0004d8ae, 0x0004dcae, 0x0004e0ae, 0x0004e4ae, + 0x0004e8ae, 0x0004ecae, 0x0004f0ae, 0x0004f4ae, + 0x0004f8ae, 0x0004fcae, 0x000500ae, 0x000504ae, + 0x000508ae, 0x00050cae, 0x000510ae, 0x000514ae, + 0x000518ae, 0x00051cae, 0x000520ae, 0x000524ae, + 0x000528ae, 0x00052cae, 0x000530ae, 0x000534ae, + 0x000538ae, 0x00053cae, 0x000540ae, 0x000544ae, + 0x000548ae, 0x00054cae, 0x000550ae, 0x000554ae, + 0x000558ae, 0x00055cae, 0x000560ae, 0x000564ae, + 0x000568ae, 0x00056cae, 0x000570ae, 0x000574ae, + 0x000578ae, 0x00057cae, 0x000580ae, 0x000584ae, + 0x000588ae, 0x00058cae, 0x000590ae, 0x000594ae, + 0x000598ae, 0x00059cae, 0x0005a0ae, 0x0005a4ae, + 0x0005a8ae, 0x0005acae, 0x0005b0ae, 0x0005b4ae, + 0x0005b8ae, 0x0005bcae, 0x0005c0ae, 0x0005c4ae, + 0x0005c8ae, 0x0005ccae, 0x0005d0ae, 0x0005d4ae, + 0x0005d8ae, 0x0005dcae, 0x0005e0ae, 0x0005e4ae, + 0x0005e8ae, 0x0005ecae, 0x0005f0ae, 0x0005f4ae, + 0x0005f8ae, 0x0005fcae, 0x000600ae, 0x000604ae, + 0x000608ae, 0x00060cae, 0x000610ae, 0x000614ae, + 0x000618ae, 0x00061cae, 0x000620ae, 0x000624ae, + 0x000628ae, 0x00062cae, 0x000630ae, 0x000634ae, + 0x000638ae, 0x00063cae, 0x000640ae, 0x000644ae, + 0x000648ae, 0x00064cae, 0x000650ae, 0x000654ae, + 0x000658ae, 0x00065cae, 0x000660ae, 0x000664ae, + 0x000668ae, 0x00066cae, 0x000670ae, 0x000674ae, + 0x000678ae, 0x00067cae, 0x000680ae, 0x000684ae, + 0x000688ae, 0x00068cae, 0x000690ae, 0x000694ae, + 0x000698ae, 0x00069cae, 0x0006a0ae, 0x0006a4ae, + 0x0006a8ae, 0x0006acae, 0x0006b0ae, 0x0006b4ae, + 0x0006b8ae, 0x0006bcae, 0x0006c0ae, 0x0006c4ae, + 0x0006c8ae, 0x0006ccae, 0x0006d0ae, 0x0006d4ae, + 0x0006d8ae, 0x0006dcae, 0x0006e0ae, 0x0006e4ae, + 0x0006e8ae, 0x0006ecae, 0x0006f0ae, 0x0006f4ae, + 0x0006f8ae, 0x0006fcae, 0x000700ae, 0x000704ae, + 0x000708ae, 0x00070cae, 0x000710ae, 0x000714ae, + 0x000718ae, 0x00071cae, 0x000720ae, 0x000724ae, + 0x000728ae, 0x00072cae, 0x000730ae, 0x000734ae, + 0x000738ae, 0x00073cae, 0x000740ae, 0x000744ae, + 0x000748ae, 0x00074cae, 0x000750ae, 0x000754ae, + 0x000758ae, 0x00075cae, 0x000760ae, 0x000764ae, + 0x000768ae, 0x00076cae, 0x000770ae, 0x000774ae, + 0x000778ae, 0x00077cae, 0x000780ae, 0x000784ae, + 0x000788ae, 0x00078cae, 0x000790ae, 0x000794ae, + 0x000798ae, 0x00079cae, 0x0007a0ae, 0x0007a4ae, + 0x0007a8ae, 0x0007acae, 0x0007b0ae, 0x0007b4ae, + 0x0007b8ae, 0x0007bcae, 0x0007c0ae, 0x0007c4ae, + 0x0007c8ae, 0x0007ccae, 0x0007d0ae, 0x0007d4ae, + 0x0007d8ae, 0x0007dcae, 0x0007e0ae, 0x0007e4ae, + 0x0007e8ae, 0x0007ecae, 0x0007f0ae, 0x0007f4ae, + 0x0007f8ae, 0x0007fcae, 0x000002ae, 0x000006ae, + 0x00000aae, 0x00000eae, 0x000012ae, 0x000016ae, + 0x00001aae, 0x00001eae, 0x000022ae, 0x000026ae, + 0x00002aae, 0x00002eae, 0x000032ae, 0x000036ae, + 0x00003aae, 0x00003eae, 0x000042ae, 0x000046ae, + 0x00004aae, 0x00004eae, 0x000052ae, 0x000056ae, + 0x00005aae, 0x00005eae, 0x000062ae, 0x000066ae, + 0x00006aae, 0x00006eae, 0x000072ae, 0x000076ae, + 0x00007aae, 0x00007eae, 0x000082ae, 0x000086ae, + 0x00008aae, 0x00008eae, 0x000092ae, 0x000096ae, + 0x00009aae, 0x00009eae, 0x0000a2ae, 0x0000a6ae, + 0x0000aaae, 0x0000aeae, 0x0000b2ae, 0x0000b6ae, + 0x0000baae, 0x0000beae, 0x0000c2ae, 0x0000c6ae, + 0x0000caae, 0x0000ceae, 0x0000d2ae, 0x0000d6ae, + 0x0000daae, 0x0000deae, 0x0000e2ae, 0x0000e6ae, + 0x0000eaae, 0x0000eeae, 0x0000f2ae, 0x0000f6ae, + 0x0000faae, 0x0000feae, 0x000102ae, 0x000106ae, + 0x00010aae, 0x00010eae, 0x000112ae, 0x000116ae, + 0x00011aae, 0x00011eae, 0x000122ae, 0x000126ae, + 0x00012aae, 0x00012eae, 0x000132ae, 0x000136ae, + 0x00013aae, 0x00013eae, 0x000142ae, 0x000146ae, + 0x00014aae, 0x00014eae, 0x000152ae, 0x000156ae, + 0x00015aae, 0x00015eae, 0x000162ae, 0x000166ae, + 0x00016aae, 0x00016eae, 0x000172ae, 0x000176ae, + 0x00017aae, 0x00017eae, 0x000182ae, 0x000186ae, + 0x00018aae, 0x00018eae, 0x000192ae, 0x000196ae, + 0x00019aae, 0x00019eae, 0x0001a2ae, 0x0001a6ae, + 0x0001aaae, 0x0001aeae, 0x0001b2ae, 0x0001b6ae, + 0x0001baae, 0x0001beae, 0x0001c2ae, 0x0001c6ae, + 0x0001caae, 0x0001ceae, 0x0001d2ae, 0x0001d6ae, + 0x0001daae, 0x0001deae, 0x0001e2ae, 0x0001e6ae, + 0x0001eaae, 0x0001eeae, 0x0001f2ae, 0x0001f6ae, + 0x0001faae, 0x0001feae, 0x000202ae, 0x000206ae, + 0x00020aae, 0x00020eae, 0x000212ae, 0x000216ae, + 0x00021aae, 0x00021eae, 0x000222ae, 0x000226ae, + 0x00022aae, 0x00022eae, 0x000232ae, 0x000236ae, + 0x00023aae, 0x00023eae, 0x000242ae, 0x000246ae, + 0x00024aae, 0x00024eae, 0x000252ae, 0x000256ae, + 0x00025aae, 0x00025eae, 0x000262ae, 0x000266ae, + 0x00026aae, 0x00026eae, 0x000272ae, 0x000276ae, + 0x00027aae, 0x00027eae, 0x000282ae, 0x000286ae, + 0x00028aae, 0x00028eae, 0x000292ae, 0x000296ae, + 0x00029aae, 0x00029eae, 0x0002a2ae, 0x0002a6ae, + 0x0002aaae, 0x0002aeae, 0x0002b2ae, 0x0002b6ae, + 0x0002baae, 0x0002beae, 0x0002c2ae, 0x0002c6ae, + 0x0002caae, 0x0002ceae, 0x0002d2ae, 0x0002d6ae, + 0x0002daae, 0x0002deae, 0x0002e2ae, 0x0002e6ae, + 0x0002eaae, 0x0002eeae, 0x0002f2ae, 0x0002f6ae, + 0x0002faae, 0x0002feae, 0x000302ae, 0x000306ae, + 0x00030aae, 0x00030eae, 0x000312ae, 0x000316ae, + 0x00031aae, 0x00031eae, 0x000322ae, 0x000326ae, + 0x00032aae, 0x00032eae, 0x000332ae, 0x000336ae, + 0x00033aae, 0x00033eae, 0x000342ae, 0x000346ae, + 0x00034aae, 0x00034eae, 0x000352ae, 0x000356ae, + 0x00035aae, 0x00035eae, 0x000362ae, 0x000366ae, + 0x00036aae, 0x00036eae, 0x000372ae, 0x000376ae, + 0x00037aae, 0x00037eae, 0x000382ae, 0x000386ae, + 0x00038aae, 0x00038eae, 0x000392ae, 0x000396ae, + 0x00039aae, 0x00039eae, 0x0003a2ae, 0x0003a6ae, + 0x0003aaae, 0x0003aeae, 0x0003b2ae, 0x0003b6ae, + 0x0003baae, 0x0003beae, 0x0003c2ae, 0x0003c6ae, + 0x0003caae, 0x0003ceae, 0x0003d2ae, 0x0003d6ae, + 0x0003daae, 0x0003deae, 0x0003e2ae, 0x0003e6ae, + 0x0003eaae, 0x0003eeae, 0x0003f2ae, 0x0003f6ae, + 0x0003faae, 0x0003feae, 0x000402ae, 0x000406ae, + 0x00040aae, 0x00040eae, 0x000412ae, 0x000416ae, + 0x00041aae, 0x00041eae, 0x000422ae, 0x000426ae, + 0x00042aae, 0x00042eae, 0x000432ae, 0x000436ae, + 0x00043aae, 0x00043eae, 0x000442ae, 0x000446ae, + 0x00044aae, 0x00044eae, 0x000452ae, 0x000456ae, + 0x00045aae, 0x00045eae, 0x000462ae, 0x000466ae, + 0x00046aae, 0x00046eae, 0x000472ae, 0x000476ae, + 0x00047aae, 0x00047eae, 0x000482ae, 0x000486ae, + 0x00048aae, 0x00048eae, 0x000492ae, 0x000496ae, + 0x00049aae, 0x00049eae, 0x0004a2ae, 0x0004a6ae, + 0x0004aaae, 0x0004aeae, 0x0004b2ae, 0x0004b6ae, + 0x0004baae, 0x0004beae, 0x0004c2ae, 0x0004c6ae, + 0x0004caae, 0x0004ceae, 0x0004d2ae, 0x0004d6ae, + 0x0004daae, 0x0004deae, 0x0004e2ae, 0x0004e6ae, + 0x0004eaae, 0x0004eeae, 0x0004f2ae, 0x0004f6ae, + 0x0004faae, 0x0004feae, 0x000502ae, 0x000506ae, + 0x00050aae, 0x00050eae, 0x000512ae, 0x000516ae, + 0x00051aae, 0x00051eae, 0x000522ae, 0x000526ae, + 0x00052aae, 0x00052eae, 0x000532ae, 0x000536ae, + 0x00053aae, 0x00053eae, 0x000542ae, 0x000546ae, + 0x00054aae, 0x00054eae, 0x000552ae, 0x000556ae, + 0x00055aae, 0x00055eae, 0x000562ae, 0x000566ae, + 0x00056aae, 0x00056eae, 0x000572ae, 0x000576ae, + 0x00057aae, 0x00057eae, 0x000582ae, 0x000586ae, + 0x00058aae, 0x00058eae, 0x000592ae, 0x000596ae, + 0x00059aae, 0x00059eae, 0x0005a2ae, 0x0005a6ae, + 0x0005aaae, 0x0005aeae, 0x0005b2ae, 0x0005b6ae, + 0x0005baae, 0x0005beae, 0x0005c2ae, 0x0005c6ae, + 0x0005caae, 0x0005ceae, 0x0005d2ae, 0x0005d6ae, + 0x0005daae, 0x0005deae, 0x0005e2ae, 0x0005e6ae, + 0x0005eaae, 0x0005eeae, 0x0005f2ae, 0x0005f6ae, + 0x0005faae, 0x0005feae, 0x000602ae, 0x000606ae, + 0x00060aae, 0x00060eae, 0x000612ae, 0x000616ae, + 0x00061aae, 0x00061eae, 0x000622ae, 0x000626ae, + 0x00062aae, 0x00062eae, 0x000632ae, 0x000636ae, + 0x00063aae, 0x00063eae, 0x000642ae, 0x000646ae, + 0x00064aae, 0x00064eae, 0x000652ae, 0x000656ae, + 0x00065aae, 0x00065eae, 0x000662ae, 0x000666ae, + 0x00066aae, 0x00066eae, 0x000672ae, 0x000676ae, + 0x00067aae, 0x00067eae, 0x000682ae, 0x000686ae, + 0x00068aae, 0x00068eae, 0x000692ae, 0x000696ae, + 0x00069aae, 0x00069eae, 0x0006a2ae, 0x0006a6ae, + 0x0006aaae, 0x0006aeae, 0x0006b2ae, 0x0006b6ae, + 0x0006baae, 0x0006beae, 0x0006c2ae, 0x0006c6ae, + 0x0006caae, 0x0006ceae, 0x0006d2ae, 0x0006d6ae, + 0x0006daae, 0x0006deae, 0x0006e2ae, 0x0006e6ae, + 0x0006eaae, 0x0006eeae, 0x0006f2ae, 0x0006f6ae, + 0x0006faae, 0x0006feae, 0x000702ae, 0x000706ae, + 0x00070aae, 0x00070eae, 0x000712ae, 0x000716ae, + 0x00071aae, 0x00071eae, 0x000722ae, 0x000726ae, + 0x00072aae, 0x00072eae, 0x000732ae, 0x000736ae, + 0x00073aae, 0x00073eae, 0x000742ae, 0x000746ae, + 0x00074aae, 0x00074eae, 0x000752ae, 0x000756ae, + 0x00075aae, 0x00075eae, 0x000762ae, 0x000766ae, + 0x00076aae, 0x00076eae, 0x000772ae, 0x000776ae, + 0x00077aae, 0x00077eae, 0x000782ae, 0x000786ae, + 0x00078aae, 0x00078eae, 0x000792ae, 0x000796ae, + 0x00079aae, 0x00079eae, 0x0007a2ae, 0x0007a6ae, + 0x0007aaae, 0x0007aeae, 0x0007b2ae, 0x0007b6ae, + 0x0007baae, 0x0007beae, 0x0007c2ae, 0x0007c6ae, + 0x0007caae, 0x0007ceae, 0x0007d2ae, 0x0007d6ae, + 0x0007daae, 0x0007deae, 0x0007e2ae, 0x0007e6ae, + 0x0007eaae, 0x0007eeae, 0x0007f2ae, 0x0007f6ae, + 0x0007faae, 0x0007feae, 0x000001af, 0x000005af, + 0x000009af, 0x00000daf, 0x000011af, 0x000015af, + 0x000019af, 0x00001daf, 0x000021af, 0x000025af, + 0x000029af, 0x00002daf, 0x000031af, 0x000035af, + 0x000039af, 0x00003daf, 0x000041af, 0x000045af, + 0x000049af, 0x00004daf, 0x000051af, 0x000055af, + 0x000059af, 0x00005daf, 0x000061af, 0x000065af, + 0x000069af, 0x00006daf, 0x000071af, 0x000075af, + 0x000079af, 0x00007daf, 0x000081af, 0x000085af, + 0x000089af, 0x00008daf, 0x000091af, 0x000095af, + 0x000099af, 0x00009daf, 0x0000a1af, 0x0000a5af, + 0x0000a9af, 0x0000adaf, 0x0000b1af, 0x0000b5af, + 0x0000b9af, 0x0000bdaf, 0x0000c1af, 0x0000c5af, + 0x0000c9af, 0x0000cdaf, 0x0000d1af, 0x0000d5af, + 0x0000d9af, 0x0000ddaf, 0x0000e1af, 0x0000e5af, + 0x0000e9af, 0x0000edaf, 0x0000f1af, 0x0000f5af, + 0x0000f9af, 0x0000fdaf, 0x000101af, 0x000105af, + 0x000109af, 0x00010daf, 0x000111af, 0x000115af, + 0x000119af, 0x00011daf, 0x000121af, 0x000125af, + 0x000129af, 0x00012daf, 0x000131af, 0x000135af, + 0x000139af, 0x00013daf, 0x000141af, 0x000145af, + 0x000149af, 0x00014daf, 0x000151af, 0x000155af, + 0x000159af, 0x00015daf, 0x000161af, 0x000165af, + 0x000169af, 0x00016daf, 0x000171af, 0x000175af, + 0x000179af, 0x00017daf, 0x000181af, 0x000185af, + 0x000189af, 0x00018daf, 0x000191af, 0x000195af, + 0x000199af, 0x00019daf, 0x0001a1af, 0x0001a5af, + 0x0001a9af, 0x0001adaf, 0x0001b1af, 0x0001b5af, + 0x0001b9af, 0x0001bdaf, 0x0001c1af, 0x0001c5af, + 0x0001c9af, 0x0001cdaf, 0x0001d1af, 0x0001d5af, + 0x0001d9af, 0x0001ddaf, 0x0001e1af, 0x0001e5af, + 0x0001e9af, 0x0001edaf, 0x0001f1af, 0x0001f5af, + 0x0001f9af, 0x0001fdaf, 0x000201af, 0x000205af, + 0x000209af, 0x00020daf, 0x000211af, 0x000215af, + 0x000219af, 0x00021daf, 0x000221af, 0x000225af, + 0x000229af, 0x00022daf, 0x000231af, 0x000235af, + 0x000239af, 0x00023daf, 0x000241af, 0x000245af, + 0x000249af, 0x00024daf, 0x000251af, 0x000255af, + 0x000259af, 0x00025daf, 0x000261af, 0x000265af, + 0x000269af, 0x00026daf, 0x000271af, 0x000275af, + 0x000279af, 0x00027daf, 0x000281af, 0x000285af, + 0x000289af, 0x00028daf, 0x000291af, 0x000295af, + 0x000299af, 0x00029daf, 0x0002a1af, 0x0002a5af, + 0x0002a9af, 0x0002adaf, 0x0002b1af, 0x0002b5af, + 0x0002b9af, 0x0002bdaf, 0x0002c1af, 0x0002c5af, + 0x0002c9af, 0x0002cdaf, 0x0002d1af, 0x0002d5af, + 0x0002d9af, 0x0002ddaf, 0x0002e1af, 0x0002e5af, + 0x0002e9af, 0x0002edaf, 0x0002f1af, 0x0002f5af, + 0x0002f9af, 0x0002fdaf, 0x000301af, 0x000305af, + 0x000309af, 0x00030daf, 0x000311af, 0x000315af, + 0x000319af, 0x00031daf, 0x000321af, 0x000325af, + 0x000329af, 0x00032daf, 0x000331af, 0x000335af, + 0x000339af, 0x00033daf, 0x000341af, 0x000345af, + 0x000349af, 0x00034daf, 0x000351af, 0x000355af, + 0x000359af, 0x00035daf, 0x000361af, 0x000365af, + 0x000369af, 0x00036daf, 0x000371af, 0x000375af, + 0x000379af, 0x00037daf, 0x000381af, 0x000385af, + 0x000389af, 0x00038daf, 0x000391af, 0x000395af, + 0x000399af, 0x00039daf, 0x0003a1af, 0x0003a5af, + 0x0003a9af, 0x0003adaf, 0x0003b1af, 0x0003b5af, + 0x0003b9af, 0x0003bdaf, 0x0003c1af, 0x0003c5af, + 0x0003c9af, 0x0003cdaf, 0x0003d1af, 0x0003d5af, + 0x0003d9af, 0x0003ddaf, 0x0003e1af, 0x0003e5af, + 0x0003e9af, 0x0003edaf, 0x0003f1af, 0x0003f5af, + 0x0003f9af, 0x0003fdaf, 0x000401af, 0x000405af, + 0x000409af, 0x00040daf, 0x000411af, 0x000415af, + 0x000419af, 0x00041daf, 0x000421af, 0x000425af, + 0x000429af, 0x00042daf, 0x000431af, 0x000435af, + 0x000439af, 0x00043daf, 0x000441af, 0x000445af, + 0x000449af, 0x00044daf, 0x000451af, 0x000455af, + 0x000459af, 0x00045daf, 0x000461af, 0x000465af, + 0x000469af, 0x00046daf, 0x000471af, 0x000475af, + 0x000479af, 0x00047daf, 0x000481af, 0x000485af, + 0x000489af, 0x00048daf, 0x000491af, 0x000495af, + 0x000499af, 0x00049daf, 0x0004a1af, 0x0004a5af, + 0x0004a9af, 0x0004adaf, 0x0004b1af, 0x0004b5af, + 0x0004b9af, 0x0004bdaf, 0x0004c1af, 0x0004c5af, + 0x0004c9af, 0x0004cdaf, 0x0004d1af, 0x0004d5af, + 0x0004d9af, 0x0004ddaf, 0x0004e1af, 0x0004e5af, + 0x0004e9af, 0x0004edaf, 0x0004f1af, 0x0004f5af, + 0x0004f9af, 0x0004fdaf, 0x000501af, 0x000505af, + 0x000509af, 0x00050daf, 0x000511af, 0x000515af, + 0x000519af, 0x00051daf, 0x000521af, 0x000525af, + 0x000529af, 0x00052daf, 0x000531af, 0x000535af, + 0x000539af, 0x00053daf, 0x000541af, 0x000545af, + 0x000549af, 0x00054daf, 0x000551af, 0x000555af, + 0x000559af, 0x00055daf, 0x000561af, 0x000565af, + 0x000569af, 0x00056daf, 0x000571af, 0x000575af, + 0x000579af, 0x00057daf, 0x000581af, 0x000585af, + 0x000589af, 0x00058daf, 0x000591af, 0x000595af, + 0x000599af, 0x00059daf, 0x0005a1af, 0x0005a5af, + 0x0005a9af, 0x0005adaf, 0x0005b1af, 0x0005b5af, + 0x0005b9af, 0x0005bdaf, 0x0005c1af, 0x0005c5af, + 0x0005c9af, 0x0005cdaf, 0x0005d1af, 0x0005d5af, + 0x0005d9af, 0x0005ddaf, 0x0005e1af, 0x0005e5af, + 0x0005e9af, 0x0005edaf, 0x0005f1af, 0x0005f5af, + 0x0005f9af, 0x0005fdaf, 0x000601af, 0x000605af, + 0x000609af, 0x00060daf, 0x000611af, 0x000615af, + 0x000619af, 0x00061daf, 0x000621af, 0x000625af, + 0x000629af, 0x00062daf, 0x000631af, 0x000635af, + 0x000639af, 0x00063daf, 0x000641af, 0x000645af, + 0x000649af, 0x00064daf, 0x000651af, 0x000655af, + 0x000659af, 0x00065daf, 0x000661af, 0x000665af, + 0x000669af, 0x00066daf, 0x000671af, 0x000675af, + 0x000679af, 0x00067daf, 0x000681af, 0x000685af, + 0x000689af, 0x00068daf, 0x000691af, 0x000695af, + 0x000699af, 0x00069daf, 0x0006a1af, 0x0006a5af, + 0x0006a9af, 0x0006adaf, 0x0006b1af, 0x0006b5af, + 0x0006b9af, 0x0006bdaf, 0x0006c1af, 0x0006c5af, + 0x0006c9af, 0x0006cdaf, 0x0006d1af, 0x0006d5af, + 0x0006d9af, 0x0006ddaf, 0x0006e1af, 0x0006e5af, + 0x0006e9af, 0x0006edaf, 0x0006f1af, 0x0006f5af, + 0x0006f9af, 0x0006fdaf, 0x000701af, 0x000705af, + 0x000709af, 0x00070daf, 0x000711af, 0x000715af, + 0x000719af, 0x00071daf, 0x000721af, 0x000725af, + 0x000729af, 0x00072daf, 0x000731af, 0x000735af, + 0x000739af, 0x00073daf, 0x000741af, 0x000745af, + 0x000749af, 0x00074daf, 0x000751af, 0x000755af, + 0x000759af, 0x00075daf, 0x000761af, 0x000765af, + 0x000769af, 0x00076daf, 0x000771af, 0x000775af, + 0x000779af, 0x00077daf, 0x000781af, 0x000785af, + 0x000789af, 0x00078daf, 0x000791af, 0x000795af, + 0x000799af, 0x00079daf, 0x0007a1af, 0x0007a5af, + 0x0007a9af, 0x0007adaf, 0x0007b1af, 0x0007b5af, + 0x0007b9af, 0x0007bdaf, 0x0007c1af, 0x0007c5af, + 0x0007c9af, 0x0007cdaf, 0x0007d1af, 0x0007d5af, + 0x0007d9af, 0x0007ddaf, 0x0007e1af, 0x0007e5af, + 0x0007e9af, 0x0007edaf, 0x0007f1af, 0x0007f5af, + 0x0007f9af, 0x0007fdaf, 0x000801af, 0x000805af, + 0x000809af, 0x00080daf, 0x000811af, 0x000815af, + 0x000819af, 0x00081daf, 0x000821af, 0x000825af, + 0x000829af, 0x00082daf, 0x000831af, 0x000835af, + 0x000839af, 0x00083daf, 0x000841af, 0x000845af, + 0x000849af, 0x00084daf, 0x000851af, 0x000855af, + 0x000859af, 0x00085daf, 0x000861af, 0x000865af, + 0x000869af, 0x00086daf, 0x000871af, 0x000875af, + 0x000879af, 0x00087daf, 0x000881af, 0x000885af, + 0x000889af, 0x00088daf, 0x000891af, 0x000895af, + 0x000899af, 0x00089daf, 0x0008a1af, 0x0008a5af, + 0x0008a9af, 0x0008adaf, 0x0008b1af, 0x0008b5af, + 0x0008b9af, 0x0008bdaf, 0x0008c1af, 0x0008c5af, + 0x0008c9af, 0x0008cdaf, 0x0008d1af, 0x0008d5af, + 0x0008d9af, 0x0008ddaf, 0x0008e1af, 0x0008e5af, + 0x0008e9af, 0x0008edaf, 0x0008f1af, 0x0008f5af, + 0x0008f9af, 0x0008fdaf, 0x000901af, 0x000905af, + 0x000909af, 0x00090daf, 0x000911af, 0x000915af, + 0x000919af, 0x00091daf, 0x000921af, 0x000925af, + 0x000929af, 0x00092daf, 0x000931af, 0x000935af, + 0x000939af, 0x00093daf, 0x000941af, 0x000945af, + 0x000949af, 0x00094daf, 0x000951af, 0x000955af, + 0x000959af, 0x00095daf, 0x000961af, 0x000965af, + 0x000969af, 0x00096daf, 0x000971af, 0x000975af, + 0x000979af, 0x00097daf, 0x000981af, 0x000985af, + 0x000989af, 0x00098daf, 0x000991af, 0x000995af, + 0x000999af, 0x00099daf, 0x0009a1af, 0x0009a5af, + 0x0009a9af, 0x0009adaf, 0x0009b1af, 0x0009b5af, + 0x0009b9af, 0x0009bdaf, 0x0009c1af, 0x0009c5af, + 0x0009c9af, 0x0009cdaf, 0x0009d1af, 0x0009d5af, + 0x0009d9af, 0x0009ddaf, 0x0009e1af, 0x0009e5af, + 0x0009e9af, 0x0009edaf, 0x0009f1af, 0x0009f5af, + 0x0009f9af, 0x0009fdaf, 0x000a01af, 0x000a05af, + 0x000a09af, 0x000a0daf, 0x000a11af, 0x000a15af, + 0x000a19af, 0x000a1daf, 0x000a21af, 0x000a25af, + 0x000a29af, 0x000a2daf, 0x000a31af, 0x000a35af, + 0x000a39af, 0x000a3daf, 0x000a41af, 0x000a45af, + 0x000a49af, 0x000a4daf, 0x000a51af, 0x000a55af, + 0x000a59af, 0x000a5daf, 0x000a61af, 0x000a65af, + 0x000a69af, 0x000a6daf, 0x000a71af, 0x000a75af, + 0x000a79af, 0x000a7daf, 0x000a81af, 0x000a85af, + 0x000a89af, 0x000a8daf, 0x000a91af, 0x000a95af, + 0x000a99af, 0x000a9daf, 0x000aa1af, 0x000aa5af, + 0x000aa9af, 0x000aadaf, 0x000ab1af, 0x000ab5af, + 0x000ab9af, 0x000abdaf, 0x000ac1af, 0x000ac5af, + 0x000ac9af, 0x000acdaf, 0x000ad1af, 0x000ad5af, + 0x000ad9af, 0x000addaf, 0x000ae1af, 0x000ae5af, + 0x000ae9af, 0x000aedaf, 0x000af1af, 0x000af5af, + 0x000af9af, 0x000afdaf, 0x000b01af, 0x000b05af, + 0x000b09af, 0x000b0daf, 0x000b11af, 0x000b15af, + 0x000b19af, 0x000b1daf, 0x000b21af, 0x000b25af, + 0x000b29af, 0x000b2daf, 0x000b31af, 0x000b35af, + 0x000b39af, 0x000b3daf, 0x000b41af, 0x000b45af, + 0x000b49af, 0x000b4daf, 0x000b51af, 0x000b55af, + 0x000b59af, 0x000b5daf, 0x000b61af, 0x000b65af, + 0x000b69af, 0x000b6daf, 0x000b71af, 0x000b75af, + 0x000b79af, 0x000b7daf, 0x000b81af, 0x000b85af, + 0x000b89af, 0x000b8daf, 0x000b91af, 0x000b95af, + 0x000b99af, 0x000b9daf, 0x000ba1af, 0x000ba5af, + 0x000ba9af, 0x000badaf, 0x000bb1af, 0x000bb5af, + 0x000bb9af, 0x000bbdaf, 0x000bc1af, 0x000bc5af, + 0x000bc9af, 0x000bcdaf, 0x000bd1af, 0x000bd5af, + 0x000bd9af, 0x000bddaf, 0x000be1af, 0x000be5af, + 0x000be9af, 0x000bedaf, 0x000bf1af, 0x000bf5af, + 0x000bf9af, 0x000bfdaf, 0x000c01af, 0x000c05af, + 0x000c09af, 0x000c0daf, 0x000c11af, 0x000c15af, + 0x000c19af, 0x000c1daf, 0x000c21af, 0x000c25af, + 0x000c29af, 0x000c2daf, 0x000c31af, 0x000c35af, + 0x000c39af, 0x000c3daf, 0x000c41af, 0x000c45af, + 0x000c49af, 0x000c4daf, 0x000c51af, 0x000c55af, + 0x000c59af, 0x000c5daf, 0x000c61af, 0x000c65af, + 0x000c69af, 0x000c6daf, 0x000c71af, 0x000c75af, + 0x000c79af, 0x000c7daf, 0x000c81af, 0x000c85af, + 0x000c89af, 0x000c8daf, 0x000c91af, 0x000c95af, + 0x000c99af, 0x000c9daf, 0x000ca1af, 0x000ca5af, + 0x000ca9af, 0x000cadaf, 0x000cb1af, 0x000cb5af, + 0x000cb9af, 0x000cbdaf, 0x000cc1af, 0x000cc5af, + 0x000cc9af, 0x000ccdaf, 0x000cd1af, 0x000cd5af, + 0x000cd9af, 0x000cddaf, 0x000ce1af, 0x000ce5af, + 0x000ce9af, 0x000cedaf, 0x000cf1af, 0x000cf5af, + 0x000cf9af, 0x000cfdaf, 0x000d01af, 0x000d05af, + 0x000d09af, 0x000d0daf, 0x000d11af, 0x000d15af, + 0x000d19af, 0x000d1daf, 0x000d21af, 0x000d25af, + 0x000d29af, 0x000d2daf, 0x000d31af, 0x000d35af, + 0x000d39af, 0x000d3daf, 0x000d41af, 0x000d45af, + 0x000d49af, 0x000d4daf, 0x000d51af, 0x000d55af, + 0x000d59af, 0x000d5daf, 0x000d61af, 0x000d65af, + 0x000d69af, 0x000d6daf, 0x000d71af, 0x000d75af, + 0x000d79af, 0x000d7daf, 0x000d81af, 0x000d85af, + 0x000d89af, 0x000d8daf, 0x000d91af, 0x000d95af, + 0x000d99af, 0x000d9daf, 0x000da1af, 0x000da5af, + 0x000da9af, 0x000dadaf, 0x000db1af, 0x000db5af, + 0x000db9af, 0x000dbdaf, 0x000dc1af, 0x000dc5af, + 0x000dc9af, 0x000dcdaf, 0x000dd1af, 0x000dd5af, + 0x000dd9af, 0x000dddaf, 0x000de1af, 0x000de5af, + 0x000de9af, 0x000dedaf, 0x000df1af, 0x000df5af, + 0x000df9af, 0x000dfdaf, 0x000e01af, 0x000e05af, + 0x000e09af, 0x000e0daf, 0x000e11af, 0x000e15af, + 0x000e19af, 0x000e1daf, 0x000e21af, 0x000e25af, + 0x000e29af, 0x000e2daf, 0x000e31af, 0x000e35af, + 0x000e39af, 0x000e3daf, 0x000e41af, 0x000e45af, + 0x000e49af, 0x000e4daf, 0x000e51af, 0x000e55af, + 0x000e59af, 0x000e5daf, 0x000e61af, 0x000e65af, + 0x000e69af, 0x000e6daf, 0x000e71af, 0x000e75af, + 0x000e79af, 0x000e7daf, 0x000e81af, 0x000e85af, + 0x000e89af, 0x000e8daf, 0x000e91af, 0x000e95af, + 0x000e99af, 0x000e9daf, 0x000ea1af, 0x000ea5af, + 0x000ea9af, 0x000eadaf, 0x000eb1af, 0x000eb5af, + 0x000eb9af, 0x000ebdaf, 0x000ec1af, 0x000ec5af, + 0x000ec9af, 0x000ecdaf, 0x000ed1af, 0x000ed5af, + 0x000ed9af, 0x000eddaf, 0x000ee1af, 0x000ee5af, + 0x000ee9af, 0x000eedaf, 0x000ef1af, 0x000ef5af, + 0x000ef9af, 0x000efdaf, 0x000f01af, 0x000f05af, + 0x000f09af, 0x000f0daf, 0x000f11af, 0x000f15af, + 0x000f19af, 0x000f1daf, 0x000f21af, 0x000f25af, + 0x000f29af, 0x000f2daf, 0x000f31af, 0x000f35af, + 0x000f39af, 0x000f3daf, 0x000f41af, 0x000f45af, + 0x000f49af, 0x000f4daf, 0x000f51af, 0x000f55af, + 0x000f59af, 0x000f5daf, 0x000f61af, 0x000f65af, + 0x000f69af, 0x000f6daf, 0x000f71af, 0x000f75af, + 0x000f79af, 0x000f7daf, 0x000f81af, 0x000f85af, + 0x000f89af, 0x000f8daf, 0x000f91af, 0x000f95af, + 0x000f99af, 0x000f9daf, 0x000fa1af, 0x000fa5af, + 0x000fa9af, 0x000fadaf, 0x000fb1af, 0x000fb5af, + 0x000fb9af, 0x000fbdaf, 0x000fc1af, 0x000fc5af, + 0x000fc9af, 0x000fcdaf, 0x000fd1af, 0x000fd5af, + 0x000fd9af, 0x000fddaf, 0x000fe1af, 0x000fe5af, + 0x000fe9af, 0x000fedaf, 0x000ff1af, 0x000ff5af, + 0x000ff9af, 0x000ffdaf, 0x000003af, 0x000007af, + 0x00000baf, 0x00000faf, 0x000013af, 0x000017af, + 0x00001baf, 0x00001faf, 0x000023af, 0x000027af, + 0x00002baf, 0x00002faf, 0x000033af, 0x000037af, + 0x00003baf, 0x00003faf, 0x000043af, 0x000047af, + 0x00004baf, 0x00004faf, 0x000053af, 0x000057af, + 0x00005baf, 0x00005faf, 0x000063af, 0x000067af, + 0x00006baf, 0x00006faf, 0x000073af, 0x000077af, + 0x00007baf, 0x00007faf, 0x000083af, 0x000087af, + 0x00008baf, 0x00008faf, 0x000093af, 0x000097af, + 0x00009baf, 0x00009faf, 0x0000a3af, 0x0000a7af, + 0x0000abaf, 0x0000afaf, 0x0000b3af, 0x0000b7af, + 0x0000bbaf, 0x0000bfaf, 0x0000c3af, 0x0000c7af, + 0x0000cbaf, 0x0000cfaf, 0x0000d3af, 0x0000d7af, + 0x0000dbaf, 0x0000dfaf, 0x0000e3af, 0x0000e7af, + 0x0000ebaf, 0x0000efaf, 0x0000f3af, 0x0000f7af, + 0x0000fbaf, 0x0000ffaf, 0x000103af, 0x000107af, + 0x00010baf, 0x00010faf, 0x000113af, 0x000117af, + 0x00011baf, 0x00011faf, 0x000123af, 0x000127af, + 0x00012baf, 0x00012faf, 0x000133af, 0x000137af, + 0x00013baf, 0x00013faf, 0x000143af, 0x000147af, + 0x00014baf, 0x00014faf, 0x000153af, 0x000157af, + 0x00015baf, 0x00015faf, 0x000163af, 0x000167af, + 0x00016baf, 0x00016faf, 0x000173af, 0x000177af, + 0x00017baf, 0x00017faf, 0x000183af, 0x000187af, + 0x00018baf, 0x00018faf, 0x000193af, 0x000197af, + 0x00019baf, 0x00019faf, 0x0001a3af, 0x0001a7af, + 0x0001abaf, 0x0001afaf, 0x0001b3af, 0x0001b7af, + 0x0001bbaf, 0x0001bfaf, 0x0001c3af, 0x0001c7af, + 0x0001cbaf, 0x0001cfaf, 0x0001d3af, 0x0001d7af, + 0x0001dbaf, 0x0001dfaf, 0x0001e3af, 0x0001e7af, + 0x0001ebaf, 0x0001efaf, 0x0001f3af, 0x0001f7af, + 0x0001fbaf, 0x0001ffaf, 0x000203af, 0x000207af, + 0x00020baf, 0x00020faf, 0x000213af, 0x000217af, + 0x00021baf, 0x00021faf, 0x000223af, 0x000227af, + 0x00022baf, 0x00022faf, 0x000233af, 0x000237af, + 0x00023baf, 0x00023faf, 0x000243af, 0x000247af, + 0x00024baf, 0x00024faf, 0x000253af, 0x000257af, + 0x00025baf, 0x00025faf, 0x000263af, 0x000267af, + 0x00026baf, 0x00026faf, 0x000273af, 0x000277af, + 0x00027baf, 0x00027faf, 0x000283af, 0x000287af, + 0x00028baf, 0x00028faf, 0x000293af, 0x000297af, + 0x00029baf, 0x00029faf, 0x0002a3af, 0x0002a7af, + 0x0002abaf, 0x0002afaf, 0x0002b3af, 0x0002b7af, + 0x0002bbaf, 0x0002bfaf, 0x0002c3af, 0x0002c7af, + 0x0002cbaf, 0x0002cfaf, 0x0002d3af, 0x0002d7af, + 0x0002dbaf, 0x0002dfaf, 0x0002e3af, 0x0002e7af, + 0x0002ebaf, 0x0002efaf, 0x0002f3af, 0x0002f7af, + 0x0002fbaf, 0x0002ffaf, 0x000303af, 0x000307af, + 0x00030baf, 0x00030faf, 0x000313af, 0x000317af, + 0x00031baf, 0x00031faf, 0x000323af, 0x000327af, + 0x00032baf, 0x00032faf, 0x000333af, 0x000337af, + 0x00033baf, 0x00033faf, 0x000343af, 0x000347af, + 0x00034baf, 0x00034faf, 0x000353af, 0x000357af, + 0x00035baf, 0x00035faf, 0x000363af, 0x000367af, + 0x00036baf, 0x00036faf, 0x000373af, 0x000377af, + 0x00037baf, 0x00037faf, 0x000383af, 0x000387af, + 0x00038baf, 0x00038faf, 0x000393af, 0x000397af, + 0x00039baf, 0x00039faf, 0x0003a3af, 0x0003a7af, + 0x0003abaf, 0x0003afaf, 0x0003b3af, 0x0003b7af, + 0x0003bbaf, 0x0003bfaf, 0x0003c3af, 0x0003c7af, + 0x0003cbaf, 0x0003cfaf, 0x0003d3af, 0x0003d7af, + 0x0003dbaf, 0x0003dfaf, 0x0003e3af, 0x0003e7af, + 0x0003ebaf, 0x0003efaf, 0x0003f3af, 0x0003f7af, + 0x0003fbaf, 0x0003ffaf, 0x000403af, 0x000407af, + 0x00040baf, 0x00040faf, 0x000413af, 0x000417af, + 0x00041baf, 0x00041faf, 0x000423af, 0x000427af, + 0x00042baf, 0x00042faf, 0x000433af, 0x000437af, + 0x00043baf, 0x00043faf, 0x000443af, 0x000447af, + 0x00044baf, 0x00044faf, 0x000453af, 0x000457af, + 0x00045baf, 0x00045faf, 0x000463af, 0x000467af, + 0x00046baf, 0x00046faf, 0x000473af, 0x000477af, + 0x00047baf, 0x00047faf, 0x000483af, 0x000487af, + 0x00048baf, 0x00048faf, 0x000493af, 0x000497af, + 0x00049baf, 0x00049faf, 0x0004a3af, 0x0004a7af, + 0x0004abaf, 0x0004afaf, 0x0004b3af, 0x0004b7af, + 0x0004bbaf, 0x0004bfaf, 0x0004c3af, 0x0004c7af, + 0x0004cbaf, 0x0004cfaf, 0x0004d3af, 0x0004d7af, + 0x0004dbaf, 0x0004dfaf, 0x0004e3af, 0x0004e7af, + 0x0004ebaf, 0x0004efaf, 0x0004f3af, 0x0004f7af, + 0x0004fbaf, 0x0004ffaf, 0x000503af, 0x000507af, + 0x00050baf, 0x00050faf, 0x000513af, 0x000517af, + 0x00051baf, 0x00051faf, 0x000523af, 0x000527af, + 0x00052baf, 0x00052faf, 0x000533af, 0x000537af, + 0x00053baf, 0x00053faf, 0x000543af, 0x000547af, + 0x00054baf, 0x00054faf, 0x000553af, 0x000557af, + 0x00055baf, 0x00055faf, 0x000563af, 0x000567af, + 0x00056baf, 0x00056faf, 0x000573af, 0x000577af, + 0x00057baf, 0x00057faf, 0x000583af, 0x000587af, + 0x00058baf, 0x00058faf, 0x000593af, 0x000597af, + 0x00059baf, 0x00059faf, 0x0005a3af, 0x0005a7af, + 0x0005abaf, 0x0005afaf, 0x0005b3af, 0x0005b7af, + 0x0005bbaf, 0x0005bfaf, 0x0005c3af, 0x0005c7af, + 0x0005cbaf, 0x0005cfaf, 0x0005d3af, 0x0005d7af, + 0x0005dbaf, 0x0005dfaf, 0x0005e3af, 0x0005e7af, + 0x0005ebaf, 0x0005efaf, 0x0005f3af, 0x0005f7af, + 0x0005fbaf, 0x0005ffaf, 0x000603af, 0x000607af, + 0x00060baf, 0x00060faf, 0x000613af, 0x000617af, + 0x00061baf, 0x00061faf, 0x000623af, 0x000627af, + 0x00062baf, 0x00062faf, 0x000633af, 0x000637af, + 0x00063baf, 0x00063faf, 0x000643af, 0x000647af, + 0x00064baf, 0x00064faf, 0x000653af, 0x000657af, + 0x00065baf, 0x00065faf, 0x000663af, 0x000667af, + 0x00066baf, 0x00066faf, 0x000673af, 0x000677af, + 0x00067baf, 0x00067faf, 0x000683af, 0x000687af, + 0x00068baf, 0x00068faf, 0x000693af, 0x000697af, + 0x00069baf, 0x00069faf, 0x0006a3af, 0x0006a7af, + 0x0006abaf, 0x0006afaf, 0x0006b3af, 0x0006b7af, + 0x0006bbaf, 0x0006bfaf, 0x0006c3af, 0x0006c7af, + 0x0006cbaf, 0x0006cfaf, 0x0006d3af, 0x0006d7af, + 0x0006dbaf, 0x0006dfaf, 0x0006e3af, 0x0006e7af, + 0x0006ebaf, 0x0006efaf, 0x0006f3af, 0x0006f7af, + 0x0006fbaf, 0x0006ffaf, 0x000703af, 0x000707af, + 0x00070baf, 0x00070faf, 0x000713af, 0x000717af, + 0x00071baf, 0x00071faf, 0x000723af, 0x000727af, + 0x00072baf, 0x00072faf, 0x000733af, 0x000737af, + 0x00073baf, 0x00073faf, 0x000743af, 0x000747af, + 0x00074baf, 0x00074faf, 0x000753af, 0x000757af, + 0x00075baf, 0x00075faf, 0x000763af, 0x000767af, + 0x00076baf, 0x00076faf, 0x000773af, 0x000777af, + 0x00077baf, 0x00077faf, 0x000783af, 0x000787af, + 0x00078baf, 0x00078faf, 0x000793af, 0x000797af, + 0x00079baf, 0x00079faf, 0x0007a3af, 0x0007a7af, + 0x0007abaf, 0x0007afaf, 0x0007b3af, 0x0007b7af, + 0x0007bbaf, 0x0007bfaf, 0x0007c3af, 0x0007c7af, + 0x0007cbaf, 0x0007cfaf, 0x0007d3af, 0x0007d7af, + 0x0007dbaf, 0x0007dfaf, 0x0007e3af, 0x0007e7af, + 0x0007ebaf, 0x0007efaf, 0x0007f3af, 0x0007f7af, + 0x0007fbaf, 0x0007ffaf, 0x000803af, 0x000807af, + 0x00080baf, 0x00080faf, 0x000813af, 0x000817af, + 0x00081baf, 0x00081faf, 0x000823af, 0x000827af, + 0x00082baf, 0x00082faf, 0x000833af, 0x000837af, + 0x00083baf, 0x00083faf, 0x000843af, 0x000847af, + 0x00084baf, 0x00084faf, 0x000853af, 0x000857af, + 0x00085baf, 0x00085faf, 0x000863af, 0x000867af, + 0x00086baf, 0x00086faf, 0x000873af, 0x000877af, + 0x00087baf, 0x00087faf, 0x000883af, 0x000887af, + 0x00088baf, 0x00088faf, 0x000893af, 0x000897af, + 0x00089baf, 0x00089faf, 0x0008a3af, 0x0008a7af, + 0x0008abaf, 0x0008afaf, 0x0008b3af, 0x0008b7af, + 0x0008bbaf, 0x0008bfaf, 0x0008c3af, 0x0008c7af, + 0x0008cbaf, 0x0008cfaf, 0x0008d3af, 0x0008d7af, + 0x0008dbaf, 0x0008dfaf, 0x0008e3af, 0x0008e7af, + 0x0008ebaf, 0x0008efaf, 0x0008f3af, 0x0008f7af, + 0x0008fbaf, 0x0008ffaf, 0x000903af, 0x000907af, + 0x00090baf, 0x00090faf, 0x000913af, 0x000917af, + 0x00091baf, 0x00091faf, 0x000923af, 0x000927af, + 0x00092baf, 0x00092faf, 0x000933af, 0x000937af, + 0x00093baf, 0x00093faf, 0x000943af, 0x000947af, + 0x00094baf, 0x00094faf, 0x000953af, 0x000957af, + 0x00095baf, 0x00095faf, 0x000963af, 0x000967af, + 0x00096baf, 0x00096faf, 0x000973af, 0x000977af, + 0x00097baf, 0x00097faf, 0x000983af, 0x000987af, + 0x00098baf, 0x00098faf, 0x000993af, 0x000997af, + 0x00099baf, 0x00099faf, 0x0009a3af, 0x0009a7af, + 0x0009abaf, 0x0009afaf, 0x0009b3af, 0x0009b7af, + 0x0009bbaf, 0x0009bfaf, 0x0009c3af, 0x0009c7af, + 0x0009cbaf, 0x0009cfaf, 0x0009d3af, 0x0009d7af, + 0x0009dbaf, 0x0009dfaf, 0x0009e3af, 0x0009e7af, + 0x0009ebaf, 0x0009efaf, 0x0009f3af, 0x0009f7af, + 0x0009fbaf, 0x0009ffaf, 0x000a03af, 0x000a07af, + 0x000a0baf, 0x000a0faf, 0x000a13af, 0x000a17af, + 0x000a1baf, 0x000a1faf, 0x000a23af, 0x000a27af, + 0x000a2baf, 0x000a2faf, 0x000a33af, 0x000a37af, + 0x000a3baf, 0x000a3faf, 0x000a43af, 0x000a47af, + 0x000a4baf, 0x000a4faf, 0x000a53af, 0x000a57af, + 0x000a5baf, 0x000a5faf, 0x000a63af, 0x000a67af, + 0x000a6baf, 0x000a6faf, 0x000a73af, 0x000a77af, + 0x000a7baf, 0x000a7faf, 0x000a83af, 0x000a87af, + 0x000a8baf, 0x000a8faf, 0x000a93af, 0x000a97af, + 0x000a9baf, 0x000a9faf, 0x000aa3af, 0x000aa7af, + 0x000aabaf, 0x000aafaf, 0x000ab3af, 0x000ab7af, + 0x000abbaf, 0x000abfaf, 0x000ac3af, 0x000ac7af, + 0x000acbaf, 0x000acfaf, 0x000ad3af, 0x000ad7af, + 0x000adbaf, 0x000adfaf, 0x000ae3af, 0x000ae7af, + 0x000aebaf, 0x000aefaf, 0x000af3af, 0x000af7af, + 0x000afbaf, 0x000affaf, 0x000b03af, 0x000b07af, + 0x000b0baf, 0x000b0faf, 0x000b13af, 0x000b17af, + 0x000b1baf, 0x000b1faf, 0x000b23af, 0x000b27af, + 0x000b2baf, 0x000b2faf, 0x000b33af, 0x000b37af, + 0x000b3baf, 0x000b3faf, 0x000b43af, 0x000b47af, + 0x000b4baf, 0x000b4faf, 0x000b53af, 0x000b57af, + 0x000b5baf, 0x000b5faf, 0x000b63af, 0x000b67af, + 0x000b6baf, 0x000b6faf, 0x000b73af, 0x000b77af, + 0x000b7baf, 0x000b7faf, 0x000b83af, 0x000b87af, + 0x000b8baf, 0x000b8faf, 0x000b93af, 0x000b97af, + 0x000b9baf, 0x000b9faf, 0x000ba3af, 0x000ba7af, + 0x000babaf, 0x000bafaf, 0x000bb3af, 0x000bb7af, + 0x000bbbaf, 0x000bbfaf, 0x000bc3af, 0x000bc7af, + 0x000bcbaf, 0x000bcfaf, 0x000bd3af, 0x000bd7af, + 0x000bdbaf, 0x000bdfaf, 0x000be3af, 0x000be7af, + 0x000bebaf, 0x000befaf, 0x000bf3af, 0x000bf7af, + 0x000bfbaf, 0x000bffaf, 0x000c03af, 0x000c07af, + 0x000c0baf, 0x000c0faf, 0x000c13af, 0x000c17af, + 0x000c1baf, 0x000c1faf, 0x000c23af, 0x000c27af, + 0x000c2baf, 0x000c2faf, 0x000c33af, 0x000c37af, + 0x000c3baf, 0x000c3faf, 0x000c43af, 0x000c47af, + 0x000c4baf, 0x000c4faf, 0x000c53af, 0x000c57af, + 0x000c5baf, 0x000c5faf, 0x000c63af, 0x000c67af, + 0x000c6baf, 0x000c6faf, 0x000c73af, 0x000c77af, + 0x000c7baf, 0x000c7faf, 0x000c83af, 0x000c87af, + 0x000c8baf, 0x000c8faf, 0x000c93af, 0x000c97af, + 0x000c9baf, 0x000c9faf, 0x000ca3af, 0x000ca7af, + 0x000cabaf, 0x000cafaf, 0x000cb3af, 0x000cb7af, + 0x000cbbaf, 0x000cbfaf, 0x000cc3af, 0x000cc7af, + 0x000ccbaf, 0x000ccfaf, 0x000cd3af, 0x000cd7af, + 0x000cdbaf, 0x000cdfaf, 0x000ce3af, 0x000ce7af, + 0x000cebaf, 0x000cefaf, 0x000cf3af, 0x000cf7af, + 0x000cfbaf, 0x000cffaf, 0x000d03af, 0x000d07af, + 0x000d0baf, 0x000d0faf, 0x000d13af, 0x000d17af, + 0x000d1baf, 0x000d1faf, 0x000d23af, 0x000d27af, + 0x000d2baf, 0x000d2faf, 0x000d33af, 0x000d37af, + 0x000d3baf, 0x000d3faf, 0x000d43af, 0x000d47af, + 0x000d4baf, 0x000d4faf, 0x000d53af, 0x000d57af, + 0x000d5baf, 0x000d5faf, 0x000d63af, 0x000d67af, + 0x000d6baf, 0x000d6faf, 0x000d73af, 0x000d77af, + 0x000d7baf, 0x000d7faf, 0x000d83af, 0x000d87af, + 0x000d8baf, 0x000d8faf, 0x000d93af, 0x000d97af, + 0x000d9baf, 0x000d9faf, 0x000da3af, 0x000da7af, + 0x000dabaf, 0x000dafaf, 0x000db3af, 0x000db7af, + 0x000dbbaf, 0x000dbfaf, 0x000dc3af, 0x000dc7af, + 0x000dcbaf, 0x000dcfaf, 0x000dd3af, 0x000dd7af, + 0x000ddbaf, 0x000ddfaf, 0x000de3af, 0x000de7af, + 0x000debaf, 0x000defaf, 0x000df3af, 0x000df7af, + 0x000dfbaf, 0x000dffaf, 0x000e03af, 0x000e07af, + 0x000e0baf, 0x000e0faf, 0x000e13af, 0x000e17af, + 0x000e1baf, 0x000e1faf, 0x000e23af, 0x000e27af, + 0x000e2baf, 0x000e2faf, 0x000e33af, 0x000e37af, + 0x000e3baf, 0x000e3faf, 0x000e43af, 0x000e47af, + 0x000e4baf, 0x000e4faf, 0x000e53af, 0x000e57af, + 0x000e5baf, 0x000e5faf, 0x000e63af, 0x000e67af, + 0x000e6baf, 0x000e6faf, 0x000e73af, 0x000e77af, + 0x000e7baf, 0x000e7faf, 0x000e83af, 0x000e87af, + 0x000e8baf, 0x000e8faf, 0x000e93af, 0x000e97af, + 0x000e9baf, 0x000e9faf, 0x000ea3af, 0x000ea7af, + 0x000eabaf, 0x000eafaf, 0x000eb3af, 0x000eb7af, + 0x000ebbaf, 0x000ebfaf, 0x000ec3af, 0x000ec7af, + 0x000ecbaf, 0x000ecfaf, 0x000ed3af, 0x000ed7af, + 0x000edbaf, 0x000edfaf, 0x000ee3af, 0x000ee7af, + 0x000eebaf, 0x000eefaf, 0x000ef3af, 0x000ef7af, + 0x000efbaf, 0x000effaf, 0x000f03af, 0x000f07af, + 0x000f0baf, 0x000f0faf, 0x000f13af, 0x000f17af, + 0x000f1baf, 0x000f1faf, 0x000f23af, 0x000f27af, + 0x000f2baf, 0x000f2faf, 0x000f33af, 0x000f37af, + 0x000f3baf, 0x000f3faf, 0x000f43af, 0x000f47af, + 0x000f4baf, 0x000f4faf, 0x000f53af, 0x000f57af, + 0x000f5baf, 0x000f5faf, 0x000f63af, 0x000f67af, + 0x000f6baf, 0x000f6faf, 0x000f73af, 0x000f77af, + 0x000f7baf, 0x000f7faf, 0x000f83af, 0x000f87af, + 0x000f8baf, 0x000f8faf, 0x000f93af, 0x000f97af, + 0x000f9baf, 0x000f9faf, 0x000fa3af, 0x000fa7af, + 0x000fabaf, 0x000fafaf, 0x000fb3af, 0x000fb7af, + 0x000fbbaf, 0x000fbfaf, 0x000fc3af, 0x000fc7af, + 0x000fcbaf, 0x000fcfaf, 0x000fd3af, 0x000fd7af, + 0x000fdbaf, 0x000fdfaf, 0x000fe3af, 0x000fe7af, + 0x000febaf, 0x000fefaf, 0x000ff3af, 0x000ff7af, + 0x000ffbaf, 0x000fffaf, 0x00000070, 0x00000470, + 0x00000870, 0x00000c70, 0x00001070, 0x00001470, + 0x00001870, 0x00001c70, 0x00002070, 0x00002470, + 0x00002870, 0x00002c70, 0x00003070, 0x00003470, + 0x00003870, 0x00003c70, 0x00004070, 0x00004470, + 0x00004870, 0x00004c70, 0x00005070, 0x00005470, + 0x00005870, 0x00005c70, 0x00006070, 0x00006470, + 0x00006870, 0x00006c70, 0x00007070, 0x00007470, + 0x00007870, 0x00007c70, 0x00008070, 0x00008470, + 0x00008870, 0x00008c70, 0x00009070, 0x00009470, + 0x00009870, 0x00009c70, 0x0000a070, 0x0000a470, + 0x0000a870, 0x0000ac70, 0x0000b070, 0x0000b470, + 0x0000b870, 0x0000bc70, 0x0000c070, 0x0000c470, + 0x0000c870, 0x0000cc70, 0x0000d070, 0x0000d470, + 0x0000d870, 0x0000dc70, 0x0000e070, 0x0000e470, + 0x0000e870, 0x0000ec70, 0x0000f070, 0x0000f470, + 0x0000f870, 0x0000fc70, 0x00010070, 0x00010470, + 0x00010870, 0x00010c70, 0x00011070, 0x00011470, + 0x00011870, 0x00011c70, 0x00012070, 0x00012470, + 0x00012870, 0x00012c70, 0x00013070, 0x00013470, + 0x00013870, 0x00013c70, 0x00014070, 0x00014470, + 0x00014870, 0x00014c70, 0x00015070, 0x00015470, + 0x00015870, 0x00015c70, 0x00016070, 0x00016470, + 0x00016870, 0x00016c70, 0x00017070, 0x00017470, + 0x00017870, 0x00017c70, 0x00018070, 0x00018470, + 0x00018870, 0x00018c70, 0x00019070, 0x00019470, + 0x00019870, 0x00019c70, 0x0001a070, 0x0001a470, + 0x0001a870, 0x0001ac70, 0x0001b070, 0x0001b470, + 0x0001b870, 0x0001bc70, 0x0001c070, 0x0001c470, + 0x0001c870, 0x0001cc70, 0x0001d070, 0x0001d470, + 0x0001d870, 0x0001dc70, 0x0001e070, 0x0001e470, + 0x0001e870, 0x0001ec70, 0x0001f070, 0x0001f470, + 0x0001f870, 0x0001fc70, 0x00020070, 0x00020470, + 0x00020870, 0x00020c70, 0x00021070, 0x00021470, + 0x00021870, 0x00021c70, 0x00022070, 0x00022470, + 0x00022870, 0x00022c70, 0x00023070, 0x00023470, + 0x00023870, 0x00023c70, 0x00024070, 0x00024470, + 0x00024870, 0x00024c70, 0x00025070, 0x00025470, + 0x00025870, 0x00025c70, 0x00026070, 0x00026470, + 0x00026870, 0x00026c70, 0x00027070, 0x00027470, + 0x00027870, 0x00027c70, 0x00028070, 0x00028470, + 0x00028870, 0x00028c70, 0x00029070, 0x00029470, + 0x00029870, 0x00029c70, 0x0002a070, 0x0002a470, + 0x0002a870, 0x0002ac70, 0x0002b070, 0x0002b470, + 0x0002b870, 0x0002bc70, 0x0002c070, 0x0002c470, + 0x0002c870, 0x0002cc70, 0x0002d070, 0x0002d470, + 0x0002d870, 0x0002dc70, 0x0002e070, 0x0002e470, + 0x0002e870, 0x0002ec70, 0x0002f070, 0x0002f470, + 0x0002f870, 0x0002fc70, 0x00030070, 0x00030470, + 0x00030870, 0x00030c70, 0x00031070, 0x00031470, + 0x00031870, 0x00031c70, 0x00032070, 0x00032470, + 0x00032870, 0x00032c70, 0x00033070, 0x00033470, + 0x00033870, 0x00033c70, 0x00034070, 0x00034470, + 0x00034870, 0x00034c70, 0x00035070, 0x00035470, + 0x00035870, 0x00035c70, 0x00036070, 0x00036470, + 0x00036870, 0x00036c70, 0x00037070, 0x00037470, + 0x00037870, 0x00037c70, 0x00038070, 0x00038470, + 0x00038870, 0x00038c70, 0x00039070, 0x00039470, + 0x00039870, 0x00039c70, 0x0003a070, 0x0003a470, + 0x0003a870, 0x0003ac70, 0x0003b070, 0x0003b470, + 0x0003b870, 0x0003bc70, 0x0003c070, 0x0003c470, + 0x0003c870, 0x0003cc70, 0x0003d070, 0x0003d470, + 0x0003d870, 0x0003dc70, 0x0003e070, 0x0003e470, + 0x0003e870, 0x0003ec70, 0x0003f070, 0x0003f470, + 0x0003f870, 0x0003fc70, 0x00040070, 0x00040470, + 0x00040870, 0x00040c70, 0x00041070, 0x00041470, + 0x00041870, 0x00041c70, 0x00042070, 0x00042470, + 0x00042870, 0x00042c70, 0x00043070, 0x00043470, + 0x00043870, 0x00043c70, 0x00044070, 0x00044470, + 0x00044870, 0x00044c70, 0x00045070, 0x00045470, + 0x00045870, 0x00045c70, 0x00046070, 0x00046470, + 0x00046870, 0x00046c70, 0x00047070, 0x00047470, + 0x00047870, 0x00047c70, 0x00048070, 0x00048470, + 0x00048870, 0x00048c70, 0x00049070, 0x00049470, + 0x00049870, 0x00049c70, 0x0004a070, 0x0004a470, + 0x0004a870, 0x0004ac70, 0x0004b070, 0x0004b470, + 0x0004b870, 0x0004bc70, 0x0004c070, 0x0004c470, + 0x0004c870, 0x0004cc70, 0x0004d070, 0x0004d470, + 0x0004d870, 0x0004dc70, 0x0004e070, 0x0004e470, + 0x0004e870, 0x0004ec70, 0x0004f070, 0x0004f470, + 0x0004f870, 0x0004fc70, 0x00050070, 0x00050470, + 0x00050870, 0x00050c70, 0x00051070, 0x00051470, + 0x00051870, 0x00051c70, 0x00052070, 0x00052470, + 0x00052870, 0x00052c70, 0x00053070, 0x00053470, + 0x00053870, 0x00053c70, 0x00054070, 0x00054470, + 0x00054870, 0x00054c70, 0x00055070, 0x00055470, + 0x00055870, 0x00055c70, 0x00056070, 0x00056470, + 0x00056870, 0x00056c70, 0x00057070, 0x00057470, + 0x00057870, 0x00057c70, 0x00058070, 0x00058470, + 0x00058870, 0x00058c70, 0x00059070, 0x00059470, + 0x00059870, 0x00059c70, 0x0005a070, 0x0005a470, + 0x0005a870, 0x0005ac70, 0x0005b070, 0x0005b470, + 0x0005b870, 0x0005bc70, 0x0005c070, 0x0005c470, + 0x0005c870, 0x0005cc70, 0x0005d070, 0x0005d470, + 0x0005d870, 0x0005dc70, 0x0005e070, 0x0005e470, + 0x0005e870, 0x0005ec70, 0x0005f070, 0x0005f470, + 0x0005f870, 0x0005fc70, 0x00060070, 0x00060470, + 0x00060870, 0x00060c70, 0x00061070, 0x00061470, + 0x00061870, 0x00061c70, 0x00062070, 0x00062470, + 0x00062870, 0x00062c70, 0x00063070, 0x00063470, + 0x00063870, 0x00063c70, 0x00064070, 0x00064470, + 0x00064870, 0x00064c70, 0x00065070, 0x00065470, + 0x00065870, 0x00065c70, 0x00066070, 0x00066470, + 0x00066870, 0x00066c70, 0x00067070, 0x00067470, + 0x00067870, 0x00067c70, 0x00068070, 0x00068470, + 0x00068870, 0x00068c70, 0x00069070, 0x00069470, + 0x00069870, 0x00069c70, 0x0006a070, 0x0006a470, + 0x0006a870, 0x0006ac70, 0x0006b070, 0x0006b470, + 0x0006b870, 0x0006bc70, 0x0006c070, 0x0006c470, + 0x0006c870, 0x0006cc70, 0x0006d070, 0x0006d470, + 0x0006d870, 0x0006dc70, 0x0006e070, 0x0006e470, + 0x0006e870, 0x0006ec70, 0x0006f070, 0x0006f470, + 0x0006f870, 0x0006fc70, 0x00070070, 0x00070470, + 0x00070870, 0x00070c70, 0x00071070, 0x00071470, + 0x00071870, 0x00071c70, 0x00072070, 0x00072470, + 0x00072870, 0x00072c70, 0x00073070, 0x00073470, + 0x00073870, 0x00073c70, 0x00074070, 0x00074470, + 0x00074870, 0x00074c70, 0x00075070, 0x00075470, + 0x00075870, 0x00075c70, 0x00076070, 0x00076470, + 0x00076870, 0x00076c70, 0x00077070, 0x00077470, + 0x00077870, 0x00077c70, 0x00078070, 0x00078470, + 0x00078870, 0x00078c70, 0x00079070, 0x00079470, + 0x00079870, 0x00079c70, 0x0007a070, 0x0007a470, + 0x0007a870, 0x0007ac70, 0x0007b070, 0x0007b470, + 0x0007b870, 0x0007bc70, 0x0007c070, 0x0007c470, + 0x0007c870, 0x0007cc70, 0x0007d070, 0x0007d470, + 0x0007d870, 0x0007dc70, 0x0007e070, 0x0007e470, + 0x0007e870, 0x0007ec70, 0x0007f070, 0x0007f470, + 0x0007f870, 0x0007fc70, 0x00080070, 0x00080470, + 0x00080870, 0x00080c70, 0x00081070, 0x00081470, + 0x00081870, 0x00081c70, 0x00082070, 0x00082470, + 0x00082870, 0x00082c70, 0x00083070, 0x00083470, + 0x00083870, 0x00083c70, 0x00084070, 0x00084470, + 0x00084870, 0x00084c70, 0x00085070, 0x00085470, + 0x00085870, 0x00085c70, 0x00086070, 0x00086470, + 0x00086870, 0x00086c70, 0x00087070, 0x00087470, + 0x00087870, 0x00087c70, 0x00088070, 0x00088470, + 0x00088870, 0x00088c70, 0x00089070, 0x00089470, + 0x00089870, 0x00089c70, 0x0008a070, 0x0008a470, + 0x0008a870, 0x0008ac70, 0x0008b070, 0x0008b470, + 0x0008b870, 0x0008bc70, 0x0008c070, 0x0008c470, + 0x0008c870, 0x0008cc70, 0x0008d070, 0x0008d470, + 0x0008d870, 0x0008dc70, 0x0008e070, 0x0008e470, + 0x0008e870, 0x0008ec70, 0x0008f070, 0x0008f470, + 0x0008f870, 0x0008fc70, 0x00090070, 0x00090470, + 0x00090870, 0x00090c70, 0x00091070, 0x00091470, + 0x00091870, 0x00091c70, 0x00092070, 0x00092470, + 0x00092870, 0x00092c70, 0x00093070, 0x00093470, + 0x00093870, 0x00093c70, 0x00094070, 0x00094470, + 0x00094870, 0x00094c70, 0x00095070, 0x00095470, + 0x00095870, 0x00095c70, 0x00096070, 0x00096470, + 0x00096870, 0x00096c70, 0x00097070, 0x00097470, + 0x00097870, 0x00097c70, 0x00098070, 0x00098470, + 0x00098870, 0x00098c70, 0x00099070, 0x00099470, + 0x00099870, 0x00099c70, 0x0009a070, 0x0009a470, + 0x0009a870, 0x0009ac70, 0x0009b070, 0x0009b470, + 0x0009b870, 0x0009bc70, 0x0009c070, 0x0009c470, + 0x0009c870, 0x0009cc70, 0x0009d070, 0x0009d470, + 0x0009d870, 0x0009dc70, 0x0009e070, 0x0009e470, + 0x0009e870, 0x0009ec70, 0x0009f070, 0x0009f470, + 0x0009f870, 0x0009fc70, 0x000a0070, 0x000a0470, + 0x000a0870, 0x000a0c70, 0x000a1070, 0x000a1470, + 0x000a1870, 0x000a1c70, 0x000a2070, 0x000a2470, + 0x000a2870, 0x000a2c70, 0x000a3070, 0x000a3470, + 0x000a3870, 0x000a3c70, 0x000a4070, 0x000a4470, + 0x000a4870, 0x000a4c70, 0x000a5070, 0x000a5470, + 0x000a5870, 0x000a5c70, 0x000a6070, 0x000a6470, + 0x000a6870, 0x000a6c70, 0x000a7070, 0x000a7470, + 0x000a7870, 0x000a7c70, 0x000a8070, 0x000a8470, + 0x000a8870, 0x000a8c70, 0x000a9070, 0x000a9470, + 0x000a9870, 0x000a9c70, 0x000aa070, 0x000aa470, + 0x000aa870, 0x000aac70, 0x000ab070, 0x000ab470, + 0x000ab870, 0x000abc70, 0x000ac070, 0x000ac470, + 0x000ac870, 0x000acc70, 0x000ad070, 0x000ad470, + 0x000ad870, 0x000adc70, 0x000ae070, 0x000ae470, + 0x000ae870, 0x000aec70, 0x000af070, 0x000af470, + 0x000af870, 0x000afc70, 0x000b0070, 0x000b0470, + 0x000b0870, 0x000b0c70, 0x000b1070, 0x000b1470, + 0x000b1870, 0x000b1c70, 0x000b2070, 0x000b2470, + 0x000b2870, 0x000b2c70, 0x000b3070, 0x000b3470, + 0x000b3870, 0x000b3c70, 0x000b4070, 0x000b4470, + 0x000b4870, 0x000b4c70, 0x000b5070, 0x000b5470, + 0x000b5870, 0x000b5c70, 0x000b6070, 0x000b6470, + 0x000b6870, 0x000b6c70, 0x000b7070, 0x000b7470, + 0x000b7870, 0x000b7c70, 0x000b8070, 0x000b8470, + 0x000b8870, 0x000b8c70, 0x000b9070, 0x000b9470, + 0x000b9870, 0x000b9c70, 0x000ba070, 0x000ba470, + 0x000ba870, 0x000bac70, 0x000bb070, 0x000bb470, + 0x000bb870, 0x000bbc70, 0x000bc070, 0x000bc470, + 0x000bc870, 0x000bcc70, 0x000bd070, 0x000bd470, + 0x000bd870, 0x000bdc70, 0x000be070, 0x000be470, + 0x000be870, 0x000bec70, 0x000bf070, 0x000bf470, + 0x000bf870, 0x000bfc70, 0x000c0070, 0x000c0470, + 0x000c0870, 0x000c0c70, 0x000c1070, 0x000c1470, + 0x000c1870, 0x000c1c70, 0x000c2070, 0x000c2470, + 0x000c2870, 0x000c2c70, 0x000c3070, 0x000c3470, + 0x000c3870, 0x000c3c70, 0x000c4070, 0x000c4470, + 0x000c4870, 0x000c4c70, 0x000c5070, 0x000c5470, + 0x000c5870, 0x000c5c70, 0x000c6070, 0x000c6470, + 0x000c6870, 0x000c6c70, 0x000c7070, 0x000c7470, + 0x000c7870, 0x000c7c70, 0x000c8070, 0x000c8470, + 0x000c8870, 0x000c8c70, 0x000c9070, 0x000c9470, + 0x000c9870, 0x000c9c70, 0x000ca070, 0x000ca470, + 0x000ca870, 0x000cac70, 0x000cb070, 0x000cb470, + 0x000cb870, 0x000cbc70, 0x000cc070, 0x000cc470, + 0x000cc870, 0x000ccc70, 0x000cd070, 0x000cd470, + 0x000cd870, 0x000cdc70, 0x000ce070, 0x000ce470, + 0x000ce870, 0x000cec70, 0x000cf070, 0x000cf470, + 0x000cf870, 0x000cfc70, 0x000d0070, 0x000d0470, + 0x000d0870, 0x000d0c70, 0x000d1070, 0x000d1470, + 0x000d1870, 0x000d1c70, 0x000d2070, 0x000d2470, + 0x000d2870, 0x000d2c70, 0x000d3070, 0x000d3470, + 0x000d3870, 0x000d3c70, 0x000d4070, 0x000d4470, + 0x000d4870, 0x000d4c70, 0x000d5070, 0x000d5470, + 0x000d5870, 0x000d5c70, 0x000d6070, 0x000d6470, + 0x000d6870, 0x000d6c70, 0x000d7070, 0x000d7470, + 0x000d7870, 0x000d7c70, 0x000d8070, 0x000d8470, + 0x000d8870, 0x000d8c70, 0x000d9070, 0x000d9470, + 0x000d9870, 0x000d9c70, 0x000da070, 0x000da470, + 0x000da870, 0x000dac70, 0x000db070, 0x000db470, + 0x000db870, 0x000dbc70, 0x000dc070, 0x000dc470, + 0x000dc870, 0x000dcc70, 0x000dd070, 0x000dd470, + 0x000dd870, 0x000ddc70, 0x000de070, 0x000de470, + 0x000de870, 0x000dec70, 0x000df070, 0x000df470, + 0x000df870, 0x000dfc70, 0x000e0070, 0x000e0470, + 0x000e0870, 0x000e0c70, 0x000e1070, 0x000e1470, + 0x000e1870, 0x000e1c70, 0x000e2070, 0x000e2470, + 0x000e2870, 0x000e2c70, 0x000e3070, 0x000e3470, + 0x000e3870, 0x000e3c70, 0x000e4070, 0x000e4470, + 0x000e4870, 0x000e4c70, 0x000e5070, 0x000e5470, + 0x000e5870, 0x000e5c70, 0x000e6070, 0x000e6470, + 0x000e6870, 0x000e6c70, 0x000e7070, 0x000e7470, + 0x000e7870, 0x000e7c70, 0x000e8070, 0x000e8470, + 0x000e8870, 0x000e8c70, 0x000e9070, 0x000e9470, + 0x000e9870, 0x000e9c70, 0x000ea070, 0x000ea470, + 0x000ea870, 0x000eac70, 0x000eb070, 0x000eb470, + 0x000eb870, 0x000ebc70, 0x000ec070, 0x000ec470, + 0x000ec870, 0x000ecc70, 0x000ed070, 0x000ed470, + 0x000ed870, 0x000edc70, 0x000ee070, 0x000ee470, + 0x000ee870, 0x000eec70, 0x000ef070, 0x000ef470, + 0x000ef870, 0x000efc70, 0x000f0070, 0x000f0470, + 0x000f0870, 0x000f0c70, 0x000f1070, 0x000f1470, + 0x000f1870, 0x000f1c70, 0x000f2070, 0x000f2470, + 0x000f2870, 0x000f2c70, 0x000f3070, 0x000f3470, + 0x000f3870, 0x000f3c70, 0x000f4070, 0x000f4470, + 0x000f4870, 0x000f4c70, 0x000f5070, 0x000f5470, + 0x000f5870, 0x000f5c70, 0x000f6070, 0x000f6470, + 0x000f6870, 0x000f6c70, 0x000f7070, 0x000f7470, + 0x000f7870, 0x000f7c70, 0x000f8070, 0x000f8470, + 0x000f8870, 0x000f8c70, 0x000f9070, 0x000f9470, + 0x000f9870, 0x000f9c70, 0x000fa070, 0x000fa470, + 0x000fa870, 0x000fac70, 0x000fb070, 0x000fb470, + 0x000fb870, 0x000fbc70, 0x000fc070, 0x000fc470, + 0x000fc870, 0x000fcc70, 0x000fd070, 0x000fd470, + 0x000fd870, 0x000fdc70, 0x000fe070, 0x000fe470, + 0x000fe870, 0x000fec70, 0x000ff070, 0x000ff470, + 0x000ff870, 0x000ffc70, 0x00100070, 0x00100470, + 0x00100870, 0x00100c70, 0x00101070, 0x00101470, + 0x00101870, 0x00101c70, 0x00102070, 0x00102470, + 0x00102870, 0x00102c70, 0x00103070, 0x00103470, + 0x00103870, 0x00103c70, 0x00104070, 0x00104470, + 0x00104870, 0x00104c70, 0x00105070, 0x00105470, + 0x00105870, 0x00105c70, 0x00106070, 0x00106470, + 0x00106870, 0x00106c70, 0x00107070, 0x00107470, + 0x00107870, 0x00107c70, 0x00108070, 0x00108470, + 0x00108870, 0x00108c70, 0x00109070, 0x00109470, + 0x00109870, 0x00109c70, 0x0010a070, 0x0010a470, + 0x0010a870, 0x0010ac70, 0x0010b070, 0x0010b470, + 0x0010b870, 0x0010bc70, 0x0010c070, 0x0010c470, + 0x0010c870, 0x0010cc70, 0x0010d070, 0x0010d470, + 0x0010d870, 0x0010dc70, 0x0010e070, 0x0010e470, + 0x0010e870, 0x0010ec70, 0x0010f070, 0x0010f470, + 0x0010f870, 0x0010fc70, 0x00110070, 0x00110470, + 0x00110870, 0x00110c70, 0x00111070, 0x00111470, + 0x00111870, 0x00111c70, 0x00112070, 0x00112470, + 0x00112870, 0x00112c70, 0x00113070, 0x00113470, + 0x00113870, 0x00113c70, 0x00114070, 0x00114470, + 0x00114870, 0x00114c70, 0x00115070, 0x00115470, + 0x00115870, 0x00115c70, 0x00116070, 0x00116470, + 0x00116870, 0x00116c70, 0x00117070, 0x00117470, + 0x00117870, 0x00117c70, 0x00118070, 0x00118470, + 0x00118870, 0x00118c70, 0x00119070, 0x00119470, + 0x00119870, 0x00119c70, 0x0011a070, 0x0011a470, + 0x0011a870, 0x0011ac70, 0x0011b070, 0x0011b470, + 0x0011b870, 0x0011bc70, 0x0011c070, 0x0011c470, + 0x0011c870, 0x0011cc70, 0x0011d070, 0x0011d470, + 0x0011d870, 0x0011dc70, 0x0011e070, 0x0011e470, + 0x0011e870, 0x0011ec70, 0x0011f070, 0x0011f470, + 0x0011f870, 0x0011fc70, 0x00120070, 0x00120470, + 0x00120870, 0x00120c70, 0x00121070, 0x00121470, + 0x00121870, 0x00121c70, 0x00122070, 0x00122470, + 0x00122870, 0x00122c70, 0x00123070, 0x00123470, + 0x00123870, 0x00123c70, 0x00124070, 0x00124470, + 0x00124870, 0x00124c70, 0x00125070, 0x00125470, + 0x00125870, 0x00125c70, 0x00126070, 0x00126470, + 0x00126870, 0x00126c70, 0x00127070, 0x00127470, + 0x00127870, 0x00127c70, 0x00128070, 0x00128470, + 0x00128870, 0x00128c70, 0x00129070, 0x00129470, + 0x00129870, 0x00129c70, 0x0012a070, 0x0012a470, + 0x0012a870, 0x0012ac70, 0x0012b070, 0x0012b470, + 0x0012b870, 0x0012bc70, 0x0012c070, 0x0012c470, + 0x0012c870, 0x0012cc70, 0x0012d070, 0x0012d470, + 0x0012d870, 0x0012dc70, 0x0012e070, 0x0012e470, + 0x0012e870, 0x0012ec70, 0x0012f070, 0x0012f470, + 0x0012f870, 0x0012fc70, 0x00130070, 0x00130470, + 0x00130870, 0x00130c70, 0x00131070, 0x00131470, + 0x00131870, 0x00131c70, 0x00132070, 0x00132470, + 0x00132870, 0x00132c70, 0x00133070, 0x00133470, + 0x00133870, 0x00133c70, 0x00134070, 0x00134470, + 0x00134870, 0x00134c70, 0x00135070, 0x00135470, + 0x00135870, 0x00135c70, 0x00136070, 0x00136470, + 0x00136870, 0x00136c70, 0x00137070, 0x00137470, + 0x00137870, 0x00137c70, 0x00138070, 0x00138470, + 0x00138870, 0x00138c70, 0x00139070, 0x00139470, + 0x00139870, 0x00139c70, 0x0013a070, 0x0013a470, + 0x0013a870, 0x0013ac70, 0x0013b070, 0x0013b470, + 0x0013b870, 0x0013bc70, 0x0013c070, 0x0013c470, + 0x0013c870, 0x0013cc70, 0x0013d070, 0x0013d470, + 0x0013d870, 0x0013dc70, 0x0013e070, 0x0013e470, + 0x0013e870, 0x0013ec70, 0x0013f070, 0x0013f470, + 0x0013f870, 0x0013fc70, 0x00140070, 0x00140470, + 0x00140870, 0x00140c70, 0x00141070, 0x00141470, + 0x00141870, 0x00141c70, 0x00142070, 0x00142470, + 0x00142870, 0x00142c70, 0x00143070, 0x00143470, + 0x00143870, 0x00143c70, 0x00144070, 0x00144470, + 0x00144870, 0x00144c70, 0x00145070, 0x00145470, + 0x00145870, 0x00145c70, 0x00146070, 0x00146470, + 0x00146870, 0x00146c70, 0x00147070, 0x00147470, + 0x00147870, 0x00147c70, 0x00148070, 0x00148470, + 0x00148870, 0x00148c70, 0x00149070, 0x00149470, + 0x00149870, 0x00149c70, 0x0014a070, 0x0014a470, + 0x0014a870, 0x0014ac70, 0x0014b070, 0x0014b470, + 0x0014b870, 0x0014bc70, 0x0014c070, 0x0014c470, + 0x0014c870, 0x0014cc70, 0x0014d070, 0x0014d470, + 0x0014d870, 0x0014dc70, 0x0014e070, 0x0014e470, + 0x0014e870, 0x0014ec70, 0x0014f070, 0x0014f470, + 0x0014f870, 0x0014fc70, 0x00150070, 0x00150470, + 0x00150870, 0x00150c70, 0x00151070, 0x00151470, + 0x00151870, 0x00151c70, 0x00152070, 0x00152470, + 0x00152870, 0x00152c70, 0x00153070, 0x00153470, + 0x00153870, 0x00153c70, 0x00154070, 0x00154470, + 0x00154870, 0x00154c70, 0x00155070, 0x00155470, + 0x00155870, 0x00155c70, 0x00156070, 0x00156470, + 0x00156870, 0x00156c70, 0x00157070, 0x00157470, + 0x00157870, 0x00157c70, 0x00158070, 0x00158470, + 0x00158870, 0x00158c70, 0x00159070, 0x00159470, + 0x00159870, 0x00159c70, 0x0015a070, 0x0015a470, + 0x0015a870, 0x0015ac70, 0x0015b070, 0x0015b470, + 0x0015b870, 0x0015bc70, 0x0015c070, 0x0015c470, + 0x0015c870, 0x0015cc70, 0x0015d070, 0x0015d470, + 0x0015d870, 0x0015dc70, 0x0015e070, 0x0015e470, + 0x0015e870, 0x0015ec70, 0x0015f070, 0x0015f470, + 0x0015f870, 0x0015fc70, 0x00160070, 0x00160470, + 0x00160870, 0x00160c70, 0x00161070, 0x00161470, + 0x00161870, 0x00161c70, 0x00162070, 0x00162470, + 0x00162870, 0x00162c70, 0x00163070, 0x00163470, + 0x00163870, 0x00163c70, 0x00164070, 0x00164470, + 0x00164870, 0x00164c70, 0x00165070, 0x00165470, + 0x00165870, 0x00165c70, 0x00166070, 0x00166470, + 0x00166870, 0x00166c70, 0x00167070, 0x00167470, + 0x00167870, 0x00167c70, 0x00168070, 0x00168470, + 0x00168870, 0x00168c70, 0x00169070, 0x00169470, + 0x00169870, 0x00169c70, 0x0016a070, 0x0016a470, + 0x0016a870, 0x0016ac70, 0x0016b070, 0x0016b470, + 0x0016b870, 0x0016bc70, 0x0016c070, 0x0016c470, + 0x0016c870, 0x0016cc70, 0x0016d070, 0x0016d470, + 0x0016d870, 0x0016dc70, 0x0016e070, 0x0016e470, + 0x0016e870, 0x0016ec70, 0x0016f070, 0x0016f470, + 0x0016f870, 0x0016fc70, 0x00170070, 0x00170470, + 0x00170870, 0x00170c70, 0x00171070, 0x00171470, + 0x00171870, 0x00171c70, 0x00172070, 0x00172470, + 0x00172870, 0x00172c70, 0x00173070, 0x00173470, + 0x00173870, 0x00173c70, 0x00174070, 0x00174470, + 0x00174870, 0x00174c70, 0x00175070, 0x00175470, + 0x00175870, 0x00175c70, 0x00176070, 0x00176470, + 0x00176870, 0x00176c70, 0x00177070, 0x00177470, + 0x00177870, 0x00177c70, 0x00178070, 0x00178470, + 0x00178870, 0x00178c70, 0x00179070, 0x00179470, + 0x00179870, 0x00179c70, 0x0017a070, 0x0017a470, + 0x0017a870, 0x0017ac70, 0x0017b070, 0x0017b470, + 0x0017b870, 0x0017bc70, 0x0017c070, 0x0017c470, + 0x0017c870, 0x0017cc70, 0x0017d070, 0x0017d470, + 0x0017d870, 0x0017dc70, 0x0017e070, 0x0017e470, + 0x0017e870, 0x0017ec70, 0x0017f070, 0x0017f470, + 0x0017f870, 0x0017fc70, 0x00180070, 0x00180470, + 0x00180870, 0x00180c70, 0x00181070, 0x00181470, + 0x00181870, 0x00181c70, 0x00182070, 0x00182470, + 0x00182870, 0x00182c70, 0x00183070, 0x00183470, + 0x00183870, 0x00183c70, 0x00184070, 0x00184470, + 0x00184870, 0x00184c70, 0x00185070, 0x00185470, + 0x00185870, 0x00185c70, 0x00186070, 0x00186470, + 0x00186870, 0x00186c70, 0x00187070, 0x00187470, + 0x00187870, 0x00187c70, 0x00188070, 0x00188470, + 0x00188870, 0x00188c70, 0x00189070, 0x00189470, + 0x00189870, 0x00189c70, 0x0018a070, 0x0018a470, + 0x0018a870, 0x0018ac70, 0x0018b070, 0x0018b470, + 0x0018b870, 0x0018bc70, 0x0018c070, 0x0018c470, + 0x0018c870, 0x0018cc70, 0x0018d070, 0x0018d470, + 0x0018d870, 0x0018dc70, 0x0018e070, 0x0018e470, + 0x0018e870, 0x0018ec70, 0x0018f070, 0x0018f470, + 0x0018f870, 0x0018fc70, 0x00190070, 0x00190470, + 0x00190870, 0x00190c70, 0x00191070, 0x00191470, + 0x00191870, 0x00191c70, 0x00192070, 0x00192470, + 0x00192870, 0x00192c70, 0x00193070, 0x00193470, + 0x00193870, 0x00193c70, 0x00194070, 0x00194470, + 0x00194870, 0x00194c70, 0x00195070, 0x00195470, + 0x00195870, 0x00195c70, 0x00196070, 0x00196470, + 0x00196870, 0x00196c70, 0x00197070, 0x00197470, + 0x00197870, 0x00197c70, 0x00198070, 0x00198470, + 0x00198870, 0x00198c70, 0x00199070, 0x00199470, + 0x00199870, 0x00199c70, 0x0019a070, 0x0019a470, + 0x0019a870, 0x0019ac70, 0x0019b070, 0x0019b470, + 0x0019b870, 0x0019bc70, 0x0019c070, 0x0019c470, + 0x0019c870, 0x0019cc70, 0x0019d070, 0x0019d470, + 0x0019d870, 0x0019dc70, 0x0019e070, 0x0019e470, + 0x0019e870, 0x0019ec70, 0x0019f070, 0x0019f470, + 0x0019f870, 0x0019fc70, 0x001a0070, 0x001a0470, + 0x001a0870, 0x001a0c70, 0x001a1070, 0x001a1470, + 0x001a1870, 0x001a1c70, 0x001a2070, 0x001a2470, + 0x001a2870, 0x001a2c70, 0x001a3070, 0x001a3470, + 0x001a3870, 0x001a3c70, 0x001a4070, 0x001a4470, + 0x001a4870, 0x001a4c70, 0x001a5070, 0x001a5470, + 0x001a5870, 0x001a5c70, 0x001a6070, 0x001a6470, + 0x001a6870, 0x001a6c70, 0x001a7070, 0x001a7470, + 0x001a7870, 0x001a7c70, 0x001a8070, 0x001a8470, + 0x001a8870, 0x001a8c70, 0x001a9070, 0x001a9470, + 0x001a9870, 0x001a9c70, 0x001aa070, 0x001aa470, + 0x001aa870, 0x001aac70, 0x001ab070, 0x001ab470, + 0x001ab870, 0x001abc70, 0x001ac070, 0x001ac470, + 0x001ac870, 0x001acc70, 0x001ad070, 0x001ad470, + 0x001ad870, 0x001adc70, 0x001ae070, 0x001ae470, + 0x001ae870, 0x001aec70, 0x001af070, 0x001af470, + 0x001af870, 0x001afc70, 0x001b0070, 0x001b0470, + 0x001b0870, 0x001b0c70, 0x001b1070, 0x001b1470, + 0x001b1870, 0x001b1c70, 0x001b2070, 0x001b2470, + 0x001b2870, 0x001b2c70, 0x001b3070, 0x001b3470, + 0x001b3870, 0x001b3c70, 0x001b4070, 0x001b4470, + 0x001b4870, 0x001b4c70, 0x001b5070, 0x001b5470, + 0x001b5870, 0x001b5c70, 0x001b6070, 0x001b6470, + 0x001b6870, 0x001b6c70, 0x001b7070, 0x001b7470, + 0x001b7870, 0x001b7c70, 0x001b8070, 0x001b8470, + 0x001b8870, 0x001b8c70, 0x001b9070, 0x001b9470, + 0x001b9870, 0x001b9c70, 0x001ba070, 0x001ba470, + 0x001ba870, 0x001bac70, 0x001bb070, 0x001bb470, + 0x001bb870, 0x001bbc70, 0x001bc070, 0x001bc470, + 0x001bc870, 0x001bcc70, 0x001bd070, 0x001bd470, + 0x001bd870, 0x001bdc70, 0x001be070, 0x001be470, + 0x001be870, 0x001bec70, 0x001bf070, 0x001bf470, + 0x001bf870, 0x001bfc70, 0x001c0070, 0x001c0470, + 0x001c0870, 0x001c0c70, 0x001c1070, 0x001c1470, + 0x001c1870, 0x001c1c70, 0x001c2070, 0x001c2470, + 0x001c2870, 0x001c2c70, 0x001c3070, 0x001c3470, + 0x001c3870, 0x001c3c70, 0x001c4070, 0x001c4470, + 0x001c4870, 0x001c4c70, 0x001c5070, 0x001c5470, + 0x001c5870, 0x001c5c70, 0x001c6070, 0x001c6470, + 0x001c6870, 0x001c6c70, 0x001c7070, 0x001c7470, + 0x001c7870, 0x001c7c70, 0x001c8070, 0x001c8470, + 0x001c8870, 0x001c8c70, 0x001c9070, 0x001c9470, + 0x001c9870, 0x001c9c70, 0x001ca070, 0x001ca470, + 0x001ca870, 0x001cac70, 0x001cb070, 0x001cb470, + 0x001cb870, 0x001cbc70, 0x001cc070, 0x001cc470, + 0x001cc870, 0x001ccc70, 0x001cd070, 0x001cd470, + 0x001cd870, 0x001cdc70, 0x001ce070, 0x001ce470, + 0x001ce870, 0x001cec70, 0x001cf070, 0x001cf470, + 0x001cf870, 0x001cfc70, 0x001d0070, 0x001d0470, + 0x001d0870, 0x001d0c70, 0x001d1070, 0x001d1470, + 0x001d1870, 0x001d1c70, 0x001d2070, 0x001d2470, + 0x001d2870, 0x001d2c70, 0x001d3070, 0x001d3470, + 0x001d3870, 0x001d3c70, 0x001d4070, 0x001d4470, + 0x001d4870, 0x001d4c70, 0x001d5070, 0x001d5470, + 0x001d5870, 0x001d5c70, 0x001d6070, 0x001d6470, + 0x001d6870, 0x001d6c70, 0x001d7070, 0x001d7470, + 0x001d7870, 0x001d7c70, 0x001d8070, 0x001d8470, + 0x001d8870, 0x001d8c70, 0x001d9070, 0x001d9470, + 0x001d9870, 0x001d9c70, 0x001da070, 0x001da470, + 0x001da870, 0x001dac70, 0x001db070, 0x001db470, + 0x001db870, 0x001dbc70, 0x001dc070, 0x001dc470, + 0x001dc870, 0x001dcc70, 0x001dd070, 0x001dd470, + 0x001dd870, 0x001ddc70, 0x001de070, 0x001de470, + 0x001de870, 0x001dec70, 0x001df070, 0x001df470, + 0x001df870, 0x001dfc70, 0x001e0070, 0x001e0470, + 0x001e0870, 0x001e0c70, 0x001e1070, 0x001e1470, + 0x001e1870, 0x001e1c70, 0x001e2070, 0x001e2470, + 0x001e2870, 0x001e2c70, 0x001e3070, 0x001e3470, + 0x001e3870, 0x001e3c70, 0x001e4070, 0x001e4470, + 0x001e4870, 0x001e4c70, 0x001e5070, 0x001e5470, + 0x001e5870, 0x001e5c70, 0x001e6070, 0x001e6470, + 0x001e6870, 0x001e6c70, 0x001e7070, 0x001e7470, + 0x001e7870, 0x001e7c70, 0x001e8070, 0x001e8470, + 0x001e8870, 0x001e8c70, 0x001e9070, 0x001e9470, + 0x001e9870, 0x001e9c70, 0x001ea070, 0x001ea470, + 0x001ea870, 0x001eac70, 0x001eb070, 0x001eb470, + 0x001eb870, 0x001ebc70, 0x001ec070, 0x001ec470, + 0x001ec870, 0x001ecc70, 0x001ed070, 0x001ed470, + 0x001ed870, 0x001edc70, 0x001ee070, 0x001ee470, + 0x001ee870, 0x001eec70, 0x001ef070, 0x001ef470, + 0x001ef870, 0x001efc70, 0x001f0070, 0x001f0470, + 0x001f0870, 0x001f0c70, 0x001f1070, 0x001f1470, + 0x001f1870, 0x001f1c70, 0x001f2070, 0x001f2470, + 0x001f2870, 0x001f2c70, 0x001f3070, 0x001f3470, + 0x001f3870, 0x001f3c70, 0x001f4070, 0x001f4470, + 0x001f4870, 0x001f4c70, 0x001f5070, 0x001f5470, + 0x001f5870, 0x001f5c70, 0x001f6070, 0x001f6470, + 0x001f6870, 0x001f6c70, 0x001f7070, 0x001f7470, + 0x001f7870, 0x001f7c70, 0x001f8070, 0x001f8470, + 0x001f8870, 0x001f8c70, 0x001f9070, 0x001f9470, + 0x001f9870, 0x001f9c70, 0x001fa070, 0x001fa470, + 0x001fa870, 0x001fac70, 0x001fb070, 0x001fb470, + 0x001fb870, 0x001fbc70, 0x001fc070, 0x001fc470, + 0x001fc870, 0x001fcc70, 0x001fd070, 0x001fd470, + 0x001fd870, 0x001fdc70, 0x001fe070, 0x001fe470, + 0x001fe870, 0x001fec70, 0x001ff070, 0x001ff470, + 0x001ff870, 0x001ffc70, 0x00000270, 0x00000670, + 0x00000a70, 0x00000e70, 0x00001270, 0x00001670, + 0x00001a70, 0x00001e70, 0x00002270, 0x00002670, + 0x00002a70, 0x00002e70, 0x00003270, 0x00003670, + 0x00003a70, 0x00003e70, 0x00004270, 0x00004670, + 0x00004a70, 0x00004e70, 0x00005270, 0x00005670, + 0x00005a70, 0x00005e70, 0x00006270, 0x00006670, + 0x00006a70, 0x00006e70, 0x00007270, 0x00007670, + 0x00007a70, 0x00007e70, 0x00008270, 0x00008670, + 0x00008a70, 0x00008e70, 0x00009270, 0x00009670, + 0x00009a70, 0x00009e70, 0x0000a270, 0x0000a670, + 0x0000aa70, 0x0000ae70, 0x0000b270, 0x0000b670, + 0x0000ba70, 0x0000be70, 0x0000c270, 0x0000c670, + 0x0000ca70, 0x0000ce70, 0x0000d270, 0x0000d670, + 0x0000da70, 0x0000de70, 0x0000e270, 0x0000e670, + 0x0000ea70, 0x0000ee70, 0x0000f270, 0x0000f670, + 0x0000fa70, 0x0000fe70, 0x00010270, 0x00010670, + 0x00010a70, 0x00010e70, 0x00011270, 0x00011670, + 0x00011a70, 0x00011e70, 0x00012270, 0x00012670, + 0x00012a70, 0x00012e70, 0x00013270, 0x00013670, + 0x00013a70, 0x00013e70, 0x00014270, 0x00014670, + 0x00014a70, 0x00014e70, 0x00015270, 0x00015670, + 0x00015a70, 0x00015e70, 0x00016270, 0x00016670, + 0x00016a70, 0x00016e70, 0x00017270, 0x00017670, + 0x00017a70, 0x00017e70, 0x00018270, 0x00018670, + 0x00018a70, 0x00018e70, 0x00019270, 0x00019670, + 0x00019a70, 0x00019e70, 0x0001a270, 0x0001a670, + 0x0001aa70, 0x0001ae70, 0x0001b270, 0x0001b670, + 0x0001ba70, 0x0001be70, 0x0001c270, 0x0001c670, + 0x0001ca70, 0x0001ce70, 0x0001d270, 0x0001d670, + 0x0001da70, 0x0001de70, 0x0001e270, 0x0001e670, + 0x0001ea70, 0x0001ee70, 0x0001f270, 0x0001f670, + 0x0001fa70, 0x0001fe70, 0x00020270, 0x00020670, + 0x00020a70, 0x00020e70, 0x00021270, 0x00021670, + 0x00021a70, 0x00021e70, 0x00022270, 0x00022670, + 0x00022a70, 0x00022e70, 0x00023270, 0x00023670, + 0x00023a70, 0x00023e70, 0x00024270, 0x00024670, + 0x00024a70, 0x00024e70, 0x00025270, 0x00025670, + 0x00025a70, 0x00025e70, 0x00026270, 0x00026670, + 0x00026a70, 0x00026e70, 0x00027270, 0x00027670, + 0x00027a70, 0x00027e70, 0x00028270, 0x00028670, + 0x00028a70, 0x00028e70, 0x00029270, 0x00029670, + 0x00029a70, 0x00029e70, 0x0002a270, 0x0002a670, + 0x0002aa70, 0x0002ae70, 0x0002b270, 0x0002b670, + 0x0002ba70, 0x0002be70, 0x0002c270, 0x0002c670, + 0x0002ca70, 0x0002ce70, 0x0002d270, 0x0002d670, + 0x0002da70, 0x0002de70, 0x0002e270, 0x0002e670, + 0x0002ea70, 0x0002ee70, 0x0002f270, 0x0002f670, + 0x0002fa70, 0x0002fe70, 0x00030270, 0x00030670, + 0x00030a70, 0x00030e70, 0x00031270, 0x00031670, + 0x00031a70, 0x00031e70, 0x00032270, 0x00032670, + 0x00032a70, 0x00032e70, 0x00033270, 0x00033670, + 0x00033a70, 0x00033e70, 0x00034270, 0x00034670, + 0x00034a70, 0x00034e70, 0x00035270, 0x00035670, + 0x00035a70, 0x00035e70, 0x00036270, 0x00036670, + 0x00036a70, 0x00036e70, 0x00037270, 0x00037670, + 0x00037a70, 0x00037e70, 0x00038270, 0x00038670, + 0x00038a70, 0x00038e70, 0x00039270, 0x00039670, + 0x00039a70, 0x00039e70, 0x0003a270, 0x0003a670, + 0x0003aa70, 0x0003ae70, 0x0003b270, 0x0003b670, + 0x0003ba70, 0x0003be70, 0x0003c270, 0x0003c670, + 0x0003ca70, 0x0003ce70, 0x0003d270, 0x0003d670, + 0x0003da70, 0x0003de70, 0x0003e270, 0x0003e670, + 0x0003ea70, 0x0003ee70, 0x0003f270, 0x0003f670, + 0x0003fa70, 0x0003fe70, 0x00040270, 0x00040670, + 0x00040a70, 0x00040e70, 0x00041270, 0x00041670, + 0x00041a70, 0x00041e70, 0x00042270, 0x00042670, + 0x00042a70, 0x00042e70, 0x00043270, 0x00043670, + 0x00043a70, 0x00043e70, 0x00044270, 0x00044670, + 0x00044a70, 0x00044e70, 0x00045270, 0x00045670, + 0x00045a70, 0x00045e70, 0x00046270, 0x00046670, + 0x00046a70, 0x00046e70, 0x00047270, 0x00047670, + 0x00047a70, 0x00047e70, 0x00048270, 0x00048670, + 0x00048a70, 0x00048e70, 0x00049270, 0x00049670, + 0x00049a70, 0x00049e70, 0x0004a270, 0x0004a670, + 0x0004aa70, 0x0004ae70, 0x0004b270, 0x0004b670, + 0x0004ba70, 0x0004be70, 0x0004c270, 0x0004c670, + 0x0004ca70, 0x0004ce70, 0x0004d270, 0x0004d670, + 0x0004da70, 0x0004de70, 0x0004e270, 0x0004e670, + 0x0004ea70, 0x0004ee70, 0x0004f270, 0x0004f670, + 0x0004fa70, 0x0004fe70, 0x00050270, 0x00050670, + 0x00050a70, 0x00050e70, 0x00051270, 0x00051670, + 0x00051a70, 0x00051e70, 0x00052270, 0x00052670, + 0x00052a70, 0x00052e70, 0x00053270, 0x00053670, + 0x00053a70, 0x00053e70, 0x00054270, 0x00054670, + 0x00054a70, 0x00054e70, 0x00055270, 0x00055670, + 0x00055a70, 0x00055e70, 0x00056270, 0x00056670, + 0x00056a70, 0x00056e70, 0x00057270, 0x00057670, + 0x00057a70, 0x00057e70, 0x00058270, 0x00058670, + 0x00058a70, 0x00058e70, 0x00059270, 0x00059670, + 0x00059a70, 0x00059e70, 0x0005a270, 0x0005a670, + 0x0005aa70, 0x0005ae70, 0x0005b270, 0x0005b670, + 0x0005ba70, 0x0005be70, 0x0005c270, 0x0005c670, + 0x0005ca70, 0x0005ce70, 0x0005d270, 0x0005d670, + 0x0005da70, 0x0005de70, 0x0005e270, 0x0005e670, + 0x0005ea70, 0x0005ee70, 0x0005f270, 0x0005f670, + 0x0005fa70, 0x0005fe70, 0x00060270, 0x00060670, + 0x00060a70, 0x00060e70, 0x00061270, 0x00061670, + 0x00061a70, 0x00061e70, 0x00062270, 0x00062670, + 0x00062a70, 0x00062e70, 0x00063270, 0x00063670, + 0x00063a70, 0x00063e70, 0x00064270, 0x00064670, + 0x00064a70, 0x00064e70, 0x00065270, 0x00065670, + 0x00065a70, 0x00065e70, 0x00066270, 0x00066670, + 0x00066a70, 0x00066e70, 0x00067270, 0x00067670, + 0x00067a70, 0x00067e70, 0x00068270, 0x00068670, + 0x00068a70, 0x00068e70, 0x00069270, 0x00069670, + 0x00069a70, 0x00069e70, 0x0006a270, 0x0006a670, + 0x0006aa70, 0x0006ae70, 0x0006b270, 0x0006b670, + 0x0006ba70, 0x0006be70, 0x0006c270, 0x0006c670, + 0x0006ca70, 0x0006ce70, 0x0006d270, 0x0006d670, + 0x0006da70, 0x0006de70, 0x0006e270, 0x0006e670, + 0x0006ea70, 0x0006ee70, 0x0006f270, 0x0006f670, + 0x0006fa70, 0x0006fe70, 0x00070270, 0x00070670, + 0x00070a70, 0x00070e70, 0x00071270, 0x00071670, + 0x00071a70, 0x00071e70, 0x00072270, 0x00072670, + 0x00072a70, 0x00072e70, 0x00073270, 0x00073670, + 0x00073a70, 0x00073e70, 0x00074270, 0x00074670, + 0x00074a70, 0x00074e70, 0x00075270, 0x00075670, + 0x00075a70, 0x00075e70, 0x00076270, 0x00076670, + 0x00076a70, 0x00076e70, 0x00077270, 0x00077670, + 0x00077a70, 0x00077e70, 0x00078270, 0x00078670, + 0x00078a70, 0x00078e70, 0x00079270, 0x00079670, + 0x00079a70, 0x00079e70, 0x0007a270, 0x0007a670, + 0x0007aa70, 0x0007ae70, 0x0007b270, 0x0007b670, + 0x0007ba70, 0x0007be70, 0x0007c270, 0x0007c670, + 0x0007ca70, 0x0007ce70, 0x0007d270, 0x0007d670, + 0x0007da70, 0x0007de70, 0x0007e270, 0x0007e670, + 0x0007ea70, 0x0007ee70, 0x0007f270, 0x0007f670, + 0x0007fa70, 0x0007fe70, 0x00080270, 0x00080670, + 0x00080a70, 0x00080e70, 0x00081270, 0x00081670, + 0x00081a70, 0x00081e70, 0x00082270, 0x00082670, + 0x00082a70, 0x00082e70, 0x00083270, 0x00083670, + 0x00083a70, 0x00083e70, 0x00084270, 0x00084670, + 0x00084a70, 0x00084e70, 0x00085270, 0x00085670, + 0x00085a70, 0x00085e70, 0x00086270, 0x00086670, + 0x00086a70, 0x00086e70, 0x00087270, 0x00087670, + 0x00087a70, 0x00087e70, 0x00088270, 0x00088670, + 0x00088a70, 0x00088e70, 0x00089270, 0x00089670, + 0x00089a70, 0x00089e70, 0x0008a270, 0x0008a670, + 0x0008aa70, 0x0008ae70, 0x0008b270, 0x0008b670, + 0x0008ba70, 0x0008be70, 0x0008c270, 0x0008c670, + 0x0008ca70, 0x0008ce70, 0x0008d270, 0x0008d670, + 0x0008da70, 0x0008de70, 0x0008e270, 0x0008e670, + 0x0008ea70, 0x0008ee70, 0x0008f270, 0x0008f670, + 0x0008fa70, 0x0008fe70, 0x00090270, 0x00090670, + 0x00090a70, 0x00090e70, 0x00091270, 0x00091670, + 0x00091a70, 0x00091e70, 0x00092270, 0x00092670, + 0x00092a70, 0x00092e70, 0x00093270, 0x00093670, + 0x00093a70, 0x00093e70, 0x00094270, 0x00094670, + 0x00094a70, 0x00094e70, 0x00095270, 0x00095670, + 0x00095a70, 0x00095e70, 0x00096270, 0x00096670, + 0x00096a70, 0x00096e70, 0x00097270, 0x00097670, + 0x00097a70, 0x00097e70, 0x00098270, 0x00098670, + 0x00098a70, 0x00098e70, 0x00099270, 0x00099670, + 0x00099a70, 0x00099e70, 0x0009a270, 0x0009a670, + 0x0009aa70, 0x0009ae70, 0x0009b270, 0x0009b670, + 0x0009ba70, 0x0009be70, 0x0009c270, 0x0009c670, + 0x0009ca70, 0x0009ce70, 0x0009d270, 0x0009d670, + 0x0009da70, 0x0009de70, 0x0009e270, 0x0009e670, + 0x0009ea70, 0x0009ee70, 0x0009f270, 0x0009f670, + 0x0009fa70, 0x0009fe70, 0x000a0270, 0x000a0670, + 0x000a0a70, 0x000a0e70, 0x000a1270, 0x000a1670, + 0x000a1a70, 0x000a1e70, 0x000a2270, 0x000a2670, + 0x000a2a70, 0x000a2e70, 0x000a3270, 0x000a3670, + 0x000a3a70, 0x000a3e70, 0x000a4270, 0x000a4670, + 0x000a4a70, 0x000a4e70, 0x000a5270, 0x000a5670, + 0x000a5a70, 0x000a5e70, 0x000a6270, 0x000a6670, + 0x000a6a70, 0x000a6e70, 0x000a7270, 0x000a7670, + 0x000a7a70, 0x000a7e70, 0x000a8270, 0x000a8670, + 0x000a8a70, 0x000a8e70, 0x000a9270, 0x000a9670, + 0x000a9a70, 0x000a9e70, 0x000aa270, 0x000aa670, + 0x000aaa70, 0x000aae70, 0x000ab270, 0x000ab670, + 0x000aba70, 0x000abe70, 0x000ac270, 0x000ac670, + 0x000aca70, 0x000ace70, 0x000ad270, 0x000ad670, + 0x000ada70, 0x000ade70, 0x000ae270, 0x000ae670, + 0x000aea70, 0x000aee70, 0x000af270, 0x000af670, + 0x000afa70, 0x000afe70, 0x000b0270, 0x000b0670, + 0x000b0a70, 0x000b0e70, 0x000b1270, 0x000b1670, + 0x000b1a70, 0x000b1e70, 0x000b2270, 0x000b2670, + 0x000b2a70, 0x000b2e70, 0x000b3270, 0x000b3670, + 0x000b3a70, 0x000b3e70, 0x000b4270, 0x000b4670, + 0x000b4a70, 0x000b4e70, 0x000b5270, 0x000b5670, + 0x000b5a70, 0x000b5e70, 0x000b6270, 0x000b6670, + 0x000b6a70, 0x000b6e70, 0x000b7270, 0x000b7670, + 0x000b7a70, 0x000b7e70, 0x000b8270, 0x000b8670, + 0x000b8a70, 0x000b8e70, 0x000b9270, 0x000b9670, + 0x000b9a70, 0x000b9e70, 0x000ba270, 0x000ba670, + 0x000baa70, 0x000bae70, 0x000bb270, 0x000bb670, + 0x000bba70, 0x000bbe70, 0x000bc270, 0x000bc670, + 0x000bca70, 0x000bce70, 0x000bd270, 0x000bd670, + 0x000bda70, 0x000bde70, 0x000be270, 0x000be670, + 0x000bea70, 0x000bee70, 0x000bf270, 0x000bf670, + 0x000bfa70, 0x000bfe70, 0x000c0270, 0x000c0670, + 0x000c0a70, 0x000c0e70, 0x000c1270, 0x000c1670, + 0x000c1a70, 0x000c1e70, 0x000c2270, 0x000c2670, + 0x000c2a70, 0x000c2e70, 0x000c3270, 0x000c3670, + 0x000c3a70, 0x000c3e70, 0x000c4270, 0x000c4670, + 0x000c4a70, 0x000c4e70, 0x000c5270, 0x000c5670, + 0x000c5a70, 0x000c5e70, 0x000c6270, 0x000c6670, + 0x000c6a70, 0x000c6e70, 0x000c7270, 0x000c7670, + 0x000c7a70, 0x000c7e70, 0x000c8270, 0x000c8670, + 0x000c8a70, 0x000c8e70, 0x000c9270, 0x000c9670, + 0x000c9a70, 0x000c9e70, 0x000ca270, 0x000ca670, + 0x000caa70, 0x000cae70, 0x000cb270, 0x000cb670, + 0x000cba70, 0x000cbe70, 0x000cc270, 0x000cc670, + 0x000cca70, 0x000cce70, 0x000cd270, 0x000cd670, + 0x000cda70, 0x000cde70, 0x000ce270, 0x000ce670, + 0x000cea70, 0x000cee70, 0x000cf270, 0x000cf670, + 0x000cfa70, 0x000cfe70, 0x000d0270, 0x000d0670, + 0x000d0a70, 0x000d0e70, 0x000d1270, 0x000d1670, + 0x000d1a70, 0x000d1e70, 0x000d2270, 0x000d2670, + 0x000d2a70, 0x000d2e70, 0x000d3270, 0x000d3670, + 0x000d3a70, 0x000d3e70, 0x000d4270, 0x000d4670, + 0x000d4a70, 0x000d4e70, 0x000d5270, 0x000d5670, + 0x000d5a70, 0x000d5e70, 0x000d6270, 0x000d6670, + 0x000d6a70, 0x000d6e70, 0x000d7270, 0x000d7670, + 0x000d7a70, 0x000d7e70, 0x000d8270, 0x000d8670, + 0x000d8a70, 0x000d8e70, 0x000d9270, 0x000d9670, + 0x000d9a70, 0x000d9e70, 0x000da270, 0x000da670, + 0x000daa70, 0x000dae70, 0x000db270, 0x000db670, + 0x000dba70, 0x000dbe70, 0x000dc270, 0x000dc670, + 0x000dca70, 0x000dce70, 0x000dd270, 0x000dd670, + 0x000dda70, 0x000dde70, 0x000de270, 0x000de670, + 0x000dea70, 0x000dee70, 0x000df270, 0x000df670, + 0x000dfa70, 0x000dfe70, 0x000e0270, 0x000e0670, + 0x000e0a70, 0x000e0e70, 0x000e1270, 0x000e1670, + 0x000e1a70, 0x000e1e70, 0x000e2270, 0x000e2670, + 0x000e2a70, 0x000e2e70, 0x000e3270, 0x000e3670, + 0x000e3a70, 0x000e3e70, 0x000e4270, 0x000e4670, + 0x000e4a70, 0x000e4e70, 0x000e5270, 0x000e5670, + 0x000e5a70, 0x000e5e70, 0x000e6270, 0x000e6670, + 0x000e6a70, 0x000e6e70, 0x000e7270, 0x000e7670, + 0x000e7a70, 0x000e7e70, 0x000e8270, 0x000e8670, + 0x000e8a70, 0x000e8e70, 0x000e9270, 0x000e9670, + 0x000e9a70, 0x000e9e70, 0x000ea270, 0x000ea670, + 0x000eaa70, 0x000eae70, 0x000eb270, 0x000eb670, + 0x000eba70, 0x000ebe70, 0x000ec270, 0x000ec670, + 0x000eca70, 0x000ece70, 0x000ed270, 0x000ed670, + 0x000eda70, 0x000ede70, 0x000ee270, 0x000ee670, + 0x000eea70, 0x000eee70, 0x000ef270, 0x000ef670, + 0x000efa70, 0x000efe70, 0x000f0270, 0x000f0670, + 0x000f0a70, 0x000f0e70, 0x000f1270, 0x000f1670, + 0x000f1a70, 0x000f1e70, 0x000f2270, 0x000f2670, + 0x000f2a70, 0x000f2e70, 0x000f3270, 0x000f3670, + 0x000f3a70, 0x000f3e70, 0x000f4270, 0x000f4670, + 0x000f4a70, 0x000f4e70, 0x000f5270, 0x000f5670, + 0x000f5a70, 0x000f5e70, 0x000f6270, 0x000f6670, + 0x000f6a70, 0x000f6e70, 0x000f7270, 0x000f7670, + 0x000f7a70, 0x000f7e70, 0x000f8270, 0x000f8670, + 0x000f8a70, 0x000f8e70, 0x000f9270, 0x000f9670, + 0x000f9a70, 0x000f9e70, 0x000fa270, 0x000fa670, + 0x000faa70, 0x000fae70, 0x000fb270, 0x000fb670, + 0x000fba70, 0x000fbe70, 0x000fc270, 0x000fc670, + 0x000fca70, 0x000fce70, 0x000fd270, 0x000fd670, + 0x000fda70, 0x000fde70, 0x000fe270, 0x000fe670, + 0x000fea70, 0x000fee70, 0x000ff270, 0x000ff670, + 0x000ffa70, 0x000ffe70, 0x00100270, 0x00100670, + 0x00100a70, 0x00100e70, 0x00101270, 0x00101670, + 0x00101a70, 0x00101e70, 0x00102270, 0x00102670, + 0x00102a70, 0x00102e70, 0x00103270, 0x00103670, + 0x00103a70, 0x00103e70, 0x00104270, 0x00104670, + 0x00104a70, 0x00104e70, 0x00105270, 0x00105670, + 0x00105a70, 0x00105e70, 0x00106270, 0x00106670, + 0x00106a70, 0x00106e70, 0x00107270, 0x00107670, + 0x00107a70, 0x00107e70, 0x00108270, 0x00108670, + 0x00108a70, 0x00108e70, 0x00109270, 0x00109670, + 0x00109a70, 0x00109e70, 0x0010a270, 0x0010a670, + 0x0010aa70, 0x0010ae70, 0x0010b270, 0x0010b670, + 0x0010ba70, 0x0010be70, 0x0010c270, 0x0010c670, + 0x0010ca70, 0x0010ce70, 0x0010d270, 0x0010d670, + 0x0010da70, 0x0010de70, 0x0010e270, 0x0010e670, + 0x0010ea70, 0x0010ee70, 0x0010f270, 0x0010f670, + 0x0010fa70, 0x0010fe70, 0x00110270, 0x00110670, + 0x00110a70, 0x00110e70, 0x00111270, 0x00111670, + 0x00111a70, 0x00111e70, 0x00112270, 0x00112670, + 0x00112a70, 0x00112e70, 0x00113270, 0x00113670, + 0x00113a70, 0x00113e70, 0x00114270, 0x00114670, + 0x00114a70, 0x00114e70, 0x00115270, 0x00115670, + 0x00115a70, 0x00115e70, 0x00116270, 0x00116670, + 0x00116a70, 0x00116e70, 0x00117270, 0x00117670, + 0x00117a70, 0x00117e70, 0x00118270, 0x00118670, + 0x00118a70, 0x00118e70, 0x00119270, 0x00119670, + 0x00119a70, 0x00119e70, 0x0011a270, 0x0011a670, + 0x0011aa70, 0x0011ae70, 0x0011b270, 0x0011b670, + 0x0011ba70, 0x0011be70, 0x0011c270, 0x0011c670, + 0x0011ca70, 0x0011ce70, 0x0011d270, 0x0011d670, + 0x0011da70, 0x0011de70, 0x0011e270, 0x0011e670, + 0x0011ea70, 0x0011ee70, 0x0011f270, 0x0011f670, + 0x0011fa70, 0x0011fe70, 0x00120270, 0x00120670, + 0x00120a70, 0x00120e70, 0x00121270, 0x00121670, + 0x00121a70, 0x00121e70, 0x00122270, 0x00122670, + 0x00122a70, 0x00122e70, 0x00123270, 0x00123670, + 0x00123a70, 0x00123e70, 0x00124270, 0x00124670, + 0x00124a70, 0x00124e70, 0x00125270, 0x00125670, + 0x00125a70, 0x00125e70, 0x00126270, 0x00126670, + 0x00126a70, 0x00126e70, 0x00127270, 0x00127670, + 0x00127a70, 0x00127e70, 0x00128270, 0x00128670, + 0x00128a70, 0x00128e70, 0x00129270, 0x00129670, + 0x00129a70, 0x00129e70, 0x0012a270, 0x0012a670, + 0x0012aa70, 0x0012ae70, 0x0012b270, 0x0012b670, + 0x0012ba70, 0x0012be70, 0x0012c270, 0x0012c670, + 0x0012ca70, 0x0012ce70, 0x0012d270, 0x0012d670, + 0x0012da70, 0x0012de70, 0x0012e270, 0x0012e670, + 0x0012ea70, 0x0012ee70, 0x0012f270, 0x0012f670, + 0x0012fa70, 0x0012fe70, 0x00130270, 0x00130670, + 0x00130a70, 0x00130e70, 0x00131270, 0x00131670, + 0x00131a70, 0x00131e70, 0x00132270, 0x00132670, + 0x00132a70, 0x00132e70, 0x00133270, 0x00133670, + 0x00133a70, 0x00133e70, 0x00134270, 0x00134670, + 0x00134a70, 0x00134e70, 0x00135270, 0x00135670, + 0x00135a70, 0x00135e70, 0x00136270, 0x00136670, + 0x00136a70, 0x00136e70, 0x00137270, 0x00137670, + 0x00137a70, 0x00137e70, 0x00138270, 0x00138670, + 0x00138a70, 0x00138e70, 0x00139270, 0x00139670, + 0x00139a70, 0x00139e70, 0x0013a270, 0x0013a670, + 0x0013aa70, 0x0013ae70, 0x0013b270, 0x0013b670, + 0x0013ba70, 0x0013be70, 0x0013c270, 0x0013c670, + 0x0013ca70, 0x0013ce70, 0x0013d270, 0x0013d670, + 0x0013da70, 0x0013de70, 0x0013e270, 0x0013e670, + 0x0013ea70, 0x0013ee70, 0x0013f270, 0x0013f670, + 0x0013fa70, 0x0013fe70, 0x00140270, 0x00140670, + 0x00140a70, 0x00140e70, 0x00141270, 0x00141670, + 0x00141a70, 0x00141e70, 0x00142270, 0x00142670, + 0x00142a70, 0x00142e70, 0x00143270, 0x00143670, + 0x00143a70, 0x00143e70, 0x00144270, 0x00144670, + 0x00144a70, 0x00144e70, 0x00145270, 0x00145670, + 0x00145a70, 0x00145e70, 0x00146270, 0x00146670, + 0x00146a70, 0x00146e70, 0x00147270, 0x00147670, + 0x00147a70, 0x00147e70, 0x00148270, 0x00148670, + 0x00148a70, 0x00148e70, 0x00149270, 0x00149670, + 0x00149a70, 0x00149e70, 0x0014a270, 0x0014a670, + 0x0014aa70, 0x0014ae70, 0x0014b270, 0x0014b670, + 0x0014ba70, 0x0014be70, 0x0014c270, 0x0014c670, + 0x0014ca70, 0x0014ce70, 0x0014d270, 0x0014d670, + 0x0014da70, 0x0014de70, 0x0014e270, 0x0014e670, + 0x0014ea70, 0x0014ee70, 0x0014f270, 0x0014f670, + 0x0014fa70, 0x0014fe70, 0x00150270, 0x00150670, + 0x00150a70, 0x00150e70, 0x00151270, 0x00151670, + 0x00151a70, 0x00151e70, 0x00152270, 0x00152670, + 0x00152a70, 0x00152e70, 0x00153270, 0x00153670, + 0x00153a70, 0x00153e70, 0x00154270, 0x00154670, + 0x00154a70, 0x00154e70, 0x00155270, 0x00155670, + 0x00155a70, 0x00155e70, 0x00156270, 0x00156670, + 0x00156a70, 0x00156e70, 0x00157270, 0x00157670, + 0x00157a70, 0x00157e70, 0x00158270, 0x00158670, + 0x00158a70, 0x00158e70, 0x00159270, 0x00159670, + 0x00159a70, 0x00159e70, 0x0015a270, 0x0015a670, + 0x0015aa70, 0x0015ae70, 0x0015b270, 0x0015b670, + 0x0015ba70, 0x0015be70, 0x0015c270, 0x0015c670, + 0x0015ca70, 0x0015ce70, 0x0015d270, 0x0015d670, + 0x0015da70, 0x0015de70, 0x0015e270, 0x0015e670, + 0x0015ea70, 0x0015ee70, 0x0015f270, 0x0015f670, + 0x0015fa70, 0x0015fe70, 0x00160270, 0x00160670, + 0x00160a70, 0x00160e70, 0x00161270, 0x00161670, + 0x00161a70, 0x00161e70, 0x00162270, 0x00162670, + 0x00162a70, 0x00162e70, 0x00163270, 0x00163670, + 0x00163a70, 0x00163e70, 0x00164270, 0x00164670, + 0x00164a70, 0x00164e70, 0x00165270, 0x00165670, + 0x00165a70, 0x00165e70, 0x00166270, 0x00166670, + 0x00166a70, 0x00166e70, 0x00167270, 0x00167670, + 0x00167a70, 0x00167e70, 0x00168270, 0x00168670, + 0x00168a70, 0x00168e70, 0x00169270, 0x00169670, + 0x00169a70, 0x00169e70, 0x0016a270, 0x0016a670, + 0x0016aa70, 0x0016ae70, 0x0016b270, 0x0016b670, + 0x0016ba70, 0x0016be70, 0x0016c270, 0x0016c670, + 0x0016ca70, 0x0016ce70, 0x0016d270, 0x0016d670, + 0x0016da70, 0x0016de70, 0x0016e270, 0x0016e670, + 0x0016ea70, 0x0016ee70, 0x0016f270, 0x0016f670, + 0x0016fa70, 0x0016fe70, 0x00170270, 0x00170670, + 0x00170a70, 0x00170e70, 0x00171270, 0x00171670, + 0x00171a70, 0x00171e70, 0x00172270, 0x00172670, + 0x00172a70, 0x00172e70, 0x00173270, 0x00173670, + 0x00173a70, 0x00173e70, 0x00174270, 0x00174670, + 0x00174a70, 0x00174e70, 0x00175270, 0x00175670, + 0x00175a70, 0x00175e70, 0x00176270, 0x00176670, + 0x00176a70, 0x00176e70, 0x00177270, 0x00177670, + 0x00177a70, 0x00177e70, 0x00178270, 0x00178670, + 0x00178a70, 0x00178e70, 0x00179270, 0x00179670, + 0x00179a70, 0x00179e70, 0x0017a270, 0x0017a670, + 0x0017aa70, 0x0017ae70, 0x0017b270, 0x0017b670, + 0x0017ba70, 0x0017be70, 0x0017c270, 0x0017c670, + 0x0017ca70, 0x0017ce70, 0x0017d270, 0x0017d670, + 0x0017da70, 0x0017de70, 0x0017e270, 0x0017e670, + 0x0017ea70, 0x0017ee70, 0x0017f270, 0x0017f670, + 0x0017fa70, 0x0017fe70, 0x00180270, 0x00180670, + 0x00180a70, 0x00180e70, 0x00181270, 0x00181670, + 0x00181a70, 0x00181e70, 0x00182270, 0x00182670, + 0x00182a70, 0x00182e70, 0x00183270, 0x00183670, + 0x00183a70, 0x00183e70, 0x00184270, 0x00184670, + 0x00184a70, 0x00184e70, 0x00185270, 0x00185670, + 0x00185a70, 0x00185e70, 0x00186270, 0x00186670, + 0x00186a70, 0x00186e70, 0x00187270, 0x00187670, + 0x00187a70, 0x00187e70, 0x00188270, 0x00188670, + 0x00188a70, 0x00188e70, 0x00189270, 0x00189670, + 0x00189a70, 0x00189e70, 0x0018a270, 0x0018a670, + 0x0018aa70, 0x0018ae70, 0x0018b270, 0x0018b670, + 0x0018ba70, 0x0018be70, 0x0018c270, 0x0018c670, + 0x0018ca70, 0x0018ce70, 0x0018d270, 0x0018d670, + 0x0018da70, 0x0018de70, 0x0018e270, 0x0018e670, + 0x0018ea70, 0x0018ee70, 0x0018f270, 0x0018f670, + 0x0018fa70, 0x0018fe70, 0x00190270, 0x00190670, + 0x00190a70, 0x00190e70, 0x00191270, 0x00191670, + 0x00191a70, 0x00191e70, 0x00192270, 0x00192670, + 0x00192a70, 0x00192e70, 0x00193270, 0x00193670, + 0x00193a70, 0x00193e70, 0x00194270, 0x00194670, + 0x00194a70, 0x00194e70, 0x00195270, 0x00195670, + 0x00195a70, 0x00195e70, 0x00196270, 0x00196670, + 0x00196a70, 0x00196e70, 0x00197270, 0x00197670, + 0x00197a70, 0x00197e70, 0x00198270, 0x00198670, + 0x00198a70, 0x00198e70, 0x00199270, 0x00199670, + 0x00199a70, 0x00199e70, 0x0019a270, 0x0019a670, + 0x0019aa70, 0x0019ae70, 0x0019b270, 0x0019b670, + 0x0019ba70, 0x0019be70, 0x0019c270, 0x0019c670, + 0x0019ca70, 0x0019ce70, 0x0019d270, 0x0019d670, + 0x0019da70, 0x0019de70, 0x0019e270, 0x0019e670, + 0x0019ea70, 0x0019ee70, 0x0019f270, 0x0019f670, + 0x0019fa70, 0x0019fe70, 0x001a0270, 0x001a0670, + 0x001a0a70, 0x001a0e70, 0x001a1270, 0x001a1670, + 0x001a1a70, 0x001a1e70, 0x001a2270, 0x001a2670, + 0x001a2a70, 0x001a2e70, 0x001a3270, 0x001a3670, + 0x001a3a70, 0x001a3e70, 0x001a4270, 0x001a4670, + 0x001a4a70, 0x001a4e70, 0x001a5270, 0x001a5670, + 0x001a5a70, 0x001a5e70, 0x001a6270, 0x001a6670, + 0x001a6a70, 0x001a6e70, 0x001a7270, 0x001a7670, + 0x001a7a70, 0x001a7e70, 0x001a8270, 0x001a8670, + 0x001a8a70, 0x001a8e70, 0x001a9270, 0x001a9670, + 0x001a9a70, 0x001a9e70, 0x001aa270, 0x001aa670, + 0x001aaa70, 0x001aae70, 0x001ab270, 0x001ab670, + 0x001aba70, 0x001abe70, 0x001ac270, 0x001ac670, + 0x001aca70, 0x001ace70, 0x001ad270, 0x001ad670, + 0x001ada70, 0x001ade70, 0x001ae270, 0x001ae670, + 0x001aea70, 0x001aee70, 0x001af270, 0x001af670, + 0x001afa70, 0x001afe70, 0x001b0270, 0x001b0670, + 0x001b0a70, 0x001b0e70, 0x001b1270, 0x001b1670, + 0x001b1a70, 0x001b1e70, 0x001b2270, 0x001b2670, + 0x001b2a70, 0x001b2e70, 0x001b3270, 0x001b3670, + 0x001b3a70, 0x001b3e70, 0x001b4270, 0x001b4670, + 0x001b4a70, 0x001b4e70, 0x001b5270, 0x001b5670, + 0x001b5a70, 0x001b5e70, 0x001b6270, 0x001b6670, + 0x001b6a70, 0x001b6e70, 0x001b7270, 0x001b7670, + 0x001b7a70, 0x001b7e70, 0x001b8270, 0x001b8670, + 0x001b8a70, 0x001b8e70, 0x001b9270, 0x001b9670, + 0x001b9a70, 0x001b9e70, 0x001ba270, 0x001ba670, + 0x001baa70, 0x001bae70, 0x001bb270, 0x001bb670, + 0x001bba70, 0x001bbe70, 0x001bc270, 0x001bc670, + 0x001bca70, 0x001bce70, 0x001bd270, 0x001bd670, + 0x001bda70, 0x001bde70, 0x001be270, 0x001be670, + 0x001bea70, 0x001bee70, 0x001bf270, 0x001bf670, + 0x001bfa70, 0x001bfe70, 0x001c0270, 0x001c0670, + 0x001c0a70, 0x001c0e70, 0x001c1270, 0x001c1670, + 0x001c1a70, 0x001c1e70, 0x001c2270, 0x001c2670, + 0x001c2a70, 0x001c2e70, 0x001c3270, 0x001c3670, + 0x001c3a70, 0x001c3e70, 0x001c4270, 0x001c4670, + 0x001c4a70, 0x001c4e70, 0x001c5270, 0x001c5670, + 0x001c5a70, 0x001c5e70, 0x001c6270, 0x001c6670, + 0x001c6a70, 0x001c6e70, 0x001c7270, 0x001c7670, + 0x001c7a70, 0x001c7e70, 0x001c8270, 0x001c8670, + 0x001c8a70, 0x001c8e70, 0x001c9270, 0x001c9670, + 0x001c9a70, 0x001c9e70, 0x001ca270, 0x001ca670, + 0x001caa70, 0x001cae70, 0x001cb270, 0x001cb670, + 0x001cba70, 0x001cbe70, 0x001cc270, 0x001cc670, + 0x001cca70, 0x001cce70, 0x001cd270, 0x001cd670, + 0x001cda70, 0x001cde70, 0x001ce270, 0x001ce670, + 0x001cea70, 0x001cee70, 0x001cf270, 0x001cf670, + 0x001cfa70, 0x001cfe70, 0x001d0270, 0x001d0670, + 0x001d0a70, 0x001d0e70, 0x001d1270, 0x001d1670, + 0x001d1a70, 0x001d1e70, 0x001d2270, 0x001d2670, + 0x001d2a70, 0x001d2e70, 0x001d3270, 0x001d3670, + 0x001d3a70, 0x001d3e70, 0x001d4270, 0x001d4670, + 0x001d4a70, 0x001d4e70, 0x001d5270, 0x001d5670, + 0x001d5a70, 0x001d5e70, 0x001d6270, 0x001d6670, + 0x001d6a70, 0x001d6e70, 0x001d7270, 0x001d7670, + 0x001d7a70, 0x001d7e70, 0x001d8270, 0x001d8670, + 0x001d8a70, 0x001d8e70, 0x001d9270, 0x001d9670, + 0x001d9a70, 0x001d9e70, 0x001da270, 0x001da670, + 0x001daa70, 0x001dae70, 0x001db270, 0x001db670, + 0x001dba70, 0x001dbe70, 0x001dc270, 0x001dc670, + 0x001dca70, 0x001dce70, 0x001dd270, 0x001dd670, + 0x001dda70, 0x001dde70, 0x001de270, 0x001de670, + 0x001dea70, 0x001dee70, 0x001df270, 0x001df670, + 0x001dfa70, 0x001dfe70, 0x001e0270, 0x001e0670, + 0x001e0a70, 0x001e0e70, 0x001e1270, 0x001e1670, + 0x001e1a70, 0x001e1e70, 0x001e2270, 0x001e2670, + 0x001e2a70, 0x001e2e70, 0x001e3270, 0x001e3670, + 0x001e3a70, 0x001e3e70, 0x001e4270, 0x001e4670, + 0x001e4a70, 0x001e4e70, 0x001e5270, 0x001e5670, + 0x001e5a70, 0x001e5e70, 0x001e6270, 0x001e6670, + 0x001e6a70, 0x001e6e70, 0x001e7270, 0x001e7670, + 0x001e7a70, 0x001e7e70, 0x001e8270, 0x001e8670, + 0x001e8a70, 0x001e8e70, 0x001e9270, 0x001e9670, + 0x001e9a70, 0x001e9e70, 0x001ea270, 0x001ea670, + 0x001eaa70, 0x001eae70, 0x001eb270, 0x001eb670, + 0x001eba70, 0x001ebe70, 0x001ec270, 0x001ec670, + 0x001eca70, 0x001ece70, 0x001ed270, 0x001ed670, + 0x001eda70, 0x001ede70, 0x001ee270, 0x001ee670, + 0x001eea70, 0x001eee70, 0x001ef270, 0x001ef670, + 0x001efa70, 0x001efe70, 0x001f0270, 0x001f0670, + 0x001f0a70, 0x001f0e70, 0x001f1270, 0x001f1670, + 0x001f1a70, 0x001f1e70, 0x001f2270, 0x001f2670, + 0x001f2a70, 0x001f2e70, 0x001f3270, 0x001f3670, + 0x001f3a70, 0x001f3e70, 0x001f4270, 0x001f4670, + 0x001f4a70, 0x001f4e70, 0x001f5270, 0x001f5670, + 0x001f5a70, 0x001f5e70, 0x001f6270, 0x001f6670, + 0x001f6a70, 0x001f6e70, 0x001f7270, 0x001f7670, + 0x001f7a70, 0x001f7e70, 0x001f8270, 0x001f8670, + 0x001f8a70, 0x001f8e70, 0x001f9270, 0x001f9670, + 0x001f9a70, 0x001f9e70, 0x001fa270, 0x001fa670, + 0x001faa70, 0x001fae70, 0x001fb270, 0x001fb670, + 0x001fba70, 0x001fbe70, 0x001fc270, 0x001fc670, + 0x001fca70, 0x001fce70, 0x001fd270, 0x001fd670, + 0x001fda70, 0x001fde70, 0x001fe270, 0x001fe670, + 0x001fea70, 0x001fee70, 0x001ff270, 0x001ff670, + 0x001ffa70, 0x001ffe70 +#endif /* LONGER_HUFFTABLE */ + }, .len_table = { - 0x00000004, 0x00000104, 0x00000185, 0x00000385, - 0x000007c6, 0x00000026, 0x000003a7, 0x00000426, - 0x00000227, 0x00000a27, 0x00000627, 0x00000e27, - 0x00000127, 0x00000927, 0x00000ba8, 0x00001ba8, - 0x00000528, 0x00000d28, 0x00001528, 0x00001d28, - 0x0000066a, 0x0000266a, 0x0000466a, 0x0000666a, - 0x0000166a, 0x0000366a, 0x0000566a, 0x0000766a, - 0x0000276b, 0x0000676b, 0x0000a76b, 0x0000e76b, - 0x00000e6b, 0x00002e6b, 0x00004e6b, 0x00006e6b, - 0x00008e6b, 0x0000ae6b, 0x0000ce6b, 0x0000ee6b, - 0x00001e6b, 0x00003e6b, 0x00005e6b, 0x00007e6b, - 0x00009e6b, 0x0000be6b, 0x0000de6b, 0x0000fe6b, - 0x00005fee, 0x00015fee, 0x00025fee, 0x00035fee, - 0x00045fee, 0x00055fee, 0x00065fee, 0x00075fee, - 0x0000176c, 0x0000576c, 0x0000976c, 0x0000d76c, - 0x0001176c, 0x0001576c, 0x0001976c, 0x0001d76c, - 0x0000dfef, 0x0001dfef, 0x0002dfef, 0x0003dfef, - 0x0004dfef, 0x0005dfef, 0x0006dfef, 0x0007dfef, - 0x0008dfef, 0x0009dfef, 0x000adfef, 0x000bdfef, - 0x000cdfef, 0x000ddfef, 0x000edfef, 0x000fdfef, - 0x00003fef, 0x00013fef, 0x00023fef, 0x00033fef, - 0x00043fef, 0x00053fef, 0x00063fef, 0x00073fef, - 0x00083fef, 0x00093fef, 0x000a3fef, 0x000b3fef, - 0x000c3fef, 0x000d3fef, 0x000e3fef, 0x000f3fef, - 0x000051ee, 0x0000d1ee, 0x000151ee, 0x0001d1ee, - 0x000251ee, 0x0002d1ee, 0x000351ee, 0x0003d1ee, - 0x000451ee, 0x0004d1ee, 0x000551ee, 0x0005d1ee, - 0x000651ee, 0x0006d1ee, 0x000751ee, 0x0007d1ee, - 0x0000376d, 0x0000776d, 0x0000b76d, 0x0000f76d, - 0x0001376d, 0x0001776d, 0x0001b76d, 0x0001f76d, - 0x0002376d, 0x0002776d, 0x0002b76d, 0x0002f76d, - 0x0003376d, 0x0003776d, 0x0003b76d, 0x0003f76d, - 0x0000bff0, 0x0001bff0, 0x0002bff0, 0x0003bff0, - 0x0004bff0, 0x0005bff0, 0x0006bff0, 0x0007bff0, - 0x0008bff0, 0x0009bff0, 0x000abff0, 0x000bbff0, - 0x000cbff0, 0x000dbff0, 0x000ebff0, 0x000fbff0, - 0x0010bff0, 0x0011bff0, 0x0012bff0, 0x0013bff0, - 0x0014bff0, 0x0015bff0, 0x0016bff0, 0x0017bff0, - 0x0018bff0, 0x0019bff0, 0x001abff0, 0x001bbff0, - 0x001cbff0, 0x001dbff0, 0x001ebff0, 0x001fbff0, - 0x000031ef, 0x0000b1ef, 0x000131ef, 0x0001b1ef, - 0x000231ef, 0x0002b1ef, 0x000331ef, 0x0003b1ef, - 0x000431ef, 0x0004b1ef, 0x000531ef, 0x0005b1ef, - 0x000631ef, 0x0006b1ef, 0x000731ef, 0x0007b1ef, - 0x000831ef, 0x0008b1ef, 0x000931ef, 0x0009b1ef, - 0x000a31ef, 0x000ab1ef, 0x000b31ef, 0x000bb1ef, - 0x000c31ef, 0x000cb1ef, 0x000d31ef, 0x000db1ef, - 0x000e31ef, 0x000eb1ef, 0x000f31ef, 0x000fb1ef, - 0x00007ff0, 0x00017ff0, 0x00027ff0, 0x00037ff0, - 0x00047ff0, 0x00057ff0, 0x00067ff0, 0x00077ff0, - 0x00087ff0, 0x00097ff0, 0x000a7ff0, 0x000b7ff0, - 0x000c7ff0, 0x000d7ff0, 0x000e7ff0, 0x000f7ff0, - 0x00107ff0, 0x00117ff0, 0x00127ff0, 0x00137ff0, - 0x00147ff0, 0x00157ff0, 0x00167ff0, 0x00177ff0, - 0x00187ff0, 0x00197ff0, 0x001a7ff0, 0x001b7ff0, - 0x001c7ff0, 0x001d7ff0, 0x001e7ff0, 0x001f7ff0, - 0x0000fff0, 0x0001fff0, 0x0002fff0, 0x0003fff0, - 0x0004fff0, 0x0005fff0, 0x0006fff0, 0x0007fff0, - 0x0008fff0, 0x0009fff0, 0x000afff0, 0x000bfff0, - 0x000cfff0, 0x000dfff0, 0x000efff0, 0x000ffff0, - 0x0010fff0, 0x0011fff0, 0x0012fff0, 0x0013fff0, - 0x0014fff0, 0x0015fff0, 0x0016fff0, 0x0017fff0, - 0x0018fff0, 0x0019fff0, 0x001afff0, 0x001bfff0, - 0x001cfff0, 0x001dfff0, 0x001efff0, 0x000071ea }, + 0x00000807, 0x00000407, 0x00000c07, 0x00000207, + 0x00000a07, 0x00000607, 0x00000e07, 0x00000107, + 0x00000908, 0x00001908, 0x00000508, 0x00001508, + 0x00000d08, 0x00001d08, 0x00000308, 0x00001308, + 0x00000b09, 0x00001b09, 0x00002b09, 0x00003b09, + 0x00000709, 0x00001709, 0x00002709, 0x00003709, + 0x00000f09, 0x00001f09, 0x00002f09, 0x00003f09, + 0x00000089, 0x00001089, 0x00002089, 0x00003089, + 0x0000088a, 0x0000188a, 0x0000288a, 0x0000388a, + 0x0000488a, 0x0000588a, 0x0000688a, 0x0000788a, + 0x0000048a, 0x0000148a, 0x0000248a, 0x0000348a, + 0x0000448a, 0x0000548a, 0x0000648a, 0x0000748a, + 0x00000c8a, 0x00001c8a, 0x00002c8a, 0x00003c8a, + 0x00004c8a, 0x00005c8a, 0x00006c8a, 0x00007c8a, + 0x0000028a, 0x0000128a, 0x0000228a, 0x0000328a, + 0x0000428a, 0x0000528a, 0x0000628a, 0x0000728a, + 0x00000a8b, 0x00001a8b, 0x00002a8b, 0x00003a8b, + 0x00004a8b, 0x00005a8b, 0x00006a8b, 0x00007a8b, + 0x00008a8b, 0x00009a8b, 0x0000aa8b, 0x0000ba8b, + 0x0000ca8b, 0x0000da8b, 0x0000ea8b, 0x0000fa8b, + 0x0000068b, 0x0000168b, 0x0000268b, 0x0000368b, + 0x0000468b, 0x0000568b, 0x0000668b, 0x0000768b, + 0x0000868b, 0x0000968b, 0x0000a68b, 0x0000b68b, + 0x0000c68b, 0x0000d68b, 0x0000e68b, 0x0000f68b, + 0x00000e8b, 0x00001e8b, 0x00002e8b, 0x00003e8b, + 0x00004e8b, 0x00005e8b, 0x00006e8b, 0x00007e8b, + 0x00008e8b, 0x00009e8b, 0x0000ae8b, 0x0000be8b, + 0x0000ce8b, 0x0000de8b, 0x0000ee8b, 0x0000fe8b, + 0x0000006c, 0x0000206c, 0x0000406c, 0x0000606c, + 0x0000806c, 0x0000a06c, 0x0000c06c, 0x0000e06c, + 0x0001006c, 0x0001206c, 0x0001406c, 0x0001606c, + 0x0001806c, 0x0001a06c, 0x0001c06c, 0x0001e06c, + 0x0000106d, 0x0000306d, 0x0000506d, 0x0000706d, + 0x0000906d, 0x0000b06d, 0x0000d06d, 0x0000f06d, + 0x0001106d, 0x0001306d, 0x0001506d, 0x0001706d, + 0x0001906d, 0x0001b06d, 0x0001d06d, 0x0001f06d, + 0x0002106d, 0x0002306d, 0x0002506d, 0x0002706d, + 0x0002906d, 0x0002b06d, 0x0002d06d, 0x0002f06d, + 0x0003106d, 0x0003306d, 0x0003506d, 0x0003706d, + 0x0003906d, 0x0003b06d, 0x0003d06d, 0x0003f06d, + 0x0000086d, 0x0000286d, 0x0000486d, 0x0000686d, + 0x0000886d, 0x0000a86d, 0x0000c86d, 0x0000e86d, + 0x0001086d, 0x0001286d, 0x0001486d, 0x0001686d, + 0x0001886d, 0x0001a86d, 0x0001c86d, 0x0001e86d, + 0x0002086d, 0x0002286d, 0x0002486d, 0x0002686d, + 0x0002886d, 0x0002a86d, 0x0002c86d, 0x0002e86d, + 0x0003086d, 0x0003286d, 0x0003486d, 0x0003686d, + 0x0003886d, 0x0003a86d, 0x0003c86d, 0x0003e86d, + 0x0000186d, 0x0000386d, 0x0000586d, 0x0000786d, + 0x0000986d, 0x0000b86d, 0x0000d86d, 0x0000f86d, + 0x0001186d, 0x0001386d, 0x0001586d, 0x0001786d, + 0x0001986d, 0x0001b86d, 0x0001d86d, 0x0001f86d, + 0x0002186d, 0x0002386d, 0x0002586d, 0x0002786d, + 0x0002986d, 0x0002b86d, 0x0002d86d, 0x0002f86d, + 0x0003186d, 0x0003386d, 0x0003586d, 0x0003786d, + 0x0003986d, 0x0003b86d, 0x0003d86d, 0x0003f86d, + 0x0000046d, 0x0000246d, 0x0000446d, 0x0000646d, + 0x0000846d, 0x0000a46d, 0x0000c46d, 0x0000e46d, + 0x0001046d, 0x0001246d, 0x0001446d, 0x0001646d, + 0x0001846d, 0x0001a46d, 0x0001c46d, 0x0001e46d, + 0x0002046d, 0x0002246d, 0x0002446d, 0x0002646d, + 0x0002846d, 0x0002a46d, 0x0002c46d, 0x0002e46d, + 0x0003046d, 0x0003246d, 0x0003446d, 0x0003646d, + 0x0003846d, 0x0003a46d, 0x0003c46d, 0x00001468}, .lit_table = { - 0x007b, 0x004f, 0x027b, 0x044f, 0x024f, 0x017b, 0x064f, 0x037b, - 0x014f, 0x0019, 0x0002, 0x054f, 0x00fb, 0x02fb, 0x034f, 0x074f, - 0x00cf, 0x04cf, 0x01fb, 0x02cf, 0x03fb, 0x0007, 0x0207, 0x0107, - 0x06cf, 0x01cf, 0x0307, 0x05cf, 0x0087, 0x0287, 0x03cf, 0x07cf, - 0x0004, 0x003d, 0x0022, 0x0187, 0x002f, 0x0387, 0x000b, 0x0059, - 0x0012, 0x0039, 0x0047, 0x00bd, 0x0079, 0x007d, 0x0032, 0x00fd, - 0x0003, 0x042f, 0x010b, 0x0247, 0x008b, 0x022f, 0x0147, 0x062f, - 0x012f, 0x052f, 0x018b, 0x0005, 0x004b, 0x0045, 0x014b, 0x032f, - 0x072f, 0x0083, 0x00cb, 0x0043, 0x01cb, 0x00c3, 0x002b, 0x012b, - 0x0023, 0x00ab, 0x00af, 0x0347, 0x01ab, 0x00a3, 0x006b, 0x016b, - 0x00eb, 0x00c7, 0x0063, 0x00e3, 0x0025, 0x01eb, 0x001b, 0x04af, - 0x0013, 0x02af, 0x02c7, 0x011b, 0x009b, 0x019b, 0x01c7, 0x0065, - 0x06af, 0x000a, 0x0093, 0x002a, 0x001a, 0x0014, 0x0015, 0x0055, - 0x0035, 0x003a, 0x005b, 0x015b, 0x0006, 0x0075, 0x0026, 0x0016, - 0x000d, 0x00db, 0x0036, 0x000e, 0x002e, 0x001e, 0x004d, 0x002d, - 0x0053, 0x006d, 0x01af, 0x01db, 0x003b, 0x00d3, 0x05af, 0x03c7, - 0x03af, 0x07af, 0x006f, 0x046f, 0x026f, 0x066f, 0x016f, 0x056f, - 0x036f, 0x076f, 0x00ef, 0x04ef, 0x0027, 0x0227, 0x02ef, 0x0127, - 0x0327, 0x00a7, 0x02a7, 0x01a7, 0x03a7, 0x06ef, 0x01ef, 0x05ef, - 0x0067, 0x03ef, 0x07ef, 0x0267, 0x0167, 0x0367, 0x00e7, 0x001f, - 0x041f, 0x021f, 0x061f, 0x02e7, 0x01e7, 0x03e7, 0x011f, 0x0017, - 0x0217, 0x051f, 0x031f, 0x0117, 0x0317, 0x0097, 0x0297, 0x071f, - 0x009f, 0x049f, 0x029f, 0x069f, 0x019f, 0x0197, 0x0397, 0x059f, - 0x039f, 0x0057, 0x0257, 0x0157, 0x0357, 0x079f, 0x005f, 0x045f, - 0x025f, 0x00d7, 0x02d7, 0x065f, 0x015f, 0x055f, 0x01d7, 0x035f, - 0x075f, 0x03d7, 0x0037, 0x00df, 0x04df, 0x02df, 0x06df, 0x01df, - 0x05df, 0x03df, 0x0237, 0x07df, 0x003f, 0x0137, 0x0337, 0x043f, - 0x023f, 0x063f, 0x00b7, 0x02b7, 0x01b7, 0x03b7, 0x0077, 0x013f, - 0x053f, 0x033f, 0x073f, 0x00bf, 0x0277, 0x0177, 0x04bf, 0x02bf, - 0x06bf, 0x01bf, 0x05bf, 0x0377, 0x00f7, 0x02f7, 0x01f7, 0x03f7, - 0x000f, 0x03bf, 0x07bf, 0x020f, 0x010f, 0x007f, 0x047f, 0x030f, - 0x027f, 0x067f, 0x017f, 0x057f, 0x037f, 0x077f, 0x00ff, 0x008f, - 0x04ff }, + 0x000c, 0x008c, 0x004c, 0x00cc, 0x002c, 0x00ac, 0x006c, 0x00ec, + 0x001c, 0x009c, 0x005c, 0x00dc, 0x003c, 0x00bc, 0x007c, 0x00fc, + 0x0002, 0x0082, 0x0042, 0x00c2, 0x0022, 0x00a2, 0x0062, 0x00e2, + 0x0012, 0x0092, 0x0052, 0x00d2, 0x0032, 0x00b2, 0x0072, 0x00f2, + 0x000a, 0x008a, 0x004a, 0x00ca, 0x002a, 0x00aa, 0x006a, 0x00ea, + 0x001a, 0x009a, 0x005a, 0x00da, 0x003a, 0x00ba, 0x007a, 0x00fa, + 0x0006, 0x0086, 0x0046, 0x00c6, 0x0026, 0x00a6, 0x0066, 0x00e6, + 0x0016, 0x0096, 0x0056, 0x00d6, 0x0036, 0x00b6, 0x0076, 0x00f6, + 0x000e, 0x008e, 0x004e, 0x00ce, 0x002e, 0x00ae, 0x006e, 0x00ee, + 0x001e, 0x009e, 0x005e, 0x00de, 0x003e, 0x00be, 0x007e, 0x00fe, + 0x0001, 0x0081, 0x0041, 0x00c1, 0x0021, 0x00a1, 0x0061, 0x00e1, + 0x0011, 0x0091, 0x0051, 0x00d1, 0x0031, 0x00b1, 0x0071, 0x00f1, + 0x0009, 0x0089, 0x0049, 0x00c9, 0x0029, 0x00a9, 0x0069, 0x00e9, + 0x0019, 0x0099, 0x0059, 0x00d9, 0x0039, 0x00b9, 0x0079, 0x00f9, + 0x0005, 0x0085, 0x0045, 0x00c5, 0x0025, 0x00a5, 0x0065, 0x00e5, + 0x0015, 0x0095, 0x0055, 0x00d5, 0x0035, 0x00b5, 0x0075, 0x00f5, + 0x000d, 0x008d, 0x004d, 0x00cd, 0x002d, 0x00ad, 0x006d, 0x00ed, + 0x001d, 0x009d, 0x005d, 0x00dd, 0x003d, 0x00bd, 0x007d, 0x00fd, + 0x0013, 0x0113, 0x0093, 0x0193, 0x0053, 0x0153, 0x00d3, 0x01d3, + 0x0033, 0x0133, 0x00b3, 0x01b3, 0x0073, 0x0173, 0x00f3, 0x01f3, + 0x000b, 0x010b, 0x008b, 0x018b, 0x004b, 0x014b, 0x00cb, 0x01cb, + 0x002b, 0x012b, 0x00ab, 0x01ab, 0x006b, 0x016b, 0x00eb, 0x01eb, + 0x001b, 0x011b, 0x009b, 0x019b, 0x005b, 0x015b, 0x00db, 0x01db, + 0x003b, 0x013b, 0x00bb, 0x01bb, 0x007b, 0x017b, 0x00fb, 0x01fb, + 0x0007, 0x0107, 0x0087, 0x0187, 0x0047, 0x0147, 0x00c7, 0x01c7, + 0x0027, 0x0127, 0x00a7, 0x01a7, 0x0067, 0x0167, 0x00e7, 0x01e7, + 0x0017, 0x0117, 0x0097, 0x0197, 0x0057, 0x0157, 0x00d7, 0x01d7, + 0x0037, 0x0137, 0x00b7, 0x01b7, 0x0077, 0x0177, 0x00f7, 0x01f7, + 0x000f, 0x010f, 0x008f, 0x018f, 0x004f, 0x014f, 0x00cf, 0x01cf, + 0x002f, 0x012f, 0x00af, 0x01af, 0x006f, 0x016f, 0x00ef, 0x01ef, + 0x001f, 0x011f, 0x009f, 0x019f, 0x005f, 0x015f, 0x00df, 0x01df, + 0x003f, 0x013f, 0x00bf, 0x01bf, 0x007f, 0x017f, 0x00ff, 0x01ff, + 0x0000}, .lit_table_sizes = { - 0xa, 0xb, 0xa, 0xb, 0xb, 0xa, 0xb, 0xa, - 0xb, 0x7, 0x6, 0xb, 0xa, 0xa, 0xb, 0xb, - 0xb, 0xb, 0xa, 0xb, 0xa, 0xa, 0xa, 0xa, - 0xb, 0xb, 0xa, 0xb, 0xa, 0xa, 0xb, 0xb, - 0x5, 0x8, 0x6, 0xa, 0xb, 0xa, 0x9, 0x7, - 0x6, 0x7, 0xa, 0x8, 0x7, 0x8, 0x6, 0x8, - 0x8, 0xb, 0x9, 0xa, 0x9, 0xb, 0xa, 0xb, - 0xb, 0xb, 0x9, 0x7, 0x9, 0x7, 0x9, 0xb, - 0xb, 0x8, 0x9, 0x8, 0x9, 0x8, 0x9, 0x9, - 0x8, 0x9, 0xb, 0xa, 0x9, 0x8, 0x9, 0x9, - 0x9, 0xa, 0x8, 0x8, 0x7, 0x9, 0x9, 0xb, - 0x8, 0xb, 0xa, 0x9, 0x9, 0x9, 0xa, 0x7, - 0xb, 0x6, 0x8, 0x6, 0x6, 0x5, 0x7, 0x7, - 0x7, 0x6, 0x9, 0x9, 0x6, 0x7, 0x6, 0x6, - 0x7, 0x9, 0x6, 0x6, 0x6, 0x6, 0x7, 0x7, - 0x8, 0x7, 0xb, 0x9, 0x9, 0x8, 0xb, 0xa, - 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, - 0xb, 0xb, 0xb, 0xb, 0xa, 0xa, 0xb, 0xa, - 0xa, 0xa, 0xa, 0xa, 0xa, 0xb, 0xb, 0xb, - 0xa, 0xb, 0xb, 0xa, 0xa, 0xa, 0xa, 0xb, - 0xb, 0xb, 0xb, 0xa, 0xa, 0xa, 0xb, 0xa, - 0xa, 0xb, 0xb, 0xa, 0xa, 0xa, 0xa, 0xb, - 0xb, 0xb, 0xb, 0xb, 0xb, 0xa, 0xa, 0xb, - 0xb, 0xa, 0xa, 0xa, 0xa, 0xb, 0xb, 0xb, - 0xb, 0xa, 0xa, 0xb, 0xb, 0xb, 0xa, 0xb, - 0xb, 0xa, 0xa, 0xb, 0xb, 0xb, 0xb, 0xb, - 0xb, 0xb, 0xa, 0xb, 0xb, 0xa, 0xa, 0xb, - 0xb, 0xb, 0xa, 0xa, 0xa, 0xa, 0xa, 0xb, - 0xb, 0xb, 0xb, 0xb, 0xa, 0xa, 0xb, 0xb, - 0xb, 0xb, 0xb, 0xa, 0xa, 0xa, 0xa, 0xa, - 0xa, 0xb, 0xb, 0xa, 0xa, 0xb, 0xb, 0xa, - 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xa, - 0xb }, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x07}, #ifndef LONGER_HUFFTABLE .dcodes = { - 0x000d, 0x001b, 0x0007, 0x0017, 0x00bf, 0x01bf, 0x007f, 0x017f, - 0x00ff, 0x01ff }, - .dcodes_sizes = { 0x4, 0x5, 0x5, 0x5, 0x9, 0x9, 0x9, 0x9,0x9, 0x9 } + 0x0000, 0x0010, 0x0008, 0x0018, 0x0004, 0x0014, 0x000c, 0x001c, + 0x0002, 0x0012, 0x000a, 0x001a, 0x0006, 0x0016, 0x000e, 0x001e, + 0x0001, 0x0011, 0x0009, 0x0019, 0x0005, 0x0015, 0x000d, 0x001d, + 0x0003, 0x0013, 0x000b, 0x001b, 0x0007, 0x0017}, + + .dcodes_sizes = { + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05} #else - .dcodes = { 0x007f, 0x017f, 0x00ff, 0x01ff }, - .dcodes_sizes = { 0x9, 0x9, 0x9, 0x9 } + .dcodes = { + 0x000b, 0x001b, 0x0007, 0x0017}, + + .dcodes_sizes = { + 0x05, 0x05, 0x05, 0x05} #endif }; diff --git a/ceph/src/isa-l/igzip/igzip.c b/ceph/src/isa-l/igzip/igzip.c index 94b0c3a0f..6ac1c1500 100644 --- a/ceph/src/isa-l/igzip/igzip.c +++ b/ceph/src/isa-l/igzip/igzip.c @@ -35,39 +35,37 @@ # include #endif -#ifndef IGZIP_USE_GZIP_FORMAT -# define DEFLATE 1 -#endif - #define MAX_WRITE_BITS_SIZE 8 #define FORCE_FLUSH 64 #define MIN_OBUF_SIZE 224 #define NON_EMPTY_BLOCK_SIZE 6 #define MAX_SYNC_FLUSH_SIZE NON_EMPTY_BLOCK_SIZE + MAX_WRITE_BITS_SIZE +#define MAX_TOKENS (16 * 1024) + #include "huffman.h" #include "bitbuf2.h" #include "igzip_lib.h" #include "repeated_char_result.h" +#include "huff_codes.h" +#include "encode_df.h" +#include "igzip_level_buf_structs.h" extern const uint8_t gzip_hdr[]; extern const uint32_t gzip_hdr_bytes; extern const uint32_t gzip_trl_bytes; extern const struct isal_hufftables hufftables_default; +extern const struct isal_hufftables hufftables_static; extern uint32_t crc32_gzip(uint32_t init_crc, const unsigned char *buf, uint64_t len); static int write_stored_block_stateless(struct isal_zstream *stream, uint32_t stored_len, uint32_t crc32); -#ifndef DEFLATE + static int write_gzip_header_stateless(struct isal_zstream *stream); -#endif +static void write_gzip_header(struct isal_zstream *stream); static int write_deflate_header_stateless(struct isal_zstream *stream); static int write_deflate_header_unaligned_stateless(struct isal_zstream *stream); -static int write_trailer_stateless(struct isal_zstream *stream, uint32_t avail_in, - uint32_t crc32); - -void isal_deflate_body_stateless(struct isal_zstream *stream); unsigned int detect_repeated_char(uint8_t * buf, uint32_t size); @@ -76,14 +74,16 @@ unsigned int detect_repeated_char(uint8_t * buf, uint32_t size); void isal_deflate_body(struct isal_zstream *stream); void isal_deflate_finish(struct isal_zstream *stream); -uint32_t crc_512to32_01(uint32_t * crc); -uint32_t get_crc(uint32_t * crc); +void isal_deflate_icf_body(struct isal_zstream *stream); +void isal_deflate_icf_finish(struct isal_zstream *stream); /*****************************************************************/ /* Forward declarations */ static inline void reset_match_history(struct isal_zstream *stream); -void write_header(struct isal_zstream *stream); +void write_header(struct isal_zstream *stream, uint8_t * deflate_hdr, + uint32_t deflate_hdr_count, uint32_t extra_bits_count, uint32_t next_state, + uint32_t toggle_end_of_stream); void write_deflate_header(struct isal_zstream *stream); void write_trailer(struct isal_zstream *stream); @@ -97,37 +97,34 @@ struct slver { struct slver isal_deflate_init_slver_01030081; struct slver isal_deflate_init_slver = { 0x0081, 0x03, 0x01 }; +struct slver isal_deflate_stateless_init_slver_00010084; +struct slver isal_deflate_stateless_init_slver = { 0x0084, 0x01, 0x00 }; + struct slver isal_deflate_slver_01030082; struct slver isal_deflate_slver = { 0x0082, 0x03, 0x01 }; struct slver isal_deflate_stateless_slver_01010083; struct slver isal_deflate_stateless_slver = { 0x0083, 0x01, 0x01 }; -/*****************************************************************/ - -uint32_t file_size(struct isal_zstate *state) -{ - return state->b_bytes_valid + (uint32_t) (state->buffer - state->file_start); -} +struct slver isal_deflate_set_hufftables_slver_00_01_008b; +struct slver isal_deflate_set_hufftables_slver = { 0x008b, 0x01, 0x00 }; +/*****************************************************************/ static void sync_flush(struct isal_zstream *stream) { struct isal_zstate *state = &stream->internal_state; uint64_t bits_to_write = 0xFFFF0000, bits_len; - uint64_t code = 0, len = 0, bytes; + uint64_t bytes; int flush_size; if (stream->avail_out >= 8) { set_buf(&state->bitbuf, stream->next_out, stream->avail_out); - if (!state->has_eob) - get_lit_code(stream->hufftables, 256, &code, &len); - - flush_size = (-(state->bitbuf.m_bit_count + len + 3)) % 8; + flush_size = (-(state->bitbuf.m_bit_count + 3)) % 8; bits_to_write <<= flush_size + 3; - bits_len = 32 + len + flush_size + 3; + bits_len = 32 + flush_size + 3; #ifdef USE_BITBUFB /* Write Bits Always */ state->state = ZSTATE_NEW_HDR; @@ -136,9 +133,6 @@ void sync_flush(struct isal_zstream *stream) #endif state->has_eob = 0; - if (len > 0) - bits_to_write = (bits_to_write << len) | code; - write_bits(&state->bitbuf, bits_to_write, bits_len); bytes = buffer_used(&state->bitbuf); @@ -149,6 +143,9 @@ void sync_flush(struct isal_zstream *stream) if (stream->flush == FULL_FLUSH) { /* Clear match history so there are no cross * block length distance pairs */ + state->file_start -= state->b_bytes_processed; + state->b_bytes_valid -= state->b_bytes_processed; + state->b_bytes_processed = 0; reset_match_history(stream); } } @@ -169,11 +166,122 @@ static void flush_write_buffer(struct isal_zstream *stream) } } -static void isal_deflate_int(struct isal_zstream *stream) +static void flush_icf_block(struct isal_zstream *stream) +{ + struct isal_zstate *state = &stream->internal_state; + struct level_2_buf *level_buf = (struct level_2_buf *)stream->level_buf; + struct BitBuf2 *write_buf = &state->bitbuf; + struct deflate_icf *icf_buf_encoded_next; + + set_buf(write_buf, stream->next_out, stream->avail_out); + +#if defined (USE_BITBUF8) || (USE_BITBUF_ELSE) + if (!is_full(write_buf)) + flush_bits(write_buf); +#endif + + icf_buf_encoded_next = encode_deflate_icf(level_buf->icf_buf_start + state->count, + level_buf->icf_buf_next, write_buf, + &level_buf->encode_tables); + + state->count = icf_buf_encoded_next - level_buf->icf_buf_start; + stream->next_out = buffer_ptr(write_buf); + stream->total_out += buffer_used(write_buf); + stream->avail_out -= buffer_used(write_buf); + + if (level_buf->icf_buf_next <= icf_buf_encoded_next) { + state->count = 0; + if (stream->avail_in == 0 && stream->end_of_stream) + state->state = ZSTATE_TRL; + else if (stream->avail_in == 0 && stream->flush != NO_FLUSH) + state->state = ZSTATE_SYNC_FLUSH; + else + state->state = ZSTATE_NEW_HDR; + } +} + +static void init_new_icf_block(struct isal_zstream *stream) +{ + struct isal_zstate *state = &stream->internal_state; + struct level_2_buf *level_buf = (struct level_2_buf *)stream->level_buf; + + if (stream->level_buf_size >= + sizeof(struct level_2_buf) + 100 * sizeof(struct deflate_icf)) { + level_buf->icf_buf_next = level_buf->icf_buf_start; + level_buf->icf_buf_avail_out = + stream->level_buf_size - sizeof(struct level_2_buf) - + sizeof(struct deflate_icf); + memset(&state->hist, 0, sizeof(struct isal_mod_hist)); + state->state = ZSTATE_BODY; + } +} + +static void create_icf_block_hdr(struct isal_zstream *stream) +{ + struct isal_zstate *state = &stream->internal_state; + struct level_2_buf *level_buf = (struct level_2_buf *)stream->level_buf; + struct BitBuf2 *write_buf = &state->bitbuf; + struct BitBuf2 write_buf_tmp; + uint32_t out_size = stream->avail_out; + uint8_t *end_out = stream->next_out + out_size; + /* Write EOB in icf_buf */ + state->hist.ll_hist[256] = 1; + level_buf->icf_buf_next->lit_len = 0x100; + level_buf->icf_buf_next->lit_dist = NULL_DIST_SYM; + level_buf->icf_buf_next->dist_extra = 0; + level_buf->icf_buf_next++; + + state->has_eob_hdr = stream->end_of_stream && !stream->avail_in; + if (end_out - stream->next_out >= ISAL_DEF_MAX_HDR_SIZE) { + /* Determine whether this is the final block */ + + if (stream->gzip_flag == IGZIP_GZIP) + write_gzip_header_stateless(stream); + + set_buf(write_buf, stream->next_out, stream->avail_out); + + create_hufftables_icf(write_buf, &level_buf->encode_tables, &state->hist, + state->has_eob_hdr); + state->state = ZSTATE_FLUSH_ICF_BUFFER; + stream->next_out = buffer_ptr(write_buf); + stream->total_out += buffer_used(write_buf); + stream->avail_out -= buffer_used(write_buf); + } else { + /* Start writing into temporary buffer */ + write_buf_tmp.m_bits = write_buf->m_bits; + write_buf_tmp.m_bit_count = write_buf->m_bit_count; + + write_buf->m_bits = 0; + write_buf->m_bit_count = 0; + + set_buf(&write_buf_tmp, level_buf->deflate_hdr, ISAL_DEF_MAX_HDR_SIZE); + + create_hufftables_icf(&write_buf_tmp, &level_buf->encode_tables, + &state->hist, state->has_eob_hdr); + + level_buf->deflate_hdr_count = buffer_used(&write_buf_tmp); + level_buf->deflate_hdr_extra_bits = write_buf_tmp.m_bit_count; + flush(&write_buf_tmp); + + state->state = ZSTATE_HDR; + } +} + +static void isal_deflate_pass(struct isal_zstream *stream) { struct isal_zstate *state = &stream->internal_state; - if (state->state == ZSTATE_NEW_HDR || state->state == ZSTATE_HDR) - write_header(stream); + struct isal_hufftables *hufftables = stream->hufftables; + uint8_t *start_in = stream->next_in; + + if (state->state == ZSTATE_NEW_HDR || state->state == ZSTATE_HDR) { + if (state->count == 0) + /* Assume the final header is being written since the header + * stored in hufftables is the final header. */ + state->has_eob_hdr = 1; + write_header(stream, hufftables->deflate_hdr, hufftables->deflate_hdr_count, + hufftables->deflate_hdr_extra_bits, ZSTATE_BODY, + !stream->end_of_stream); + } if (state->state == ZSTATE_BODY) isal_deflate_body(stream); @@ -187,14 +295,134 @@ static void isal_deflate_int(struct isal_zstream *stream) if (state->state == ZSTATE_FLUSH_WRITE_BUFFER) flush_write_buffer(stream); + if (stream->gzip_flag) + state->crc = crc32_gzip(state->crc, start_in, stream->next_in - start_in); + if (state->state == ZSTATE_TRL) write_trailer(stream); } -static uint32_t write_constant_compressed_stateless(struct isal_zstream *stream, - uint32_t repeated_char, - uint32_t repeated_length, - uint32_t end_of_stream) +static void isal_deflate_icf_pass(struct isal_zstream *stream) +{ + uint8_t *start_in = stream->next_in; + struct isal_zstate *state = &stream->internal_state; + struct level_2_buf *level_buf = (struct level_2_buf *)stream->level_buf; + + do { + if (state->state == ZSTATE_NEW_HDR) + init_new_icf_block(stream); + + if (state->state == ZSTATE_BODY) + isal_deflate_icf_body(stream); + + if (state->state == ZSTATE_FLUSH_READ_BUFFER) + isal_deflate_icf_finish(stream); + + if (state->state == ZSTATE_CREATE_HDR) + create_icf_block_hdr(stream); + + if (state->state == ZSTATE_HDR) + /* Note that the header may be prepended by the + * remaining bits in the previous block, as such the + * toggle header flag cannot be used */ + write_header(stream, level_buf->deflate_hdr, + level_buf->deflate_hdr_count, + level_buf->deflate_hdr_extra_bits, + ZSTATE_FLUSH_ICF_BUFFER, 0); + + if (state->state == ZSTATE_FLUSH_ICF_BUFFER) + flush_icf_block(stream); + + } while (state->state == ZSTATE_NEW_HDR); + + if (state->state == ZSTATE_SYNC_FLUSH) + sync_flush(stream); + + if (state->state == ZSTATE_FLUSH_WRITE_BUFFER) + flush_write_buffer(stream); + + if (stream->gzip_flag) + state->crc = crc32_gzip(state->crc, start_in, stream->next_in - start_in); + + if (state->state == ZSTATE_TRL) + write_trailer(stream); +} + +static void isal_deflate_int(struct isal_zstream *stream) +{ + struct isal_zstate *state = &stream->internal_state; + uint32_t size; + + /* Move data from temporary output buffer to output buffer */ + if (state->state >= ZSTATE_TMP_OFFSET) { + size = state->tmp_out_end - state->tmp_out_start; + if (size > stream->avail_out) + size = stream->avail_out; + memcpy(stream->next_out, state->tmp_out_buff + state->tmp_out_start, size); + stream->next_out += size; + stream->avail_out -= size; + stream->total_out += size; + state->tmp_out_start += size; + + if (state->tmp_out_start == state->tmp_out_end) + state->state -= ZSTATE_TMP_OFFSET; + + if (stream->avail_out == 0 || state->state == ZSTATE_END + // or do not write out empty blocks since the outbuffer was processed + || (state->state == ZSTATE_NEW_HDR && stream->avail_out == 0)) + return; + } + assert(state->tmp_out_start == state->tmp_out_end); + + if (stream->level == 0) + isal_deflate_pass(stream); + else + isal_deflate_icf_pass(stream); + + /* Fill temporary output buffer then complete filling output buffer */ + if (stream->avail_out > 0 && stream->avail_out < 8 && state->state != ZSTATE_NEW_HDR) { + uint8_t *next_out; + uint32_t avail_out; + uint32_t total_out; + + next_out = stream->next_out; + avail_out = stream->avail_out; + total_out = stream->total_out; + + stream->next_out = state->tmp_out_buff; + stream->avail_out = sizeof(state->tmp_out_buff); + stream->total_out = 0; + + if (stream->level == 0) + isal_deflate_pass(stream); + else + isal_deflate_icf_pass(stream); + + state->tmp_out_start = 0; + state->tmp_out_end = stream->total_out; + + stream->next_out = next_out; + stream->avail_out = avail_out; + stream->total_out = total_out; + if (state->tmp_out_end) { + size = state->tmp_out_end; + if (size > stream->avail_out) + size = stream->avail_out; + memcpy(stream->next_out, state->tmp_out_buff, size); + stream->next_out += size; + stream->avail_out -= size; + stream->total_out += size; + state->tmp_out_start += size; + if (state->tmp_out_start != state->tmp_out_end) + state->state += ZSTATE_TMP_OFFSET; + + } + } + +} + +static void write_constant_compressed_stateless(struct isal_zstream *stream, + uint32_t repeated_length) { /* Assumes repeated_length is at least 1. * Assumes the input end_of_stream is either 0 or 1. */ @@ -203,16 +431,24 @@ static uint32_t write_constant_compressed_stateless(struct isal_zstream *stream, uint32_t rep_bytes = rep_bits / 8; uint32_t rep_extra = (repeated_length - 1) % 258; uint32_t bytes; + uint32_t repeated_char = *stream->next_in; + uint8_t *start_in = stream->next_in; /* Guarantee there is enough space for the header even in the worst case */ if (stream->avail_out < HEADER_LENGTH + MAX_FIXUP_CODE_LENGTH + rep_bytes + 8) - return STATELESS_OVERFLOW; + return; /* Assumes the repeated char is either 0 or 0xFF. */ memcpy(stream->next_out, repeated_char_header[repeated_char & 1], HEADER_LENGTH); - if (end_of_stream > 0) + if (stream->avail_in == repeated_length && stream->end_of_stream > 0) { stream->next_out[0] |= 1; + state->has_eob_hdr = 1; + state->has_eob = 1; + state->state = ZSTATE_TRL; + } else { + state->state = ZSTATE_NEW_HDR; + } memset(stream->next_out + HEADER_LENGTH, 0, rep_bytes); stream->avail_out -= HEADER_LENGTH + rep_bytes; @@ -239,8 +475,8 @@ static uint32_t write_constant_compressed_stateless(struct isal_zstream *stream, if (rep_extra >= 230) { write_bits(&state->bitbuf, - CODE_280 | ((rep_extra / 2 - 115) << CODE_280_LENGTH), - CODE_280_TOTAL_LENGTH); + CODE_280 | ((rep_extra / 2 - 115) << + CODE_280_LENGTH), CODE_280_TOTAL_LENGTH); rep_extra -= rep_extra / 2; } @@ -270,7 +506,10 @@ static uint32_t write_constant_compressed_stateless(struct isal_zstream *stream, stream->avail_out -= bytes; stream->total_out += bytes; - return COMP_OK; + if (stream->gzip_flag) + state->crc = crc32_gzip(state->crc, start_in, stream->next_in - start_in); + + return; } int detect_repeated_char_length(uint8_t * in, uint32_t length) @@ -291,64 +530,58 @@ int detect_repeated_char_length(uint8_t * in, uint32_t length) return p_8 - in; } -static int isal_deflate_int_stateless(struct isal_zstream *stream, uint8_t * next_in, - const uint32_t avail_in) +static int isal_deflate_int_stateless(struct isal_zstream *stream) { - uint32_t crc32 = 0; - uint32_t repeated_char_length; + uint32_t repeat_length; + struct isal_zstate *state = &stream->internal_state; -#ifndef DEFLATE - if (write_gzip_header_stateless(stream)) - return STATELESS_OVERFLOW; -#endif + if (stream->gzip_flag == IGZIP_GZIP) + if (write_gzip_header_stateless(stream)) + return STATELESS_OVERFLOW; - if (avail_in >= 8 + if (stream->avail_in >= 8 && (*(uint64_t *) stream->next_in == 0 - || *(uint64_t *) stream->next_in == ~(uint64_t) 0)) - repeated_char_length = - detect_repeated_char_length(stream->next_in, stream->avail_in); - else - repeated_char_length = 0; + || *(uint64_t *) stream->next_in == ~(uint64_t) 0)) { + repeat_length = detect_repeated_char_length(stream->next_in, stream->avail_in); - if (stream->avail_in == repeated_char_length) { - if (write_constant_compressed_stateless(stream, - stream->next_in[0], - repeated_char_length, 1) != COMP_OK) - return STATELESS_OVERFLOW; + if (stream->avail_in == repeat_length || repeat_length >= MIN_REPEAT_LEN) + write_constant_compressed_stateless(stream, repeat_length); + } -#ifndef DEFLATE - crc32 = crc32_gzip(0x0, next_in, avail_in); -#endif + if (stream->level == 0) { + if (state->state == ZSTATE_NEW_HDR || state->state == ZSTATE_HDR) { + write_deflate_header_unaligned_stateless(stream); + if (state->state == ZSTATE_NEW_HDR || state->state == ZSTATE_HDR) + return STATELESS_OVERFLOW; - /* write_trailer_stateless is required because if flushes out the last of the output */ - if (write_trailer_stateless(stream, avail_in, crc32) != COMP_OK) - return STATELESS_OVERFLOW; - return COMP_OK; + reset_match_history(stream); + } - } else if (repeated_char_length >= MIN_REPEAT_LEN) { - if (write_constant_compressed_stateless - (stream, stream->next_in[0], repeated_char_length, 0) != COMP_OK) - return STATELESS_OVERFLOW; - } + state->file_start = stream->next_in - stream->total_in; + isal_deflate_pass(stream); - if (write_deflate_header_unaligned_stateless(stream) != COMP_OK) - return STATELESS_OVERFLOW; - if (stream->avail_out < 8) - return STATELESS_OVERFLOW; + } else if (stream->level == 1) { + if (stream->level_buf == NULL || stream->level_buf_size < ISAL_DEF_LVL1_MIN) { + /* Default to internal buffer if invalid size is supplied */ + stream->level_buf = state->buffer; + stream->level_buf_size = sizeof(state->buffer); + } - isal_deflate_body_stateless(stream); + if (state->state == ZSTATE_NEW_HDR || state->state == ZSTATE_HDR) + reset_match_history(stream); - if (!stream->internal_state.has_eob) - return STATELESS_OVERFLOW; + state->count = 0; + state->file_start = stream->next_in - stream->total_in; + isal_deflate_icf_pass(stream); -#ifndef DEFLATE - crc32 = crc32_gzip(0x0, next_in, avail_in); -#endif + } else + return ISAL_INVALID_LEVEL; - if (write_trailer_stateless(stream, avail_in, crc32) != COMP_OK) + if (state->state == ZSTATE_END + || (state->state == ZSTATE_NEW_HDR && stream->flush == FULL_FLUSH)) + return COMP_OK; + else return STATELESS_OVERFLOW; - - return COMP_OK; } static int write_stored_block_stateless(struct isal_zstream *stream, @@ -357,10 +590,7 @@ static int write_stored_block_stateless(struct isal_zstream *stream, uint64_t stored_blk_hdr; uint32_t copy_size; uint32_t avail_in; - -#ifndef DEFLATE uint64_t gzip_trl; -#endif if (stream->avail_out < stored_len) return STATELESS_OVERFLOW; @@ -369,10 +599,11 @@ static int write_stored_block_stateless(struct isal_zstream *stream, stream->total_out += stored_len; avail_in = stream->avail_in; -#ifndef DEFLATE - memcpy(stream->next_out, gzip_hdr, gzip_hdr_bytes); - stream->next_out += gzip_hdr_bytes; -#endif + if (stream->gzip_flag == IGZIP_GZIP) { + memcpy(stream->next_out, gzip_hdr, gzip_hdr_bytes); + stream->next_out += gzip_hdr_bytes; + stream->gzip_flag = IGZIP_GZIP_NO_HDR; + } do { if (avail_in >= STORED_BLK_MAX_BZ) { @@ -388,9 +619,12 @@ static int write_stored_block_stateless(struct isal_zstream *stream, avail_in -= copy_size; /* Handle BFINAL bit */ - if (avail_in == 0) - stored_blk_hdr |= 0x1; - + if (avail_in == 0) { + if (stream->flush == NO_FLUSH || stream->end_of_stream) { + stored_blk_hdr |= 0x1; + stream->internal_state.has_eob_hdr = 1; + } + } memcpy(stream->next_out, &stored_blk_hdr, STORED_BLK_HDR_BZ); stream->next_out += STORED_BLK_HDR_BZ; @@ -400,13 +634,13 @@ static int write_stored_block_stateless(struct isal_zstream *stream, stream->total_in += copy_size; } while (avail_in != 0); -#ifndef DEFLATE - gzip_trl = stream->avail_in; - gzip_trl <<= 32; - gzip_trl |= crc32 & 0xFFFFFFFF; - memcpy(stream->next_out, &gzip_trl, gzip_trl_bytes); - stream->next_out += gzip_trl_bytes; -#endif + if (stream->gzip_flag && stream->internal_state.has_eob_hdr) { + gzip_trl = stream->avail_in; + gzip_trl <<= 32; + gzip_trl |= crc32 & 0xFFFFFFFF; + memcpy(stream->next_out, &gzip_trl, gzip_trl_bytes); + stream->next_out += gzip_trl_bytes; + } stream->avail_in = 0; return COMP_OK; @@ -418,43 +652,90 @@ static inline void reset_match_history(struct isal_zstream *stream) uint16_t *head = stream->internal_state.head; int i = 0; - for (i = 0; i < sizeof(state->head) / 2; i++) - head[i] = - (uint16_t) (state->b_bytes_processed + state->buffer - state->file_start - - (IGZIP_D + 1)); + state->has_hist = 0; + + if (stream->total_in == 0) + memset(stream->internal_state.head, 0, sizeof(stream->internal_state.head)); + else { + for (i = 0; i < sizeof(state->head) / 2; i++) { + head[i] = (uint16_t) (stream->total_in); + } + } } -void isal_deflate_init_01(struct isal_zstream *stream) +void isal_deflate_init(struct isal_zstream *stream) { struct isal_zstate *state = &stream->internal_state; stream->total_in = 0; stream->total_out = 0; stream->hufftables = (struct isal_hufftables *)&hufftables_default; - stream->flush = 0; + stream->level = 0; + stream->level_buf = NULL; + stream->level_buf_size = 0; + stream->end_of_stream = 0; + stream->flush = NO_FLUSH; + stream->gzip_flag = 0; state->b_bytes_valid = 0; state->b_bytes_processed = 0; state->has_eob = 0; state->has_eob_hdr = 0; - state->left_over = 0; - state->last_flush = 0; - state->has_gzip_hdr = 0; + state->has_hist = 0; state->state = ZSTATE_NEW_HDR; state->count = 0; state->tmp_out_start = 0; state->tmp_out_end = 0; - state->file_start = state->buffer; + state->file_start = stream->next_in; init(&state->bitbuf); - memset(state->crc, 0, sizeof(state->crc)); - *state->crc = 0x9db42487; + state->crc = 0; + + memset(state->head, 0, sizeof(state->head)); - reset_match_history(stream); + return; +} +int isal_deflate_set_hufftables(struct isal_zstream *stream, + struct isal_hufftables *hufftables, int type) +{ + if (stream->internal_state.state != ZSTATE_NEW_HDR) + return ISAL_INVALID_OPERATION; + + switch (type) { + case IGZIP_HUFFTABLE_DEFAULT: + stream->hufftables = (struct isal_hufftables *)&hufftables_default; + break; + case IGZIP_HUFFTABLE_STATIC: + stream->hufftables = (struct isal_hufftables *)&hufftables_static; + break; + case IGZIP_HUFFTABLE_CUSTOM: + if (hufftables != NULL) { + stream->hufftables = hufftables; + break; + } + default: + return ISAL_INVALID_OPERATION; + } + + return COMP_OK; +} + +void isal_deflate_stateless_init(struct isal_zstream *stream) +{ + stream->total_in = 0; + stream->total_out = 0; + stream->hufftables = (struct isal_hufftables *)&hufftables_default; + stream->level = 0; + stream->level_buf = NULL; + stream->level_buf_size = 0; + stream->end_of_stream = 0; + stream->flush = NO_FLUSH; + stream->gzip_flag = 0; + stream->internal_state.state = ZSTATE_NEW_HDR; return; } @@ -462,15 +743,30 @@ int isal_deflate_stateless(struct isal_zstream *stream) { uint8_t *next_in = stream->next_in; const uint32_t avail_in = stream->avail_in; + const uint32_t total_in = stream->total_in; uint8_t *next_out = stream->next_out; const uint32_t avail_out = stream->avail_out; + const uint32_t total_out = stream->total_out; + const uint32_t gzip_flag = stream->gzip_flag; uint32_t crc32 = 0; uint32_t stored_len; - uint32_t dyn_min_len; - uint32_t min_len; - uint32_t select_stored_blk = 0; + + /* Final block has already been written */ + stream->internal_state.has_eob_hdr = 0; + init(&stream->internal_state.bitbuf); + stream->internal_state.state = ZSTATE_NEW_HDR; + stream->internal_state.crc = 0; + + if (stream->flush == NO_FLUSH) + stream->end_of_stream = 1; + + if (stream->flush != NO_FLUSH && stream->flush != FULL_FLUSH) + return INVALID_FLUSH; + + if (stream->level != 0 && stream->level != 1) + return ISAL_INVALID_LEVEL; if (avail_in == 0) stored_len = STORED_BLK_HDR_BZ; @@ -484,125 +780,146 @@ int isal_deflate_stateless(struct isal_zstream *stream) contains the EOB */ - dyn_min_len = stream->hufftables->deflate_hdr_count + 1; -#ifndef DEFLATE - dyn_min_len += gzip_hdr_bytes + gzip_trl_bytes + 1; - stored_len += gzip_hdr_bytes + gzip_trl_bytes; -#endif - - min_len = dyn_min_len; + if (stream->gzip_flag == IGZIP_GZIP) + stored_len += gzip_hdr_bytes + gzip_trl_bytes; - if (stored_len < dyn_min_len) { - min_len = stored_len; - select_stored_blk = 1; - } + else if (stream->gzip_flag == IGZIP_GZIP_NO_HDR) + stored_len += gzip_trl_bytes; /* the output buffer should be no less than 8 bytes while empty stored deflate block is 5 bytes only */ - if (avail_out < min_len || stream->avail_out < 8) + if (stream->avail_out < 8) return STATELESS_OVERFLOW; - if (!select_stored_blk) { - if (isal_deflate_int_stateless(stream, next_in, avail_in) == COMP_OK) - return COMP_OK; + if (isal_deflate_int_stateless(stream) == COMP_OK) + return COMP_OK; + else { + if (stream->flush == FULL_FLUSH) { + stream->internal_state.file_start = + (uint8_t *) & stream->internal_state.buffer; + reset_match_history(stream); + } + stream->internal_state.has_eob_hdr = 0; } + if (avail_out < stored_len) return STATELESS_OVERFLOW; - isal_deflate_init(stream); - stream->next_in = next_in; stream->avail_in = avail_in; - stream->total_in = 0; + stream->total_in = total_in; stream->next_out = next_out; stream->avail_out = avail_out; - stream->total_out = 0; + stream->total_out = total_out; + + stream->gzip_flag = gzip_flag; + + if (stream->gzip_flag) + crc32 = crc32_gzip(0x0, next_in, avail_in); -#ifndef DEFLATE - crc32 = crc32_gzip(0x0, next_in, avail_in); -#endif return write_stored_block_stateless(stream, stored_len, crc32); } int isal_deflate(struct isal_zstream *stream) { struct isal_zstate *state = &stream->internal_state; - uint32_t size; int ret = COMP_OK; + uint8_t *next_in; + uint32_t avail_in, avail_in_start; + uint32_t flush_type = stream->flush; + uint32_t end_of_stream = stream->end_of_stream; + int size = 0; + uint8_t *copy_down_src = NULL; + uint64_t copy_down_size = 0; + int32_t processed = -(state->b_bytes_valid - state->b_bytes_processed); + + if (stream->flush >= 3) + return INVALID_FLUSH; + + next_in = stream->next_in; + avail_in = stream->avail_in; + stream->total_in -= state->b_bytes_valid - state->b_bytes_processed; - if (stream->flush < 3) { + do { + size = avail_in; + if (size > sizeof(state->buffer) - state->b_bytes_valid) { + size = sizeof(state->buffer) - state->b_bytes_valid; + stream->flush = NO_FLUSH; + stream->end_of_stream = 0; + } + memcpy(&state->buffer[state->b_bytes_valid], next_in, size); - state->last_flush = stream->flush; + next_in += size; + avail_in -= size; + state->b_bytes_valid += size; - if (state->state >= TMP_OFFSET_SIZE) { - size = state->tmp_out_end - state->tmp_out_start; - if (size > stream->avail_out) - size = stream->avail_out; - memcpy(stream->next_out, state->tmp_out_buff + state->tmp_out_start, - size); - stream->next_out += size; - stream->avail_out -= size; - stream->total_out += size; - state->tmp_out_start += size; + stream->next_in = &state->buffer[state->b_bytes_processed]; + stream->avail_in = state->b_bytes_valid - state->b_bytes_processed; + state->file_start = stream->next_in - stream->total_in; + processed += stream->avail_in; - if (state->tmp_out_start == state->tmp_out_end) - state->state -= TMP_OFFSET_SIZE; + if (stream->avail_in > IGZIP_HIST_SIZE + || stream->end_of_stream || stream->flush != NO_FLUSH) { + avail_in_start = stream->avail_in; + isal_deflate_int(stream); + state->b_bytes_processed += avail_in_start - stream->avail_in; + + if (state->b_bytes_processed > IGZIP_HIST_SIZE) { + copy_down_src = + &state->buffer[state->b_bytes_processed - IGZIP_HIST_SIZE]; + copy_down_size = + state->b_bytes_valid - state->b_bytes_processed + + IGZIP_HIST_SIZE; + memmove(state->buffer, copy_down_src, copy_down_size); + + state->b_bytes_valid -= copy_down_src - state->buffer; + state->b_bytes_processed -= copy_down_src - state->buffer; + } - if (stream->avail_out == 0 || state->state == ZSTATE_END) - return ret; } - assert(state->tmp_out_start == state->tmp_out_end); - isal_deflate_int(stream); + stream->flush = flush_type; + stream->end_of_stream = end_of_stream; + processed -= stream->avail_in; + } while (processed < IGZIP_HIST_SIZE + ISAL_LOOK_AHEAD && avail_in > 0 + && stream->avail_out > 0); - if (stream->avail_out == 0) - return ret; + if (processed >= IGZIP_HIST_SIZE + ISAL_LOOK_AHEAD) { + stream->next_in = next_in - stream->avail_in; + stream->avail_in = avail_in + stream->avail_in; - else if (stream->avail_out < 8) { - uint8_t *next_out; - uint32_t avail_out; - uint32_t total_out; + state->file_start = stream->next_in - stream->total_in; - next_out = stream->next_out; - avail_out = stream->avail_out; - total_out = stream->total_out; + if (stream->avail_in > 0 && stream->avail_out > 0) + isal_deflate_int(stream); - stream->next_out = state->tmp_out_buff; - stream->avail_out = sizeof(state->tmp_out_buff); - stream->total_out = 0; + size = stream->avail_in; + if (stream->avail_in > IGZIP_HIST_SIZE) + size = 0; - isal_deflate_int(stream); + memmove(state->buffer, stream->next_in - IGZIP_HIST_SIZE, + size + IGZIP_HIST_SIZE); + state->b_bytes_processed = IGZIP_HIST_SIZE; + state->b_bytes_valid = size + IGZIP_HIST_SIZE; - state->tmp_out_start = 0; - state->tmp_out_end = stream->total_out; - - stream->next_out = next_out; - stream->avail_out = avail_out; - stream->total_out = total_out; - if (state->tmp_out_end) { - size = state->tmp_out_end; - if (size > stream->avail_out) - size = stream->avail_out; - memcpy(stream->next_out, state->tmp_out_buff, size); - stream->next_out += size; - stream->avail_out -= size; - stream->total_out += size; - state->tmp_out_start += size; - if (state->tmp_out_start != state->tmp_out_end) - state->state += TMP_OFFSET_SIZE; + stream->next_in += size; + stream->avail_in -= size; + stream->total_in += size; - } - } - } else - ret = INVALID_FLUSH; + } else { + stream->total_in += state->b_bytes_valid - state->b_bytes_processed; + stream->next_in = next_in; + stream->avail_in = avail_in; + state->file_start = stream->next_in - stream->total_in; + + } return ret; } -#ifndef DEFLATE static int write_gzip_header_stateless(struct isal_zstream *stream) { if (gzip_hdr_bytes >= stream->avail_out) @@ -614,6 +931,7 @@ static int write_gzip_header_stateless(struct isal_zstream *stream) memcpy(stream->next_out, gzip_hdr, gzip_hdr_bytes); stream->next_out += gzip_hdr_bytes; + stream->gzip_flag = IGZIP_GZIP_NO_HDR; return COMP_OK; } @@ -633,7 +951,7 @@ static void write_gzip_header(struct isal_zstream *stream) if (state->count == gzip_hdr_bytes) { state->count = 0; - state->has_gzip_hdr = 1; + stream->gzip_flag = IGZIP_GZIP_NO_HDR; } stream->avail_out -= bytes_to_write; @@ -641,12 +959,12 @@ static void write_gzip_header(struct isal_zstream *stream) stream->next_out += bytes_to_write; } -#endif static int write_deflate_header_stateless(struct isal_zstream *stream) { struct isal_zstate *state = &stream->internal_state; struct isal_hufftables *hufftables = stream->hufftables; + uint64_t hdr_extra_bits = hufftables->deflate_hdr[hufftables->deflate_hdr_count]; uint32_t count; if (hufftables->deflate_hdr_count + 8 >= stream->avail_out) @@ -654,20 +972,29 @@ static int write_deflate_header_stateless(struct isal_zstream *stream) memcpy(stream->next_out, hufftables->deflate_hdr, hufftables->deflate_hdr_count); + if (stream->end_of_stream == 0) { + if (hufftables->deflate_hdr_count > 0) + *stream->next_out -= 1; + else + hdr_extra_bits -= 1; + } else + state->has_eob_hdr = 1; + stream->avail_out -= hufftables->deflate_hdr_count; stream->total_out += hufftables->deflate_hdr_count; stream->next_out += hufftables->deflate_hdr_count; set_buf(&state->bitbuf, stream->next_out, stream->avail_out); - write_bits(&state->bitbuf, hufftables->deflate_hdr[hufftables->deflate_hdr_count], - hufftables->deflate_hdr_extra_bits); + write_bits(&state->bitbuf, hdr_extra_bits, hufftables->deflate_hdr_extra_bits); count = buffer_used(&state->bitbuf); stream->next_out = buffer_ptr(&state->bitbuf); stream->avail_out -= count; stream->total_out += count; + state->state = ZSTATE_BODY; + return COMP_OK; } @@ -692,15 +1019,23 @@ static int write_deflate_header_unaligned_stateless(struct isal_zstream *stream) header_next = (uint64_t *) hufftables->deflate_hdr; header_end = header_next + hufftables->deflate_hdr_count / 8; + header_bits = *header_next; + + if (stream->end_of_stream == 0) + header_bits--; + else + state->has_eob_hdr = 1; + + header_next++; + /* Write out Complete Header bits */ - for (; header_next < header_end; header_next++) { - header_bits = *header_next; + for (; header_next <= header_end; header_next++) { write_bits(&state->bitbuf, header_bits, 32); header_bits >>= 32; write_bits(&state->bitbuf, header_bits, 32); + header_bits = *header_next; } - header_bits = *header_next; bit_count = (hufftables->deflate_hdr_count & 0x7) * 8 + hufftables->deflate_hdr_extra_bits; @@ -723,15 +1058,19 @@ static int write_deflate_header_unaligned_stateless(struct isal_zstream *stream) stream->avail_out -= count; stream->total_out += count; + state->state = ZSTATE_BODY; + return COMP_OK; } -void write_header(struct isal_zstream *stream) +/* Toggle end of stream only works when deflate header is aligned */ +void write_header(struct isal_zstream *stream, uint8_t * deflate_hdr, + uint32_t deflate_hdr_count, uint32_t extra_bits_count, uint32_t next_state, + uint32_t toggle_end_of_stream) { struct isal_zstate *state = &stream->internal_state; - struct isal_hufftables *hufftables = stream->hufftables; + uint32_t hdr_extra_bits = deflate_hdr[deflate_hdr_count]; uint32_t count; - state->state = ZSTATE_HDR; if (state->bitbuf.m_bit_count != 0) { @@ -744,24 +1083,22 @@ void write_header(struct isal_zstream *stream) stream->avail_out -= count; stream->total_out += count; } -#ifndef DEFLATE - if (!state->has_gzip_hdr) + + if (stream->gzip_flag == IGZIP_GZIP) write_gzip_header(stream); -#endif - count = hufftables->deflate_hdr_count - state->count; + count = deflate_hdr_count - state->count; if (count != 0) { if (count > stream->avail_out) count = stream->avail_out; - memcpy(stream->next_out, hufftables->deflate_hdr + state->count, count); + memcpy(stream->next_out, deflate_hdr + state->count, count); - if (state->count == 0 && count > 0) { - if (!stream->end_of_stream) - *stream->next_out &= 0xfe; - else - state->has_eob_hdr = 1; + if (toggle_end_of_stream && state->count == 0 && count > 0) { + /* Assumes the final block bit is the first bit */ + *stream->next_out ^= 1; + state->has_eob_hdr = !state->has_eob_hdr; } stream->next_out += count; @@ -769,18 +1106,20 @@ void write_header(struct isal_zstream *stream) stream->total_out += count; state->count += count; - count = hufftables->deflate_hdr_count - state->count; + count = deflate_hdr_count - state->count; + } else if (toggle_end_of_stream && deflate_hdr_count == 0) { + /* Assumes the final block bit is the first bit */ + hdr_extra_bits ^= 1; + state->has_eob_hdr = !state->has_eob_hdr; } if ((count == 0) && (stream->avail_out >= 8)) { set_buf(&state->bitbuf, stream->next_out, stream->avail_out); - write_bits(&state->bitbuf, - hufftables->deflate_hdr[hufftables->deflate_hdr_count], - hufftables->deflate_hdr_extra_bits); + write_bits(&state->bitbuf, hdr_extra_bits, extra_bits_count); - state->state = ZSTATE_BODY; + state->state = next_state; state->count = 0; count = buffer_used(&state->bitbuf); @@ -791,15 +1130,11 @@ void write_header(struct isal_zstream *stream) } -uint32_t get_crc_01(uint32_t * crc) -{ - return crc_512to32_01(crc); -} - void write_trailer(struct isal_zstream *stream) { struct isal_zstate *state = &stream->internal_state; unsigned int bytes; + uint32_t crc = state->crc; if (stream->avail_out >= 8) { set_buf(&state->bitbuf, stream->next_out, stream->avail_out); @@ -828,55 +1163,18 @@ void write_trailer(struct isal_zstream *stream) stream->next_out = buffer_ptr(&state->bitbuf); bytes = buffer_used(&state->bitbuf); -#ifndef DEFLATE - uint32_t *crc = state->crc; - - if (!is_full(&state->bitbuf)) { - *(uint64_t *) stream->next_out = - ((uint64_t) file_size(state) << 32) | get_crc(crc); - stream->next_out += 8; - bytes += 8; + if (stream->gzip_flag) { + if (!is_full(&state->bitbuf)) { + *(uint64_t *) stream->next_out = + ((uint64_t) stream->total_in << 32) | crc; + stream->next_out += 8; + bytes += 8; + state->state = ZSTATE_END; + } + } else state->state = ZSTATE_END; - } -#else - state->state = ZSTATE_END; -#endif - - stream->avail_out -= bytes; - stream->total_out += bytes; - } -} - -static int write_trailer_stateless(struct isal_zstream *stream, uint32_t avail_in, - uint32_t crc32) -{ - int ret = COMP_OK; - struct isal_zstate *state = &stream->internal_state; - unsigned int bytes; - - if (stream->avail_out < 8) { - ret = STATELESS_OVERFLOW; - } else { - set_buf(&state->bitbuf, stream->next_out, stream->avail_out); - /* the flush() will pad to the next byte and write up to 8 bytes - * to the output stream/buffer. - */ - flush(&state->bitbuf); - stream->next_out = buffer_ptr(&state->bitbuf); - bytes = buffer_used(&state->bitbuf); -#ifndef DEFLATE - if (is_full(&state->bitbuf)) { - ret = STATELESS_OVERFLOW; - } else { - *(uint64_t *) stream->next_out = ((uint64_t) avail_in << 32) | crc32; - stream->next_out += 8; - bytes += 8; - } -#endif stream->avail_out -= bytes; stream->total_out += bytes; } - - return ret; } diff --git a/ceph/src/isa-l/igzip/igzip_base.c b/ceph/src/isa-l/igzip/igzip_base.c index 49bf0b157..0e2b70506 100644 --- a/ceph/src/isa-l/igzip/igzip_base.c +++ b/ceph/src/isa-l/igzip/igzip_base.c @@ -6,52 +6,15 @@ extern const struct isal_hufftables hufftables_default; -void isal_deflate_init_base(struct isal_zstream *stream) +static inline void update_state(struct isal_zstream *stream, uint8_t * start_in, + uint8_t * next_in, uint8_t * end_in) { struct isal_zstate *state = &stream->internal_state; - int i; - - uint32_t *crc = state->crc; - - stream->total_in = 0; - stream->total_out = 0; - stream->hufftables = (struct isal_hufftables *)&hufftables_default; - stream->flush = 0; - state->b_bytes_valid = 0; - state->b_bytes_processed = 0; - state->has_eob = 0; - state->has_eob_hdr = 0; - state->left_over = 0; - state->last_flush = 0; - state->has_gzip_hdr = 0; - state->state = ZSTATE_NEW_HDR; - state->count = 0; - - state->tmp_out_start = 0; - state->tmp_out_end = 0; - - state->file_start = state->buffer; - - init(&state->bitbuf); - - *crc = ~0; - - for (i = 0; i < HASH_SIZE; i++) - state->head[i] = (uint16_t) - (IGZIP_D + 1); - return; -} - -uint32_t get_crc_base(uint32_t * crc) -{ - return ~*crc; -} - -static inline void update_state(struct isal_zstream *stream, struct isal_zstate *state, - uint8_t * start_in) -{ uint32_t bytes_written; - stream->total_in += stream->next_in - start_in; + stream->next_in = next_in; + stream->total_in += next_in - start_in; + stream->avail_in = end_in - next_in; bytes_written = buffer_used(&state->bitbuf); stream->total_out += bytes_written; @@ -65,11 +28,10 @@ void isal_deflate_body_base(struct isal_zstream *stream) uint32_t literal, hash; uint8_t *start_in, *next_in, *end_in, *end, *next_hash; uint16_t match_length; - uint32_t dist, bytes_to_buffer, offset; + uint32_t dist; uint64_t code, code_len, code2, code_len2; struct isal_zstate *state = &stream->internal_state; uint16_t *last_seen = state->head; - uint32_t *crc = state->crc; if (stream->avail_in == 0) { if (stream->end_of_stream || stream->flush != NO_FLUSH) @@ -78,61 +40,95 @@ void isal_deflate_body_base(struct isal_zstream *stream) } set_buf(&state->bitbuf, stream->next_out, stream->avail_out); + start_in = stream->next_in; + end_in = start_in + stream->avail_in; + next_in = start_in; + + while (next_in + ISAL_LOOK_AHEAD < end_in) { + + if (is_full(&state->bitbuf)) { + update_state(stream, start_in, next_in, end_in); + return; + } + + literal = *(uint32_t *) next_in; + hash = compute_hash(literal) & HASH_MASK; + dist = (next_in - state->file_start - last_seen[hash]) & 0xFFFF; + last_seen[hash] = (uint64_t) (next_in - state->file_start); + + /* The -1 are to handle the case when dist = 0 */ + if (dist - 1 < IGZIP_HIST_SIZE - 1) { + assert(dist != 0); + + match_length = compare258(next_in - dist, next_in, 258); + + if (match_length >= SHORTEST_MATCH) { + next_hash = next_in; +#ifdef ISAL_LIMIT_HASH_UPDATE + end = next_hash + 3; +#else + end = next_hash + match_length; +#endif + next_hash++; - while (stream->avail_in != 0) { - bytes_to_buffer = - IGZIP_D + IGZIP_LA - (state->b_bytes_valid - state->b_bytes_processed); - - if (bytes_to_buffer > IGZIP_D) - bytes_to_buffer = IGZIP_D; - - if (stream->avail_in < IGZIP_D) - bytes_to_buffer = stream->avail_in; - - if (bytes_to_buffer > BSIZE - state->b_bytes_valid) { - if (state->b_bytes_valid - state->b_bytes_processed > IGZIP_LA) { - /* There was an out buffer overflow last round, - * complete the processing of data */ - bytes_to_buffer = 0; - - } else { - /* Not enough room in the buffer, shift the - * buffer down to make space for the new data */ - offset = state->b_bytes_processed - IGZIP_D; // state->b_bytes_valid - (IGZIP_D + IGZIP_LA); - memmove(state->buffer, state->buffer + offset, - IGZIP_D + IGZIP_LA); - - state->b_bytes_processed -= offset; - state->b_bytes_valid -= offset; - state->file_start -= offset; - - stream->avail_in -= bytes_to_buffer; - memcpy(state->buffer + state->b_bytes_valid, stream->next_in, - bytes_to_buffer); - update_crc(crc, stream->next_in, bytes_to_buffer); - stream->next_in += bytes_to_buffer; + for (; next_hash < end; next_hash++) { + literal = *(uint32_t *) next_hash; + hash = compute_hash(literal) & HASH_MASK; + last_seen[hash] = + (uint64_t) (next_hash - state->file_start); + } + + get_len_code(stream->hufftables, match_length, &code, + &code_len); + get_dist_code(stream->hufftables, dist, &code2, &code_len2); + + code |= code2 << code_len; + code_len += code_len2; + + write_bits(&state->bitbuf, code, code_len); + + next_in += match_length; + + continue; } - } else { - /* There is enough space in the buffer, copy in the new data */ - stream->avail_in -= bytes_to_buffer; - memcpy(state->buffer + state->b_bytes_valid, stream->next_in, - bytes_to_buffer); - update_crc(crc, stream->next_in, bytes_to_buffer); - stream->next_in += bytes_to_buffer; } - state->b_bytes_valid += bytes_to_buffer; + get_lit_code(stream->hufftables, literal & 0xFF, &code, &code_len); + write_bits(&state->bitbuf, code, code_len); + next_in++; + } - end_in = state->buffer + state->b_bytes_valid - IGZIP_LA; + update_state(stream, start_in, next_in, end_in); - next_in = state->b_bytes_processed + state->buffer; + assert(stream->avail_in <= ISAL_LOOK_AHEAD); + if (stream->end_of_stream || stream->flush != NO_FLUSH) + state->state = ZSTATE_FLUSH_READ_BUFFER; - while (next_in < end_in) { + return; + +} +void isal_deflate_finish_base(struct isal_zstream *stream) +{ + uint32_t literal = 0, hash; + uint8_t *start_in, *next_in, *end_in, *end, *next_hash; + uint16_t match_length; + uint32_t dist; + uint64_t code, code_len, code2, code_len2; + struct isal_zstate *state = &stream->internal_state; + uint16_t *last_seen = state->head; + + set_buf(&state->bitbuf, stream->next_out, stream->avail_out); + + start_in = stream->next_in; + end_in = start_in + stream->avail_in; + next_in = start_in; + + if (stream->avail_in != 0) { + while (next_in + 3 < end_in) { if (is_full(&state->bitbuf)) { - state->b_bytes_processed = next_in - state->buffer; - update_state(stream, state, start_in); + update_state(stream, start_in, next_in, end_in); return; } @@ -141,22 +137,20 @@ void isal_deflate_body_base(struct isal_zstream *stream) dist = (next_in - state->file_start - last_seen[hash]) & 0xFFFF; last_seen[hash] = (uint64_t) (next_in - state->file_start); - if (dist - 1 < IGZIP_D - 1) { /* The -1 are to handle the case when dist = 0 */ - assert(next_in - dist >= state->buffer); - assert(dist != 0); - - match_length = compare258(next_in - dist, next_in, 258); + if (dist - 1 < IGZIP_HIST_SIZE - 1) { /* The -1 are to handle the case when dist = 0 */ + match_length = + compare258(next_in - dist, next_in, end_in - next_in); if (match_length >= SHORTEST_MATCH) { next_hash = next_in; -#ifdef LIMIT_HASH_UPDATE +#ifdef ISAL_LIMIT_HASH_UPDATE end = next_hash + 3; #else end = next_hash + match_length; #endif next_hash++; - for (; next_hash < end; next_hash++) { + for (; next_hash < end - 3; next_hash++) { literal = *(uint32_t *) next_hash; hash = compute_hash(literal) & HASH_MASK; last_seen[hash] = @@ -182,111 +176,35 @@ void isal_deflate_body_base(struct isal_zstream *stream) get_lit_code(stream->hufftables, literal & 0xFF, &code, &code_len); write_bits(&state->bitbuf, code, code_len); next_in++; - } - state->b_bytes_processed = next_in - state->buffer; - - } - - update_state(stream, state, start_in); - - if (stream->avail_in == 0) { - if (stream->end_of_stream || stream->flush != NO_FLUSH) - state->state = ZSTATE_FLUSH_READ_BUFFER; - return; - } - - return; - -} - -void isal_deflate_finish_base(struct isal_zstream *stream) -{ - uint32_t literal = 0, hash; - uint8_t *next_in, *end_in, *end, *next_hash; - uint16_t match_length; - uint32_t dist; - uint64_t code, code_len, code2, code_len2; - struct isal_zstate *state = &stream->internal_state; - uint16_t *last_seen = state->head; - - set_buf(&state->bitbuf, stream->next_out, stream->avail_out); - - end_in = state->b_bytes_valid + (uint8_t *) state->buffer; - - next_in = state->b_bytes_processed + state->buffer; - - while (next_in < end_in) { - - if (is_full(&state->bitbuf)) { - state->b_bytes_processed = next_in - state->buffer; - update_state(stream, state, stream->next_in); - return; } - literal = *(uint32_t *) next_in; - hash = compute_hash(literal) & HASH_MASK; - dist = (next_in - state->file_start - last_seen[hash]) & 0xFFFF; - last_seen[hash] = (uint64_t) (next_in - state->file_start); - - if (dist - 1 < IGZIP_D - 1) { /* The -1 are to handle the case when dist = 0 */ - assert(next_in - dist >= state->buffer); - match_length = compare258(next_in - dist, next_in, end_in - next_in); - - if (match_length >= SHORTEST_MATCH) { - next_hash = next_in; -#ifdef LIMIT_HASH_UPDATE - end = next_hash + 3; -#else - end = next_hash + match_length; -#endif - next_hash++; - - for (; next_hash < end; next_hash++) { - literal = *(uint32_t *) next_hash; - hash = compute_hash(literal) & HASH_MASK; - last_seen[hash] = - (uint64_t) (next_hash - state->file_start); - } - - get_len_code(stream->hufftables, match_length, &code, - &code_len); - get_dist_code(stream->hufftables, dist, &code2, &code_len2); - - code |= code2 << code_len; - code_len += code_len2; - - write_bits(&state->bitbuf, code, code_len); - - next_in += match_length; - - continue; + while (next_in < end_in) { + if (is_full(&state->bitbuf)) { + update_state(stream, start_in, next_in, end_in); + return; } - } - get_lit_code(stream->hufftables, literal & 0xFF, &code, &code_len); - write_bits(&state->bitbuf, code, code_len); - next_in++; + literal = *next_in; + get_lit_code(stream->hufftables, literal & 0xFF, &code, &code_len); + write_bits(&state->bitbuf, code, code_len); + next_in++; + } } - state->b_bytes_processed = next_in - state->buffer; + if (!is_full(&state->bitbuf)) { + get_lit_code(stream->hufftables, 256, &code, &code_len); + write_bits(&state->bitbuf, code, code_len); + state->has_eob = 1; - if (is_full(&state->bitbuf) || state->left_over > 0) { - update_state(stream, state, stream->next_in); - return; + if (stream->end_of_stream == 1) + state->state = ZSTATE_TRL; + else + state->state = ZSTATE_SYNC_FLUSH; } - get_lit_code(stream->hufftables, 256, &code, &code_len); - write_bits(&state->bitbuf, code, code_len); - state->has_eob = 1; - - update_state(stream, state, stream->next_in); - - if (stream->end_of_stream == 1) - state->state = ZSTATE_TRL; - else - state->state = ZSTATE_SYNC_FLUSH; + update_state(stream, start_in, next_in, end_in); return; } diff --git a/ceph/src/isa-l/igzip/igzip_base_aliases.c b/ceph/src/isa-l/igzip/igzip_base_aliases.c new file mode 100644 index 000000000..c9d551daa --- /dev/null +++ b/ceph/src/isa-l/igzip/igzip_base_aliases.c @@ -0,0 +1,87 @@ +/********************************************************************** + Copyright(c) 2011-2017 Intel Corporation All rights reserved. + + 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 Intel Corporation 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 + 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. +**********************************************************************/ + +#include +#include "igzip_lib.h" +#include "encode_df.h" + +void isal_deflate_body_base(struct isal_zstream *stream); +void isal_deflate_finish_base(struct isal_zstream *stream); +void isal_deflate_icf_body_base(struct isal_zstream *stream); +void isal_deflate_icf_finish_base(struct isal_zstream *stream); +void isal_update_histogram_base(uint8_t * start_stream, int length, + struct isal_huff_histogram *histogram); +struct deflate_icf *encode_deflate_icf_base(struct deflate_icf *next_in, + struct deflate_icf *end_in, struct BitBuf2 *bb, + struct hufftables_icf *hufftables); +uint32_t crc32_gzip_base(uint32_t init_crc, const unsigned char *buf, uint64_t len); +int decode_huffman_code_block_stateless_base(struct inflate_state *s); + +void isal_deflate_body(struct isal_zstream *stream) +{ + isal_deflate_body_base(stream); +} + +void isal_deflate_finish(struct isal_zstream *stream) +{ + isal_deflate_finish_base(stream); +} + +void isal_deflate_icf_body(struct isal_zstream *stream) +{ + isal_deflate_icf_body_base(stream); +} + +void isal_deflate_icf_finish(struct isal_zstream *stream) +{ + isal_deflate_icf_finish_base(stream); +} + +void isal_update_histogram(uint8_t * start_stream, int length, + struct isal_huff_histogram *histogram) +{ + isal_update_histogram_base(start_stream, length, histogram); +} + +struct deflate_icf *encode_deflate_icf(struct deflate_icf *next_in, + struct deflate_icf *end_in, struct BitBuf2 *bb, + struct hufftables_icf *hufftables) +{ + return encode_deflate_icf_base(next_in, end_in, bb, hufftables); +} + +uint32_t crc32_gzip(uint32_t init_crc, const unsigned char *buf, uint64_t len) +{ + return crc32_gzip_base(init_crc, buf, len); +} + +int decode_huffman_code_block_stateless(struct inflate_state *s) +{ + return decode_huffman_code_block_stateless_base(s); +} diff --git a/ceph/src/isa-l/igzip/igzip_body.asm b/ceph/src/isa-l/igzip/igzip_body.asm index a4a351688..e588af60a 100644 --- a/ceph/src/isa-l/igzip/igzip_body.asm +++ b/ceph/src/isa-l/igzip/igzip_body.asm @@ -28,26 +28,16 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; %include "options.asm" -%ifndef TEST - -extern fold_4 %include "lz0a_const.asm" %include "data_struct2.asm" %include "bitbuf2.asm" %include "huffman.asm" %include "igzip_compare_types.asm" - %include "reg_sizes.asm" %include "stdmac.asm" -%if (ARCH == 04) - %define MOVDQA vmovdqa -%else - %define MOVDQA movdqa -%endif - %ifdef DEBUG %macro MARK 1 global %1 @@ -61,95 +51,74 @@ global %1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -%define tmp2 rcx -%define hash2 rcx -%define b_bytes_valid rax -%define curr_data rax -%define code rax -%define tmp5 rax +%define tmp2 rcx +%define hash2 rcx -%define tmp4 rbx -%define dist rbx -%define code2 rbx +%define curr_data rax +%define code rax +%define tmp5 rax -%define x rdx -%define len rdx -%define hash rdx -%define code_len3 rdx +%define tmp4 rbx +%define dist rbx +%define code2 rbx -%define tmp1 rsi -%define code_len2 rsi +%define hash rdx +%define len rdx +%define code_len3 rdx +%define tmp8 rdx -%define blen rdi -%define file_start rdi +%define tmp1 rsi +%define code_len2 rsi -%define m_bit_count rbp +%define file_start rdi -%define in_buf r8 -%define curr_data2 r8 -%define len2 r8 -%define tmp6 r8 +%define m_bit_count rbp -%define m_bits r9 +%define curr_data2 r8 +%define len2 r8 +%define tmp6 r8 -%define f_i r10 +%define m_bits r9 -%define m_out_buf r11 +%define f_i r10 -%define f_end_i r12 -%define dist2 r12 -%define tmp7 r12 -%define code4 r12 +%define m_out_buf r11 -%define tmp3 r13 -%define code3 r13 +%define f_end_i r12 +%define dist2 r12 +%define tmp7 r12 +%define code4 r12 -%define stream r14 +%define tmp3 r13 +%define code3 r13 -%define hufftables r15 +%define stream r14 -%define crc_0 xmm0 ; in/out: crc state -%define crc_1 xmm1 ; in/out: crc state -%define crc_2 xmm2 ; in/out: crc state -%define crc_3 xmm3 ; in/out: crc state -%define crc_fold xmm4 ; in: (loaded from fold_4) +%define hufftables r15 -%define xtmp0 xmm5 ; tmp -%define xtmp1 xmm6 ; tmp -%define xtmp2 xmm7 ; tmp -%define xtmp3 xmm8 ; tmp -%define xtmp4 xmm9 ; tmp +;; GPR r8 & r15 can be used + +%define xtmp0 xmm0 ; tmp +%define xtmp1 xmm1 ; tmp +%define xhash xmm2 +%define xmask xmm3 +%define xdata xmm4 + +%define ytmp0 ymm0 ; tmp +%define ytmp1 ymm1 ; tmp -%define ytmp0 ymm5 ; tmp -%define ytmp1 ymm6 ; tmp -%if (ARCH == 04) -%define vtmp0 ymm5 ; tmp -%define vtmp1 ymm6 ; tmp -%define vtmp2 ymm7 ; tmp -%define vtmp3 ymm8 ; tmp -%define vtmp4 ymm9 ; tmp -%else -%define vtmp0 xmm5 ; tmp -%define vtmp1 xmm6 ; tmp -%define vtmp2 xmm7 ; tmp -%define vtmp3 xmm8 ; tmp -%define vtmp4 xmm9 ; tmp -%endif ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -%define b_bytes_processed f_i blen_mem_offset equ 0 ; local variable (8 bytes) -in_buf_mem_offset equ 8 -f_end_i_mem_offset equ 16 -empty_buffer_flag equ 24 -gpr_save_mem_offset equ 32 ; gpr save area (8*8 bytes) -xmm_save_mem_offset equ 32 + 8*8 ; xmm save area (4*16 bytes) (16 byte aligned) -stack_size equ 4*8 + 8*8 + 4*16 + 8 +f_end_i_mem_offset equ 8 +gpr_save_mem_offset equ 16 ; gpr save area (8*8 bytes) +xmm_save_mem_offset equ 16 + 8*8 ; xmm save area (4*16 bytes) (16 byte aligned) +stack_size equ 2*8 + 8*8 + 4*16 + 8 ;;; 8 because stack address is odd multiple of 8 after a function call and ;;; we want it aligned to 16 bytes @@ -193,258 +162,123 @@ skip1: mov [rsp + gpr_save_mem_offset + 5*8], r13 mov [rsp + gpr_save_mem_offset + 6*8], r14 mov [rsp + gpr_save_mem_offset + 7*8], r15 - MOVDQA [rsp + xmm_save_mem_offset + 0*16], xmm6 - MOVDQA [rsp + xmm_save_mem_offset + 1*16], xmm7 - MOVDQA [rsp + xmm_save_mem_offset + 2*16], xmm8 - MOVDQA [rsp + xmm_save_mem_offset + 3*16], xmm9 mov stream, rcx - - MOVDQA crc_0, [stream + _internal_state_crc + 0*16] - MOVDQA crc_1, [stream + _internal_state_crc + 1*16] - MOVDQA crc_2, [stream + _internal_state_crc + 2*16] - MOVDQA crc_3, [stream + _internal_state_crc + 3*16] - MOVDQA crc_fold, [fold_4] mov dword [stream + _internal_state_has_eob], 0 + MOVDQU xmask, [mask] + ; state->bitbuf.set_buf(stream->next_out, stream->avail_out); mov m_out_buf, [stream + _next_out] mov [stream + _internal_state_bitbuf_m_out_start], m_out_buf mov tmp1 %+ d, [stream + _avail_out] add tmp1, m_out_buf sub tmp1, SLOP -skip_SLOP: + mov [stream + _internal_state_bitbuf_m_out_end], tmp1 mov m_bits, [stream + _internal_state_bitbuf_m_bits] mov m_bit_count %+ d, [stream + _internal_state_bitbuf_m_bit_count] - mov hufftables, [stream + _hufftables] - ; in_buf = stream->next_in - mov in_buf, [stream + _next_in] - mov blen %+ d, [stream + _avail_in] - - mov dword [rsp + empty_buffer_flag], 0 - cmp dword [stream + _flush], _FULL_FLUSH - sete byte [rsp + empty_buffer_flag] - cmp dword [stream + _internal_state_b_bytes_processed], 0 - sete byte [rsp + empty_buffer_flag + 1] - - ; while (blen != 0) -MARK __Compute_X_ %+ ARCH -loop1: - ; x = D + LA - (state->b_bytes_valid - state->b_bytes_processed); - mov b_bytes_valid %+ d, [stream + _internal_state_b_bytes_valid] - mov b_bytes_processed %+ d, [stream + _internal_state_b_bytes_processed] - lea x, [b_bytes_processed + D + LA] - sub x, b_bytes_valid - - ; if (x > D) x = D; - cmp x, D - cmova x, [const_D] - - ; if (blen < D) x = blen; - cmp blen, D - cmovb x, blen - - ;; process x bytes starting at in_buf - - ;; If there isn't enough room, shift buffer down - ; if (x > BSIZE - state->b_bytes_valid) { - mov tmp1, BSIZE - sub tmp1, b_bytes_valid - cmp x, tmp1 - jbe skip_move - - ; if (state->b_bytes_processed < state->b_bytes_valid - LA) { - mov tmp1, b_bytes_valid - sub tmp1, LA - cmp b_bytes_processed, tmp1 - jae do_move - - ;; We need to move an odd amount, skip move for this copy of loop - xor x,x - mov [rsp + blen_mem_offset], blen - jmp skip_move_zero - -MARK __shift_data_down_ %+ ARCH -do_move: - ; offset = state->b_bytes_valid - (D + LA); - mov tmp4, b_bytes_valid - sub tmp4, D + LA - ; copy_D_LA(state->buffer, state->buffer + offset); - lea tmp1, [stream + _internal_state_buffer] - lea tmp2, [tmp1 + tmp4] - copy_D_LA tmp1, tmp2, tmp3, vtmp0, vtmp1, vtmp2, vtmp3 - ; tmp1 clobbered - - ; state->file_start -= offset; - sub [stream + _internal_state_file_start], tmp4 - ; state->b_bytes_processed -= offset; - sub b_bytes_processed, tmp4 - mov b_bytes_valid, D + LA - -MARK __copy_in_ %+ ARCH -skip_move: - sub blen, x - - mov [rsp + blen_mem_offset], blen - - ; copy_in(state->buffer + state->b_bytes_valid, in_buf, x); - lea tmp1, [stream + _internal_state_buffer + b_bytes_valid] - mov tmp2, in_buf - mov tmp3, x - - - COPY_IN_CRC tmp1, tmp2, tmp3, tmp4, crc_0, crc_1, crc_2, crc_3, crc_fold, \ - xtmp0, xtmp1, xtmp2, xtmp3, xtmp4 - - ; in_buf += x; - add in_buf, x -MARK __prepare_loop_ %+ ARCH -skip_move_zero: - mov [rsp + in_buf_mem_offset], in_buf - ; state->b_bytes_valid += x; - add b_bytes_valid, x - mov [stream + _internal_state_b_bytes_valid], b_bytes_valid %+ d - - ; f_end_i = state->b_bytes_valid - LA; -%ifnidn f_end_i, b_bytes_valid - mov f_end_i, b_bytes_valid -%endif + + mov file_start, [stream + _next_in] + + mov f_i %+ d, dword [stream + _total_in] + sub file_start, f_i + + mov f_end_i %+ d, [stream + _avail_in] + add f_end_i, f_i + + ; f_end_i -= LA; sub f_end_i, LA - ; if (f_end_i <= 0) continue; - cmp f_end_i, 0 - jle continue_while - - ; f_start_i = state->b_bytes_processed; - ;; f_i and b_bytes_processed are same register, just store b_bytes_proc - mov [stream + _internal_state_b_bytes_processed], b_bytes_processed %+ d - - ; f_start_i += (uint32_t)(state->buffer - state->file_start); - mov file_start, [stream + _internal_state_file_start] - lea tmp1, [stream + _internal_state_buffer] - sub tmp1, file_start - add f_i, tmp1 - add f_end_i, tmp1 mov [rsp + f_end_i_mem_offset], f_end_i + ; if (f_end_i <= 0) continue; + + cmp f_end_i, f_i + jle input_end ; for (f_i = f_start_i; f_i < f_end_i; f_i++) { - cmp f_i, f_end_i - jge end_loop_2 +MARK __body_compute_hash_ %+ ARCH + MOVDQU xdata, [file_start + f_i] + mov curr_data, [file_start + f_i] + mov tmp3, curr_data + mov tmp6, curr_data -MARK __misc_compute_hash_lookup_ %+ ARCH - mov curr_data %+ d, [file_start + f_i] + compute_hash hash, curr_data - cmp dword [rsp + empty_buffer_flag], 0 - jne write_first_byte + shr tmp3, 8 + compute_hash hash2, tmp3 - mov curr_data2, curr_data + and hash, HASH_MASK + and hash2, HASH_MASK - compute_hash hash, curr_data - jmp loop2 + cmp dword [stream + _internal_state_has_hist], 0 + je write_first_byte + jmp loop2 align 16 loop2: - shr curr_data2, 8 - xor hash2 %+ d, hash2 %+ d - crc32 hash2 %+ d, curr_data2 %+ d - - ; hash = compute_hash(state->file_start + f_i) & HASH_MASK; - and hash %+ d, HASH_MASK - and hash2 %+ d, HASH_MASK - ; if (state->bitbuf.is_full()) { cmp m_out_buf, [stream + _internal_state_bitbuf_m_out_end] - ja bitbuf_full + ja output_end xor dist, dist xor dist2, dist2 xor tmp3, tmp3 lea tmp1, [file_start + f_i] - lea tmp6, [tmp1 - 1] mov dist %+ w, f_i %+ w + dec dist sub dist %+ w, word [stream + _internal_state_head + 2 * hash] - - ; state->head[hash] = (uint16_t) f_i; mov [stream + _internal_state_head + 2 * hash], f_i %+ w inc f_i + MOVQ tmp6, xdata + shr tmp5, 16 + mov tmp8, tmp5 + compute_hash tmp6, tmp5 + mov dist2 %+ w, f_i %+ w - sub dist2 %+ w, word [stream + _internal_state_head + 2 * hash2] dec dist2 - - ; state->head[hash2] = (uint16_t) f_i; + sub dist2 %+ w, word [stream + _internal_state_head + 2 * hash2] mov [stream + _internal_state_head + 2 * hash2], f_i %+ w - mov tmp2, tmp1 - sub tmp2, dist - dec dist - ; if ((dist-1) < (D-1)) { - cmp dist %+ d, (D-1) - cmovae tmp2, tmp6 - cmovae dist, tmp3 - inc dist + and dist %+ d, (D-1) + neg dist - cmp dist2 %+ d, (D-1) - cmovae dist2, tmp3 - inc dist2 + shr tmp8, 8 + compute_hash tmp2, tmp8 -MARK __compare_ %+ ARCH - ; len = compare258(state->file_start + f_i, - ; state->file_start + f_i - dist); - - ;; Specutively load distance code (except for when large windows are used) - get_packed_dist_code dist, code2, hufftables + and dist2 %+ d, (D-1) + neg dist2 +MARK __body_compare_ %+ ARCH ;; Check for long len/dist match (>7) with first literal - mov len, [tmp1] - xor len, [tmp2] + MOVQ len, xdata + mov curr_data, len + PSRLDQ xdata, 1 + xor len, [tmp1 + dist - 1] jz compare_loop -%ifdef USE_HSWNI - blsmsk tmp3, len - or tmp3, 0xFFFFFF -%endif - - lea tmp1, [file_start + f_i] - mov tmp2, tmp1 - sub tmp2, dist2 - - ;; Specutively load distance code (except for when large windows are used) - get_packed_dist_code dist2, code4, hufftables + MOVD xhash, tmp6 %+ d + PINSRD xhash, tmp2 %+ d, 1 + PAND xhash, xhash, xmask ;; Check for len/dist match (>7) with second literal - mov len2, [tmp1] - xor len2, [tmp2] + MOVQ len2, xdata + xor len2, [tmp1 + dist2] jz compare_loop2 -%ifdef USE_HSWNI - ;; Check for len/dist match for first literal - test tmp3, len2 - jz len_dist_lit_huffman_pre - - cmp tmp3, 0xFFFFFF - je encode_2_literals - jmp len_dist_huffman_pre - - -MARK __len_dist_lit_huffman_ %+ ARCH -len_dist_lit_huffman_pre: - movzx tmp1, curr_data %+ b - get_lit_code tmp1, code3, code_len3, hufftables -%else ;; Specutively load the code for the first literal movzx tmp1, curr_data %+ b get_lit_code tmp1, code3, rcx, hufftables ;; Check for len/dist match for first literal - test len, 0xFFFFFF + test len %+ d, 0xFFFFFFFF jz len_dist_huffman_pre ;; Specutively load the code for the second literal @@ -452,82 +286,110 @@ len_dist_lit_huffman_pre: and curr_data, 0xff get_lit_code curr_data, code2, code_len2, hufftables - shl code2, cl + SHLX code2, code2, rcx or code2, code3 add code_len2, rcx ;; Check for len/dist match for second literal - test len2, 0xFFFFFF + test len2 %+ d, 0xFFFFFFFF jnz write_lit_bits -MARK __len_dist_lit_huffman_ %+ ARCH +MARK __body_len_dist_lit_huffman_ %+ ARCH len_dist_lit_huffman_pre: mov code_len3, rcx -%endif bsf len2, len2 shr len2, 3 len_dist_lit_huffman: + neg dist2 + %ifndef LONGER_HUFFTABLE mov tmp4, dist2 get_dist_code tmp4, code4, code_len2, hufftables ;; clobbers dist, rcx %else - unpack_dist_code code4, code_len2 + get_dist_code dist2, code4, code_len2, hufftables %endif get_len_code len2, code, rcx, hufftables ;; rcx is code_len -%ifdef USE_HSWNI - shlx code4, code4, rcx -%else - shl code4, cl -%endif + SHLX code4, code4, rcx or code4, code add code_len2, rcx - mov rcx, code_len3 + add f_i, len2 + neg len2 -%ifdef USE_HSWNI - shlx code4, code4, rcx -%else - shl code4, cl -%endif + MOVQ tmp5, xdata + shr tmp5, 24 + compute_hash tmp4, tmp5 + and tmp4, HASH_MASK + + SHLX code4, code4, code_len3 or code4, code3 - add code_len2, rcx + add code_len2, code_len3 - mov code2, code4 ;; Setup for updating hash - lea tmp3, [f_i + 1] ; tmp3 <= k - add f_i, len2 - - ; hash = compute_hash(state->file_start + k) & HASH_MASK; - mov tmp5 %+ d, [file_start + tmp3] - mov tmp7, tmp5 - shr tmp7, 8 + lea tmp3, [f_i + len2 + 1] ; tmp3 <= k - compute_hash hash, tmp5 - and hash %+ d, HASH_MASK + MOVDQU xdata, [file_start + f_i] + mov curr_data, [file_start + f_i] + mov curr_data2, curr_data - ; state->head[hash] = k; + MOVD hash %+ d, xhash + PEXTRD hash2 %+ d, xhash, 1 mov [stream + _internal_state_head + 2 * hash], tmp3 %+ w + compute_hash hash, curr_data + add tmp3,1 + mov [stream + _internal_state_head + 2 * hash2], tmp3 %+ w - jmp update_hash_for_symbol + add tmp3, 1 + mov [stream + _internal_state_head + 2 * tmp4], tmp3 %+ w + + write_bits m_bits, m_bit_count, code4, code_len2, m_out_buf, tmp4 + mov f_end_i, [rsp + f_end_i_mem_offset] + + shr curr_data2, 8 + compute_hash hash2, curr_data2 + +%ifdef NO_LIMIT_HASH_UPDATE +loop3: + add tmp3,1 + cmp tmp3, f_i + jae loop3_done + mov tmp6, [file_start + tmp3] + compute_hash tmp4, tmp6 + and tmp4 %+ d, HASH_MASK + ; state->head[hash] = k; + mov [stream + _internal_state_head + 2 * tmp4], tmp3 %+ w + jmp loop3 +loop3_done: +%endif + ; hash = compute_hash(state->file_start + f_i) & HASH_MASK; + and hash %+ d, HASH_MASK + and hash2 %+ d, HASH_MASK + + ; continue + cmp f_i, f_end_i + jl loop2 + jmp input_end ;; encode as dist/len -MARK __len_dist_huffman_ %+ ARCH +MARK __body_len_dist_huffman_ %+ ARCH len_dist_huffman_pre: bsf len, len shr len, 3 + len_dist_huffman: - dec f_i + dec f_i + neg dist ; get_dist_code(dist, &code2, &code_len2); %ifndef LONGER_HUFFTABLE mov tmp3, dist ; since code2 and dist are rbx get_dist_code tmp3, code2, code_len2, hufftables ;; clobbers dist, rcx %else - unpack_dist_code code2, code_len2 + get_dist_code dist, code2, code_len2, hufftables %endif ; get_len_code(len, &code, &code_len); get_len_code len, code, rcx, hufftables ;; rcx is code_len @@ -535,119 +397,71 @@ len_dist_huffman: ; code2 <<= code_len ; code2 |= code ; code_len2 += code_len -%ifdef USE_HSWNI - shlx code2, code2, rcx -%else - shl code2, cl -%endif + SHLX code2, code2, rcx or code2, code add code_len2, rcx ;; Setup for updateing hash lea tmp3, [f_i + 2] ; tmp3 <= k add f_i, len - mov tmp7 %+ d, [file_start + tmp3] -MARK __update_hash_for_symbol_ %+ ARCH -update_hash_for_symbol: - mov curr_data %+ d, [file_start + f_i] + MOVD hash %+ d, xhash + PEXTRD hash2 %+ d, xhash, 1 + mov [stream + _internal_state_head + 2 * hash], tmp3 %+ w + add tmp3,1 + mov [stream + _internal_state_head + 2 * hash2], tmp3 %+ w + + MOVDQU xdata, [file_start + f_i] + mov curr_data, [file_start + f_i] mov curr_data2, curr_data compute_hash hash, curr_data -%ifdef LIMIT_HASH_UPDATE - ; only update hash twice, first hash was already calculated. - ; hash = compute_hash(state->file_start + k) & HASH_MASK; - compute_hash hash2, tmp7 - and hash2 %+ d, HASH_MASK - ; state->head[hash] = k; - mov [stream + _internal_state_head + 2 * hash2], tmp3 %+ w + write_bits m_bits, m_bit_count, code2, code_len2, m_out_buf, tmp7 + mov f_end_i, [rsp + f_end_i_mem_offset] -%else -loop3: - ; hash = compute_hash(state->file_start + k) & HASH_MASK; - mov tmp7 %+ d, [file_start + tmp3] - compute_hash hash2, tmp7 - and hash2 %+ d, HASH_MASK - ; state->head[hash] = k; - mov [stream + _internal_state_head + 2 * hash2], tmp3 %+ w - add tmp3,1 + shr curr_data2, 8 + compute_hash hash2, curr_data2 + +%ifdef NO_LIMIT_HASH_UPDATE +loop4: + add tmp3,1 cmp tmp3, f_i - jl loop3 + jae loop4_done + mov tmp6, [file_start + tmp3] + compute_hash tmp4, tmp6 + and tmp4, HASH_MASK + mov [stream + _internal_state_head + 2 * tmp4], tmp3 %+ w + jmp loop4 +loop4_done: %endif - -MARK __write_len_dist_bits_ %+ ARCH - mov f_end_i, [rsp + f_end_i_mem_offset] - write_bits m_bits, m_bit_count, code2, code_len2, m_out_buf, tmp3 + ; hash = compute_hash(state->file_start + f_i) & HASH_MASK; + and hash %+ d, HASH_MASK + and hash2 %+ d, HASH_MASK ; continue cmp f_i, f_end_i jl loop2 - jmp end_loop_2 - - -MARK __write_lit_bits_ %+ ARCH -%ifdef USE_HSWNI -encode_2_literals: - movzx tmp1, curr_data %+ b - get_lit_code tmp1, code3, rcx, hufftables - - shr curr_data, 8 - and curr_data, 0xff - get_lit_code curr_data, code2, code_len2, hufftables + jmp input_end - ;; Calculate code associated with both literals - shlx code2, code2, rcx - or code2, code3 - add code_len2, rcx -%endif +MARK __body_write_lit_bits_ %+ ARCH write_lit_bits: + MOVDQU xdata, [file_start + f_i + 1] mov f_end_i, [rsp + f_end_i_mem_offset] add f_i, 1 - mov curr_data %+ d, [file_start + f_i] - mov curr_data2, curr_data + mov curr_data, [file_start + f_i] - compute_hash hash, curr_data + MOVD hash %+ d, xhash write_bits m_bits, m_bit_count, code2, code_len2, m_out_buf, tmp3 + PEXTRD hash2 %+ d, xhash, 1 + ; continue cmp f_i, f_end_i jl loop2 - -MARK __end_loops_ %+ ARCH -end_loop_2: - - ; state->b_bytes_processed = f_i - (state->buffer - state->file_start); - add f_i, [stream + _internal_state_file_start] - sub f_i, stream - sub f_i, _internal_state_buffer - mov [stream + _internal_state_b_bytes_processed], f_i %+ d - - ; continue -continue_while: - mov blen, [rsp + blen_mem_offset] - mov in_buf, [rsp + in_buf_mem_offset] - cmp blen, 0 - jnz loop1 - -end: - ;; update input buffer - ; stream->total_in += (uint32_t)(in_buf - stream->next_in); // bytes copied - mov tmp1 %+ d, [stream + _total_in] - mov in_buf, [rsp + in_buf_mem_offset] - add tmp1, in_buf - sub tmp1, [stream + _next_in] - mov [stream + _total_in], tmp1 %+ d - - mov [stream + _next_in], in_buf - mov [stream + _avail_in], blen %+ d - - cmp blen, 0 - jne skip2 - - ;; Set stream's next state +input_end: mov tmp1, ZSTATE_FLUSH_READ_BUFFER mov tmp5, ZSTATE_BODY cmp dword [stream + _end_of_stream], 0 @@ -655,9 +469,18 @@ end: cmp dword [stream + _flush], _NO_FLUSH cmovne tmp5, tmp1 mov dword [stream + _internal_state_state], tmp5 %+ d -skip2: + +output_end: + ;; update input buffer + add f_end_i, LA + mov [stream + _total_in], f_i %+ d + add file_start, f_i + mov [stream + _next_in], file_start + sub f_end_i, f_i + mov [stream + _avail_in], f_end_i %+ d + + ;; update output buffer mov [stream + _next_out], m_out_buf - ; offset = state->bitbuf.buffer_used(); sub m_out_buf, [stream + _internal_state_bitbuf_m_out_start] sub [stream + _avail_out], m_out_buf %+ d add [stream + _total_out], m_out_buf %+ d @@ -665,12 +488,6 @@ skip2: mov [stream + _internal_state_bitbuf_m_bits], m_bits mov [stream + _internal_state_bitbuf_m_bit_count], m_bit_count %+ d - - MOVDQA [stream + _internal_state_crc + 0*16], crc_0 - MOVDQA [stream + _internal_state_crc + 1*16], crc_1 - MOVDQA [stream + _internal_state_crc + 2*16], crc_2 - MOVDQA [stream + _internal_state_crc + 3*16], crc_3 - mov rbx, [rsp + gpr_save_mem_offset + 0*8] mov rsi, [rsp + gpr_save_mem_offset + 1*8] mov rdi, [rsp + gpr_save_mem_offset + 2*8] @@ -679,10 +496,6 @@ skip2: mov r13, [rsp + gpr_save_mem_offset + 5*8] mov r14, [rsp + gpr_save_mem_offset + 6*8] mov r15, [rsp + gpr_save_mem_offset + 7*8] - MOVDQA xmm6, [rsp + xmm_save_mem_offset + 0*16] - MOVDQA xmm7, [rsp + xmm_save_mem_offset + 1*16] - MOVDQA xmm8, [rsp + xmm_save_mem_offset + 2*16] - MOVDQA xmm9, [rsp + xmm_save_mem_offset + 3*16] %ifndef ALIGN_STACK add rsp, stack_size @@ -692,18 +505,12 @@ skip2: %endif ret -MARK __bitbuf_full_ %+ ARCH -bitbuf_full: - mov blen, [rsp + blen_mem_offset] - ; state->b_bytes_processed = f_i - (state->buffer - state->file_start); - add f_i, [stream + _internal_state_file_start] - sub f_i, stream - sub f_i, _internal_state_buffer - mov [stream + _internal_state_b_bytes_processed], f_i %+ d - jmp end - -MARK __compare_loops_ %+ ARCH +MARK __body_compare_loops_ %+ ARCH compare_loop: + MOVD xhash, tmp6 %+ d + PINSRD xhash, tmp2 %+ d, 1 + PAND xhash, xhash, xmask + lea tmp2, [tmp1 + dist - 1] %if (COMPARE_TYPE == 1) compare250 tmp1, tmp2, len, tmp3 %elif (COMPARE_TYPE == 2) @@ -717,6 +524,8 @@ compare_loop: jmp len_dist_huffman compare_loop2: + lea tmp2, [tmp1 + dist2] + add tmp1, 1 %if (COMPARE_TYPE == 1) compare250 tmp1, tmp2, len2, tmp3 %elif (COMPARE_TYPE == 2) @@ -734,18 +543,25 @@ compare_loop2: MARK __write_first_byte_ %+ ARCH write_first_byte: cmp m_out_buf, [stream + _internal_state_bitbuf_m_out_end] - ja bitbuf_full + ja output_end + + mov dword [stream + _internal_state_has_hist], 1 - mov dword [rsp + empty_buffer_flag], 0 - compute_hash hash, curr_data - and hash %+ d, HASH_MASK mov [stream + _internal_state_head + 2 * hash], f_i %+ w + + mov hash, hash2 + shr tmp6, 16 + compute_hash hash2, tmp6 + + MOVD xhash, hash %+ d + PINSRD xhash, hash2 %+ d, 1 + PAND xhash, xhash, xmask + and curr_data, 0xff get_lit_code curr_data, code2, code_len2, hufftables jmp write_lit_bits section .data - align 4 + align 16 +mask: dd HASH_MASK, HASH_MASK, HASH_MASK, HASH_MASK const_D: dq D - -%endif ;; ifndef TEST diff --git a/ceph/src/isa-l/igzip/igzip_body_01.asm b/ceph/src/isa-l/igzip/igzip_body_01.asm index 0d130c748..648a335c6 100644 --- a/ceph/src/isa-l/igzip/igzip_body_01.asm +++ b/ceph/src/isa-l/igzip/igzip_body_01.asm @@ -4,5 +4,4 @@ %define COMPARE_TYPE 2 %endif -%include "igzip_buffer_utils_01.asm" %include "igzip_body.asm" diff --git a/ceph/src/isa-l/igzip/igzip_body_02.asm b/ceph/src/isa-l/igzip/igzip_body_02.asm new file mode 100644 index 000000000..23ad1323a --- /dev/null +++ b/ceph/src/isa-l/igzip/igzip_body_02.asm @@ -0,0 +1,7 @@ +%define ARCH 02 + +%ifndef COMPARE_TYPE +%define COMPARE_TYPE 2 +%endif + +%include "igzip_body.asm" diff --git a/ceph/src/isa-l/igzip/igzip_body_04.asm b/ceph/src/isa-l/igzip/igzip_body_04.asm index 97b134b07..16b9b7a89 100644 --- a/ceph/src/isa-l/igzip/igzip_body_04.asm +++ b/ceph/src/isa-l/igzip/igzip_body_04.asm @@ -5,5 +5,4 @@ %define COMPARE_TYPE 3 %endif -%include "igzip_buffer_utils_04.asm" %include "igzip_body.asm" diff --git a/ceph/src/isa-l/igzip/igzip_buffer_utils_01.asm b/ceph/src/isa-l/igzip/igzip_buffer_utils_01.asm deleted file mode 100644 index c6cb834e1..000000000 --- a/ceph/src/isa-l/igzip/igzip_buffer_utils_01.asm +++ /dev/null @@ -1,543 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Copyright(c) 2011-2016 Intel Corporation All rights reserved. -; -; 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 Intel Corporation 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 -; 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. -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -%ifndef BUFFER_UTILS -%define BUFFER_UTILS - -%include "options.asm" - -extern pshufb_shf_table -extern mask3 - -%ifdef FIX_CACHE_READ -%define movntdqa movdqa -%else -%macro prefetchnta 1 -%endm -%endif - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; code for doing the CRC calculation as part of copy-in, using pclmulqdq - -; "shift" 4 input registers down 4 places -; macro FOLD4 xmm0, xmm1, xmm2, xmm3, const, tmp0, tmp1 -%macro FOLD4 7 -%define %%xmm0 %1 ; xmm reg, in/out -%define %%xmm1 %2 ; xmm reg, in/out -%define %%xmm2 %3 ; xmm reg, in/out -%define %%xmm3 %4 ; xmm reg, in/out -%define %%const %5 ; xmm reg, in -%define %%tmp0 %6 ; xmm reg, tmp -%define %%tmp1 %7 ; xmm reg, tmp - - movaps %%tmp0, %%xmm0 - movaps %%tmp1, %%xmm1 - - pclmulqdq %%xmm0, %%const, 0x01 - pclmulqdq %%xmm1, %%const, 0x01 - - pclmulqdq %%tmp0, %%const, 0x10 - pclmulqdq %%tmp1, %%const, 0x10 - - xorps %%xmm0, %%tmp0 - xorps %%xmm1, %%tmp1 - - - movaps %%tmp0, %%xmm2 - movaps %%tmp1, %%xmm3 - - pclmulqdq %%xmm2, %%const, 0x01 - pclmulqdq %%xmm3, %%const, 0x01 - - pclmulqdq %%tmp0, %%const, 0x10 - pclmulqdq %%tmp1, %%const, 0x10 - - xorps %%xmm2, %%tmp0 - xorps %%xmm3, %%tmp1 -%endm - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; "shift" 3 input registers down 4 places -; macro FOLD3 x0, x1, x2, x3, const, tmp0 -; x0 x1 x2 x3 -; In A B C D -; Out D A' B' C' -%macro FOLD3 6 -%define %%x0 %1 ; xmm reg, in/out -%define %%x1 %2 ; xmm reg, in/out -%define %%x2 %3 ; xmm reg, in/out -%define %%x3 %4 ; xmm reg, in/out -%define %%const %5 ; xmm reg, in -%define %%tmp0 %6 ; xmm reg, tmp - - movdqa %%tmp0, %%x3 - - movaps %%x3, %%x2 - pclmulqdq %%x2, %%const, 0x01 - pclmulqdq %%x3, %%const, 0x10 - xorps %%x3, %%x2 - - movaps %%x2, %%x1 - pclmulqdq %%x1, %%const, 0x01 - pclmulqdq %%x2, %%const, 0x10 - xorps %%x2, %%x1 - - movaps %%x1, %%x0 - pclmulqdq %%x0, %%const, 0x01 - pclmulqdq %%x1, %%const, 0x10 - xorps %%x1, %%x0 - - movdqa %%x0, %%tmp0 -%endm - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; "shift" 2 input registers down 4 places -; macro FOLD2 x0, x1, x2, x3, const, tmp0 -; x0 x1 x2 x3 -; In A B C D -; Out C D A' B' -%macro FOLD2 6 -%define %%x0 %1 ; xmm reg, in/out -%define %%x1 %2 ; xmm reg, in/out -%define %%x2 %3 ; xmm reg, in/out -%define %%x3 %4 ; xmm reg, in/out -%define %%const %5 ; xmm reg, in -%define %%tmp0 %6 ; xmm reg, tmp - - movdqa %%tmp0, %%x3 - - movaps %%x3, %%x1 - pclmulqdq %%x1, %%const, 0x01 - pclmulqdq %%x3, %%const, 0x10 - xorps %%x3, %%x1 - - movdqa %%x1, %%tmp0 - movdqa %%tmp0, %%x2 - - movaps %%x2, %%x0 - pclmulqdq %%x0, %%const, 0x01 - pclmulqdq %%x2, %%const, 0x10 - xorps %%x2, %%x0 - - movdqa %%x0, %%tmp0 -%endm - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; "shift" 1 input registers down 4 places -; macro FOLD1 x0, x1, x2, x3, const, tmp0 -; x0 x1 x2 x3 -; In A B C D -; Out B C D A' -%macro FOLD1 6 -%define %%x0 %1 ; xmm reg, in/out -%define %%x1 %2 ; xmm reg, in/out -%define %%x2 %3 ; xmm reg, in/out -%define %%x3 %4 ; xmm reg, in/out -%define %%const %5 ; xmm reg, in -%define %%tmp0 %6 ; xmm reg, tmp - - movdqa %%tmp0, %%x3 - - movaps %%x3, %%x0 - pclmulqdq %%x0, %%const, 0x01 - pclmulqdq %%x3, %%const, 0x10 - xorps %%x3, %%x0 - - movdqa %%x0, %%x1 - movdqa %%x1, %%x2 - movdqa %%x2, %%tmp0 -%endm - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; macro PARTIAL_FOLD x0, x1, x2, x3, xp, size, xfold, xt0, xt1, xt2, xt3 - -; XP X3 X2 X1 X0 tmp2 -; Initial state xI HG FE DC BA -; after shift IH GF ED CB A0 -; after fold ff GF ED CB ff = merge(IH, A0) -; -%macro PARTIAL_FOLD 12 -%define %%x0 %1 ; xmm reg, in/out -%define %%x1 %2 ; xmm reg, in/out -%define %%x2 %3 ; xmm reg, in/out -%define %%x3 %4 ; xmm reg, in/out -%define %%xp %5 ; xmm partial reg, in/clobbered -%define %%size %6 ; GPR, in/clobbered (1...15) -%define %%const %7 ; xmm reg, in -%define %%shl %8 ; xmm reg, tmp -%define %%shr %9 ; xmm reg, tmp -%define %%tmp2 %10 ; xmm reg, tmp -%define %%tmp3 %11 ; xmm reg, tmp -%define %%gtmp %12 ; GPR, tmp - - ; {XP X3 X2 X1 X0} = {xI HG FE DC BA} - shl %%size, 4 ; size *= 16 - lea %%gtmp, [pshufb_shf_table - 16 WRT_OPT] - movdqa %%shl, [%%gtmp + %%size] ; shl constant - movdqa %%shr, %%shl - pxor %%shr, [mask3 WRT_OPT] ; shr constant - - movdqa %%tmp2, %%x0 ; tmp2 = BA - pshufb %%tmp2, %%shl ; tmp2 = A0 - - pshufb %%x0, %%shr ; x0 = 0B - movdqa %%tmp3, %%x1 ; tmp3 = DC - pshufb %%tmp3, %%shl ; tmp3 = C0 - por %%x0, %%tmp3 ; x0 = CB - - pshufb %%x1, %%shr ; x1 = 0D - movdqa %%tmp3, %%x2 ; tmp3 = FE - pshufb %%tmp3, %%shl ; tmp3 = E0 - por %%x1, %%tmp3 ; x1 = ED - - pshufb %%x2, %%shr ; x2 = 0F - movdqa %%tmp3, %%x3 ; tmp3 = HG - pshufb %%tmp3, %%shl ; tmp3 = G0 - por %%x2, %%tmp3 ; x2 = GF - - pshufb %%x3, %%shr ; x3 = 0H - pshufb %%xp, %%shl ; xp = I0 - por %%x3, %%xp ; x3 = IH - - ; fold tmp2 into X3 - movaps %%tmp3, %%tmp2 - pclmulqdq %%tmp2, %%const, 0x01 - pclmulqdq %%tmp3, %%const, 0x10 - xorps %%x3, %%tmp2 - xorps %%x3, %%tmp3 -%endm - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; LOAD_FRACTIONAL_XMM: Packs xmm register with data when data input is less than 16 bytes. -; Returns 0 if data has length 0. -; Input: The input data (src), that data's length (size). -; Output: The packed xmm register (xmm_out). -; size is clobbered. -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -%macro LOAD_FRACTIONAL_XMM 3 -%define %%xmm_out %1 ; %%xmm_out is an xmm register -%define %%src %2 -%define %%size %3 - - pxor %%xmm_out, %%xmm_out - - cmp %%size, 0 - je %%_done - - add %%src, %%size - - cmp %%size, 8 - jl %%_byte_loop - - sub %%src, 8 - pinsrq %%xmm_out, [%%src], 0 ;Read in 8 bytes if they exists - sub %%size, 8 - - je %%_done - -%%_byte_loop: ;Read in data 1 byte at a time while data is left - pslldq %%xmm_out, 1 - - dec %%src - pinsrb %%xmm_out, BYTE [%%src], 0 - dec %%size - - jg %%_byte_loop - -%%_done: - -%endmacro ; LOAD_FRACTIONAL_XMM - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; copy x bytes (rounded up to 16 bytes) from src to dst -; src & dst are unaligned -; macro COPY_IN_CRC dst, src, size_in_bytes, tmp, x0, x1, x2, x3, xfold, -; xt0, xt1, xt2, xt3, xt4 -%macro COPY_IN_CRC 14 -%define %%dst %1 ; reg, in/clobbered -%define %%src %2 ; reg, in/clobbered -%define %%size %3 ; reg, in/clobbered -%define %%tmp %4 ; reg, tmp -%define %%x0 %5 ; xmm, in/out: crc state -%define %%x1 %6 ; xmm, in/out: crc state -%define %%x2 %7 ; xmm, in/out: crc state -%define %%x3 %8 ; xmm, in/out: crc state -%define %%xfold %9 ; xmm, in: (loaded from fold4) -%define %%xtmp0 %10 ; xmm, tmp -%define %%xtmp1 %11 ; xmm, tmp -%define %%xtmp2 %12 ; xmm, tmp -%define %%xtmp3 %13 ; xmm, tmp -%define %%xtmp4 %14 ; xmm, tmp - - cmp %%size, 16 - jl %%lt_16 - - ; align source - xor %%tmp, %%tmp - sub %%tmp, %%src - and %%tmp, 15 - jz %%already_aligned - - ; need to align, tmp contains number of bytes to transfer - movdqu %%xtmp0, [%%src] - movdqu [%%dst], %%xtmp0 - add %%dst, %%tmp - add %%src, %%tmp - sub %%size, %%tmp - -%ifndef DEFLATE - push %%dst - - PARTIAL_FOLD %%x0, %%x1, %%x2, %%x3, %%xtmp0, %%tmp, %%xfold, \ - %%xtmp1, %%xtmp2, %%xtmp3, %%xtmp4, %%dst - pop %%dst -%endif - -%%already_aligned: - sub %%size, 64 - jl %%end_loop - jmp %%loop -align 16 -%%loop: - movntdqa %%xtmp0, [%%src+0*16] - movntdqa %%xtmp1, [%%src+1*16] - movntdqa %%xtmp2, [%%src+2*16] - -%ifndef DEFLATE - FOLD4 %%x0, %%x1, %%x2, %%x3, %%xfold, %%xtmp3, %%xtmp4 -%endif - movntdqa %%xtmp3, [%%src+3*16] - - movdqu [%%dst+0*16], %%xtmp0 - movdqu [%%dst+1*16], %%xtmp1 - movdqu [%%dst+2*16], %%xtmp2 - movdqu [%%dst+3*16], %%xtmp3 - -%ifndef DEFLATE - pxor %%x0, %%xtmp0 - pxor %%x1, %%xtmp1 - pxor %%x2, %%xtmp2 - pxor %%x3, %%xtmp3 -%endif - add %%src, 4*16 - add %%dst, 4*16 - sub %%size, 4*16 - jge %%loop - -%%end_loop: - ; %%size contains (num bytes left - 64) - add %%size, 16 - jge %%three_full_regs - add %%size, 16 - jge %%two_full_regs - add %%size, 16 - jge %%one_full_reg - add %%size, 16 - -%%no_full_regs: ; 0 <= %%size < 16, no full regs - jz %%done ; if no bytes left, we're done - jmp %%partial - - ;; Handle case where input is <16 bytes -%%lt_16: - test %%size, %%size - jz %%done ; if no bytes left, we're done - jmp %%partial - - -%%one_full_reg: - movntdqa %%xtmp0, [%%src+0*16] - -%ifndef DEFLATE - FOLD1 %%x0, %%x1, %%x2, %%x3, %%xfold, %%xtmp3 -%endif - movdqu [%%dst+0*16], %%xtmp0 - -%ifndef DEFLATE - pxor %%x3, %%xtmp0 -%endif - test %%size, %%size - jz %%done ; if no bytes left, we're done - - add %%dst, 1*16 - add %%src, 1*16 - jmp %%partial - - -%%two_full_regs: - movntdqa %%xtmp0, [%%src+0*16] - movntdqa %%xtmp1, [%%src+1*16] - -%ifndef DEFLATE - FOLD2 %%x0, %%x1, %%x2, %%x3, %%xfold, %%xtmp3 -%endif - movdqu [%%dst+0*16], %%xtmp0 - movdqu [%%dst+1*16], %%xtmp1 - -%ifndef DEFLATE - pxor %%x2, %%xtmp0 - pxor %%x3, %%xtmp1 -%endif - test %%size, %%size - jz %%done ; if no bytes left, we're done - - add %%dst, 2*16 - add %%src, 2*16 - jmp %%partial - - -%%three_full_regs: - movntdqa %%xtmp0, [%%src+0*16] - movntdqa %%xtmp1, [%%src+1*16] - movntdqa %%xtmp2, [%%src+2*16] - -%ifndef DEFLATE - FOLD3 %%x0, %%x1, %%x2, %%x3, %%xfold, %%xtmp3 -%endif - movdqu [%%dst+0*16], %%xtmp0 - movdqu [%%dst+1*16], %%xtmp1 - movdqu [%%dst+2*16], %%xtmp2 - -%ifndef DEFLATE - pxor %%x1, %%xtmp0 - pxor %%x2, %%xtmp1 - pxor %%x3, %%xtmp2 -%endif - test %%size, %%size - jz %%done ; if no bytes left, we're done - - add %%dst, 3*16 - add %%src, 3*16 - - ; fall through to %%partial -%%partial: ; 0 <= %%size < 16 - -%ifndef DEFLATE - mov %%tmp, %%size -%endif - - LOAD_FRACTIONAL_XMM %%xtmp0, %%src, %%size - - movdqu [%%dst], %%xtmp0 - -%ifndef DEFLATE - PARTIAL_FOLD %%x0, %%x1, %%x2, %%x3, %%xtmp0, %%tmp, %%xfold, \ - %%xtmp1, %%xtmp2, %%xtmp3, %%xtmp4, %%dst -%endif - -%%done: -%endm - - -;%assign K 1024; -;%assign D 8 * K; ; Amount of history -;%assign LA 17 * 16; ; Max look-ahead, rounded up to 32 byte boundary - -; copy D + LA bytes from src to dst -; dst is aligned -;void copy_D_LA(uint8_t *dst, uint8_t *src); -; arg 1: rcx : dst -; arg 2: rdx : src -; copy_D_LA dst, src, tmp, xtmp0, xtmp1, xtmp2, xtmp3 -%macro copy_D_LA 7 -%define %%dst %1 ; reg, clobbered -%define %%src %2 ; reg, clobbered -%define %%tmp %3 -%define %%xtmp0 %4 -%define %%xtmp1 %5 -%define %%xtmp2 %6 -%define %%xtmp3 %7 - -%assign %%SIZE (D + LA) / 16 ; number of DQ words to be copied -%assign %%SIZE4 %%SIZE/4 - - lea %%tmp, [%%dst + 4 * 16 * %%SIZE4] - jmp %%copy_D_LA_1 -align 16 -%%copy_D_LA_1: - movdqu %%xtmp0, [%%src] - movdqu %%xtmp1, [%%src+16] - movdqu %%xtmp2, [%%src+32] - movdqu %%xtmp3, [%%src+48] - movdqa [%%dst], %%xtmp0 - movdqa [%%dst+16], %%xtmp1 - movdqa [%%dst+32], %%xtmp2 - movdqa [%%dst+48], %%xtmp3 - add %%src, 4*16 - add %%dst, 4*16 - cmp %%dst, %%tmp - jne %%copy_D_LA_1 -%assign %%i 0 -%rep (%%SIZE - 4 * %%SIZE4) - -%if (%%i == 0) - movdqu %%xtmp0, [%%src + %%i*16] -%elif (%%i == 1) - movdqu %%xtmp1, [%%src + %%i*16] -%elif (%%i == 2) - movdqu %%xtmp2, [%%src + %%i*16] -%elif (%%i == 3) - movdqu %%xtmp3, [%%src + %%i*16] -%else - %error too many i - % error -%endif - -%assign %%i %%i+1 -%endrep -%assign %%i 0 -%rep (%%SIZE - 4 * %%SIZE4) - -%if (%%i == 0) - movdqa [%%dst + %%i*16], %%xtmp0 -%elif (%%i == 1) - movdqa [%%dst + %%i*16], %%xtmp1 -%elif (%%i == 2) - movdqa [%%dst + %%i*16], %%xtmp2 -%elif (%%i == 3) - movdqa [%%dst + %%i*16], %%xtmp3 -%else - %error too many i - % error -%endif - -%assign %%i %%i+1 -%endrep -%endm -%endif diff --git a/ceph/src/isa-l/igzip/igzip_buffer_utils_04.asm b/ceph/src/isa-l/igzip/igzip_buffer_utils_04.asm deleted file mode 100644 index 94487cfc6..000000000 --- a/ceph/src/isa-l/igzip/igzip_buffer_utils_04.asm +++ /dev/null @@ -1,552 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Copyright(c) 2011-2016 Intel Corporation All rights reserved. -; -; 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 Intel Corporation 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 -; 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. -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -%ifndef BUFFER_UTILS -%define BUFFER_UTILS - -%include "options.asm" - -extern pshufb_shf_table -extern mask3 - -%ifdef FIX_CACHE_READ -%define vmovntdqa vmovdqa -%else -%macro prefetchnta 1 -%endm -%endif - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; code for doing the CRC calculation as part of copy-in, using pclmulqdq - -; "shift" 4 input registers down 4 places -; macro FOLD4 xmm0, xmm1, xmm2, xmm3, const, tmp0, tmp1 -%macro FOLD4 7 -%define %%xmm0 %1 ; xmm reg, in/out -%define %%xmm1 %2 ; xmm reg, in/out -%define %%xmm2 %3 ; xmm reg, in/out -%define %%xmm3 %4 ; xmm reg, in/out -%define %%const %5 ; xmm reg, in -%define %%tmp0 %6 ; xmm reg, tmp -%define %%tmp1 %7 ; xmm reg, tmp - - vmovaps %%tmp0, %%xmm0 - vmovaps %%tmp1, %%xmm1 - - vpclmulqdq %%xmm0, %%const, 0x01 - vpclmulqdq %%xmm1, %%const, 0x01 - - vpclmulqdq %%tmp0, %%const, 0x10 - vpclmulqdq %%tmp1, %%const, 0x10 - - vxorps %%xmm0, %%tmp0 - vxorps %%xmm1, %%tmp1 - - - vmovaps %%tmp0, %%xmm2 - vmovaps %%tmp1, %%xmm3 - - vpclmulqdq %%xmm2, %%const, 0x01 - vpclmulqdq %%xmm3, %%const, 0x01 - - vpclmulqdq %%tmp0, %%const, 0x10 - vpclmulqdq %%tmp1, %%const, 0x10 - - vxorps %%xmm2, %%tmp0 - vxorps %%xmm3, %%tmp1 -%endm - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; "shift" 3 input registers down 4 places -; macro FOLD3 x0, x1, x2, x3, const, tmp0 -; x0 x1 x2 x3 -; In A B C D -; Out D A' B' C' -%macro FOLD3 6 -%define %%x0 %1 ; xmm reg, in/out -%define %%x1 %2 ; xmm reg, in/out -%define %%x2 %3 ; xmm reg, in/out -%define %%x3 %4 ; xmm reg, in/out -%define %%const %5 ; xmm reg, in -%define %%tmp0 %6 ; xmm reg, tmp - - vmovdqa %%tmp0, %%x3 - - vmovaps %%x3, %%x2 - vpclmulqdq %%x2, %%const, 0x01 - vpclmulqdq %%x3, %%const, 0x10 - vxorps %%x3, %%x2 - - vmovaps %%x2, %%x1 - vpclmulqdq %%x1, %%const, 0x01 - vpclmulqdq %%x2, %%const, 0x10 - vxorps %%x2, %%x1 - - vmovaps %%x1, %%x0 - vpclmulqdq %%x0, %%const, 0x01 - vpclmulqdq %%x1, %%const, 0x10 - vxorps %%x1, %%x0 - - vmovdqa %%x0, %%tmp0 -%endm - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; "shift" 2 input registers down 4 places -; macro FOLD2 x0, x1, x2, x3, const, tmp0 -; x0 x1 x2 x3 -; In A B C D -; Out C D A' B' -%macro FOLD2 6 -%define %%x0 %1 ; xmm reg, in/out -%define %%x1 %2 ; xmm reg, in/out -%define %%x2 %3 ; xmm reg, in/out -%define %%x3 %4 ; xmm reg, in/out -%define %%const %5 ; xmm reg, in -%define %%tmp0 %6 ; xmm reg, tmp - - vmovdqa %%tmp0, %%x3 - - vmovaps %%x3, %%x1 - vpclmulqdq %%x1, %%const, 0x01 - vpclmulqdq %%x3, %%const, 0x10 - vxorps %%x3, %%x1 - - vmovdqa %%x1, %%tmp0 - vmovdqa %%tmp0, %%x2 - - vmovaps %%x2, %%x0 - vpclmulqdq %%x0, %%const, 0x01 - vpclmulqdq %%x2, %%const, 0x10 - vxorps %%x2, %%x0 - - vmovdqa %%x0, %%tmp0 -%endm - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; "shift" 1 input registers down 4 places -; macro FOLD1 x0, x1, x2, x3, const, tmp0 -; x0 x1 x2 x3 -; In A B C D -; Out B C D A' -%macro FOLD1 6 -%define %%x0 %1 ; xmm reg, in/out -%define %%x1 %2 ; xmm reg, in/out -%define %%x2 %3 ; xmm reg, in/out -%define %%x3 %4 ; xmm reg, in/out -%define %%const %5 ; xmm reg, in -%define %%tmp0 %6 ; xmm reg, tmp - - vmovdqa %%tmp0, %%x3 - - vmovaps %%x3, %%x0 - vpclmulqdq %%x0, %%const, 0x01 - vpclmulqdq %%x3, %%const, 0x10 - vxorps %%x3, %%x0 - - vmovdqa %%x0, %%x1 - vmovdqa %%x1, %%x2 - vmovdqa %%x2, %%tmp0 -%endm - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; macro PARTIAL_FOLD x0, x1, x2, x3, xp, size, xfold, xt0, xt1, xt2, xt3 - -; XP X3 X2 X1 X0 tmp2 -; Initial state xI HG FE DC BA -; after shift IH GF ED CB A0 -; after fold ff GF ED CB ff = merge(IH, A0) -; -%macro PARTIAL_FOLD 12 -%define %%x0 %1 ; xmm reg, in/out -%define %%x1 %2 ; xmm reg, in/out -%define %%x2 %3 ; xmm reg, in/out -%define %%x3 %4 ; xmm reg, in/out -%define %%xp %5 ; xmm partial reg, in/clobbered -%define %%size %6 ; GPR, in/clobbered (1...15) -%define %%const %7 ; xmm reg, in -%define %%shl %8 ; xmm reg, tmp -%define %%shr %9 ; xmm reg, tmp -%define %%tmp2 %10 ; xmm reg, tmp -%define %%tmp3 %11 ; xmm reg, tmp -%define %%gtmp %12 ; GPR, tmp - - ; {XP X3 X2 X1 X0} = {xI HG FE DC BA} - shl %%size, 4 ; size *= 16 - lea %%gtmp, [pshufb_shf_table - 16 WRT_OPT] - vmovdqa %%shl, [%%gtmp + %%size] ; shl constant - vmovdqa %%shr, %%shl - vpxor %%shr, [mask3 WRT_OPT] ; shr constant - - vmovdqa %%tmp2, %%x0 ; tmp2 = BA - vpshufb %%tmp2, %%shl ; tmp2 = A0 - - vpshufb %%x0, %%shr ; x0 = 0B - vmovdqa %%tmp3, %%x1 ; tmp3 = DC - vpshufb %%tmp3, %%shl ; tmp3 = C0 - vpor %%x0, %%tmp3 ; x0 = CB - - vpshufb %%x1, %%shr ; x1 = 0D - vmovdqa %%tmp3, %%x2 ; tmp3 = FE - vpshufb %%tmp3, %%shl ; tmp3 = E0 - vpor %%x1, %%tmp3 ; x1 = ED - - vpshufb %%x2, %%shr ; x2 = 0F - vmovdqa %%tmp3, %%x3 ; tmp3 = HG - vpshufb %%tmp3, %%shl ; tmp3 = G0 - vpor %%x2, %%tmp3 ; x2 = GF - - vpshufb %%x3, %%shr ; x3 = 0H - vpshufb %%xp, %%shl ; xp = I0 - vpor %%x3, %%xp ; x3 = IH - - ; fold tmp2 into X3 - vmovaps %%tmp3, %%tmp2 - vpclmulqdq %%tmp2, %%const, 0x01 - vpclmulqdq %%tmp3, %%const, 0x10 - vxorps %%x3, %%tmp2 - vxorps %%x3, %%tmp3 -%endm - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; LOAD_FRACTIONAL_XMM: Packs xmm register with data when data input is less than 16 bytes. -; Returns 0 if data has length 0. -; Input: The input data (src), that data's length (size). -; Output: The packed xmm register (xmm_out). -; size is clobbered. -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -%macro LOAD_FRACTIONAL_XMM 3 -%define %%xmm_out %1 ; %%xmm_out is an xmm register -%define %%src %2 -%define %%size %3 - - vpxor %%xmm_out, %%xmm_out - - cmp %%size, 0 - je %%_done - - add %%src, %%size - - cmp %%size, 8 - jl %%_byte_loop - - sub %%src, 8 - vpinsrq %%xmm_out, [%%src], 0 ;Read in 8 bytes if they exists - sub %%size, 8 - - je %%_done - -%%_byte_loop: ;Read in data 1 byte at a time while data is left - vpslldq %%xmm_out, 1 - - dec %%src - vpinsrb %%xmm_out, BYTE [%%src], 0 - dec %%size - - jg %%_byte_loop - -%%_done: - -%endmacro ; LOAD_FRACTIONAL_XMM - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; copy x bytes (rounded up to 16 bytes) from src to dst -; src & dst are unaligned -; macro COPY_IN_CRC dst, src, size_in_bytes, tmp, x0, x1, x2, x3, xfold, -; xt0, xt1, xt2, xt3, xt4 -%macro COPY_IN_CRC 14 -%define %%dst %1 ; reg, in/clobbered -%define %%src %2 ; reg, in/clobbered -%define %%size %3 ; reg, in/clobbered -%define %%tmp %4 ; reg, tmp -%define %%x0 %5 ; xmm, in/out: crc state -%define %%x1 %6 ; xmm, in/out: crc state -%define %%x2 %7 ; xmm, in/out: crc state -%define %%x3 %8 ; xmm, in/out: crc state -%define %%xfold %9 ; xmm, in: (loaded from fold4) -%define %%xtmp0 %10 ; xmm, tmp -%define %%xtmp1 %11 ; xmm, tmp -%define %%xtmp2 %12 ; xmm, tmp -%define %%xtmp3 %13 ; xmm, tmp -%define %%xtmp4 %14 ; xmm, tmp - - cmp %%size, 16 - jl %%lt_16 - - ; align source - xor %%tmp, %%tmp - sub %%tmp, %%src - and %%tmp, 15 - jz %%already_aligned - - ; need to align, tmp contains number of bytes to transfer - vmovdqu %%xtmp0, [%%src] - vmovdqu [%%dst], %%xtmp0 - add %%dst, %%tmp - add %%src, %%tmp - sub %%size, %%tmp - -%ifndef DEFLATE - push %%dst - - PARTIAL_FOLD %%x0, %%x1, %%x2, %%x3, %%xtmp0, %%tmp, %%xfold, \ - %%xtmp1, %%xtmp2, %%xtmp3, %%xtmp4, %%dst - pop %%dst -%endif - -%%already_aligned: - sub %%size, 64 - jl %%end_loop - jmp %%loop -align 16 -%%loop: - vmovntdqa %%xtmp0, [%%src+0*16] - vmovntdqa %%xtmp1, [%%src+1*16] - vmovntdqa %%xtmp2, [%%src+2*16] - -%ifndef DEFLATE - FOLD4 %%x0, %%x1, %%x2, %%x3, %%xfold, %%xtmp3, %%xtmp4 -%endif - vmovntdqa %%xtmp3, [%%src+3*16] - - vmovdqu [%%dst+0*16], %%xtmp0 - vmovdqu [%%dst+1*16], %%xtmp1 - vmovdqu [%%dst+2*16], %%xtmp2 - vmovdqu [%%dst+3*16], %%xtmp3 - -%ifndef DEFLATE - vpxor %%x0, %%xtmp0 - vpxor %%x1, %%xtmp1 - vpxor %%x2, %%xtmp2 - vpxor %%x3, %%xtmp3 -%endif - add %%src, 4*16 - add %%dst, 4*16 - sub %%size, 4*16 - jge %%loop - -%%end_loop: - ; %%size contains (num bytes left - 64) - add %%size, 16 - jge %%three_full_regs - add %%size, 16 - jge %%two_full_regs - add %%size, 16 - jge %%one_full_reg - add %%size, 16 - -%%no_full_regs: ; 0 <= %%size < 16, no full regs - jz %%done ; if no bytes left, we're done - jmp %%partial - - ;; Handle case where input is <16 bytes -%%lt_16: - test %%size, %%size - jz %%done ; if no bytes left, we're done - jmp %%partial - - -%%one_full_reg: - vmovntdqa %%xtmp0, [%%src+0*16] - -%ifndef DEFLATE - FOLD1 %%x0, %%x1, %%x2, %%x3, %%xfold, %%xtmp3 -%endif - vmovdqu [%%dst+0*16], %%xtmp0 - -%ifndef DEFLATE - vpxor %%x3, %%xtmp0 -%endif - test %%size, %%size - jz %%done ; if no bytes left, we're done - - add %%dst, 1*16 - add %%src, 1*16 - jmp %%partial - - -%%two_full_regs: - vmovntdqa %%xtmp0, [%%src+0*16] - vmovntdqa %%xtmp1, [%%src+1*16] - -%ifndef DEFLATE - FOLD2 %%x0, %%x1, %%x2, %%x3, %%xfold, %%xtmp3 -%endif - vmovdqu [%%dst+0*16], %%xtmp0 - vmovdqu [%%dst+1*16], %%xtmp1 - -%ifndef DEFLATE - vpxor %%x2, %%xtmp0 - vpxor %%x3, %%xtmp1 -%endif - test %%size, %%size - jz %%done ; if no bytes left, we're done - - add %%dst, 2*16 - add %%src, 2*16 - jmp %%partial - - -%%three_full_regs: - vmovntdqa %%xtmp0, [%%src+0*16] - vmovntdqa %%xtmp1, [%%src+1*16] - vmovntdqa %%xtmp2, [%%src+2*16] - -%ifndef DEFLATE - FOLD3 %%x0, %%x1, %%x2, %%x3, %%xfold, %%xtmp3 -%endif - vmovdqu [%%dst+0*16], %%xtmp0 - vmovdqu [%%dst+1*16], %%xtmp1 - vmovdqu [%%dst+2*16], %%xtmp2 - -%ifndef DEFLATE - vpxor %%x1, %%xtmp0 - vpxor %%x2, %%xtmp1 - vpxor %%x3, %%xtmp2 -%endif - test %%size, %%size - jz %%done ; if no bytes left, we're done - - add %%dst, 3*16 - add %%src, 3*16 - - ; fall through to %%partial -%%partial: ; 0 <= %%size < 16 - -%ifndef DEFLATE - mov %%tmp, %%size -%endif - - LOAD_FRACTIONAL_XMM %%xtmp0, %%src, %%size - - vmovdqu [%%dst], %%xtmp0 - -%ifndef DEFLATE - PARTIAL_FOLD %%x0, %%x1, %%x2, %%x3, %%xtmp0, %%tmp, %%xfold, \ - %%xtmp1, %%xtmp2, %%xtmp3, %%xtmp4, %%dst -%endif - -%%done: -%endm - - -;%assign K 1024; -;%assign D 8 * K; ; Amount of history -;%assign LA 17 * 16; ; Max look-ahead, rounded up to 32 byte boundary - -; copy D + LA bytes from src to dst -; dst is aligned -;void copy_D_LA(uint8_t *dst, uint8_t *src); -; arg 1: rcx : dst -; arg 2: rdx : src -; copy_D_LA dst, src, tmp, xtmp0, xtmp1, xtmp2, xtmp3 -%macro copy_D_LA 7 -%define %%dst %1 ; reg, clobbered -%define %%src %2 ; reg, clobbered -%define %%tmp %3 -%define %%ytmp0 %4 -%define %%ytmp1 %5 -%define %%ytmp2 %6 -%define %%ytmp3 %7 - -%define %%xtmp0 %4x - -%assign %%SIZE (D + LA) / 32 ; number of DQ words to be copied -%assign %%SIZE4 %%SIZE/4 -%assign %%MOD16 ((D + LA) - 32 * %%SIZE) / 16 - - lea %%tmp, [%%dst + 4 * 32 * %%SIZE4] - jmp %%copy_D_LA_1 -align 16 -%%copy_D_LA_1: - vmovdqu %%ytmp0, [%%src] - vmovdqu %%ytmp1, [%%src + 1 * 32] - vmovdqu %%ytmp2, [%%src + 2 * 32] - vmovdqu %%ytmp3, [%%src + 3 * 32] - vmovdqa [%%dst], %%ytmp0 - vmovdqa [%%dst + 1 * 32], %%ytmp1 - vmovdqa [%%dst + 2 * 32], %%ytmp2 - vmovdqa [%%dst + 3 * 32], %%ytmp3 - add %%src, 4*32 - add %%dst, 4*32 - cmp %%dst, %%tmp - jne %%copy_D_LA_1 -%assign %%i 0 -%rep (%%SIZE - 4 * %%SIZE4) - -%if (%%i == 0) - vmovdqu %%ytmp0, [%%src + %%i*32] -%elif (%%i == 1) - vmovdqu %%ytmp1, [%%src + %%i*32] -%elif (%%i == 2) - vmovdqu %%ytmp2, [%%src + %%i*32] -%elif (%%i == 3) - vmovdqu %%ytmp3, [%%src + %%i*32] -%else - %error too many i - % error -%endif - -%assign %%i %%i+1 -%endrep -%assign %%i 0 -%rep (%%SIZE - 4 * %%SIZE4) - -%if (%%i == 0) - vmovdqa [%%dst + %%i*32], %%ytmp0 -%elif (%%i == 1) - vmovdqa [%%dst + %%i*32], %%ytmp1 -%elif (%%i == 2) - vmovdqa [%%dst + %%i*32], %%ytmp2 -%elif (%%i == 3) - vmovdqa [%%dst + %%i*32], %%ytmp3 -%else - %error too many i - % error -%endif - -%assign %%i %%i+1 -%endrep - -%rep %%MOD16 - vmovdqu %%xtmp0, [%%src + (%%SIZE - 4 * %%SIZE4)*32] - vmovdqa [%%dst + (%%SIZE - 4 * %%SIZE4)*32], %%xtmp0 -%endrep - -%endm -%endif diff --git a/ceph/src/isa-l/igzip/igzip_check.c b/ceph/src/isa-l/igzip/igzip_check.c deleted file mode 100644 index 0ef79d958..000000000 --- a/ceph/src/isa-l/igzip/igzip_check.c +++ /dev/null @@ -1,1285 +0,0 @@ -/********************************************************************** - Copyright(c) 2011-2016 Intel Corporation All rights reserved. - - 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 Intel Corporation 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 - 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. -**********************************************************************/ - -#include -#include -#include -#include "igzip_lib.h" -#include "igzip_inflate_ref.h" -#include "crc_inflate.h" -#include - -#ifndef RANDOMS -# define RANDOMS 50 -#endif -#ifndef TEST_SEED -# define TEST_SEED 0x1234 -#endif - -#define IBUF_SIZE (1024*1024) - -#ifndef IGZIP_USE_GZIP_FORMAT -# define DEFLATE 1 -#endif - -#define str1 "Short test string" -#define str2 "one two three four five six seven eight nine ten eleven twelve " \ - "thirteen fourteen fifteen sixteen" - -#define TYPE0_HDR_SIZE 5 /* Size of a type 0 blocks header in bytes */ -#define TYPE0_MAX_SIZE 65535 /* Max length of a type 0 block in bytes (excludes the header) */ - -#define MAX_LOOPS 20 -/* Defines for the possible error conditions */ -enum IGZIP_TEST_ERROR_CODES { - IGZIP_COMP_OK, - - MALLOC_FAILED, - FILE_READ_FAILED, - - COMPRESS_INCORRECT_STATE, - COMPRESS_INPUT_STREAM_INTEGRITY_ERROR, - COMPRESS_OUTPUT_STREAM_INTEGRITY_ERROR, - COMPRESS_END_OF_STREAM_NOT_SET, - COMPRESS_ALL_INPUT_FAIL, - COMPRESS_OUT_BUFFER_OVERFLOW, - COMPRESS_LOOP_COUNT_OVERFLOW, - COMPRESS_GENERAL_ERROR, - - INFLATE_END_OF_INPUT, - INFLATE_INVALID_BLOCK_HEADER, - INFLATE_INVALID_SYMBOL, - INFLATE_OUT_BUFFER_OVERFLOW, - INFLATE_INVALID_NON_COMPRESSED_BLOCK_LENGTH, - INFLATE_LEFTOVER_INPUT, - INFLATE_INCORRECT_OUTPUT_SIZE, - INFLATE_INVALID_LOOK_BACK_DISTANCE, - INVALID_GZIP_HEADER, - INCORRECT_GZIP_TRAILER, - INFLATE_GENERAL_ERROR, - - INVALID_FLUSH_ERROR, - - OVERFLOW_TEST_ERROR, - RESULT_ERROR -}; - -const int hdr_bytes = 300; - -#ifndef DEFLATE -const uint8_t gzip_hdr[10] = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff -}; - -const uint32_t gzip_hdr_bytes = 10; -const uint32_t gzip_trl_bytes = 8; - -const int trl_bytes = 8; -const int gzip_extra_bytes = 18; - -#else -const int trl_bytes = 0; -const int gzip_extra_bytes = 0; - -#endif - -#define HISTORY_SIZE 32*1024 -#define MIN_LENGTH 3 -#define MIN_DIST 1 - -/* Create random compressible data. This is achieved by randomly choosing a - * random character, or to repeat previous data in the stream for a random - * length and look back distance. The probability of a random character or a - * repeat being chosen is semi-randomly chosen by setting max_repeat_data to be - * differing values */ -void create_rand_repeat_data(uint8_t * data, int size) -{ - uint32_t next_data; - uint8_t *data_start = data; - uint32_t length, distance; - uint32_t max_repeat_data = 256; - uint32_t power = rand() % 32; - /* An array of the powers of 2 (except the final element which is 0) */ - const uint32_t power_of_2_array[] = { - 0x00000001, 0x00000002, 0x00000004, 0x00000008, - 0x00000010, 0x00000020, 0x00000040, 0x00000080, - 0x00000100, 0x00000200, 0x00000400, 0x00000800, - 0x00001000, 0x00002000, 0x00004000, 0x00008000, - 0x00010000, 0x00020000, 0x00040000, 0x00080000, - 0x00100000, 0x00200000, 0x00400000, 0x00800000, - 0x01000000, 0x02000000, 0x04000000, 0x08000000, - 0x10000000, 0x20000000, 0x40000000, 0x00000000 - }; - - max_repeat_data += power_of_2_array[power]; - - if (size-- > 0) - *data++ = rand(); - - while (size > 0) { - next_data = rand() % max_repeat_data; - if (next_data < 256) { - *data++ = next_data; - size--; - } else if (size < 3) { - *data++ = rand() % 256; - size--; - } else { - length = (rand() % 256) + MIN_LENGTH; - if (length > size) - length = (rand() % (size - 2)) + MIN_LENGTH; - - distance = (rand() % HISTORY_SIZE) + MIN_DIST; - if (distance > data - data_start) - distance = (rand() % (data - data_start)) + MIN_DIST; - - size -= length; - if (distance <= length) { - while (length-- > 0) { - *data = *(data - distance); - data++; - } - } else - memcpy(data, data - distance, length); - } - } -} - -void print_error(int error_code) -{ - switch (error_code) { - case IGZIP_COMP_OK: - break; - case MALLOC_FAILED: - printf("error: failed to allocate memory\n"); - break; - case FILE_READ_FAILED: - printf("error: failed to read in file\n"); - break; - case COMPRESS_INCORRECT_STATE: - printf("error: incorrect stream internal state\n"); - break; - case COMPRESS_INPUT_STREAM_INTEGRITY_ERROR: - printf("error: inconsistent stream input buffer\n"); - break; - case COMPRESS_OUTPUT_STREAM_INTEGRITY_ERROR: - printf("error: inconsistent stream output buffer\n"); - break; - case COMPRESS_END_OF_STREAM_NOT_SET: - printf("error: end of stream not set\n"); - break; - case COMPRESS_ALL_INPUT_FAIL: - printf("error: not all input data compressed\n"); - break; - case COMPRESS_OUT_BUFFER_OVERFLOW: - printf("error: output buffer overflow while compressing data\n"); - break; - case COMPRESS_GENERAL_ERROR: - printf("error: compression failed\n"); - break; - case INFLATE_END_OF_INPUT: - printf("error: did not decompress all input\n"); - break; - case INFLATE_INVALID_BLOCK_HEADER: - printf("error: invalid header\n"); - break; - case INFLATE_INVALID_SYMBOL: - printf("error: invalid symbol found when decompressing input\n"); - break; - case INFLATE_OUT_BUFFER_OVERFLOW: - printf("error: output buffer overflow while decompressing data\n"); - break; - case INFLATE_INVALID_NON_COMPRESSED_BLOCK_LENGTH: - printf("error: invalid length bits in non-compressed block\n"); - break; - case INFLATE_GENERAL_ERROR: - printf("error: decompression failed\n"); - break; - case INFLATE_LEFTOVER_INPUT: - printf("error: the trailer of igzip output contains junk\n"); - break; - case INFLATE_INCORRECT_OUTPUT_SIZE: - printf("error: incorrect amount of data was decompressed\n"); - break; - case INFLATE_INVALID_LOOK_BACK_DISTANCE: - printf("error: invalid look back distance found while decompressing\n"); - break; - case INVALID_GZIP_HEADER: - printf("error: incorrect gzip header found when inflating data\n"); - break; - case INCORRECT_GZIP_TRAILER: - printf("error: incorrect gzip trailer found when inflating data\n"); - break; - case INVALID_FLUSH_ERROR: - printf("error: invalid flush did not cause compression to error\n"); - break; - case RESULT_ERROR: - printf("error: decompressed data is not the same as the compressed data\n"); - break; - case OVERFLOW_TEST_ERROR: - printf("error: overflow undetected\n"); - break; - default: - printf("error: unknown error code\n"); - } -} - -void print_uint8_t(uint8_t * array, uint64_t length) -{ - int i; - - const int line_size = 16; - printf("Length = %lu", length); - for (i = 0; i < length; i++) { - if ((i % line_size) == 0) - printf("\n0x%08x\t", i); - else - printf(" "); - printf("0x%02x,", array[i]); - } - printf("\n"); -} - -#ifndef DEFLATE -uint32_t check_gzip_header(uint8_t * z_buf) -{ - /* These values are defined in RFC 1952 page 4 */ - const uint8_t ID1 = 0x1f, ID2 = 0x8b, CM = 0x08, FLG = 0; - uint32_t ret = 0; - int i; - /* Verify that the gzip header is the one used in hufftables_c.c */ - for (i = 0; i < gzip_hdr_bytes; i++) - if (z_buf[i] != gzip_hdr[i]) - ret = INVALID_GZIP_HEADER; - - /* Verify that the gzip header is a valid gzip header */ - if (*z_buf++ != ID1) - ret = INVALID_GZIP_HEADER; - - if (*z_buf++ != ID2) - ret = INVALID_GZIP_HEADER; - - /* Verfiy compression method is Deflate */ - if (*z_buf++ != CM) - ret = INVALID_GZIP_HEADER; - - /* The following comparison is specific to how gzip headers are written in igzip */ - /* Verify no extra flags are set */ - if (*z_buf != FLG) - ret = INVALID_GZIP_HEADER; - - /* The last 6 bytes in the gzip header do not contain any information - * important to decomrpessing the data */ - - return ret; -} - -uint32_t check_gzip_trl(struct inflate_state * gstream) -{ - uint8_t *index = NULL; - uint32_t crc, ret = 0; - - index = gstream->out_buffer.next_out - gstream->out_buffer.total_out; - crc = find_crc(index, gstream->out_buffer.total_out); - - if (gstream->out_buffer.total_out != *(uint32_t *) (gstream->in_buffer.next_in + 4) || - crc != *(uint32_t *) gstream->in_buffer.next_in) - ret = INCORRECT_GZIP_TRAILER; - - return ret; -} -#endif - -/* Inflate the compressed data and check that the decompressed data agrees with the input data */ -int inflate_check(uint8_t * z_buf, int z_size, uint8_t * in_buf, int in_size) -{ - /* Test inflate with reference inflate */ - - int ret = 0; - struct inflate_state gstream; - uint32_t test_size = in_size; - uint8_t *test_buf = NULL; - int mem_result = 0; - - assert(in_buf != NULL); - - if (in_size > 0) { - test_buf = malloc(test_size); - - if (test_buf == NULL) - return MALLOC_FAILED; - } - if (test_buf != NULL) - memset(test_buf, 0xff, test_size); - -#ifndef DEFLATE - int gzip_hdr_result, gzip_trl_result; - - gzip_hdr_result = check_gzip_header(z_buf); - z_buf += gzip_hdr_bytes; - z_size -= gzip_hdr_bytes; -#endif - - igzip_inflate_init(&gstream, z_buf, z_size, test_buf, test_size); - ret = igzip_inflate(&gstream); - - if (test_buf != NULL) - mem_result = memcmp(in_buf, test_buf, in_size); - -#ifdef VERBOSE - int i; - if (mem_result) - for (i = 0; i < in_size; i++) { - if (in_buf[i] != test_buf[i]) { - printf("First incorrect data at 0x%x of 0x%x, 0x%x != 0x%x\n", - i, in_size, in_buf[i], test_buf[i]); - break; - } - } -#endif - -#ifndef DEFLATE - gzip_trl_result = check_gzip_trl(&gstream); - gstream.in_buffer.avail_in -= gzip_trl_bytes; - gstream.in_buffer.next_in += gzip_trl_bytes; -#endif - - if (test_buf != NULL) - free(test_buf); - - switch (ret) { - case 0: - break; - case END_OF_INPUT: - return INFLATE_END_OF_INPUT; - break; - case INVALID_BLOCK_HEADER: - return INFLATE_INVALID_BLOCK_HEADER; - break; - case INVALID_SYMBOL: - return INFLATE_INVALID_SYMBOL; - break; - case OUT_BUFFER_OVERFLOW: - return INFLATE_OUT_BUFFER_OVERFLOW; - break; - case INVALID_NON_COMPRESSED_BLOCK_LENGTH: - return INFLATE_INVALID_NON_COMPRESSED_BLOCK_LENGTH; - break; - case INVALID_LOOK_BACK_DISTANCE: - return INFLATE_INVALID_LOOK_BACK_DISTANCE; - break; - default: - return INFLATE_GENERAL_ERROR; - break; - } - - if (gstream.in_buffer.avail_in != 0) - return INFLATE_LEFTOVER_INPUT; - - if (gstream.out_buffer.total_out != in_size) - return INFLATE_INCORRECT_OUTPUT_SIZE; - - if (mem_result) - return RESULT_ERROR; - -#ifndef DEFLATE - if (gzip_hdr_result) - return INVALID_GZIP_HEADER; - - if (gzip_trl_result) - return INCORRECT_GZIP_TRAILER; -#endif - - return 0; -} - -/* Check if that the state of the data stream is consistent */ -int stream_valid_check(struct isal_zstream *stream, uint8_t * in_buf, uint32_t in_size, - uint8_t * out_buf, uint32_t out_size, uint32_t in_processed, - uint32_t out_processed, uint32_t data_size) -{ - uint32_t total_in, in_buffer_size, total_out, out_buffer_size; - - total_in = - (in_size == - 0) ? in_processed : (in_processed - in_size) + (stream->next_in - in_buf); - in_buffer_size = (in_size == 0) ? 0 : stream->next_in - in_buf + stream->avail_in; - - /* Check for a consistent amount of data processed */ - if (total_in != stream->total_in || in_buffer_size != in_size) - return COMPRESS_INPUT_STREAM_INTEGRITY_ERROR; - - total_out = - (out_size == 0) ? out_processed : out_processed + (stream->next_out - out_buf); - out_buffer_size = (out_size == 0) ? 0 : stream->next_out - out_buf + stream->avail_out; - - /* Check for a consistent amount of data compressed */ - if (total_out != stream->total_out || out_buffer_size != out_size) { - return COMPRESS_OUTPUT_STREAM_INTEGRITY_ERROR; - } - - return 0; -} - -/* Performs compression with checks to discover and verify the state of the - * stream - * stream: compress data structure which has been initialized to use - * in_buf and out_buf as the buffers - * data_size: size of all input data - * compressed_size: size of all available output buffers - * in_buf: next buffer of data to be compressed - * in_size: size of in_buf - * out_buf: next out put buffer where data is stored - * out_size: size of out_buf - * in_processed: the amount of input data which has been loaded into buffers - * to be compressed, this includes the data in in_buf - * out_processed: the amount of output data which has been compressed and stored, - * this does not include the data in the current out_buf -*/ -int isal_deflate_with_checks(struct isal_zstream *stream, uint32_t data_size, - uint32_t compressed_size, uint8_t * in_buf, uint32_t in_size, - uint32_t in_processed, uint8_t * out_buf, uint32_t out_size, - uint32_t out_processed) -{ - int ret, stream_check; - struct isal_zstate *state = &stream->internal_state; - -#ifdef VERBOSE - printf("Pre compression\n"); - printf - ("data_size = 0x%05x, in_processed = 0x%05x, in_size = 0x%05x, avail_in = 0x%05x, total_in = 0x%05x\n", - data_size, in_processed, in_size, stream->avail_in, stream->total_in); - printf - ("compressed_size = 0x%05x, out_processed = 0x%05x, out_size = 0x%05x, avail_out = 0x%05x, total_out = 0x%05x\n", - compressed_size, out_processed, out_size, stream->avail_out, stream->total_out); -#endif - - ret = isal_deflate(stream); - -#ifdef VERBOSE - printf("Post compression\n"); - printf - ("data_size = 0x%05x, in_processed = 0x%05x, in_size = 0x%05x, avail_in = 0x%05x, total_in = 0x%05x\n", - data_size, in_processed, in_size, stream->avail_in, stream->total_in); - printf - ("compressed_size = 0x%05x, out_processed = 0x%05x, out_size = 0x%05x, avail_out = 0x%05x, total_out = 0x%05x\n", - compressed_size, out_processed, out_size, stream->avail_out, stream->total_out); - printf("\n\n"); -#endif - - /* Verify the stream is in a valid state */ - stream_check = stream_valid_check(stream, in_buf, in_size, out_buf, out_size, - in_processed, out_processed, data_size); - - if (stream_check != 0) - return stream_check; - - if (ret != IGZIP_COMP_OK) - return COMPRESS_GENERAL_ERROR; - - /* Check if the compression is completed */ - if (state->state != ZSTATE_END) - if (compressed_size - out_processed - (out_size - stream->avail_out) <= 0) - return COMPRESS_OUT_BUFFER_OVERFLOW; - - return ret; - -} - -/* Compress the input data into the output buffer where the input buffer and - * output buffer are randomly segmented to test state information for the - * compression*/ -int compress_multi_pass(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf, - uint32_t * compressed_size, uint32_t flush_type) -{ - int ret = IGZIP_COMP_OK; - uint8_t *in_buf = NULL, *out_buf = NULL; - uint32_t in_size = 0, out_size = 0; - uint32_t in_processed = 0, out_processed = 0; - struct isal_zstream stream; - struct isal_zstate *state = &stream.internal_state; - uint32_t loop_count = 0; - -#ifdef VERBOSE - printf("Starting Compress Multi Pass\n"); -#endif - - create_rand_repeat_data((uint8_t *) & stream, sizeof(stream)); - - isal_deflate_init(&stream); - - if (state->state != ZSTATE_NEW_HDR) - return COMPRESS_INCORRECT_STATE; - - stream.flush = flush_type; - stream.end_of_stream = 0; - - /* These are set here to allow the loop to run correctly */ - stream.avail_in = 0; - stream.avail_out = 0; - - while (1) { - loop_count++; - - /* Setup in buffer for next round of compression */ - if (stream.avail_in == 0) { - if (flush_type != SYNC_FLUSH || state->state == ZSTATE_NEW_HDR) { - /* Randomly choose size of the next out buffer */ - in_size = rand() % (data_size + 1); - - /* Limit size of buffer to be smaller than maximum */ - if (in_size >= data_size - in_processed) { - in_size = data_size - in_processed; - stream.end_of_stream = 1; - } - - if (in_size != 0) { - if (in_buf != NULL) { - free(in_buf); - in_buf = NULL; - } - - in_buf = malloc(in_size); - if (in_buf == NULL) { - ret = MALLOC_FAILED; - break; - } - memcpy(in_buf, data + in_processed, in_size); - in_processed += in_size; - - stream.avail_in = in_size; - stream.next_in = in_buf; - } - } - } - - /* Setup out buffer for next round of compression */ - if (stream.avail_out == 0) { - /* Save compressed data inot compressed_buf */ - if (out_buf != NULL) { - memcpy(compressed_buf + out_processed, out_buf, - out_size - stream.avail_out); - out_processed += out_size - stream.avail_out; - } - - /* Randomly choose size of the next out buffer */ - out_size = rand() % (*compressed_size + 1); - - /* Limit size of buffer to be smaller than maximum */ - if (out_size > *compressed_size - out_processed) - out_size = *compressed_size - out_processed; - - if (out_size != 0) { - if (out_buf != NULL) { - free(out_buf); - out_buf = NULL; - } - - out_buf = malloc(out_size); - if (out_buf == NULL) { - ret = MALLOC_FAILED; - break; - } - - stream.avail_out = out_size; - stream.next_out = out_buf; - } - } - - ret = - isal_deflate_with_checks(&stream, data_size, *compressed_size, in_buf, - in_size, in_processed, out_buf, out_size, - out_processed); - - if (ret) { - if (ret == COMPRESS_OUT_BUFFER_OVERFLOW - || ret == COMPRESS_INCORRECT_STATE) - memcpy(compressed_buf + out_processed, out_buf, out_size); - break; - } - - /* Check if the compression is completed */ - if (state->state == ZSTATE_END) { - memcpy(compressed_buf + out_processed, out_buf, out_size); - *compressed_size = stream.total_out; - break; - } - - } - - if (in_buf != NULL) - free(in_buf); - if (out_buf != NULL) - free(out_buf); - - if (ret == COMPRESS_OUT_BUFFER_OVERFLOW && flush_type == SYNC_FLUSH - && loop_count >= MAX_LOOPS) - ret = COMPRESS_LOOP_COUNT_OVERFLOW; - - return ret; - -} - -/* Compress the input data into the outbuffer in one call to isal_deflate */ -int compress_single_pass(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf, - uint32_t * compressed_size, uint32_t flush_type) -{ - int ret = IGZIP_COMP_OK; - struct isal_zstream stream; - struct isal_zstate *state = &stream.internal_state; - -#ifdef VERBOSE - printf("Starting Compress Single Pass\n"); -#endif - - create_rand_repeat_data((uint8_t *) & stream, sizeof(stream)); - - isal_deflate_init(&stream); - - if (state->state != ZSTATE_NEW_HDR) - return COMPRESS_INCORRECT_STATE; - - stream.flush = flush_type; - stream.avail_in = data_size; - stream.next_in = data; - stream.avail_out = *compressed_size; - stream.next_out = compressed_buf; - stream.end_of_stream = 1; - - ret = - isal_deflate_with_checks(&stream, data_size, *compressed_size, data, data_size, - data_size, compressed_buf, *compressed_size, 0); - - /* Check if the compression is completed */ - if (state->state == ZSTATE_END) - *compressed_size = stream.total_out; - else if (flush_type == SYNC_FLUSH && stream.avail_out < 16) - ret = COMPRESS_OUT_BUFFER_OVERFLOW; - - return ret; - -} - -/* Statelessly compress the input buffer into the output buffer */ -int compress_stateless(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf, - uint32_t * compressed_size) -{ - int ret = IGZIP_COMP_OK; - struct isal_zstream stream; - - create_rand_repeat_data((uint8_t *) & stream, sizeof(stream)); - - isal_deflate_init(&stream); - - stream.avail_in = data_size; - stream.end_of_stream = 1; - stream.next_in = data; - stream.flush = NO_FLUSH; - - stream.avail_out = *compressed_size; - stream.next_out = compressed_buf; - - ret = isal_deflate_stateless(&stream); - - /* verify the stream */ - if (stream.next_in - data != stream.total_in || - stream.total_in + stream.avail_in != data_size) - return COMPRESS_INPUT_STREAM_INTEGRITY_ERROR; - - if (stream.next_out - compressed_buf != stream.total_out || - stream.total_out + stream.avail_out != *compressed_size) - return COMPRESS_OUTPUT_STREAM_INTEGRITY_ERROR; - - if (ret != IGZIP_COMP_OK) { - if (ret == STATELESS_OVERFLOW) - return COMPRESS_OUT_BUFFER_OVERFLOW; - else - return COMPRESS_GENERAL_ERROR; - } - - if (!stream.end_of_stream) { - return COMPRESS_END_OF_STREAM_NOT_SET; - } - - if (stream.avail_in != 0) - return COMPRESS_ALL_INPUT_FAIL; - - *compressed_size = stream.total_out; - - return ret; - -} - -/*Compress the input buffer into the output buffer, but switch the flush type in - * the middle of the compression to test what happens*/ -int compress_swap_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf, - uint32_t * compressed_size, uint32_t flush_type) -{ - int ret = IGZIP_COMP_OK; - struct isal_zstream stream; - struct isal_zstate *state = &stream.internal_state; - uint32_t partial_size; - -#ifdef VERBOSE - printf("Starting Compress Swap Flush\n"); -#endif - - isal_deflate_init(&stream); - - if (state->state != ZSTATE_NEW_HDR) - return COMPRESS_INCORRECT_STATE; - - partial_size = rand() % (data_size + 1); - - stream.flush = flush_type; - stream.avail_in = partial_size; - stream.next_in = data; - stream.avail_out = *compressed_size; - stream.next_out = compressed_buf; - stream.end_of_stream = 0; - - ret = - isal_deflate_with_checks(&stream, data_size, *compressed_size, data, partial_size, - partial_size, compressed_buf, *compressed_size, 0); - - if (ret) - return ret; - - if (flush_type == NO_FLUSH) - flush_type = SYNC_FLUSH; - else - flush_type = NO_FLUSH; - - stream.flush = flush_type; - stream.avail_in = data_size - partial_size; - stream.next_in = data + partial_size; - stream.end_of_stream = 1; - - ret = - isal_deflate_with_checks(&stream, data_size, *compressed_size, data + partial_size, - data_size - partial_size, data_size, compressed_buf, - *compressed_size, 0); - - if (ret == COMPRESS_GENERAL_ERROR) - return INVALID_FLUSH_ERROR; - - *compressed_size = stream.total_out; - - return ret; -} - -/* Test isal_deflate_stateless */ -int test_compress_stateless(uint8_t * in_buf, uint32_t in_size) -{ - int ret = IGZIP_COMP_OK; - uint32_t z_size, overflow; - uint8_t *z_buf = NULL; - - /* Test non-overflow case where a type 0 block is not written */ - z_size = 2 * in_size + hdr_bytes + trl_bytes; - - z_buf = malloc(z_size); - - if (z_buf == NULL) - return MALLOC_FAILED; - create_rand_repeat_data(z_buf, z_size); - - ret = compress_stateless(in_buf, in_size, z_buf, &z_size); - - if (!ret) - ret = inflate_check(z_buf, z_size, in_buf, in_size); - - if (z_buf != NULL) { - free(z_buf); - z_buf = NULL; - } - - print_error(ret); - - /*Test non-overflow case where a type 0 block is possible to be written */ - z_size = - TYPE0_HDR_SIZE * ((in_size + TYPE0_MAX_SIZE - 1) / TYPE0_MAX_SIZE) + in_size + - gzip_extra_bytes; - - if (z_size == gzip_extra_bytes) - z_size += TYPE0_HDR_SIZE; - - if (z_size < 8) - z_size = 8; - - z_buf = malloc(z_size); - - if (z_buf == NULL) - return MALLOC_FAILED; - - create_rand_repeat_data(z_buf, z_size); - - ret = compress_stateless(in_buf, in_size, z_buf, &z_size); - if (!ret) - ret = inflate_check(z_buf, z_size, in_buf, in_size); -#ifdef VERBOSE - if (ret) { - printf("Compressed array: "); - print_uint8_t(z_buf, z_size); - printf("\n"); - printf("Data: "); - print_uint8_t(in_buf, in_size); - } -#endif - - if (!ret) { - free(z_buf); - z_buf = NULL; - - /* Test random overflow case */ - z_size = rand() % z_size; - - if (z_size > in_size) - z_size = rand() & in_size; - - if (z_size > 0) { - z_buf = malloc(z_size); - - if (z_buf == NULL) - return MALLOC_FAILED; - } - - overflow = compress_stateless(in_buf, in_size, z_buf, &z_size); - - if (overflow != COMPRESS_OUT_BUFFER_OVERFLOW) { -#ifdef VERBOSE - printf("overflow error = %d\n", overflow); - print_error(overflow); - if (overflow == 0) { - overflow = inflate_check(z_buf, z_size, in_buf, in_size); - printf("inflate ret = %d\n", overflow); - print_error(overflow); - } - printf("Compressed array: "); - print_uint8_t(z_buf, z_size); - printf("\n"); - printf("Data: "); - print_uint8_t(in_buf, in_size); -#endif - ret = OVERFLOW_TEST_ERROR; - } - } - - print_error(ret); - - if (z_buf != NULL) - free(z_buf); - - return ret; -} - -/* Test isal_deflate */ -int test_compress(uint8_t * in_buf, uint32_t in_size, uint32_t flush_type) -{ - int ret = IGZIP_COMP_OK, fin_ret = IGZIP_COMP_OK; - uint32_t overflow = 0; - uint32_t z_size, z_size_max, z_compressed_size; - uint8_t *z_buf = NULL; - - /* Test a non overflow case */ - if (flush_type == NO_FLUSH) - z_size_max = 2 * in_size + hdr_bytes + trl_bytes + 2; - else if (flush_type == SYNC_FLUSH) - z_size_max = 2 * in_size + MAX_LOOPS * (hdr_bytes + trl_bytes + 5); - else { - printf("Invalid Flush Parameter\n"); - return COMPRESS_GENERAL_ERROR; - } - - z_size = z_size_max; - - z_buf = malloc(z_size); - if (z_buf == NULL) { - print_error(MALLOC_FAILED); - return MALLOC_FAILED; - } - create_rand_repeat_data(z_buf, z_size_max); - - ret = compress_single_pass(in_buf, in_size, z_buf, &z_size, flush_type); - - if (!ret) - ret = inflate_check(z_buf, z_size, in_buf, in_size); - - if (ret) { -#ifdef VERBOSE - printf("Compressed array: "); - print_uint8_t(z_buf, z_size); - printf("\n"); - printf("Data: "); - print_uint8_t(in_buf, in_size); -#endif - printf("Failed on compress single pass\n"); - print_error(ret); - } - - fin_ret |= ret; - - z_compressed_size = z_size; - z_size = z_size_max; - create_rand_repeat_data(z_buf, z_size_max); - - ret = compress_multi_pass(in_buf, in_size, z_buf, &z_size, flush_type); - - if (!ret) - ret = inflate_check(z_buf, z_size, in_buf, in_size); - - if (ret) { -#ifdef VERBOSE - printf("Compressed array: "); - print_uint8_t(z_buf, z_size); - printf("\n"); - printf("Data: "); - print_uint8_t(in_buf, in_size); -#endif - printf("Failed on compress multi pass\n"); - print_error(ret); - } - - fin_ret |= ret; - - ret = 0; - - /* Test random overflow case */ - if (flush_type == SYNC_FLUSH && z_compressed_size > in_size) - z_compressed_size = in_size + 1; - - z_size = rand() % z_compressed_size; - create_rand_repeat_data(z_buf, z_size_max); - - overflow = compress_single_pass(in_buf, in_size, z_buf, &z_size, flush_type); - - if (overflow != COMPRESS_OUT_BUFFER_OVERFLOW) { - if (overflow == 0) - ret = inflate_check(z_buf, z_size, in_buf, in_size); - - /* Rarely single pass overflow will compresses data - * better than the initial run. This is to stop that - * case from erroring. */ - if (overflow != 0 || ret != 0) { -#ifdef VERBOSE - printf("overflow error = %d\n", overflow); - print_error(overflow); - printf("inflate ret = %d\n", ret); - print_error(overflow); - - printf("Compressed array: "); - print_uint8_t(z_buf, z_size); - printf("\n"); - printf("Data: "); - print_uint8_t(in_buf, in_size); -#endif - printf("Failed on compress multi pass overflow\n"); - print_error(ret); - ret = OVERFLOW_TEST_ERROR; - } - } - - fin_ret |= ret; - - if (flush_type == NO_FLUSH) { - create_rand_repeat_data(z_buf, z_size_max); - - overflow = compress_multi_pass(in_buf, in_size, z_buf, &z_size, flush_type); - - if (overflow != COMPRESS_OUT_BUFFER_OVERFLOW) { - if (overflow == 0) - ret = inflate_check(z_buf, z_size, in_buf, in_size); - - /* Rarely multi pass overflow will compresses data - * better than the initial run. This is to stop that - * case from erroring */ - if (overflow != 0 || ret != 0) { -#ifdef VERBOSE - printf("overflow error = %d\n", overflow); - print_error(overflow); - printf("inflate ret = %d\n", ret); - print_error(overflow); - - printf("Compressed array: "); - print_uint8_t(z_buf, z_size); - printf("\n"); - printf("Data: "); - print_uint8_t(in_buf, in_size); -#endif - printf("Failed on compress multi pass overflow\n"); - print_error(ret); - ret = OVERFLOW_TEST_ERROR; - } - } - fin_ret |= ret; - } - - free(z_buf); - - return fin_ret; -} - -/* Test swapping flush types in the middle of compression */ -int test_flush(uint8_t * in_buf, uint32_t in_size) -{ - int fin_ret = IGZIP_COMP_OK, ret; - uint32_t z_size, flush_type = 0; - uint8_t *z_buf = NULL; - - z_size = 2 * in_size + 2 * (hdr_bytes + trl_bytes) + 8; - - z_buf = malloc(z_size); - - if (z_buf == NULL) - return MALLOC_FAILED; - - create_rand_repeat_data(z_buf, z_size); - - while (flush_type == NO_FLUSH || flush_type == SYNC_FLUSH) - flush_type = rand(); - - /* Test invalid flush */ - ret = compress_single_pass(in_buf, in_size, z_buf, &z_size, flush_type); - - if (ret == COMPRESS_GENERAL_ERROR) - ret = 0; - else { - printf("Failed when passing invalid flush parameter\n"); - ret = INVALID_FLUSH_ERROR; - } - - fin_ret |= ret; - print_error(ret); - - create_rand_repeat_data(z_buf, z_size); - - /* Test the valid case of SYNC_FLUSH followed by NO_FLUSH */ - ret = compress_swap_flush(in_buf, in_size, z_buf, &z_size, rand() % 2); - - if (!ret) - ret = inflate_check(z_buf, z_size, in_buf, in_size); - - if (ret) { -#ifdef VERBOSE - printf("Compressed array: "); - print_uint8_t(z_buf, z_size); - printf("\n"); - printf("Data: "); - print_uint8_t(in_buf, in_size); -#endif - printf("Failed on swapping from SYNC_FLUSH to NO_FLUSH\n"); - print_error(ret); - } - - fin_ret |= ret; - print_error(ret); - - return fin_ret; -} - -int get_filesize(FILE * f) -{ - int curr, end; - - curr = ftell(f); /* Save current position */ - fseek(f, 0L, SEEK_END); - end = ftell(f); - fseek(f, curr, SEEK_SET); /* Restore position */ - return end; -} - -/* Run multiple compression tests on data stored in a file */ -int test_compress_file(char *file_name) -{ - int ret = IGZIP_COMP_OK; - uint32_t in_size; - uint8_t *in_buf = NULL; - FILE *in_file = NULL; - - in_file = fopen(file_name, "rb"); - if (!in_file) - return FILE_READ_FAILED; - - in_size = get_filesize(in_file); - if (in_size != 0) { - in_buf = malloc(in_size); - if (in_buf == NULL) - return MALLOC_FAILED; - fread(in_buf, 1, in_size, in_file); - } - - ret |= test_compress_stateless(in_buf, in_size); - ret |= test_compress(in_buf, in_size, NO_FLUSH); - ret |= test_compress(in_buf, in_size, SYNC_FLUSH); - ret |= test_flush(in_buf, in_size); - - if (ret) - printf("Failed on file %s\n", file_name); - - if (in_buf != NULL) - free(in_buf); - - return ret; -} - -int main(int argc, char *argv[]) -{ - int i = 0, ret = 0, fin_ret = 0; - uint32_t in_size = 0, offset = 0; - uint8_t *in_buf; - -#ifndef VERBOSE - setbuf(stdout, NULL); -#endif - - printf("Window Size: %d K\n", HIST_SIZE); - printf("Test Seed : %d\n", TEST_SEED); - printf("Randoms : %d\n", RANDOMS); - srand(TEST_SEED); - - in_buf = malloc(IBUF_SIZE); - if (in_buf == NULL) { - fprintf(stderr, "Can't allocate in_buf memory\n"); - return -1; - } - - if (argc > 1) { - printf("igzip_rand_test files: "); - - for (i = 1; i < argc; i++) { - ret |= test_compress_file(argv[i]); - if (ret) - return ret; - } - - printf("................"); - printf("%s\n", ret ? "Fail" : "Pass"); - fin_ret |= ret; - } - - printf("igzip_rand_test stateless: "); - - ret = test_compress_stateless((uint8_t *) str1, sizeof(str1)); - if (ret) - return ret; - - ret |= test_compress_stateless((uint8_t *) str2, sizeof(str2)); - if (ret) - return ret; - - for (i = 0; i < RANDOMS; i++) { - in_size = rand() % (IBUF_SIZE + 1); - offset = rand() % (IBUF_SIZE + 1 - in_size); - in_buf += offset; - - create_rand_repeat_data(in_buf, in_size); - - ret |= test_compress_stateless(in_buf, in_size); - - in_buf -= offset; - - if (i % (RANDOMS / 16) == 0) - printf("."); - - if (ret) - return ret; - } - - fin_ret |= ret; - - printf("%s\n", ret ? "Fail" : "Pass"); - - printf("igzip_rand_test NO_FLUSH: "); - - ret = test_compress((uint8_t *) str1, sizeof(str1), NO_FLUSH); - if (ret) - return ret; - - ret |= test_compress((uint8_t *) str2, sizeof(str2), NO_FLUSH); - if (ret) - return ret; - - for (i = 0; i < RANDOMS; i++) { - in_size = rand() % (IBUF_SIZE + 1); - offset = rand() % (IBUF_SIZE + 1 - in_size); - in_buf += offset; - - create_rand_repeat_data(in_buf, in_size); - - ret |= test_compress(in_buf, in_size, NO_FLUSH); - - in_buf -= offset; - - if (i % (RANDOMS / 16) == 0) - printf("."); - if (ret) - return ret; - } - - fin_ret |= ret; - - printf("%s\n", ret ? "Fail" : "Pass"); - - printf("igzip_rand_test SYNC_FLUSH: "); - - ret = test_compress((uint8_t *) str1, sizeof(str1), SYNC_FLUSH); - if (ret) - return ret; - - ret |= test_compress((uint8_t *) str2, sizeof(str2), SYNC_FLUSH); - if (ret) - return ret; - - for (i = 0; i < RANDOMS; i++) { - in_size = rand() % (IBUF_SIZE + 1); - offset = rand() % (IBUF_SIZE + 1 - in_size); - in_buf += offset; - - create_rand_repeat_data(in_buf, in_size); - - ret |= test_compress(in_buf, in_size, SYNC_FLUSH); - - in_buf -= offset; - - if (i % (RANDOMS / 16) == 0) - printf("."); - if (ret) - return ret; - } - - fin_ret |= ret; - - printf("%s\n", ret ? "Fail" : "Pass"); - - printf("igzip rand test finished: %s\n", - fin_ret ? "Some tests failed" : "All tests passed"); - - return fin_ret != IGZIP_COMP_OK; -} diff --git a/ceph/src/isa-l/igzip/igzip_compare_types.asm b/ceph/src/isa-l/igzip/igzip_compare_types.asm index 6a4942461..a5fb6cd4f 100644 --- a/ceph/src/isa-l/igzip/igzip_compare_types.asm +++ b/ceph/src/isa-l/igzip/igzip_compare_types.asm @@ -28,6 +28,8 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; %include "options.asm" +%include "stdmac.asm" + %ifndef UTILS_ASM %define UTILS_ASM ; compare macro @@ -141,18 +143,18 @@ xor %%result, %%result %%loop1: - movdqu %%xtmp, [%%src1 + %%result] - movdqu %%xtmp2, [%%src2 + %%result] - pcmpeqb %%xtmp, %%xtmp2 - pmovmskb %%tmp32, %%xtmp + MOVDQU %%xtmp, [%%src1 + %%result] + MOVDQU %%xtmp2, [%%src2 + %%result] + PCMPEQB %%xtmp, %%xtmp, %%xtmp2 + PMOVMSKB %%tmp32, %%xtmp xor %%tmp, 0xFFFF jnz %%miscompare add %%result, 16 - movdqu %%xtmp, [%%src1 + %%result] - movdqu %%xtmp2, [%%src2 + %%result] - pcmpeqb %%xtmp, %%xtmp2 - pmovmskb %%tmp32, %%xtmp + MOVDQU %%xtmp, [%%src1 + %%result] + MOVDQU %%xtmp2, [%%src2 + %%result] + PCMPEQB %%xtmp, %%xtmp, %%xtmp2 + PMOVMSKB %%tmp32, %%xtmp xor %%tmp, 0xFFFF jnz %%miscompare add %%result, 16 @@ -195,26 +197,26 @@ %define %%xtmp2 %6 mov %%result, 8 - movdqu %%xtmp, [%%src1 + 8] - movdqu %%xtmp2, [%%src2 + 8] - pcmpeqb %%xtmp, %%xtmp2 - pmovmskb %%tmp32, %%xtmp + MOVDQU %%xtmp, [%%src1 + 8] + MOVDQU %%xtmp2, [%%src2 + 8] + PCMPEQB %%xtmp, %%xtmp, %%xtmp2 + PMOVMSKB %%tmp32, %%xtmp xor %%tmp, 0xFFFF jnz %%miscompare add %%result, 16 %%loop1: - movdqu %%xtmp, [%%src1 + %%result] - movdqu %%xtmp2, [%%src2 + %%result] - pcmpeqb %%xtmp, %%xtmp2 - pmovmskb %%tmp32, %%xtmp + MOVDQU %%xtmp, [%%src1 + %%result] + MOVDQU %%xtmp2, [%%src2 + %%result] + PCMPEQB %%xtmp, %%xtmp, %%xtmp2 + PMOVMSKB %%tmp32, %%xtmp xor %%tmp, 0xFFFF jnz %%miscompare add %%result, 16 - movdqu %%xtmp, [%%src1 + %%result] - movdqu %%xtmp2, [%%src2 + %%result] - pcmpeqb %%xtmp, %%xtmp2 - pmovmskb %%tmp32, %%xtmp + MOVDQU %%xtmp, [%%src1 + %%result] + MOVDQU %%xtmp2, [%%src2 + %%result] + PCMPEQB %%xtmp, %%xtmp, %%xtmp2 + PMOVMSKB %%tmp32, %%xtmp xor %%tmp, 0xFFFF jnz %%miscompare add %%result, 16 @@ -222,10 +224,10 @@ cmp %%result, 258 - 16 jb %%loop1 - movdqu %%xtmp, [%%src1 + %%result] - movdqu %%xtmp2, [%%src2 + %%result] - pcmpeqb %%xtmp, %%xtmp2 - pmovmskb %%tmp32, %%xtmp + MOVDQU %%xtmp, [%%src1 + %%result] + MOVDQU %%xtmp2, [%%src2 + %%result] + PCMPEQB %%xtmp, %%xtmp, %%xtmp2 + PMOVMSKB %%tmp32, %%xtmp xor %%tmp, 0xFFFF jnz %%miscompare_last ; no miscompares, return 258 diff --git a/ceph/src/isa-l/igzip/igzip_decode_block_stateless.asm b/ceph/src/isa-l/igzip/igzip_decode_block_stateless.asm new file mode 100644 index 000000000..b048223d1 --- /dev/null +++ b/ceph/src/isa-l/igzip/igzip_decode_block_stateless.asm @@ -0,0 +1,668 @@ +default rel + +%include "reg_sizes.asm" + +%define DECOMP_OK 0 +%define END_INPUT 1 +%define OUT_OVERFLOW 2 +%define INVALID_BLOCK -1 +%define INVALID_SYMBOL -2 +%define INVALID_LOOKBACK -3 + +%define ISAL_DECODE_LONG_BITS 12 +%define ISAL_DECODE_SHORT_BITS 10 + +%define MAX_LONG_CODE_LARGE (288 + (1 << (15 - ISAL_DECODE_LONG_BITS))) +%define MAX_LONG_CODE_SMALL (32 + (1 << (15 - ISAL_DECODE_SHORT_BITS))) + +%define COPY_SIZE 16 +%define COPY_LEN_MAX 258 + +%define IN_BUFFER_SLOP 8 +%define OUT_BUFFER_SLOP COPY_SIZE + COPY_LEN_MAX + +%include "inflate_data_structs.asm" +%include "stdmac.asm" + +extern rfc1951_lookup_table + +;; rax +%define tmp3 rax +%define read_in_2 rax +%define look_back_dist rax + +;; rcx +;; rdx arg3 +%define next_sym2 rdx +%define copy_start rdx +%define tmp4 rdx + +;; rdi arg1 +%define tmp1 rdi +%define look_back_dist2 rdi +%define next_bits2 rdi +%define next_sym3 rdi + +;; rsi arg2 +%define tmp2 rsi +%define next_bits rsi + +;; rbx ; Saved +%define next_in rbx + +;; rbp ; Saved +%define end_in rbp + +;; r8 +%define repeat_length r8 + +;; r9 +%define read_in r9 + +;; r10 +%define read_in_length r10 + +;; r11 +%define state r11 + +;; r12 ; Saved +%define next_out r12 + +;; r13 ; Saved +%define end_out r13 + +;; r14 ; Saved +%define next_sym r14 + +;; r15 ; Saved +%define rfc_lookup r15 + +start_out_mem_offset equ 0 +read_in_mem_offset equ 8 +read_in_length_mem_offset equ 16 +gpr_save_mem_offset equ 24 +stack_size equ 3 * 8 + 8 * 8 + +%define _dist_extra_bit_count 264 +%define _dist_start _dist_extra_bit_count + 1*32 +%define _len_extra_bit_count _dist_start + 4*32 +%define _len_start _len_extra_bit_count + 1*32 + +%ifidn __OUTPUT_FORMAT__, elf64 +%define arg0 rdi + +%macro FUNC_SAVE 0 +%ifdef ALIGN_STACK + push rbp + mov rbp, rsp + sub rsp, stack_size + and rsp, ~15 +%else + sub rsp, stack_size +%endif + + mov [rsp + gpr_save_mem_offset + 0*8], rbx + mov [rsp + gpr_save_mem_offset + 1*8], rbp + mov [rsp + gpr_save_mem_offset + 2*8], r12 + mov [rsp + gpr_save_mem_offset + 3*8], r13 + mov [rsp + gpr_save_mem_offset + 4*8], r14 + mov [rsp + gpr_save_mem_offset + 5*8], r15 +%endm + +%macro FUNC_RESTORE 0 + mov rbx, [rsp + gpr_save_mem_offset + 0*8] + mov rbp, [rsp + gpr_save_mem_offset + 1*8] + mov r12, [rsp + gpr_save_mem_offset + 2*8] + mov r13, [rsp + gpr_save_mem_offset + 3*8] + mov r14, [rsp + gpr_save_mem_offset + 4*8] + mov r15, [rsp + gpr_save_mem_offset + 5*8] + +%ifndef ALIGN_STACK + add rsp, stack_size +%else + mov rsp, rbp + pop rbp +%endif +%endm +%endif + +%ifidn __OUTPUT_FORMAT__, win64 +%define arg0 rcx +%macro FUNC_SAVE 0 +%ifdef ALIGN_STACK + push rbp + mov rbp, rsp + sub rsp, stack_size + and rsp, ~15 +%else + sub rsp, stack_size +%endif + + mov [rsp + gpr_save_mem_offset + 0*8], rbx + mov [rsp + gpr_save_mem_offset + 1*8], rsi + mov [rsp + gpr_save_mem_offset + 2*8], rdi + mov [rsp + gpr_save_mem_offset + 3*8], rbp + mov [rsp + gpr_save_mem_offset + 4*8], r12 + mov [rsp + gpr_save_mem_offset + 5*8], r13 + mov [rsp + gpr_save_mem_offset + 6*8], r14 + mov [rsp + gpr_save_mem_offset + 7*8], r15 +%endm + +%macro FUNC_RESTORE 0 + mov rbx, [rsp + gpr_save_mem_offset + 0*8] + mov rsi, [rsp + gpr_save_mem_offset + 1*8] + mov rdi, [rsp + gpr_save_mem_offset + 2*8] + mov rbp, [rsp + gpr_save_mem_offset + 3*8] + mov r12, [rsp + gpr_save_mem_offset + 4*8] + mov r13, [rsp + gpr_save_mem_offset + 5*8] + mov r14, [rsp + gpr_save_mem_offset + 6*8] + mov r15, [rsp + gpr_save_mem_offset + 7*8] + +%ifndef ALIGN_STACK + add rsp, stack_size +%else + mov rsp, rbp + pop rbp +%endif +%endm +%endif + +;; Load read_in and updated in_buffer accordingly +;; when there are at least 8 bytes in the in buffer +;; Clobbers rcx, unless rcx is %%read_in_length +%macro inflate_in_load 6 +%define %%next_in %1 +%define %%end_in %2 +%define %%read_in %3 +%define %%read_in_length %4 +%define %%tmp1 %5 ; Tmp registers +%define %%tmp2 %6 + + SHLX %%tmp1, [%%next_in], %%read_in_length + or %%read_in, %%tmp1 + + mov %%tmp1, 64 + sub %%tmp1, %%read_in_length + shr %%tmp1, 3 + + add %%next_in, %%tmp1 + lea %%read_in_length, [%%read_in_length + 8 * %%tmp1] +%%end: +%endm + +;; Load read_in and updated in_buffer accordingly +;; Clobbers rcx, unless rcx is %%read_in_length +%macro inflate_in_small_load 6 +%define %%next_in %1 +%define %%end_in %2 +%define %%read_in %3 +%define %%read_in_length %4 +%define %%avail_in %5 ; Tmp registers +%define %%tmp1 %5 +%define %%loop_count %6 + + mov %%avail_in, %%end_in + sub %%avail_in, %%next_in + +%ifnidn %%read_in_length, rcx + mov rcx, %%read_in_length +%endif + + mov %%loop_count, 64 + sub %%loop_count, %%read_in_length + shr %%loop_count, 3 + + cmp %%loop_count, %%avail_in + cmovg %%loop_count, %%avail_in + cmp %%loop_count, 0 + je %%end + +%%load_byte: + xor %%tmp1, %%tmp1 + mov %%tmp1 %+ b, byte [%%next_in] + SHLX %%tmp1, %%tmp1, rcx + or %%read_in, %%tmp1 + add rcx, 8 + add %%next_in, 1 + sub %%loop_count, 1 + jg %%load_byte +%ifnidn %%read_in_length, rcx + mov %%read_in_length, rcx +%endif +%%end: +%endm + +;; Decode next symbol +;; Clobber rcx +%macro decode_next 8 +%define %%state %1 ; State structure associated with compressed stream +%define %%lookup_size %2 ; Number of bits used for small lookup +%define %%state_offset %3 +%define %%read_in %4 ; Bits read in from compressed stream +%define %%read_in_length %5 ; Number of valid bits in read_in +%define %%next_sym %6 ; Returned symobl +%define %%next_bits %7 +%define %%next_bits2 %8 + + ;; Lookup possible next symbol + mov %%next_bits, %%read_in + and %%next_bits, (1 << %%lookup_size) - 1 + movzx %%next_sym, word [%%state + %%state_offset + 2 * %%next_bits] + + ;; Save length associated with symbol + mov rcx, %%next_sym + shr rcx, 9 + jz invalid_symbol + + ;; Check if symbol or hint was looked up + and %%next_sym, 0x81FF + cmp %%next_sym, 0x8000 + jl %%end + + ;; Decode next_sym using hint + mov %%next_bits2, %%read_in + + ;; Extract the 15-DECODE_LOOKUP_SIZE bits beyond the first DECODE_LOOKUP_SIZE bits. +%ifdef USE_HSWNI + and rcx, 0x1F + bzhi %%next_bits2, %%next_bits2, rcx +%else + neg rcx + shl %%next_bits2, cl + shr %%next_bits2, cl +%endif + shr %%next_bits2, %%lookup_size + + add %%next_bits2, %%next_sym + + ;; Lookup actual next symbol + movzx %%next_sym, word [%%state + %%state_offset + 2 * %%next_bits2 + 2 *((1 << %%lookup_size) - 0x8000)] + + ;; Save length associated with symbol + mov rcx, %%next_sym + shr rcx, 9 + jz invalid_symbol + and %%next_sym, 0x1FF +%%end: + ;; Updated read_in to reflect the bits which were decoded + sub %%read_in_length, rcx + SHRX %%read_in, %%read_in, rcx +%endm + + +;; Decode next symbol +;; Clobber rcx +%macro decode_next2 7 +%define %%state %1 ; State structure associated with compressed stream +%define %%lookup_size %2 ; Number of bits used for small lookup +%define %%state_offset %3 ; Type of huff code, should be either LIT or DIST +%define %%read_in %4 ; Bits read in from compressed stream +%define %%read_in_length %5 ; Number of valid bits in read_in +%define %%next_sym %6 ; Returned symobl +%define %%next_bits2 %7 + + ;; Save length associated with symbol + mov %%next_bits2, %%read_in + shr %%next_bits2, %%lookup_size + + mov rcx, %%next_sym + shr rcx, 9 + jz invalid_symbol + + ;; Check if symbol or hint was looked up + and %%next_sym, 0x81FF + cmp %%next_sym, 0x8000 + jl %%end + + ;; Extract the 15-DECODE_LOOKUP_SIZE bits beyond the first %%lookup_size bits. + lea %%next_sym, [%%state + 2 * %%next_sym] + sub rcx, 0x40 + %%lookup_size + +%ifdef USE_HSWNI + bzhi %%next_bits2, %%next_bits2, rcx +%else + ;; Decode next_sym using hint + neg rcx + shl %%next_bits2, cl + shr %%next_bits2, cl +%endif + + ;; Lookup actual next symbol + movzx %%next_sym, word [%%next_sym + %%state_offset + 2 * %%next_bits2 + 2 * ((1 << %%lookup_size) - 0x8000)] + + ;; Save length associated with symbol + mov rcx, %%next_sym + shr rcx, 9 + jz invalid_symbol + and %%next_sym, 0x1FF + +%%end: + ;; Updated read_in to reflect the bits which were decoded + SHRX %%read_in, %%read_in, rcx + sub %%read_in_length, rcx +%endm + +global decode_huffman_code_block_stateless_ %+ ARCH +decode_huffman_code_block_stateless_ %+ ARCH %+ : + + FUNC_SAVE + + mov state, arg0 + lea rfc_lookup, [rfc1951_lookup_table] + + mov read_in,[state + _read_in] + mov read_in_length %+ d, dword [state + _read_in_length] + mov next_out, [state + _next_out] + mov end_out %+ d, dword [state + _avail_out] + add end_out, next_out + mov next_in, [state + _next_in] + mov end_in %+ d, dword [state + _avail_in] + add end_in, next_in + + mov dword [state + _copy_overflow_len], 0 + mov dword [state + _copy_overflow_dist], 0 + + mov tmp3 %+ d, dword [state + _total_out] + sub tmp3, next_out + neg tmp3 + + mov [rsp + start_out_mem_offset], tmp3 + + sub end_out, OUT_BUFFER_SLOP + sub end_in, IN_BUFFER_SLOP + + cmp next_in, end_in + jg end_loop_block_pre + + cmp read_in_length, 64 + je skip_load + + inflate_in_load next_in, end_in, read_in, read_in_length, tmp1, tmp2 + +skip_load: + mov tmp3, read_in + and tmp3, (1 << ISAL_DECODE_LONG_BITS) - 1 + movzx next_sym, word [state + _lit_huff_code + 2 * tmp3] + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Main Loop +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +loop_block: + ;; Check if near end of in buffer or out buffer + cmp next_in, end_in + jg end_loop_block_pre + cmp next_out, end_out + jg end_loop_block_pre + + ;; Decode next symbol and reload the read_in buffer + decode_next2 state, ISAL_DECODE_LONG_BITS, _lit_huff_code, read_in, read_in_length, next_sym, tmp1 + + ;; Save next_sym in next_sym2 so next_sym can be preloaded + mov next_sym2, next_sym + + ;; Find index to specutively preload next_sym from + mov tmp3, read_in + and tmp3, (1 << ISAL_DECODE_LONG_BITS) - 1 + + ;; Start reloading read_in + mov tmp1, [next_in] + SHLX tmp1, tmp1, read_in_length + or read_in, tmp1 + + ;; Specutively load data associated with length symbol + movzx rcx, byte [rfc_lookup + _len_extra_bit_count + next_sym2 - 257] + movzx repeat_length, word [rfc_lookup + _len_start + 2 * (next_sym2 - 257)] + + ;; Test for end of block symbol + cmp next_sym2, 256 + je end_symbol_pre + + ;; Specutively load next_sym for next loop if a literal was decoded + movzx next_sym, word [state + _lit_huff_code + 2 * tmp3] + + ;; Finish updating read_in_length for read_in + mov tmp1, 64 + sub tmp1, read_in_length + shr tmp1, 3 + add next_in, tmp1 + lea read_in_length, [read_in_length + 8 * tmp1] + + ;; Specultively load next dist code + SHRX read_in_2, read_in, rcx + mov next_bits2, read_in_2 + and next_bits2, (1 << ISAL_DECODE_SHORT_BITS) - 1 + movzx next_sym3, word [state + _dist_huff_code + 2 * next_bits2] + + ;; Specutively write next_sym2 if it is a literal + mov [next_out], next_sym2 + add next_out, 1 + + ;; Check if next_sym2 is a literal, length, or end of block symbol + cmp next_sym2, 256 + jl loop_block + +decode_len_dist: + ;; Find length for length/dist pair + mov next_bits, read_in + + BZHI next_bits, next_bits, rcx, tmp4 + add repeat_length, next_bits + + ;; Update read_in for the length extra bits which were read in + sub read_in_length, rcx + + ;; Decode distance code + decode_next2 state, ISAL_DECODE_SHORT_BITS, _dist_huff_code, read_in_2, read_in_length, next_sym3, tmp2 + + movzx rcx, byte [rfc_lookup + _dist_extra_bit_count + next_sym3] + mov look_back_dist2 %+ d, [rfc_lookup + _dist_start + 4 * next_sym3] + + ;; Load distance code extra bits + mov next_bits, read_in_2 + + ;; Determine next_out after the copy is finished + add next_out, repeat_length + sub next_out, 1 + + ;; Calculate the look back distance + BZHI next_bits, next_bits, rcx, tmp4 + SHRX read_in_2, read_in_2, rcx + + ;; Setup next_sym, read_in, and read_in_length for next loop + mov read_in, read_in_2 + and read_in_2, (1 << ISAL_DECODE_LONG_BITS) - 1 + movzx next_sym, word [state + _lit_huff_code + 2 * read_in_2] + sub read_in_length, rcx + + ;; Copy distance in len/dist pair + add look_back_dist2, next_bits + + ;; Find beginning of copy + mov copy_start, next_out + sub copy_start, repeat_length + sub copy_start, look_back_dist2 + + ;; Check if a valid look back distances was decoded + cmp copy_start, [rsp + start_out_mem_offset] + jl invalid_look_back_distance + MOVDQU xmm1, [copy_start] + + ;; Set tmp2 to be the minimum of COPY_SIZE and repeat_length + ;; This is to decrease use of small_byte_copy branch + mov tmp2, COPY_SIZE + cmp tmp2, repeat_length + cmovg tmp2, repeat_length + + ;; Check for overlapping memory in the copy + cmp look_back_dist2, tmp2 + jl small_byte_copy_pre + +large_byte_copy: + ;; Copy length distance pair when memory overlap is not an issue + MOVDQU [copy_start + look_back_dist2], xmm1 + + sub repeat_length, COPY_SIZE + jle loop_block + + add copy_start, COPY_SIZE + MOVDQU xmm1, [copy_start] + jmp large_byte_copy + +small_byte_copy_pre: + ;; Copy length distance pair when source and destination overlap + add repeat_length, look_back_dist2 +small_byte_copy: + MOVDQU [copy_start + look_back_dist2], xmm1 + + shl look_back_dist2, 1 + MOVDQU xmm1, [copy_start] + cmp look_back_dist2, COPY_SIZE + jl small_byte_copy + + sub repeat_length, look_back_dist2 + jge large_byte_copy + jmp loop_block + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Finish Main Loop +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +end_loop_block_pre: + ;; Fix up in buffer and out buffer to reflect the actual buffer end + add end_out, OUT_BUFFER_SLOP + add end_in, IN_BUFFER_SLOP + +end_loop_block: + ;; Load read in buffer and decode next lit/len symbol + inflate_in_small_load next_in, end_in, read_in, read_in_length, tmp1, tmp2 + mov [rsp + read_in_mem_offset], read_in + mov [rsp + read_in_length_mem_offset], read_in_length + + decode_next state, ISAL_DECODE_LONG_BITS, _lit_huff_code, read_in, read_in_length, next_sym, tmp1, tmp2 + + ;; Check that enough input was available to decode symbol + cmp read_in_length, 0 + jl end_of_input + + cmp next_sym, 256 + jl decode_literal + je end_symbol + +decode_len_dist_2: + ;; Load length exta bits + mov next_bits, read_in + + movzx repeat_length, word [rfc_lookup + _len_start + 2 * (next_sym - 257)] + movzx rcx, byte [rfc_lookup + _len_extra_bit_count + next_sym - 257] + + ;; Calculate repeat length + BZHI next_bits, next_bits, rcx, tmp1 + add repeat_length, next_bits + + ;; Update read_in for the length extra bits which were read in + SHRX read_in, read_in, rcx + sub read_in_length, rcx + + ;; Decode distance code + decode_next state, ISAL_DECODE_SHORT_BITS, _dist_huff_code, read_in, read_in_length, next_sym, tmp1, tmp2 + + ;; Load distance code extra bits + mov next_bits, read_in + mov look_back_dist %+ d, [rfc_lookup + _dist_start + 4 * next_sym] + movzx rcx, byte [rfc_lookup + _dist_extra_bit_count + next_sym] + + + ;; Calculate the look back distance and check for enough input + BZHI next_bits, next_bits, rcx, tmp1 + SHRX read_in, read_in, rcx + add look_back_dist, next_bits + sub read_in_length, rcx + jl end_of_input + + ;; Setup code for byte copy using rep movsb + mov rsi, next_out + mov rdi, rsi + mov rcx, repeat_length + sub rsi, look_back_dist + + ;; Check if a valid look back distance was decoded + cmp rsi, [rsp + start_out_mem_offset] + jl invalid_look_back_distance + + ;; Check for out buffer overflow + add repeat_length, next_out + cmp repeat_length, end_out + jg out_buffer_overflow_repeat + + mov next_out, repeat_length + + rep movsb + jmp end_loop_block + +decode_literal: + ;; Store literal decoded from the input stream + cmp next_out, end_out + jge out_buffer_overflow_lit + add next_out, 1 + mov byte [next_out - 1], next_sym %+ b + jmp end_loop_block + +;; Set exit codes +end_of_input: + mov read_in, [rsp + read_in_mem_offset] + mov read_in_length, [rsp + read_in_length_mem_offset] + mov rax, END_INPUT + jmp end + +out_buffer_overflow_repeat: + mov rcx, end_out + sub rcx, next_out + sub repeat_length, rcx + sub repeat_length, next_out + rep movsb + + mov [state + _copy_overflow_len], repeat_length %+ d + mov [state + _copy_overflow_dist], look_back_dist %+ d + + mov next_out, end_out + + mov rax, OUT_OVERFLOW + jmp end + +out_buffer_overflow_lit: + mov read_in, [rsp + read_in_mem_offset] + mov read_in_length, [rsp + read_in_length_mem_offset] + mov rax, OUT_OVERFLOW + jmp end + +invalid_look_back_distance: + mov rax, INVALID_LOOKBACK + jmp end + +invalid_symbol: + mov rax, INVALID_SYMBOL + jmp end + +end_symbol_pre: + ;; Fix up in buffer and out buffer to reflect the actual buffer + add end_out, OUT_BUFFER_SLOP + add end_in, IN_BUFFER_SLOP +end_symbol: + ;; Set flag identifying a new block is required + mov byte [state + _block_state], ISAL_BLOCK_NEW_HDR + xor rax, rax +end: + ;; Save current buffer states + mov [state + _read_in], read_in + mov [state + _read_in_length], read_in_length %+ d + mov [state + _next_out], next_out + sub end_out, next_out + mov dword [state + _avail_out], end_out %+ d + sub next_out, [rsp + start_out_mem_offset] + mov [state + _total_out], next_out %+ d + mov [state + _next_in], next_in + sub end_in, next_in + mov [state + _avail_in], end_in %+ d + + FUNC_RESTORE + + ret diff --git a/ceph/src/isa-l/igzip/igzip_decode_block_stateless_01.asm b/ceph/src/isa-l/igzip/igzip_decode_block_stateless_01.asm new file mode 100644 index 000000000..4aa39fe1c --- /dev/null +++ b/ceph/src/isa-l/igzip/igzip_decode_block_stateless_01.asm @@ -0,0 +1,3 @@ +%define ARCH 01 + +%include "igzip_decode_block_stateless.asm" diff --git a/ceph/src/isa-l/igzip/igzip_decode_block_stateless_04.asm b/ceph/src/isa-l/igzip/igzip_decode_block_stateless_04.asm new file mode 100644 index 000000000..769fca22d --- /dev/null +++ b/ceph/src/isa-l/igzip/igzip_decode_block_stateless_04.asm @@ -0,0 +1,4 @@ +%define ARCH 04 +%define USE_HSWNI + +%include "igzip_decode_block_stateless.asm" diff --git a/ceph/src/isa-l/igzip/igzip_example.c b/ceph/src/isa-l/igzip/igzip_example.c index 9d2b99707..5930c717f 100644 --- a/ceph/src/isa-l/igzip/igzip_example.c +++ b/ceph/src/isa-l/igzip/igzip_example.c @@ -32,6 +32,11 @@ #include "igzip_lib.h" #define BUF_SIZE 8192 +#ifndef LEVEL +# define LEVEL 0 +#else +# define LEVEL 1 +#endif struct isal_zstream stream; @@ -55,16 +60,26 @@ int main(int argc, char *argv[]) exit(0); } - printf("igzip_example\nWindow Size: %d K\n", HIST_SIZE); + printf("igzip_example\nWindow Size: %d K\n", IGZIP_HIST_SIZE / 1024); fflush(0); isal_deflate_init(&stream); stream.end_of_stream = 0; stream.flush = NO_FLUSH; + if (LEVEL == 1) { + stream.level = 1; + stream.level_buf = malloc(ISAL_DEF_LVL1_DEFAULT); + stream.level_buf_size = ISAL_DEF_LVL1_DEFAULT; + if (stream.level_buf == 0) { + printf("Failed to allocate level compression buffer\n"); + exit(0); + } + } + do { stream.avail_in = (uint32_t) fread(inbuf, 1, BUF_SIZE, in); - stream.end_of_stream = feof(in); + stream.end_of_stream = feof(in) ? 1 : 0; stream.next_in = inbuf; do { stream.avail_out = BUF_SIZE; diff --git a/ceph/src/isa-l/igzip/igzip_file_perf.c b/ceph/src/isa-l/igzip/igzip_file_perf.c index 4f74faa5c..8ae45cd61 100644 --- a/ceph/src/isa-l/igzip/igzip_file_perf.c +++ b/ceph/src/isa-l/igzip/igzip_file_perf.c @@ -31,17 +31,30 @@ #include #include #include +#include #include "igzip_lib.h" #include "test.h" #define BUF_SIZE 1024 -#define MIN_TEST_LOOPS 100 +#define MIN_TEST_LOOPS 10 #ifndef RUN_MEM_SIZE # define RUN_MEM_SIZE 500000000 #endif struct isal_zstream stream; +int usage(void) +{ + fprintf(stderr, + "Usage: igzip_file_perf [options] \n" + " -h help\n" + " -X use compression level X with 0 <= X <= 1\n" + " -b input buffer size, 0 buffers all the input\n" + " -i number of iterations (at least 1)\n" + " -o output file for compresed data\n"); + exit(0); +} + int get_filesize(FILE * f) { int curr, end; @@ -56,49 +69,74 @@ int get_filesize(FILE * f) int main(int argc, char *argv[]) { FILE *in, *out = NULL; - unsigned char *inbuf, *outbuf; - int i, infile_size, iterations, outbuf_size; + unsigned char *inbuf, *outbuf, *level_buf = NULL; + int i, c, infile_size, iterations = 0, outbuf_size, inbuf_size = 0; struct isal_huff_histogram histogram; struct isal_hufftables hufftables_custom; + int level = 0, level_size = 0, avail_in; + char *in_file_name = NULL, *out_file_name = NULL; - memset(&histogram, 0, sizeof(histogram)); - - if (argc > 3 || argc < 2) { - fprintf(stderr, "Usage: igzip_file_perf infile [outfile]\n" - "\t - Runs multiple iterations of igzip on a file to " - "get more accurate time results.\n"); - exit(0); + while ((c = getopt(argc, argv, "h01i:b:o:")) != -1) { + switch (c) { + case 'o': + out_file_name = optarg; + break; + case 'i': + iterations = atoi(optarg); + if (iterations < 1) + usage(); + break; + case 'b': + inbuf_size = atoi(optarg); + break; + case '1': + level = 1; + level_size = ISAL_DEF_LVL1_LARGE; + break; + case '0': + break; + case 'h': + default: + usage(); + break; + } } - in = fopen(argv[1], "rb"); + + if (optind < argc) { + in_file_name = argv[optind]; + in = fopen(in_file_name, "rb"); + } else + usage(); + if (!in) { - fprintf(stderr, "Can't open %s for reading\n", argv[1]); + fprintf(stderr, "Can't open %s for reading\n", in_file_name); exit(0); } - if (argc > 2) { - out = fopen(argv[2], "wb"); + if (out_file_name != NULL) { + out = fopen(out_file_name, "wb"); if (!out) { - fprintf(stderr, "Can't open %s for writing\n", argv[2]); + fprintf(stderr, "Can't open %s for writing\n", out_file_name); exit(0); } - printf("outfile=%s\n", argv[2]); + printf("outfile=%s\n", out_file_name); } - printf("Window Size: %d K\n", HIST_SIZE); + + printf("Window Size: %d K\n", IGZIP_HIST_SIZE / 1024); printf("igzip_file_perf: \n"); fflush(0); + /* Allocate space for entire input file and output * (assuming some possible expansion on output size) */ infile_size = get_filesize(in); - if (infile_size != 0) { - outbuf_size = infile_size * 2; - iterations = RUN_MEM_SIZE / infile_size; - } else { - outbuf_size = BUF_SIZE; - iterations = MIN_TEST_LOOPS; + outbuf_size = 2 * infile_size + BUF_SIZE; + + if (iterations == 0) { + iterations = infile_size ? RUN_MEM_SIZE / infile_size : MIN_TEST_LOOPS; + if (iterations < MIN_TEST_LOOPS) + iterations = MIN_TEST_LOOPS; } - if (iterations < MIN_TEST_LOOPS) - iterations = MIN_TEST_LOOPS; inbuf = malloc(infile_size); if (inbuf == NULL) { @@ -111,7 +149,17 @@ int main(int argc, char *argv[]) exit(0); } - printf("igzip_file_perf: %s %d iterations\n", argv[1], iterations); + if (level_size != 0) { + level_buf = malloc(level_size); + if (level_buf == NULL) { + fprintf(stderr, "Can't allocate level buffer memory\n"); + exit(0); + } + } + + inbuf_size = inbuf_size ? inbuf_size : infile_size; + + printf("igzip_file_perf: %s %d iterations\n", in_file_name, iterations); /* Read complete input file into buffer */ stream.avail_in = (uint32_t) fread(inbuf, 1, infile_size, in); if (stream.avail_in != infile_size) { @@ -124,16 +172,30 @@ int main(int argc, char *argv[]) for (i = 0; i < iterations; i++) { isal_deflate_init(&stream); - stream.end_of_stream = 1; /* Do the entire file at once */ + stream.end_of_stream = 0; stream.flush = NO_FLUSH; - stream.next_in = inbuf; - stream.avail_in = infile_size; + stream.level = level; + stream.level_buf = level_buf; + stream.level_buf_size = level_size; stream.next_out = outbuf; stream.avail_out = outbuf_size; - isal_deflate(&stream); - if (stream.avail_in != 0) - break; + stream.next_in = inbuf; + avail_in = infile_size; + + while (avail_in > 0) { + stream.avail_in = avail_in >= inbuf_size ? inbuf_size : avail_in; + avail_in -= inbuf_size; + + if (avail_in <= 0) + stream.end_of_stream = 1; + + isal_deflate(&stream); + + if (stream.avail_in != 0) + break; + } } + perf_stop(&stop); if (stream.avail_in != 0) { @@ -141,23 +203,44 @@ int main(int argc, char *argv[]) exit(0); } - printf(" file %s - in_size=%d out_size=%d iter=%d ratio_default=%3.1f%%", argv[1], - infile_size, stream.total_out, i, 100.0 * stream.total_out / infile_size); + printf(" file %s - in_size=%d out_size=%d iter=%d ratio=%3.1f%%", + in_file_name, infile_size, stream.total_out, i, + 100.0 * stream.total_out / infile_size); - isal_update_histogram(inbuf, infile_size, &histogram); - isal_create_hufftables(&hufftables_custom, &histogram); + if (level == 0) { + memset(&histogram, 0, sizeof(histogram)); - isal_deflate_init(&stream); - stream.end_of_stream = 1; /* Do the entire file at once */ - stream.flush = NO_FLUSH; - stream.next_in = inbuf; - stream.avail_in = infile_size; - stream.next_out = outbuf; - stream.avail_out = outbuf_size; - stream.hufftables = &hufftables_custom; - isal_deflate(&stream); + isal_update_histogram(inbuf, infile_size, &histogram); + isal_create_hufftables(&hufftables_custom, &histogram); - printf(" ratio_custom=%3.1f%%\n", 100.0 * stream.total_out / infile_size); + isal_deflate_init(&stream); + stream.end_of_stream = 0; + stream.flush = NO_FLUSH; + stream.level = level; + stream.level_buf = level_buf; + stream.level_buf_size = level_size; + stream.next_out = outbuf; + stream.avail_out = outbuf_size; + stream.next_in = inbuf; + stream.hufftables = &hufftables_custom; + avail_in = infile_size; + + while (avail_in > 0) { + stream.avail_in = avail_in >= inbuf_size ? inbuf_size : avail_in; + avail_in -= inbuf_size; + + if (avail_in <= 0) + stream.end_of_stream = 1; + + isal_deflate(&stream); + + if (stream.avail_in != 0) + break; + } + + printf(" ratio_custom=%3.1f%%", 100.0 * stream.total_out / infile_size); + } + printf("\n"); if (stream.avail_in != 0) { fprintf(stderr, "Could not compress all of inbuf\n"); @@ -168,7 +251,7 @@ int main(int argc, char *argv[]) perf_print(stop, start, (long long)infile_size * i); if (argc > 2 && out) { - printf("writing %s\n", argv[2]); + printf("writing %s\n", out_file_name); fwrite(outbuf, 1, stream.total_out, out); fclose(out); } diff --git a/ceph/src/isa-l/igzip/igzip_finish.asm b/ceph/src/isa-l/igzip/igzip_finish.asm index 69b92815b..e8d5e3604 100644 --- a/ceph/src/isa-l/igzip/igzip_finish.asm +++ b/ceph/src/isa-l/igzip/igzip_finish.asm @@ -41,6 +41,7 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%define curr_data rax %define tmp1 rax %define f_index rbx @@ -69,7 +70,6 @@ %define m_bit_count r11 %define code2 r12 - %define f_end_i r12 %define file_start r13 @@ -110,24 +110,35 @@ skip_SLOP: mov hufftables, [stream + _hufftables] - ; f_i = state->b_bytes_processed; - ; f_end_i = state->b_bytes_valid; - mov f_i %+ d, [stream + _internal_state_b_bytes_processed] - mov f_end_i %+ d, [stream + _internal_state_b_bytes_valid] - - ; f_i += (uint32_t)(state->buffer - state->file_start); - ; f_end_i += (uint32_t)(state->buffer - state->file_start); - mov file_start, [stream + _internal_state_file_start] - lea tmp1, [stream + _internal_state_buffer] - sub tmp1, file_start - add f_i, tmp1 - add f_end_i, tmp1 + mov file_start, [stream + _next_in] + + mov f_i %+ d, dword [stream + _total_in] + sub file_start, f_i + + mov f_end_i %+ d, dword [stream + _avail_in] + add f_end_i, f_i + + sub f_end_i, LAST_BYTES_COUNT mov [rsp + f_end_i_mem_offset], f_end_i ; for (f_i = f_start_i; f_i < f_end_i; f_i++) { cmp f_i, f_end_i jge end_loop_2 - mov tmp1 %+ d, [file_start + f_i] + mov curr_data %+ d, [file_start + f_i] + + cmp dword [stream + _internal_state_has_hist], 0 + jne skip_write_first_byte + + cmp m_out_buf, [stream + _internal_state_bitbuf_m_out_end] + ja end_loop_2 + + compute_hash hash, curr_data + and hash %+ d, HASH_MASK + mov [stream + _internal_state_head + 2 * hash], f_i %+ w + mov dword [stream + _internal_state_has_hist], 1 + jmp encode_literal + +skip_write_first_byte: loop2: ; if (state->bitbuf.is_full()) { @@ -135,7 +146,8 @@ loop2: ja end_loop_2 ; hash = compute_hash(state->file_start + f_i) & HASH_MASK; - compute_hash hash, tmp1 + mov curr_data %+ d, [file_start + f_i] + compute_hash hash, curr_data and hash %+ d, HASH_MASK ; f_index = state->head[hash]; @@ -158,6 +170,7 @@ loop2: ; len = f_end_i - f_i; mov tmp4, [rsp + f_end_i_mem_offset] sub tmp4, f_i + add tmp4, LAST_BYTES_COUNT ; if (len > 258) len = 258; cmp tmp4, 258 @@ -177,6 +190,7 @@ loop2: ;; encode as dist/len ; get_dist_code(dist, &code2, &code_len2); + dec dist get_dist_code dist, code2, code_len2, hufftables ;; clobbers dist, rcx ; get_len_code(len, &code, &code_len); @@ -185,22 +199,20 @@ loop2: ; code2 <<= code_len ; code2 |= code ; code_len2 += code_len -%ifdef USE_HSWNI - shlx code2, code2, rcx -%else - shl code2, cl -%endif + SHLX code2, code2, rcx or code2, code add code_len2, rcx ; for (k = f_i+1, f_i += len-1; k <= f_i; k++) { lea tmp3, [f_i + 1] ; tmp3 <= k add f_i, len -%ifdef LIMIT_HASH_UPDATE + cmp f_i, [rsp + f_end_i_mem_offset] + jae skip_hash_update + ; only update hash twice ; hash = compute_hash(state->file_start + k) & HASH_MASK; - mov tmp6 %+ d, [file_start + tmp3] + mov tmp6 %+ d, dword [file_start + tmp3] compute_hash hash, tmp6 and hash %+ d, HASH_MASK ; state->head[hash] = k; @@ -209,27 +221,13 @@ loop2: add tmp3, 1 ; hash = compute_hash(state->file_start + k) & HASH_MASK; - mov tmp6 %+ d, [file_start + tmp3] + mov tmp6 %+ d, dword [file_start + tmp3] compute_hash hash, tmp6 and hash %+ d, HASH_MASK ; state->head[hash] = k; mov [stream + _internal_state_head + 2 * hash], tmp3 %+ w -%else -loop3: - ; hash = compute_hash(state->file_start + k) & HASH_MASK; - mov tmp6 %+ d, [file_start + tmp3] - compute_hash hash, tmp6 - and hash %+ d, HASH_MASK - ; state->head[hash] = k; - mov [stream + _internal_state_head + 2 * hash], tmp3 %+ w - inc tmp3 - cmp tmp3, f_i - jl loop3 -%endif - - mov tmp1 %+ d, [file_start + f_i] - +skip_hash_update: write_bits m_bits, m_bit_count, code2, code_len2, m_out_buf, tmp5 ; continue @@ -238,8 +236,6 @@ loop3: jmp end_loop_2 encode_literal: - mov tmp1 %+ d, [file_start + f_i + 1] - ; get_lit_code(state->file_start[f_i], &code2, &code_len2); movzx tmp5, byte [file_start + f_i] get_lit_code tmp5, code2, code_len2, hufftables @@ -252,19 +248,29 @@ encode_literal: jl loop2 end_loop_2: - + mov f_end_i, [rsp + f_end_i_mem_offset] + add f_end_i, LAST_BYTES_COUNT + mov [rsp + f_end_i_mem_offset], f_end_i ; if ((f_i >= f_end_i) && ! state->bitbuf.is_full()) { - cmp f_i, [rsp + f_end_i_mem_offset] - jl not_end + cmp f_i, f_end_i + jge write_eob + + xor tmp5, tmp5 +final_bytes: cmp m_out_buf, [stream + _internal_state_bitbuf_m_out_end] ja not_end + movzx tmp5, byte [file_start + f_i] + get_lit_code tmp5, code2, code_len2, hufftables + write_bits m_bits, m_bit_count, code2, code_len2, m_out_buf, tmp3 - cmp dword [stream + _end_of_stream], 1 - jne cont - cmp dword [stream + _internal_state_left_over], 0 - jg not_end + inc f_i + cmp f_i, [rsp + f_end_i_mem_offset] + jl final_bytes + +write_eob: + cmp m_out_buf, [stream + _internal_state_bitbuf_m_out_end] + ja not_end -cont: ; get_lit_code(256, &code2, &code_len2); get_lit_code 256, code2, code_len2, hufftables @@ -283,14 +289,16 @@ sync_flush: ; } not_end: - ; state->b_bytes_processed = f_i - (state->buffer - state->file_start); - add f_i, [stream + _internal_state_file_start] - sub f_i, stream - sub f_i, _internal_state_buffer - mov [stream + _internal_state_b_bytes_processed], f_i %+ d - ; // update output buffer - ; stream->next_out = state->bitbuf.buffer_ptr(); + ;; Update input buffer + mov f_end_i, [rsp + f_end_i_mem_offset] + mov [stream + _total_in], f_i %+ d + add file_start, f_i + mov [stream + _next_in], file_start + sub f_end_i, f_i + mov [stream + _avail_in], f_end_i %+ d + + ;; Update output buffer mov [stream + _next_out], m_out_buf ; len = state->bitbuf.buffer_used(); sub m_out_buf, [stream + _internal_state_bitbuf_m_out_start] diff --git a/ceph/src/isa-l/igzip/igzip_fuzz_inflate.c b/ceph/src/isa-l/igzip/igzip_fuzz_inflate.c new file mode 100644 index 000000000..844e9fbda --- /dev/null +++ b/ceph/src/isa-l/igzip/igzip_fuzz_inflate.c @@ -0,0 +1,104 @@ +#include +#include +#include +#include "huff_codes.h" +#include "igzip_lib.h" +#include "test.h" + +#define OUT_BUFFER_SIZE 64*1024 +int get_filesize(FILE * f) +{ + int curr, end; + + curr = ftell(f); /* Save current position */ + fseek(f, 0L, SEEK_END); + end = ftell(f); + fseek(f, curr, SEEK_SET); /* Restore position */ + return end; +} + +int main(int argc, char *argv[]) +{ + FILE *in = NULL; + unsigned char *in_buf = NULL, *isal_out_buf = NULL, *zlib_out_buf = NULL; + int in_file_size, out_buf_size, zret, iret; + struct inflate_state *state = NULL; + z_stream zstate; + char z_msg_invalid_code_set[] = "invalid code lengths set"; + char z_msg_invalid_dist_set[] = "invalid distances set"; + char z_msg_invalid_lit_len_set[] = "invalid literal/lengths set"; + + if (argc != 2) { + fprintf(stderr, "Usage: isal_inflate_file_perf infile\n" + "\t - Runs multiple iterations of igzip on a file to " + "get more accurate time results.\n"); + exit(1); + } + in = fopen(argv[1], "rb"); + if (!in) { + fprintf(stderr, "Can't open %s for reading\n", argv[1]); + exit(1); + } + + /* Allocate space for entire input file and output + * (assuming some possible expansion on output size) + */ + in_file_size = get_filesize(in); + + out_buf_size = OUT_BUFFER_SIZE; + + state = malloc(sizeof(struct inflate_state)); + in_buf = malloc(in_file_size); + isal_out_buf = malloc(OUT_BUFFER_SIZE); + zlib_out_buf = malloc(OUT_BUFFER_SIZE); + + if (state == NULL || in_buf == NULL || isal_out_buf == NULL || zlib_out_buf == NULL) { + fprintf(stderr, "Failed to malloc input and outputs buffers"); + exit(1); + } + + fread(in_buf, 1, in_file_size, in); + + /* Inflate data with isal_inflate */ + memset(state, 0xff, sizeof(struct inflate_state)); + + isal_inflate_init(state); + state->next_in = in_buf; + state->avail_in = in_file_size; + state->next_out = isal_out_buf; + state->avail_out = out_buf_size; + + iret = isal_inflate_stateless(state); + + /* Inflate data with zlib */ + zstate.zalloc = Z_NULL; + zstate.zfree = Z_NULL; + zstate.opaque = Z_NULL; + zstate.avail_in = in_file_size; + zstate.next_in = in_buf; + zstate.avail_out = out_buf_size; + zstate.next_out = zlib_out_buf; + inflateInit2(&zstate, -15); + + zret = inflate(&zstate, Z_FINISH); + + if (zret == Z_STREAM_END) { + /* If zlib finished, assert isal finished with the same answer */ + assert(state->block_state == ISAL_BLOCK_FINISH); + assert(zstate.total_out == state->total_out); + assert(memcmp(isal_out_buf, zlib_out_buf, state->total_out) == 0); + } else if (zret < 0) { + if (zret != Z_BUF_ERROR) + /* If zlib errors, assert isal errors, excluding a few + * cases where zlib is overzealous */ + assert(iret < 0 || strcmp(zstate.msg, z_msg_invalid_code_set) == 0 + || strcmp(zstate.msg, z_msg_invalid_dist_set) == 0 + || strcmp(zstate.msg, z_msg_invalid_lit_len_set) == 0); + } else + /* If zlib did not finish or error, assert isal did not finish + * or that isal found an invalid header since isal notices the + * error faster than zlib */ + assert(iret > 0 || iret == ISAL_INVALID_BLOCK); + + return 0; +} diff --git a/ceph/src/isa-l/igzip/igzip_hist_perf.c b/ceph/src/isa-l/igzip/igzip_hist_perf.c new file mode 100644 index 000000000..5917572b8 --- /dev/null +++ b/ceph/src/isa-l/igzip/igzip_hist_perf.c @@ -0,0 +1,146 @@ +/********************************************************************** + Copyright(c) 2011-2016 Intel Corporation All rights reserved. + + 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 Intel Corporation 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 + 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. +**********************************************************************/ + +#include +#include +#include +#include +#include "igzip_lib.h" +#include "test.h" + +#define BUF_SIZE 1024 +#define MIN_TEST_LOOPS 8 +#ifndef RUN_MEM_SIZE +# define RUN_MEM_SIZE 2000000000 +#endif + +int get_filesize(FILE * f) +{ + int curr, end; + + curr = ftell(f); /* Save current position */ + fseek(f, 0L, SEEK_END); + end = ftell(f); + fseek(f, curr, SEEK_SET); /* Restore position */ + return end; +} + +void print_histogram(struct isal_huff_histogram *histogram) +{ + int i; + printf("Lit Len histogram"); + for (i = 0; i < ISAL_DEF_LIT_LEN_SYMBOLS; i++) { + if (i % 16 == 0) + printf("\n"); + else + printf(", "); + printf("%4lu", histogram->lit_len_histogram[i]); + } + printf("\n"); + + printf("Dist histogram"); + for (i = 0; i < ISAL_DEF_DIST_SYMBOLS; i++) { + if (i % 16 == 0) + printf("\n"); + else + printf(", "); + printf("%4lu", histogram->dist_histogram[i]); + } + printf("\n"); +} + +int main(int argc, char *argv[]) +{ + FILE *in; + unsigned char *inbuf, *outbuf; + int i, infile_size, outbuf_size, iterations, avail_in; + struct isal_huff_histogram histogram1, histogram2; + + memset(&histogram1, 0, sizeof(histogram1)); + memset(&histogram2, 0, sizeof(histogram2)); + + if (argc > 3 || argc < 2) { + fprintf(stderr, "Usage: igzip_file_perf infile [outfile]\n" + "\t - Runs multiple iterations of igzip on a file to " + "get more accurate time results.\n"); + exit(0); + } + in = fopen(argv[1], "rb"); + if (!in) { + fprintf(stderr, "Can't open %s for reading\n", argv[1]); + exit(0); + } + + /* Allocate space for entire input file and output + * (assuming some possible expansion on output size) + */ + infile_size = get_filesize(in); + outbuf_size = 2 * infile_size; + + if (infile_size != 0) + iterations = RUN_MEM_SIZE / infile_size; + else + iterations = MIN_TEST_LOOPS; + + if (iterations < MIN_TEST_LOOPS) + iterations = MIN_TEST_LOOPS; + + inbuf = malloc(infile_size); + outbuf = malloc(outbuf_size); + if (inbuf == NULL) { + fprintf(stderr, "Can't allocate input buffer memory\n"); + exit(0); + } + + if (outbuf == NULL) { + fprintf(stderr, "Can't allocate output buffer memory\n"); + exit(0); + } + + avail_in = fread(inbuf, 1, infile_size, in); + if (avail_in != infile_size) { + fprintf(stderr, "Couldn't fit all of input file into buffer\n"); + exit(0); + } + + struct perf start, stop; + perf_start(&start); + + for (i = 0; i < iterations; i++) + isal_update_histogram(inbuf, infile_size, &histogram1); + perf_stop(&stop); + + printf(" file %s - in_size=%d iter=%d\n", argv[1], infile_size, i); + printf("igzip_file: "); + perf_print(stop, start, (long long)infile_size * i); + + fclose(in); + fflush(0); + return 0; +} diff --git a/ceph/src/isa-l/igzip/igzip_icf_base.c b/ceph/src/isa-l/igzip/igzip_icf_base.c new file mode 100644 index 000000000..be090f85d --- /dev/null +++ b/ceph/src/isa-l/igzip/igzip_icf_base.c @@ -0,0 +1,223 @@ +#include +#include "igzip_lib.h" +#include "huffman.h" +#include "huff_codes.h" +#include "encode_df.h" +#include "igzip_level_buf_structs.h" + +static inline void write_deflate_icf(struct deflate_icf *icf, uint32_t lit_len, + uint32_t lit_dist, uint32_t extra_bits) +{ + icf->lit_len = lit_len; + icf->lit_dist = lit_dist; + icf->dist_extra = extra_bits; +} + +static inline void update_state(struct isal_zstream *stream, uint8_t * start_in, + uint8_t * next_in, uint8_t * end_in, + struct deflate_icf *start_out, struct deflate_icf *next_out, + struct deflate_icf *end_out) +{ + stream->next_in = next_in; + stream->total_in += next_in - start_in; + stream->avail_in = end_in - next_in; + + ((struct level_2_buf *)stream->level_buf)->icf_buf_next = next_out; + ((struct level_2_buf *)stream->level_buf)->icf_buf_avail_out = end_out - next_out; +} + +void isal_deflate_icf_body_base(struct isal_zstream *stream) +{ + uint32_t literal, hash; + uint8_t *start_in, *next_in, *end_in, *end, *next_hash; + struct deflate_icf *start_out, *next_out, *end_out; + uint16_t match_length; + uint32_t dist; + uint32_t code, code2, extra_bits; + struct isal_zstate *state = &stream->internal_state; + uint16_t *last_seen = state->head; + + if (stream->avail_in == 0) { + if (stream->end_of_stream || stream->flush != NO_FLUSH) + state->state = ZSTATE_FLUSH_READ_BUFFER; + return; + } + + start_in = stream->next_in; + end_in = start_in + stream->avail_in; + next_in = start_in; + + start_out = ((struct level_2_buf *)stream->level_buf)->icf_buf_next; + end_out = + start_out + ((struct level_2_buf *)stream->level_buf)->icf_buf_avail_out / + sizeof(struct deflate_icf); + next_out = start_out; + + while (next_in + ISAL_LOOK_AHEAD < end_in) { + + if (next_out >= end_out) { + state->state = ZSTATE_CREATE_HDR; + update_state(stream, start_in, next_in, end_in, start_out, next_out, + end_out); + return; + } + + literal = *(uint32_t *) next_in; + hash = compute_hash(literal) & HASH_MASK; + dist = (next_in - state->file_start - last_seen[hash]) & 0xFFFF; + last_seen[hash] = (uint64_t) (next_in - state->file_start); + + /* The -1 are to handle the case when dist = 0 */ + if (dist - 1 < IGZIP_HIST_SIZE - 1) { + assert(dist != 0); + + match_length = compare258(next_in - dist, next_in, 258); + + if (match_length >= SHORTEST_MATCH) { + next_hash = next_in; +#ifdef ISAL_LIMIT_HASH_UPDATE + end = next_hash + 3; +#else + end = next_hash + match_length; +#endif + next_hash++; + + for (; next_hash < end; next_hash++) { + literal = *(uint32_t *) next_hash; + hash = compute_hash(literal) & HASH_MASK; + last_seen[hash] = + (uint64_t) (next_hash - state->file_start); + } + + get_len_icf_code(match_length, &code); + get_dist_icf_code(dist, &code2, &extra_bits); + + state->hist.ll_hist[code]++; + state->hist.d_hist[code2]++; + + write_deflate_icf(next_out, code, code2, extra_bits); + next_out++; + next_in += match_length; + + continue; + } + } + + get_lit_icf_code(literal & 0xFF, &code); + state->hist.ll_hist[code]++; + write_deflate_icf(next_out, code, NULL_DIST_SYM, 0); + next_out++; + next_in++; + } + + update_state(stream, start_in, next_in, end_in, start_out, next_out, end_out); + + assert(stream->avail_in <= ISAL_LOOK_AHEAD); + if (stream->end_of_stream || stream->flush != NO_FLUSH) + state->state = ZSTATE_FLUSH_READ_BUFFER; + + return; + +} + +void isal_deflate_icf_finish_base(struct isal_zstream *stream) +{ + uint32_t literal = 0, hash; + uint8_t *start_in, *next_in, *end_in, *end, *next_hash; + struct deflate_icf *start_out, *next_out, *end_out; + uint16_t match_length; + uint32_t dist; + uint32_t code, code2, extra_bits; + struct isal_zstate *state = &stream->internal_state; + uint16_t *last_seen = state->head; + + start_in = stream->next_in; + end_in = start_in + stream->avail_in; + next_in = start_in; + + start_out = ((struct level_2_buf *)stream->level_buf)->icf_buf_next; + end_out = start_out + ((struct level_2_buf *)stream->level_buf)->icf_buf_avail_out / + sizeof(struct deflate_icf); + next_out = start_out; + + while (next_in + 3 < end_in) { + if (next_out >= end_out) { + state->state = ZSTATE_CREATE_HDR; + update_state(stream, start_in, next_in, end_in, start_out, next_out, + end_out); + return; + } + + literal = *(uint32_t *) next_in; + hash = compute_hash(literal) & HASH_MASK; + dist = (next_in - state->file_start - last_seen[hash]) & 0xFFFF; + last_seen[hash] = (uint64_t) (next_in - state->file_start); + + if (dist - 1 < IGZIP_HIST_SIZE - 1) { /* The -1 are to handle the case when dist = 0 */ + match_length = compare258(next_in - dist, next_in, end_in - next_in); + + if (match_length >= SHORTEST_MATCH) { + next_hash = next_in; +#ifdef ISAL_LIMIT_HASH_UPDATE + end = next_hash + 3; +#else + end = next_hash + match_length; +#endif + next_hash++; + + for (; next_hash < end - 3; next_hash++) { + literal = *(uint32_t *) next_hash; + hash = compute_hash(literal) & HASH_MASK; + last_seen[hash] = + (uint64_t) (next_hash - state->file_start); + } + + get_len_icf_code(match_length, &code); + get_dist_icf_code(dist, &code2, &extra_bits); + + state->hist.ll_hist[code]++; + state->hist.d_hist[code2]++; + + write_deflate_icf(next_out, code, code2, extra_bits); + + next_out++; + next_in += match_length; + + continue; + } + } + + get_lit_icf_code(literal & 0xFF, &code); + state->hist.ll_hist[code]++; + write_deflate_icf(next_out, code, NULL_DIST_SYM, 0); + next_out++; + next_in++; + + } + + while (next_in < end_in) { + if (next_out >= end_out) { + state->state = ZSTATE_CREATE_HDR; + update_state(stream, start_in, next_in, end_in, start_out, next_out, + end_out); + return; + } + + literal = *next_in; + get_lit_icf_code(literal & 0xFF, &code); + state->hist.ll_hist[code]++; + write_deflate_icf(next_out, code, NULL_DIST_SYM, 0); + next_out++; + next_in++; + + } + + if (next_in == end_in) { + if (stream->end_of_stream || stream->flush != NO_FLUSH) + state->state = ZSTATE_CREATE_HDR; + } + + update_state(stream, start_in, next_in, end_in, start_out, next_out, end_out); + + return; +} diff --git a/ceph/src/isa-l/igzip/igzip_icf_body.asm b/ceph/src/isa-l/igzip/igzip_icf_body.asm new file mode 100644 index 000000000..bc761145e --- /dev/null +++ b/ceph/src/isa-l/igzip/igzip_icf_body.asm @@ -0,0 +1,513 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2016 Intel Corporation All rights reserved. +; +; 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 Intel Corporation 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 +; 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. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%include "options.asm" + +%include "lz0a_const.asm" +%include "data_struct2.asm" +%include "bitbuf2.asm" +%include "huffman.asm" +%include "igzip_compare_types.asm" +%include "reg_sizes.asm" + +%include "stdmac.asm" + +%ifdef DEBUG +%macro MARK 1 +global %1 +%1: +%endm +%else +%macro MARK 1 +%endm +%endif + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%define file_start rdi +%define file_length r15 +%define stream r14 +%define f_i r10 +%define m_out_buf r11 + +%define curr_data rax + +%define tmp2 rcx + +%define dist rbx +%define dist_code2 rbx +%define lit_code2 rbx + +%define dist2 r12 +%define dist_code r12 + +%define tmp1 rsi + +%define lit_code rsi + +%define curr_data2 r8 +%define len2 r8 +%define tmp4 r8 + +%define len rdx +%define len_code rdx +%define hash3 rdx + +%define tmp3 r13 + +%define hash rbp +%define hash2 r9 + +;; GPR r8 & r15 can be used + +%define xtmp0 xmm0 ; tmp +%define xtmp1 xmm1 ; tmp +%define xdata xmm4 + +%define ytmp0 ymm0 ; tmp +%define ytmp1 ymm1 ; tmp + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +m_out_end equ 0 ; local variable (8 bytes) +m_out_start equ 8 +f_end_i_mem_offset equ 16 +gpr_save_mem_offset equ 24 ; gpr save area (8*8 bytes) +xmm_save_mem_offset equ 24 + 8*8 ; xmm save area (4*16 bytes) (16 byte aligned) +stack_size equ 3*8 + 8*8 + 4*16 + +;;; 8 because stack address is odd multiple of 8 after a function call and +;;; we want it aligned to 16 bytes + +; void isal_deflate_icf_body ( isal_zstream *stream ) +; arg 1: rcx: addr of stream +global isal_deflate_icf_body_ %+ ARCH +isal_deflate_icf_body_ %+ ARCH %+ : +%ifidn __OUTPUT_FORMAT__, elf64 + mov rcx, rdi +%endif + + ;; do nothing if (avail_in == 0) + cmp dword [rcx + _avail_in], 0 + jne skip1 + + ;; Set stream's next state + mov rdx, ZSTATE_FLUSH_READ_BUFFER + mov rax, ZSTATE_CREATE_HDR + cmp dword [rcx + _end_of_stream], 0 + cmovne rax, rdx + cmp dword [rcx + _flush], _NO_FLUSH + cmovne rax, rdx + mov dword [rcx + _internal_state_state], eax + ret +skip1: + +%ifdef ALIGN_STACK + push rbp + mov rbp, rsp + sub rsp, stack_size + and rsp, ~15 +%else + sub rsp, stack_size +%endif + + mov [rsp + gpr_save_mem_offset + 0*8], rbx + mov [rsp + gpr_save_mem_offset + 1*8], rsi + mov [rsp + gpr_save_mem_offset + 2*8], rdi + mov [rsp + gpr_save_mem_offset + 3*8], rbp + mov [rsp + gpr_save_mem_offset + 4*8], r12 + mov [rsp + gpr_save_mem_offset + 5*8], r13 + mov [rsp + gpr_save_mem_offset + 6*8], r14 + mov [rsp + gpr_save_mem_offset + 7*8], r15 + + mov stream, rcx + mov dword [stream + _internal_state_has_eob], 0 + + ; state->bitbuf.set_buf(stream->next_out, stream->avail_out); + mov tmp1, [stream + _level_buf] + mov m_out_buf, [tmp1 + _icf_buf_next] + + mov [rsp + m_out_start], m_out_buf + mov tmp1, [tmp1 + _icf_buf_avail_out] + add tmp1, m_out_buf + sub tmp1, SLOP + + mov [rsp + m_out_end], tmp1 + + mov file_start, [stream + _next_in] + + mov f_i %+ d, dword [stream + _total_in] + sub file_start, f_i + + mov file_length %+ d, [stream + _avail_in] + add file_length, f_i + + ; file_length -= LA; + sub file_length, LA + ; if (file_length <= 0) continue; + + cmp file_length, f_i + jle input_end + + ; for (f_i = f_start_i; f_i < file_length; f_i++) { +MARK __body_compute_hash_ %+ ARCH + MOVDQU xdata, [file_start + f_i] + mov curr_data, [file_start + f_i] + mov tmp3, curr_data + mov tmp4, curr_data + + compute_hash hash, curr_data + + shr tmp3, 8 + compute_hash hash2, tmp3 + + and hash, HASH_MASK + and hash2, HASH_MASK + + cmp dword [stream + _internal_state_has_hist], 0 + je write_first_byte + + jmp loop2 + align 16 + +loop2: + ; if (state->bitbuf.is_full()) { + cmp m_out_buf, [rsp + m_out_end] + ja output_end + + xor dist, dist + xor dist2, dist2 + xor tmp3, tmp3 + + lea tmp1, [file_start + f_i] + + mov dist %+ w, f_i %+ w + dec dist + sub dist %+ w, word [stream + _internal_state_head + 2 * hash] + mov [stream + _internal_state_head + 2 * hash], f_i %+ w + + inc f_i + + mov tmp2, curr_data + shr curr_data, 16 + compute_hash hash, curr_data + and hash %+ d, HASH_MASK + + mov dist2 %+ w, f_i %+ w + dec dist2 + sub dist2 %+ w, word [stream + _internal_state_head + 2 * hash2] + mov [stream + _internal_state_head + 2 * hash2], f_i %+ w + + ; if ((dist-1) < (D-1)) { + and dist %+ d, (D-1) + neg dist + + shr tmp2, 24 + compute_hash hash2, tmp2 + and hash2 %+ d, HASH_MASK + + and dist2 %+ d, (D-1) + neg dist2 + +MARK __body_compare_ %+ ARCH + ;; Check for long len/dist match (>7) with first literal + MOVQ len, xdata + mov curr_data, len + PSRLDQ xdata, 1 + xor len, [tmp1 + dist - 1] + jz compare_loop + + ;; Check for len/dist match (>7) with second literal + MOVQ len2, xdata + xor len2, [tmp1 + dist2] + jz compare_loop2 + + movzx lit_code, curr_data %+ b + shr curr_data, 8 + + ;; Check for len/dist match for first literal + test len %+ d, 0xFFFFFFFF + jz len_dist_huffman_pre + + inc word [stream + _internal_state_hist_lit_len + HIST_ELEM_SIZE*lit_code] + movzx lit_code2, curr_data %+ b + ;; Check for len/dist match for second literal + test len2 %+ d, 0xFFFFFFFF + jnz write_lit_bits + +MARK __body_len_dist_lit_huffman_ %+ ARCH +len_dist_lit_huffman_pre: + bsf len2, len2 + shr len2, 3 + +len_dist_lit_huffman: + or lit_code, LIT + movnti dword [m_out_buf], lit_code %+ d + + neg dist2 + + get_dist_icf_code dist2, dist_code2, tmp1 + + ;; Setup for updating hash + lea tmp3, [f_i + 1] ; tmp3 <= k + + add file_start, f_i + MOVDQU xdata, [file_start + len2] + mov tmp1, [file_start + len2] + + shr curr_data, 24 + compute_hash hash3, curr_data + and hash3, HASH_MASK + + mov curr_data, tmp1 + shr tmp1, 8 + + sub file_start, f_i + add f_i, len2 + + mov [stream + _internal_state_head + 2 * hash], tmp3 %+ w + + compute_hash hash, curr_data + + add tmp3,1 + mov [stream + _internal_state_head + 2 * hash2], tmp3 %+ w + + compute_hash hash2, tmp1 + + add tmp3, 1 + mov [stream + _internal_state_head + 2 * hash3], tmp3 %+ w + + add dist_code2, 254 + add dist_code2, len2 + + inc word [stream + _internal_state_hist_lit_len + HIST_ELEM_SIZE*(len2 + 254)] + + movnti dword [m_out_buf + 4], dist_code2 %+ d + add m_out_buf, 8 + + shr dist_code2, DIST_OFFSET + and dist_code2, 0x1F + inc word [stream + _internal_state_hist_dist + HIST_ELEM_SIZE*dist_code2] + + ; hash = compute_hash(state->file_start + f_i) & HASH_MASK; + and hash %+ d, HASH_MASK + and hash2 %+ d, HASH_MASK + + ; continue + cmp f_i, file_length + jl loop2 + jmp input_end + ;; encode as dist/len + +MARK __body_len_dist_huffman_ %+ ARCH +len_dist_huffman_pre: + bsf len, len + shr len, 3 + +len_dist_huffman: + dec f_i + ;; Setup for updateing hash + lea tmp3, [f_i + 2] ; tmp3 <= k + + neg dist + + ; get_dist_code(dist, &code2, &code_len2); + get_dist_icf_code dist, dist_code, tmp1 + + add file_start, f_i + MOVDQU xdata, [file_start + len] + mov curr_data2, [file_start + len] + mov curr_data, curr_data2 + sub file_start, f_i + add f_i, len + ; get_len_code(len, &code, &code_len); + lea len_code, [len + 254] + or dist_code, len_code + + mov [stream + _internal_state_head + 2 * hash], tmp3 %+ w + add tmp3,1 + mov [stream + _internal_state_head + 2 * hash2], tmp3 %+ w + + compute_hash hash, curr_data + + shr curr_data2, 8 + compute_hash hash2, curr_data2 + + inc word [stream + _internal_state_hist_lit_len + HIST_ELEM_SIZE*len_code] + + movnti dword [m_out_buf], dist_code %+ d + add m_out_buf, 4 + + shr dist_code, DIST_OFFSET + and dist_code, 0x1F + inc word [stream + _internal_state_hist_dist + HIST_ELEM_SIZE*dist_code] + + ; hash = compute_hash(state->file_start + f_i) & HASH_MASK; + and hash %+ d, HASH_MASK + and hash2 %+ d, HASH_MASK + + ; continue + cmp f_i, file_length + jl loop2 + jmp input_end + +MARK __body_write_lit_bits_ %+ ARCH +write_lit_bits: + MOVDQU xdata, [file_start + f_i + 1] + add f_i, 1 + MOVQ curr_data, xdata + + inc word [stream + _internal_state_hist_lit_len + HIST_ELEM_SIZE*lit_code2] + + shl lit_code2, DIST_OFFSET + lea lit_code, [lit_code + lit_code2 + (31 << DIST_OFFSET)] + + movnti dword [m_out_buf], lit_code %+ d + add m_out_buf, 4 + + ; continue + cmp f_i, file_length + jl loop2 + +input_end: + mov tmp1, ZSTATE_FLUSH_READ_BUFFER + mov tmp2, ZSTATE_BODY + cmp dword [stream + _end_of_stream], 0 + cmovne tmp2, tmp1 + cmp dword [stream + _flush], _NO_FLUSH + + cmovne tmp2, tmp1 + mov dword [stream + _internal_state_state], tmp2 %+ d + jmp end + +output_end: + mov dword [stream + _internal_state_state], ZSTATE_CREATE_HDR + +end: + ;; update input buffer + add file_length, LA + mov [stream + _total_in], f_i %+ d + add file_start, f_i + mov [stream + _next_in], file_start + sub file_length, f_i + mov [stream + _avail_in], file_length %+ d + + ;; update output buffer + mov tmp1, [stream + _level_buf] + mov [tmp1 + _icf_buf_next], m_out_buf + sub m_out_buf, [rsp + m_out_start] + sub [tmp1 + _icf_buf_avail_out], m_out_buf %+ d + + mov rbx, [rsp + gpr_save_mem_offset + 0*8] + mov rsi, [rsp + gpr_save_mem_offset + 1*8] + mov rdi, [rsp + gpr_save_mem_offset + 2*8] + mov rbp, [rsp + gpr_save_mem_offset + 3*8] + mov r12, [rsp + gpr_save_mem_offset + 4*8] + mov r13, [rsp + gpr_save_mem_offset + 5*8] + mov r14, [rsp + gpr_save_mem_offset + 6*8] + mov r15, [rsp + gpr_save_mem_offset + 7*8] + +%ifndef ALIGN_STACK + add rsp, stack_size +%else + mov rsp, rbp + pop rbp +%endif + ret + +MARK __body_compare_loops_ %+ ARCH +compare_loop: + lea tmp2, [tmp1 + dist - 1] +%if (COMPARE_TYPE == 1) + compare250 tmp1, tmp2, len, tmp3 +%elif (COMPARE_TYPE == 2) + compare250_x tmp1, tmp2, len, tmp3, xtmp0, xtmp1 +%elif (COMPARE_TYPE == 3) + compare250_y tmp1, tmp2, len, tmp3, ytmp0, ytmp1 +%else + %error Unknown Compare type COMPARE_TYPE + % error +%endif + jmp len_dist_huffman + +compare_loop2: + lea tmp2, [tmp1 + dist2] + add tmp1, 1 +%if (COMPARE_TYPE == 1) + compare250 tmp1, tmp2, len2, tmp3 +%elif (COMPARE_TYPE == 2) + compare250_x tmp1, tmp2, len2, tmp3, xtmp0, xtmp1 +%elif (COMPARE_TYPE == 3) + compare250_y tmp1, tmp2, len2, tmp3, ytmp0, ytmp1 +%else +%error Unknown Compare type COMPARE_TYPE + % error +%endif + movzx lit_code, curr_data %+ b + shr curr_data, 8 + inc word [stream + _internal_state_hist_lit_len + HIST_ELEM_SIZE*lit_code] + jmp len_dist_lit_huffman + +MARK __write_first_byte_ %+ ARCH +write_first_byte: + cmp m_out_buf, [rsp + m_out_end] + ja output_end + + mov dword [stream + _internal_state_has_hist], 1 + + mov [stream + _internal_state_head + 2 * hash], f_i %+ w + + mov hash, hash2 + shr tmp4, 16 + compute_hash hash2, tmp4 + + and curr_data, 0xff + inc word [stream + _internal_state_hist_lit_len + HIST_ELEM_SIZE*curr_data] + or curr_data, LIT + + movnti dword [m_out_buf], curr_data %+ d + add m_out_buf, 4 + + MOVDQU xdata, [file_start + f_i + 1] + add f_i, 1 + mov curr_data, [file_start + f_i] + and hash %+ d, HASH_MASK + and hash2 %+ d, HASH_MASK + + cmp f_i, file_length + jl loop2 + jmp input_end + +section .data + align 16 +mask: dd HASH_MASK, HASH_MASK, HASH_MASK, HASH_MASK +const_D: dq D diff --git a/ceph/src/isa-l/igzip/igzip_icf_body_01.asm b/ceph/src/isa-l/igzip/igzip_icf_body_01.asm new file mode 100644 index 000000000..477919a73 --- /dev/null +++ b/ceph/src/isa-l/igzip/igzip_icf_body_01.asm @@ -0,0 +1,7 @@ +%define ARCH 01 + +%ifndef COMPARE_TYPE +%define COMPARE_TYPE 2 +%endif + +%include "igzip_icf_body.asm" diff --git a/ceph/src/isa-l/igzip/igzip_icf_body_02.asm b/ceph/src/isa-l/igzip/igzip_icf_body_02.asm new file mode 100644 index 000000000..5f8ab9519 --- /dev/null +++ b/ceph/src/isa-l/igzip/igzip_icf_body_02.asm @@ -0,0 +1,7 @@ +%define ARCH 02 + +%ifndef COMPARE_TYPE +%define COMPARE_TYPE 2 +%endif + +%include "igzip_icf_body.asm" diff --git a/ceph/src/isa-l/igzip/igzip_stateless_04.asm b/ceph/src/isa-l/igzip/igzip_icf_body_04.asm similarity index 73% rename from ceph/src/isa-l/igzip/igzip_stateless_04.asm rename to ceph/src/isa-l/igzip/igzip_icf_body_04.asm index 39d8ef53e..dda99d921 100644 --- a/ceph/src/isa-l/igzip/igzip_stateless_04.asm +++ b/ceph/src/isa-l/igzip/igzip_icf_body_04.asm @@ -5,4 +5,4 @@ %define COMPARE_TYPE 3 %endif -%include "igzip_stateless.asm" +%include "igzip_icf_body.asm" diff --git a/ceph/src/isa-l/igzip/igzip_icf_finish.asm b/ceph/src/isa-l/igzip/igzip_icf_finish.asm new file mode 100644 index 000000000..2d65a614b --- /dev/null +++ b/ceph/src/isa-l/igzip/igzip_icf_finish.asm @@ -0,0 +1,299 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2016 Intel Corporation All rights reserved. +; +; 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 Intel Corporation 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 +; 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. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +%include "options.asm" +%include "lz0a_const.asm" +%include "data_struct2.asm" +%include "bitbuf2.asm" +%include "huffman.asm" +%include "igzip_compare_types.asm" + +%include "stdmac.asm" +%include "reg_sizes.asm" + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +%define curr_data rax +%define tmp1 rax + +%define f_index rbx +%define code rbx +%define tmp4 rbx +%define tmp5 rbx +%define tmp6 rbx + +%define tmp2 rcx +%define hash rcx + +%define tmp3 rdx + +%define stream rsi + +%define f_i rdi + +%define code_len2 rbp + +%define m_out_buf r8 + +%define dist r10 + +%define code2 r12 +%define f_end_i r12 + +%define file_start r13 + +%define len r14 + +%define hufftables r15 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +f_end_i_mem_offset equ 0 ; local variable (8 bytes) +m_out_end equ 8 +m_out_start equ 16 +stack_size equ 32 +; void isal_deflate_icf_finish ( isal_zstream *stream ) +; arg 1: rcx: addr of stream +global isal_deflate_icf_finish_01 +isal_deflate_icf_finish_01: + PUSH_ALL rbx, rsi, rdi, rbp, r12, r13, r14, r15 + sub rsp, stack_size + +%ifidn __OUTPUT_FORMAT__, win64 + mov stream, rcx +%else + mov stream, rdi +%endif + + ; state->bitbuf.set_buf(stream->next_out, stream->avail_out); + mov tmp1, [stream + _level_buf] + mov m_out_buf, [tmp1 + _icf_buf_next] + mov [rsp + m_out_start], m_out_buf + mov tmp1, [tmp1 + _icf_buf_avail_out] + add tmp1, m_out_buf + sub tmp1, 4 + + mov [rsp + m_out_end], tmp1 + + mov hufftables, [stream + _hufftables] + + mov file_start, [stream + _next_in] + + mov f_i %+ d, dword [stream + _total_in] + sub file_start, f_i + + mov f_end_i %+ d, dword [stream + _avail_in] + add f_end_i, f_i + + sub f_end_i, LAST_BYTES_COUNT + mov [rsp + f_end_i_mem_offset], f_end_i + ; for (f_i = f_start_i; f_i < f_end_i; f_i++) { + cmp f_i, f_end_i + jge end_loop_2 + + mov curr_data %+ d, [file_start + f_i] + + cmp dword [stream + _internal_state_has_hist], 0 + jne skip_write_first_byte + + cmp m_out_buf, [rsp + m_out_end] + ja end_loop_2 + + compute_hash hash, curr_data + and hash %+ d, HASH_MASK + mov [stream + _internal_state_head + 2 * hash], f_i %+ w + mov dword [stream + _internal_state_has_hist], 1 + jmp encode_literal + +skip_write_first_byte: + +loop2: + ; if (state->bitbuf.is_full()) { + cmp m_out_buf, [rsp + m_out_end] + ja end_loop_2 + + ; hash = compute_hash(state->file_start + f_i) & HASH_MASK; + mov curr_data %+ d, [file_start + f_i] + compute_hash hash, curr_data + and hash %+ d, HASH_MASK + + ; f_index = state->head[hash]; + movzx f_index %+ d, word [stream + _internal_state_head + 2 * hash] + + ; state->head[hash] = (uint16_t) f_i; + mov [stream + _internal_state_head + 2 * hash], f_i %+ w + + ; dist = f_i - f_index; // mod 64k + mov dist %+ d, f_i %+ d + sub dist %+ d, f_index %+ d + and dist %+ d, 0xFFFF + + ; if ((dist-1) <= (D-1)) { + mov tmp1 %+ d, dist %+ d + sub tmp1 %+ d, 1 + cmp tmp1 %+ d, (D-1) + jae encode_literal + + ; len = f_end_i - f_i; + mov tmp4, [rsp + f_end_i_mem_offset] + sub tmp4, f_i + add tmp4, LAST_BYTES_COUNT + + ; if (len > 258) len = 258; + cmp tmp4, 258 + cmovg tmp4, [c258] + + ; len = compare(state->file_start + f_i, + ; state->file_start + f_i - dist, len); + lea tmp1, [file_start + f_i] + mov tmp2, tmp1 + sub tmp2, dist + compare tmp4, tmp1, tmp2, len, tmp3 + + ; if (len >= SHORTEST_MATCH) { + cmp len, SHORTEST_MATCH + jb encode_literal + + ;; encode as dist/len + + ; get_dist_code(dist, &code2, &code_len2); + dec dist + get_dist_icf_code dist, code2, tmp3 ;; clobbers dist, rcx + + ;; get_len_code + lea code, [len + 254] + + or code2, code + inc word [stream + _internal_state_hist_lit_len + HIST_ELEM_SIZE*code] + + ; for (k = f_i+1, f_i += len-1; k <= f_i; k++) { + lea tmp3, [f_i + 1] ; tmp3 <= k + add f_i, len + cmp f_i, [rsp + f_end_i_mem_offset] + jae skip_hash_update + + ; only update hash twice + + ; hash = compute_hash(state->file_start + k) & HASH_MASK; + mov tmp6 %+ d, dword [file_start + tmp3] + compute_hash hash, tmp6 + and hash %+ d, HASH_MASK + ; state->head[hash] = k; + mov [stream + _internal_state_head + 2 * hash], tmp3 %+ w + + add tmp3, 1 + + ; hash = compute_hash(state->file_start + k) & HASH_MASK; + mov tmp6 %+ d, dword [file_start + tmp3] + compute_hash hash, tmp6 + and hash %+ d, HASH_MASK + ; state->head[hash] = k; + mov [stream + _internal_state_head + 2 * hash], tmp3 %+ w + +skip_hash_update: + write_dword code2, m_out_buf + shr code2, DIST_OFFSET + and code2, 0x1F + inc word [stream + _internal_state_hist_dist + HIST_ELEM_SIZE*code2] + ; continue + cmp f_i, [rsp + f_end_i_mem_offset] + jl loop2 + jmp end_loop_2 + +encode_literal: + ; get_lit_code(state->file_start[f_i], &code2, &code_len2); + movzx tmp5, byte [file_start + f_i] + inc word [stream + _internal_state_hist_lit_len + HIST_ELEM_SIZE*tmp5] + or tmp5, LIT + write_dword tmp5, m_out_buf + ; continue + add f_i, 1 + cmp f_i, [rsp + f_end_i_mem_offset] + jl loop2 + +end_loop_2: + mov f_end_i, [rsp + f_end_i_mem_offset] + add f_end_i, LAST_BYTES_COUNT + mov [rsp + f_end_i_mem_offset], f_end_i + ; if ((f_i >= f_end_i) && ! state->bitbuf.is_full()) { + cmp f_i, f_end_i + jge input_end + + xor tmp5, tmp5 +final_bytes: + cmp m_out_buf, [rsp + m_out_end] + ja out_end + + movzx tmp5, byte [file_start + f_i] + inc word [stream + _internal_state_hist_lit_len + HIST_ELEM_SIZE*tmp5] + or tmp5, LIT + write_dword tmp5, m_out_buf + + inc f_i + cmp f_i, [rsp + f_end_i_mem_offset] + jl final_bytes + +input_end: + cmp dword [stream + _end_of_stream], 0 + jne out_end + cmp dword [stream + _flush], _NO_FLUSH + jne out_end + jmp end + +out_end: + mov dword [stream + _internal_state_state], ZSTATE_CREATE_HDR +end: + ;; Update input buffer + mov f_end_i, [rsp + f_end_i_mem_offset] + mov [stream + _total_in], f_i %+ d + add file_start, f_i + mov [stream + _next_in], file_start + sub f_end_i, f_i + mov [stream + _avail_in], f_end_i %+ d + + ;; Update output buffer + mov tmp1, [stream + _level_buf] + mov [tmp1 + _icf_buf_next], m_out_buf + + ; len = state->bitbuf.buffer_used(); + sub m_out_buf, [rsp + m_out_start] + + ; stream->avail_out -= len; + sub [tmp1 + _icf_buf_avail_out], m_out_buf + + add rsp, stack_size + POP_ALL + ret + +section .data + align 4 +c258: dq 258 diff --git a/ceph/src/isa-l/igzip/igzip_inflate.c b/ceph/src/isa-l/igzip/igzip_inflate.c new file mode 100644 index 000000000..40f5e9957 --- /dev/null +++ b/ceph/src/isa-l/igzip/igzip_inflate.c @@ -0,0 +1,1292 @@ +/********************************************************************** + Copyright(c) 2011-2016 Intel Corporation All rights reserved. + + 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 Intel Corporation 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 + 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. +**********************************************************************/ + +#include +#include "igzip_lib.h" +#include "huff_codes.h" + +extern int decode_huffman_code_block_stateless(struct inflate_state *); +extern uint32_t crc32_gzip(uint32_t init_crc, const unsigned char *buf, uint64_t len); + +/* structure contain lookup data based on RFC 1951 */ +struct rfc1951_tables { + uint8_t dist_extra_bit_count[32]; + uint32_t dist_start[32]; + uint8_t len_extra_bit_count[32]; + uint16_t len_start[32]; + +}; + +/* The following tables are based on the tables in the deflate standard, + * RFC 1951 page 11. */ +static struct rfc1951_tables rfc_lookup_table = { + .dist_extra_bit_count = { + 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, + 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, + 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, + 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x00, 0x00}, + + .dist_start = { + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0007, 0x0009, 0x000d, + 0x0011, 0x0019, 0x0021, 0x0031, 0x0041, 0x0061, 0x0081, 0x00c1, + 0x0101, 0x0181, 0x0201, 0x0301, 0x0401, 0x0601, 0x0801, 0x0c01, + 0x1001, 0x1801, 0x2001, 0x3001, 0x4001, 0x6001, 0x0000, 0x0000}, + + .len_extra_bit_count = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, + 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, + 0x05, 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00}, + + .len_start = { + 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, + 0x000b, 0x000d, 0x000f, 0x0011, 0x0013, 0x0017, 0x001b, 0x001f, + 0x0023, 0x002b, 0x0033, 0x003b, 0x0043, 0x0053, 0x0063, 0x0073, + 0x0083, 0x00a3, 0x00c3, 0x00e3, 0x0102, 0x0000, 0x0000, 0x0000} +}; + +struct slver { + uint16_t snum; + uint8_t ver; + uint8_t core; +}; + +/* Version info */ +struct slver isal_inflate_init_slver_00010088; +struct slver isal_inflate_init_slver = { 0x0088, 0x01, 0x00 }; + +struct slver isal_inflate_stateless_slver_00010089; +struct slver isal_inflate_stateless_slver = { 0x0089, 0x01, 0x00 }; + +struct slver isal_inflate_slver_0001008a; +struct slver isal_inflate_slver = { 0x008a, 0x01, 0x00 }; + +/*Performs a copy of length repeat_length data starting at dest - + * lookback_distance into dest. This copy copies data previously copied when the + * src buffer and the dest buffer overlap. */ +static void inline byte_copy(uint8_t * dest, uint64_t lookback_distance, int repeat_length) +{ + uint8_t *src = dest - lookback_distance; + + for (; repeat_length > 0; repeat_length--) + *dest++ = *src++; +} + +/* + * Returns integer with first length bits reversed and all higher bits zeroed + */ +static uint16_t inline bit_reverse2(uint16_t bits, uint8_t length) +{ + bits = ((bits >> 1) & 0x55555555) | ((bits & 0x55555555) << 1); // swap bits + bits = ((bits >> 2) & 0x33333333) | ((bits & 0x33333333) << 2); // swap pairs + bits = ((bits >> 4) & 0x0F0F0F0F) | ((bits & 0x0F0F0F0F) << 4); // swap nibbles + bits = ((bits >> 8) & 0x00FF00FF) | ((bits & 0x00FF00FF) << 8); // swap bytes + return bits >> (16 - length); +} + +/* Load data from the in_stream into a buffer to allow for handling unaligned data*/ +static void inline inflate_in_load(struct inflate_state *state, int min_required) +{ + uint64_t temp = 0; + uint8_t new_bytes; + + if (state->read_in_length >= 64) + return; + + if (state->avail_in >= 8) { + /* If there is enough space to load a 64 bits, load the data and use + * that to fill read_in */ + new_bytes = 8 - (state->read_in_length + 7) / 8; + temp = *(uint64_t *) state->next_in; + + state->read_in |= temp << state->read_in_length; + state->next_in += new_bytes; + state->avail_in -= new_bytes; + state->read_in_length += new_bytes * 8; + + } else { + /* Else fill the read_in buffer 1 byte at a time */ + while (state->read_in_length < 57 && state->avail_in > 0) { + temp = *state->next_in; + state->read_in |= temp << state->read_in_length; + state->next_in++; + state->avail_in--; + state->read_in_length += 8; + + } + } +} + +/* Returns the next bit_count bits from the in stream and shifts the stream over + * by bit-count bits */ +static uint64_t inline inflate_in_read_bits(struct inflate_state *state, uint8_t bit_count) +{ + uint64_t ret; + assert(bit_count < 57); + + /* Load inflate_in if not enough data is in the read_in buffer */ + if (state->read_in_length < bit_count) + inflate_in_load(state, bit_count); + + ret = (state->read_in) & ((1 << bit_count) - 1); + state->read_in >>= bit_count; + state->read_in_length -= bit_count; + + return ret; +} + +/* Sets result to the inflate_huff_code corresponding to the huffcode defined by + * the lengths in huff_code_table,where count is a histogram of the appearance + * of each code length */ +static void inline make_inflate_huff_code_large(struct inflate_huff_code_large *result, + struct huff_code *huff_code_table, + int table_length, uint16_t * count, + uint32_t max_symbol) +{ + int i, j, k; + uint16_t code = 0; + uint16_t next_code[MAX_HUFF_TREE_DEPTH + 1]; + uint16_t long_code_list[LIT_LEN]; + uint32_t long_code_length = 0; + uint16_t temp_code_list[1 << (15 - ISAL_DECODE_LONG_BITS)]; + uint32_t temp_code_length; + uint32_t long_code_lookup_length = 0; + uint32_t max_length; + uint16_t first_bits; + uint32_t code_length; + uint16_t long_bits; + uint16_t min_increment; + uint32_t code_list[LIT_LEN + 2]; /* The +2 is for the extra codes in the static header */ + uint32_t code_list_len; + uint32_t count_total[17]; + uint32_t insert_index; + uint32_t last_length; + uint32_t copy_size; + uint16_t *short_code_lookup = result->short_code_lookup; + + count_total[0] = 0; + count_total[1] = 0; + for (i = 2; i < 17; i++) + count_total[i] = count_total[i - 1] + count[i - 1]; + + code_list_len = count_total[16]; + if (code_list_len == 0) { + memset(result->short_code_lookup, 0, sizeof(result->short_code_lookup)); + return; + } + + for (i = 0; i < table_length; i++) { + code_length = huff_code_table[i].length; + if (code_length > 0) { + insert_index = count_total[code_length]; + code_list[insert_index] = i; + count_total[code_length]++; + } + } + + next_code[0] = code; + for (i = 1; i < MAX_HUFF_TREE_DEPTH + 1; i++) + next_code[i] = (next_code[i - 1] + count[i - 1]) << 1; + + last_length = huff_code_table[code_list[0]].length; + if (last_length > ISAL_DECODE_LONG_BITS) + last_length = ISAL_DECODE_LONG_BITS; + copy_size = (1 << last_length); + + /* Initialize short_code_lookup, so invalid lookups process data */ + memset(short_code_lookup, 0x00, copy_size * sizeof(*short_code_lookup)); + + for (k = 0; k < code_list_len; k++) { + i = code_list[k]; + if (huff_code_table[i].length > ISAL_DECODE_LONG_BITS) + break; + + while (huff_code_table[i].length > last_length) { + memcpy(short_code_lookup + copy_size, short_code_lookup, + sizeof(*short_code_lookup) * copy_size); + last_length++; + copy_size <<= 1; + } + + /* Store codes as zero for invalid codes used in static header construction */ + huff_code_table[i].code = + bit_reverse2(next_code[huff_code_table[i].length], + huff_code_table[i].length); + + next_code[huff_code_table[i].length] += 1; + + /* Set lookup table to return the current symbol concatenated + * with the code length when the first DECODE_LENGTH bits of the + * address are the same as the code for the current symbol. The + * first 9 bits are the code, bits 14:10 are the code length, + * bit 15 is a flag representing this is a symbol*/ + + if (i < max_symbol) + short_code_lookup[huff_code_table[i].code] = + i | (huff_code_table[i].length) << 9; + + else + short_code_lookup[huff_code_table[i].code] = 0; + + } + + while (ISAL_DECODE_LONG_BITS > last_length) { + memcpy(short_code_lookup + copy_size, short_code_lookup, + sizeof(*short_code_lookup) * copy_size); + last_length++; + copy_size <<= 1; + } + + while (k < code_list_len) { + i = code_list[k]; + huff_code_table[i].code = + bit_reverse2(next_code[huff_code_table[i].length], + huff_code_table[i].length); + + next_code[huff_code_table[i].length] += 1; + + /* Store the element in a list of elements with long codes. */ + long_code_list[long_code_length] = i; + long_code_length++; + k++; + } + + for (i = 0; i < long_code_length; i++) { + /*Set the look up table to point to a hint where the symbol can be found + * in the list of long codes and add the current symbol to the list of + * long codes. */ + if (huff_code_table[long_code_list[i]].code == 0xFFFF) + continue; + + max_length = huff_code_table[long_code_list[i]].length; + first_bits = + huff_code_table[long_code_list[i]].code + & ((1 << ISAL_DECODE_LONG_BITS) - 1); + + temp_code_list[0] = long_code_list[i]; + temp_code_length = 1; + + for (j = i + 1; j < long_code_length; j++) { + if ((huff_code_table[long_code_list[j]].code & + ((1 << ISAL_DECODE_LONG_BITS) - 1)) == first_bits) { + if (max_length < huff_code_table[long_code_list[j]].length) + max_length = huff_code_table[long_code_list[j]].length; + temp_code_list[temp_code_length] = long_code_list[j]; + temp_code_length++; + } + } + + memset(&result->long_code_lookup[long_code_lookup_length], 0x00, + 2 * (1 << (max_length - ISAL_DECODE_LONG_BITS))); + + for (j = 0; j < temp_code_length; j++) { + code_length = huff_code_table[temp_code_list[j]].length; + long_bits = + huff_code_table[temp_code_list[j]].code >> ISAL_DECODE_LONG_BITS; + min_increment = 1 << (code_length - ISAL_DECODE_LONG_BITS); + for (; long_bits < (1 << (max_length - ISAL_DECODE_LONG_BITS)); + long_bits += min_increment) { + result->long_code_lookup[long_code_lookup_length + long_bits] = + temp_code_list[j] | (code_length << 9); + } + huff_code_table[temp_code_list[j]].code = 0xFFFF; + } + result->short_code_lookup[first_bits] = + long_code_lookup_length | (max_length << 9) | 0x8000; + long_code_lookup_length += 1 << (max_length - ISAL_DECODE_LONG_BITS); + + } +} + +static void inline make_inflate_huff_code_small(struct inflate_huff_code_small *result, + struct huff_code *huff_code_table, + int table_length, uint16_t * count, + uint32_t max_symbol) +{ + int i, j, k; + uint16_t code = 0; + uint16_t next_code[MAX_HUFF_TREE_DEPTH + 1]; + uint16_t long_code_list[LIT_LEN]; + uint32_t long_code_length = 0; + uint16_t temp_code_list[1 << (15 - ISAL_DECODE_SHORT_BITS)]; + uint32_t temp_code_length; + uint32_t long_code_lookup_length = 0; + uint32_t max_length; + uint16_t first_bits; + uint32_t code_length; + uint16_t long_bits; + uint16_t min_increment; + uint32_t code_list[DIST_LEN + 2]; /* The +2 is for the extra codes in the static header */ + uint32_t code_list_len; + uint32_t count_total[17]; + uint32_t insert_index; + uint32_t last_length; + uint32_t copy_size; + uint16_t *short_code_lookup = result->short_code_lookup; + + count_total[0] = 0; + count_total[1] = 0; + for (i = 2; i < 17; i++) + count_total[i] = count_total[i - 1] + count[i - 1]; + + code_list_len = count_total[16]; + if (code_list_len == 0) { + memset(result->short_code_lookup, 0, sizeof(result->short_code_lookup)); + return; + } + + for (i = 0; i < table_length; i++) { + code_length = huff_code_table[i].length; + if (code_length > 0) { + insert_index = count_total[code_length]; + code_list[insert_index] = i; + count_total[code_length]++; + } + } + + next_code[0] = code; + for (i = 1; i < MAX_HUFF_TREE_DEPTH + 1; i++) + next_code[i] = (next_code[i - 1] + count[i - 1]) << 1; + + last_length = huff_code_table[code_list[0]].length; + if (last_length > ISAL_DECODE_SHORT_BITS) + last_length = ISAL_DECODE_SHORT_BITS; + copy_size = (1 << last_length); + + /* Initialize short_code_lookup, so invalid lookups process data */ + memset(short_code_lookup, 0x00, copy_size * sizeof(*short_code_lookup)); + + for (k = 0; k < code_list_len; k++) { + i = code_list[k]; + if (huff_code_table[i].length > ISAL_DECODE_SHORT_BITS) + break; + + while (huff_code_table[i].length > last_length) { + memcpy(short_code_lookup + copy_size, short_code_lookup, + sizeof(*short_code_lookup) * copy_size); + last_length++; + copy_size <<= 1; + } + + /* Store codes as zero for invalid codes used in static header construction */ + huff_code_table[i].code = + bit_reverse2(next_code[huff_code_table[i].length], + huff_code_table[i].length); + + next_code[huff_code_table[i].length] += 1; + + /* Set lookup table to return the current symbol concatenated + * with the code length when the first DECODE_LENGTH bits of the + * address are the same as the code for the current symbol. The + * first 9 bits are the code, bits 14:10 are the code length, + * bit 15 is a flag representing this is a symbol*/ + if (i < max_symbol) + short_code_lookup[huff_code_table[i].code] = + i | (huff_code_table[i].length) << 9; + else + short_code_lookup[huff_code_table[i].code] = 0; + } + + while (ISAL_DECODE_SHORT_BITS > last_length) { + memcpy(short_code_lookup + copy_size, short_code_lookup, + sizeof(*short_code_lookup) * copy_size); + last_length++; + copy_size <<= 1; + } + + while (k < code_list_len) { + i = code_list[k]; + huff_code_table[i].code = + bit_reverse2(next_code[huff_code_table[i].length], + huff_code_table[i].length); + + next_code[huff_code_table[i].length] += 1; + + /* Store the element in a list of elements with long codes. */ + long_code_list[long_code_length] = i; + long_code_length++; + k++; + } + + for (i = 0; i < long_code_length; i++) { + /*Set the look up table to point to a hint where the symbol can be found + * in the list of long codes and add the current symbol to the list of + * long codes. */ + if (huff_code_table[long_code_list[i]].code == 0xFFFF) + continue; + + max_length = huff_code_table[long_code_list[i]].length; + first_bits = + huff_code_table[long_code_list[i]].code + & ((1 << ISAL_DECODE_SHORT_BITS) - 1); + + temp_code_list[0] = long_code_list[i]; + temp_code_length = 1; + + for (j = i + 1; j < long_code_length; j++) { + if ((huff_code_table[long_code_list[j]].code & + ((1 << ISAL_DECODE_SHORT_BITS) - 1)) == first_bits) { + if (max_length < huff_code_table[long_code_list[j]].length) + max_length = huff_code_table[long_code_list[j]].length; + temp_code_list[temp_code_length] = long_code_list[j]; + temp_code_length++; + } + } + + memset(&result->long_code_lookup[long_code_lookup_length], 0x00, + 2 * (1 << (max_length - ISAL_DECODE_SHORT_BITS))); + + for (j = 0; j < temp_code_length; j++) { + code_length = huff_code_table[temp_code_list[j]].length; + long_bits = + huff_code_table[temp_code_list[j]].code >> ISAL_DECODE_SHORT_BITS; + min_increment = 1 << (code_length - ISAL_DECODE_SHORT_BITS); + for (; long_bits < (1 << (max_length - ISAL_DECODE_SHORT_BITS)); + long_bits += min_increment) { + result->long_code_lookup[long_code_lookup_length + long_bits] = + temp_code_list[j] | (code_length << 9); + } + huff_code_table[temp_code_list[j]].code = 0xFFFF; + } + result->short_code_lookup[first_bits] = + long_code_lookup_length | (max_length << 9) | 0x8000; + long_code_lookup_length += 1 << (max_length - ISAL_DECODE_SHORT_BITS); + + } +} + +/* Sets the inflate_huff_codes in state to be the huffcodes corresponding to the + * deflate static header */ +static int inline setup_static_header(struct inflate_state *state) +{ + /* This could be turned into a memcpy of this functions output for + * higher speed, but then DECODE_LOOKUP_SIZE couldn't be changed without + * regenerating the table. */ + + int i; + struct huff_code lit_code[LIT_LEN + 2]; + struct huff_code dist_code[DIST_LEN + 2]; + + /* These tables are based on the static huffman tree described in RFC + * 1951 */ + uint16_t lit_count[16] = { + 0, 0, 0, 0, 0, 0, 0, 24, 152, 112, 0, 0, 0, 0, 0, 0 + }; + uint16_t dist_count[16] = { + 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + + /* These for loops set the code lengths for the static literal/length + * and distance codes defined in the deflate standard RFC 1951 */ + for (i = 0; i < 144; i++) + lit_code[i].length = 8; + + for (i = 144; i < 256; i++) + lit_code[i].length = 9; + + for (i = 256; i < 280; i++) + lit_code[i].length = 7; + + for (i = 280; i < LIT_LEN + 2; i++) + lit_code[i].length = 8; + + for (i = 0; i < DIST_LEN + 2; i++) + dist_code[i].length = 5; + + make_inflate_huff_code_large(&state->lit_huff_code, lit_code, LIT_LEN + 2, lit_count, + LIT_LEN); + make_inflate_huff_code_small(&state->dist_huff_code, dist_code, DIST_LEN + 2, + dist_count, DIST_LEN); + + state->block_state = ISAL_BLOCK_CODED; + + return 0; +} + +/* Decodes the next symbol symbol in in_buffer using the huff code defined by + * huff_code */ +static uint16_t inline decode_next_large(struct inflate_state *state, + struct inflate_huff_code_large *huff_code) +{ + uint16_t next_bits; + uint16_t next_sym; + uint32_t bit_count; + uint32_t bit_mask; + + if (state->read_in_length <= ISAL_DEF_MAX_CODE_LEN) + inflate_in_load(state, 0); + + next_bits = state->read_in & ((1 << ISAL_DECODE_LONG_BITS) - 1); + + /* next_sym is a possible symbol decoded from next_bits. If bit 15 is 0, + * next_code is a symbol. Bits 9:0 represent the symbol, and bits 14:10 + * represent the length of that symbols huffman code. If next_sym is not + * a symbol, it provides a hint of where the large symbols containin + * this code are located. Note the hint is at largest the location the + * first actual symbol in the long code list.*/ + next_sym = huff_code->short_code_lookup[next_bits]; + + if (next_sym < 0x8000) { + /* Return symbol found if next_code is a complete huffman code + * and shift in buffer over by the length of the next_code */ + bit_count = next_sym >> 9; + state->read_in >>= bit_count; + state->read_in_length -= bit_count; + + if (bit_count == 0) + next_sym = 0x1FF; + + return next_sym & 0x1FF; + + } else { + /* If a symbol is not found, perform a linear search of the long code + * list starting from the hint in next_sym */ + bit_mask = (next_sym - 0x8000) >> 9; + bit_mask = (1 << bit_mask) - 1; + next_bits = state->read_in & bit_mask; + next_sym = + huff_code->long_code_lookup[(next_sym & 0x1FF) + + (next_bits >> ISAL_DECODE_LONG_BITS)]; + bit_count = next_sym >> 9; + state->read_in >>= bit_count; + state->read_in_length -= bit_count; + + if (bit_count == 0) + next_sym = 0x1FF; + + return next_sym & 0x1FF; + + } +} + +static uint16_t inline decode_next_small(struct inflate_state *state, + struct inflate_huff_code_small *huff_code) +{ + uint16_t next_bits; + uint16_t next_sym; + uint32_t bit_count; + uint32_t bit_mask; + + if (state->read_in_length <= ISAL_DEF_MAX_CODE_LEN) + inflate_in_load(state, 0); + + next_bits = state->read_in & ((1 << ISAL_DECODE_SHORT_BITS) - 1); + + /* next_sym is a possible symbol decoded from next_bits. If bit 15 is 0, + * next_code is a symbol. Bits 9:0 represent the symbol, and bits 14:10 + * represent the length of that symbols huffman code. If next_sym is not + * a symbol, it provides a hint of where the large symbols containin + * this code are located. Note the hint is at largest the location the + * first actual symbol in the long code list.*/ + next_sym = huff_code->short_code_lookup[next_bits]; + + if (next_sym < 0x8000) { + /* Return symbol found if next_code is a complete huffman code + * and shift in buffer over by the length of the next_code */ + bit_count = next_sym >> 9; + state->read_in >>= bit_count; + state->read_in_length -= bit_count; + + if (bit_count == 0) + next_sym = 0x1FF; + + return next_sym & 0x1FF; + + } else { + /* If a symbol is not found, perform a linear search of the long code + * list starting from the hint in next_sym */ + bit_mask = (next_sym - 0x8000) >> 9; + bit_mask = (1 << bit_mask) - 1; + next_bits = state->read_in & bit_mask; + next_sym = + huff_code->long_code_lookup[(next_sym & 0x1FF) + + (next_bits >> ISAL_DECODE_SHORT_BITS)]; + bit_count = next_sym >> 9; + state->read_in >>= bit_count; + state->read_in_length -= bit_count; + return next_sym & 0x1FF; + + } +} + +/* Reads data from the in_buffer and sets the huff code corresponding to that + * data */ +static int inline setup_dynamic_header(struct inflate_state *state) +{ + int i, j; + struct huff_code code_huff[CODE_LEN_CODES]; + struct huff_code lit_and_dist_huff[LIT_LEN + DIST_LEN]; + struct huff_code *previous = NULL, *current, *end; + struct inflate_huff_code_small inflate_code_huff; + uint8_t hclen, hdist, hlit; + uint16_t code_count[16], lit_count[16], dist_count[16]; + uint16_t *count; + uint16_t symbol; + + /* This order is defined in RFC 1951 page 13 */ + const uint8_t code_length_code_order[CODE_LEN_CODES] = { + 0x10, 0x11, 0x12, 0x00, 0x08, 0x07, 0x09, 0x06, + 0x0a, 0x05, 0x0b, 0x04, 0x0c, 0x03, 0x0d, 0x02, + 0x0e, 0x01, 0x0f + }; + + memset(code_count, 0, sizeof(code_count)); + memset(lit_count, 0, sizeof(lit_count)); + memset(dist_count, 0, sizeof(dist_count)); + memset(code_huff, 0, sizeof(code_huff)); + memset(lit_and_dist_huff, 0, sizeof(lit_and_dist_huff)); + + /* These variables are defined in the deflate standard, RFC 1951 */ + hlit = inflate_in_read_bits(state, 5); + hdist = inflate_in_read_bits(state, 5); + hclen = inflate_in_read_bits(state, 4); + + if (hlit > 29 || hdist > 29 || hclen > 15) + return ISAL_INVALID_BLOCK; + + /* Create the code huffman code for decoding the lit/len and dist huffman codes */ + for (i = 0; i < hclen + 4; i++) { + code_huff[code_length_code_order[i]].length = inflate_in_read_bits(state, 3); + + code_count[code_huff[code_length_code_order[i]].length] += 1; + } + + /* Check that the code huffman code has a symbol */ + for (i = 1; i < 16; i++) { + if (code_count[i] != 0) + break; + } + + if (state->read_in_length < 0) + return ISAL_END_INPUT; + + if (i == 16) + return ISAL_INVALID_BLOCK; + + make_inflate_huff_code_small(&inflate_code_huff, code_huff, CODE_LEN_CODES, + code_count, CODE_LEN_CODES); + + /* Decode the lit/len and dist huffman codes using the code huffman code */ + count = lit_count; + current = lit_and_dist_huff; + end = lit_and_dist_huff + LIT_LEN + hdist + 1; + + while (current < end) { + /* If finished decoding the lit/len huffman code, start decoding + * the distance code these decodings are in the same loop + * because the len/lit and dist huffman codes are run length + * encoded together. */ + if (current == lit_and_dist_huff + 257 + hlit) + current = lit_and_dist_huff + LIT_LEN; + + if (current == lit_and_dist_huff + LIT_LEN) + count = dist_count; + + symbol = decode_next_small(state, &inflate_code_huff); + + if (state->read_in_length < 0) { + if (current > &lit_and_dist_huff[256] + && lit_and_dist_huff[256].length <= 0) + return ISAL_INVALID_BLOCK; + return ISAL_END_INPUT; + } + + if (symbol < 16) { + /* If a length is found, update the current lit/len/dist + * to have length symbol */ + count[symbol]++; + current->length = symbol; + previous = current; + current++; + + } else if (symbol == 16) { + /* If a repeat length is found, update the next repeat + * length lit/len/dist elements to have the value of the + * repeated length */ + if (previous == NULL) /* No elements available to be repeated */ + return ISAL_INVALID_BLOCK; + + i = 3 + inflate_in_read_bits(state, 2); + + if (current + i > end) + return ISAL_INVALID_BLOCK; + + for (j = 0; j < i; j++) { + *current = *previous; + count[current->length]++; + previous = current; + + if (current == lit_and_dist_huff + 256 + hlit) { + current = lit_and_dist_huff + LIT_LEN; + count = dist_count; + + } else + current++; + } + + } else if (symbol == 17) { + /* If a repeat zeroes if found, update then next + * repeated zeroes length lit/len/dist elements to have + * length 0. */ + i = 3 + inflate_in_read_bits(state, 3); + + for (j = 0; j < i; j++) { + previous = current; + + if (current == lit_and_dist_huff + 256 + hlit) { + current = lit_and_dist_huff + LIT_LEN; + count = dist_count; + + } else + current++; + } + + } else if (symbol == 18) { + /* If a repeat zeroes if found, update then next + * repeated zeroes length lit/len/dist elements to have + * length 0. */ + i = 11 + inflate_in_read_bits(state, 7); + + for (j = 0; j < i; j++) { + previous = current; + + if (current == lit_and_dist_huff + 256 + hlit) { + current = lit_and_dist_huff + LIT_LEN; + count = dist_count; + + } else + current++; + } + } else + return ISAL_INVALID_BLOCK; + + } + + if (current > end || lit_and_dist_huff[256].length <= 0) + return ISAL_INVALID_BLOCK; + + if (state->read_in_length < 0) + return ISAL_END_INPUT; + + make_inflate_huff_code_large(&state->lit_huff_code, lit_and_dist_huff, LIT_LEN, + lit_count, LIT_LEN); + make_inflate_huff_code_small(&state->dist_huff_code, &lit_and_dist_huff[LIT_LEN], + DIST_LEN, dist_count, DIST_LEN); + + state->block_state = ISAL_BLOCK_CODED; + + return 0; +} + +/* Reads in the header pointed to by in_stream and sets up state to reflect that + * header information*/ +int read_header(struct inflate_state *state) +{ + uint8_t bytes; + uint32_t btype; + uint16_t len, nlen; + int ret = 0; + + /* btype and bfinal are defined in RFC 1951, bfinal represents whether + * the current block is the end of block, and btype represents the + * encoding method on the current block. */ + + state->bfinal = inflate_in_read_bits(state, 1); + btype = inflate_in_read_bits(state, 2); + + if (state->read_in_length < 0) + ret = ISAL_END_INPUT; + + else if (btype == 0) { + inflate_in_load(state, 40); + bytes = state->read_in_length / 8; + + if (bytes < 4) + return ISAL_END_INPUT; + + state->read_in >>= state->read_in_length % 8; + state->read_in_length = bytes * 8; + + len = state->read_in & 0xFFFF; + state->read_in >>= 16; + nlen = state->read_in & 0xFFFF; + state->read_in >>= 16; + state->read_in_length -= 32; + + bytes = state->read_in_length / 8; + + state->next_in -= bytes; + state->avail_in += bytes; + state->read_in = 0; + state->read_in_length = 0; + + /* Check if len and nlen match */ + if (len != (~nlen & 0xffff)) + return ISAL_INVALID_BLOCK; + + state->type0_block_len = len; + state->block_state = ISAL_BLOCK_TYPE0; + + ret = 0; + + } else if (btype == 1) + ret = setup_static_header(state); + + else if (btype == 2) + ret = setup_dynamic_header(state); + + else + ret = ISAL_INVALID_BLOCK; + + return ret; +} + +/* Reads in the header pointed to by in_stream and sets up state to reflect that + * header information*/ +int read_header_stateful(struct inflate_state *state) +{ + uint64_t read_in_start = state->read_in; + int32_t read_in_length_start = state->read_in_length; + uint8_t *next_in_start = state->next_in; + uint32_t avail_in_start = state->avail_in; + int block_state_start = state->block_state; + int ret; + int copy_size; + int bytes_read; + + if (block_state_start == ISAL_BLOCK_HDR) { + /* Setup so read_header decodes data in tmp_in_buffer */ + copy_size = ISAL_DEF_MAX_HDR_SIZE - state->tmp_in_size; + if (copy_size > state->avail_in) + copy_size = state->avail_in; + + memcpy(&state->tmp_in_buffer[state->tmp_in_size], state->next_in, copy_size); + state->next_in = state->tmp_in_buffer; + state->avail_in = state->tmp_in_size + copy_size; + } + + ret = read_header(state); + + if (block_state_start == ISAL_BLOCK_HDR) { + /* Setup so state is restored to a valid state */ + bytes_read = state->next_in - state->tmp_in_buffer - state->tmp_in_size; + if (bytes_read < 0) + bytes_read = 0; + state->next_in = next_in_start + bytes_read; + state->avail_in = avail_in_start - bytes_read; + } + + if (ret == ISAL_END_INPUT) { + /* Save off data so header can be decoded again with more data */ + state->read_in = read_in_start; + state->read_in_length = read_in_length_start; + memcpy(&state->tmp_in_buffer[state->tmp_in_size], next_in_start, + avail_in_start); + state->tmp_in_size += avail_in_start; + state->avail_in = 0; + state->next_in = next_in_start + avail_in_start; + state->block_state = ISAL_BLOCK_HDR; + } else + state->tmp_in_size = 0; + + return ret; + +} + +static int inline decode_literal_block(struct inflate_state *state) +{ + uint32_t len = state->type0_block_len; + /* If the block is uncompressed, perform a memcopy while + * updating state data */ + + state->block_state = ISAL_BLOCK_NEW_HDR; + + if (state->avail_out < len) { + len = state->avail_out; + state->block_state = ISAL_BLOCK_TYPE0; + } + + if (state->avail_in < len) { + len = state->avail_in; + state->block_state = ISAL_BLOCK_TYPE0; + } + + memcpy(state->next_out, state->next_in, len); + + state->next_out += len; + state->avail_out -= len; + state->total_out += len; + state->next_in += len; + state->avail_in -= len; + state->type0_block_len -= len; + + if (state->avail_in == 0 && state->block_state != ISAL_BLOCK_NEW_HDR) + return ISAL_END_INPUT; + + if (state->avail_out == 0 && state->type0_block_len > 0) + return ISAL_OUT_OVERFLOW; + + return 0; + +} + +/* Decodes the next block if it was encoded using a huffman code */ +int decode_huffman_code_block_stateless_base(struct inflate_state *state) +{ + uint16_t next_lit; + uint8_t next_dist; + uint32_t repeat_length; + uint32_t look_back_dist; + uint64_t read_in_tmp; + int32_t read_in_length_tmp; + uint8_t *next_in_tmp; + uint32_t avail_in_tmp; + + state->copy_overflow_length = 0; + state->copy_overflow_distance = 0; + + while (state->block_state == ISAL_BLOCK_CODED) { + /* While not at the end of block, decode the next + * symbol */ + inflate_in_load(state, 0); + + read_in_tmp = state->read_in; + read_in_length_tmp = state->read_in_length; + next_in_tmp = state->next_in; + avail_in_tmp = state->avail_in; + + next_lit = decode_next_large(state, &state->lit_huff_code); + + if (state->read_in_length < 0) { + state->read_in = read_in_tmp; + state->read_in_length = read_in_length_tmp; + state->next_in = next_in_tmp; + state->avail_in = avail_in_tmp; + return ISAL_END_INPUT; + } + + if (next_lit < 256) { + /* If the next symbol is a literal, + * write out the symbol and update state + * data accordingly. */ + if (state->avail_out < 1) { + state->read_in = read_in_tmp; + state->read_in_length = read_in_length_tmp; + state->next_in = next_in_tmp; + state->avail_in = avail_in_tmp; + return ISAL_OUT_OVERFLOW; + } + + *state->next_out = next_lit; + state->next_out++; + state->avail_out--; + state->total_out++; + + } else if (next_lit == 256) { + /* If the next symbol is the end of + * block, update the state data + * accordingly */ + state->block_state = ISAL_BLOCK_NEW_HDR; + + } else if (next_lit < 286) { + /* Else if the next symbol is a repeat + * length, read in the length extra + * bits, the distance code, the distance + * extra bits. Then write out the + * corresponding data and update the + * state data accordingly*/ + repeat_length = + rfc_lookup_table.len_start[next_lit - 257] + + inflate_in_read_bits(state, + rfc_lookup_table.len_extra_bit_count[next_lit + - 257]); + next_dist = decode_next_small(state, &state->dist_huff_code); + + if (next_dist >= DIST_LEN) + return ISAL_INVALID_SYMBOL; + + look_back_dist = rfc_lookup_table.dist_start[next_dist] + + inflate_in_read_bits(state, + rfc_lookup_table.dist_extra_bit_count + [next_dist]); + + if (state->read_in_length < 0) { + state->read_in = read_in_tmp; + state->read_in_length = read_in_length_tmp; + state->next_in = next_in_tmp; + state->avail_in = avail_in_tmp; + return ISAL_END_INPUT; + } + + if (look_back_dist > state->total_out) + return ISAL_INVALID_LOOKBACK; + + if (state->avail_out < repeat_length) { + state->copy_overflow_length = repeat_length - state->avail_out; + state->copy_overflow_distance = look_back_dist; + repeat_length = state->avail_out; + } + + if (look_back_dist > repeat_length) + memcpy(state->next_out, + state->next_out - look_back_dist, repeat_length); + else + byte_copy(state->next_out, look_back_dist, repeat_length); + + state->next_out += repeat_length; + state->avail_out -= repeat_length; + state->total_out += repeat_length; + + if (state->copy_overflow_length > 0) + return ISAL_OUT_OVERFLOW; + } else + /* Else the read in bits do not + * correspond to any valid symbol */ + return ISAL_INVALID_SYMBOL; + } + return 0; +} + +void isal_inflate_init(struct inflate_state *state) +{ + + state->read_in = 0; + state->read_in_length = 0; + state->next_in = NULL; + state->avail_in = 0; + state->next_out = NULL; + state->avail_out = 0; + state->total_out = 0; + state->block_state = ISAL_BLOCK_NEW_HDR; + state->bfinal = 0; + state->crc_flag = 0; + state->crc = 0; + state->type0_block_len = 0; + state->copy_overflow_length = 0; + state->copy_overflow_distance = 0; + state->tmp_in_size = 0; + state->tmp_out_processed = 0; + state->tmp_out_valid = 0; +} + +int isal_inflate_stateless(struct inflate_state *state) +{ + uint32_t ret = 0; + uint8_t *start_out = state->next_out; + + state->read_in = 0; + state->read_in_length = 0; + state->block_state = ISAL_BLOCK_NEW_HDR; + state->bfinal = 0; + state->crc = 0; + state->total_out = 0; + + while (state->block_state != ISAL_BLOCK_FINISH) { + if (state->block_state == ISAL_BLOCK_NEW_HDR) { + ret = read_header(state); + + if (ret) + break; + } + + if (state->block_state == ISAL_BLOCK_TYPE0) + ret = decode_literal_block(state); + else + ret = decode_huffman_code_block_stateless(state); + + if (ret) + break; + if (state->bfinal != 0 && state->block_state == ISAL_BLOCK_NEW_HDR) + state->block_state = ISAL_BLOCK_FINISH; + } + + if (state->crc_flag) + state->crc = crc32_gzip(state->crc, start_out, state->next_out - start_out); + + /* Undo count stuff of bytes read into the read buffer */ + state->next_in -= state->read_in_length / 8; + state->avail_in += state->read_in_length / 8; + + return ret; +} + +int isal_inflate(struct inflate_state *state) +{ + + uint8_t *start_out = state->next_out; + uint32_t avail_out = state->avail_out; + uint32_t copy_size = 0; + int32_t shift_size = 0; + int ret = 0; + + if (state->block_state != ISAL_BLOCK_FINISH) { + /* If space in tmp_out buffer, decompress into the tmp_out_buffer */ + if (state->tmp_out_valid < 2 * ISAL_DEF_HIST_SIZE) { + /* Setup to start decoding into temp buffer */ + state->next_out = &state->tmp_out_buffer[state->tmp_out_valid]; + state->avail_out = + sizeof(state->tmp_out_buffer) - ISAL_LOOK_AHEAD - + state->tmp_out_valid; + + if ((int32_t) state->avail_out < 0) + state->avail_out = 0; + + /* Decode into internal buffer until exit */ + while (state->block_state != ISAL_BLOCK_INPUT_DONE) { + if (state->block_state == ISAL_BLOCK_NEW_HDR + || state->block_state == ISAL_BLOCK_HDR) { + ret = read_header_stateful(state); + + if (ret) + break; + } + + if (state->block_state == ISAL_BLOCK_TYPE0) { + ret = decode_literal_block(state); + } else + ret = decode_huffman_code_block_stateless(state); + + if (ret) + break; + if (state->bfinal != 0 + && state->block_state == ISAL_BLOCK_NEW_HDR) + state->block_state = ISAL_BLOCK_INPUT_DONE; + } + + /* Copy valid data from internal buffer into out_buffer */ + if (state->copy_overflow_length != 0) { + byte_copy(state->next_out, state->copy_overflow_distance, + state->copy_overflow_length); + state->tmp_out_valid += state->copy_overflow_length; + state->next_out += state->copy_overflow_length; + state->total_out += state->copy_overflow_length; + state->copy_overflow_distance = 0; + state->copy_overflow_length = 0; + } + + state->tmp_out_valid = state->next_out - state->tmp_out_buffer; + + /* Setup state for decompressing into out_buffer */ + state->next_out = start_out; + state->avail_out = avail_out; + } + + /* Copy data from tmp_out buffer into out_buffer */ + copy_size = state->tmp_out_valid - state->tmp_out_processed; + if (copy_size > avail_out) + copy_size = avail_out; + + memcpy(state->next_out, + &state->tmp_out_buffer[state->tmp_out_processed], copy_size); + + state->tmp_out_processed += copy_size; + state->avail_out -= copy_size; + state->next_out += copy_size; + + if (ret == ISAL_INVALID_LOOKBACK || ret == ISAL_INVALID_BLOCK + || ret == ISAL_INVALID_SYMBOL) { + /* Set total_out to not count data in tmp_out_buffer */ + state->total_out -= state->tmp_out_valid - state->tmp_out_processed; + if (state->crc_flag) + state->crc = + crc32_gzip(state->crc, start_out, + state->next_out - start_out); + return ret; + } + + /* If all data from tmp_out buffer has been processed, start + * decompressing into the out buffer */ + if (state->tmp_out_processed == state->tmp_out_valid) { + while (state->block_state != ISAL_BLOCK_INPUT_DONE) { + if (state->block_state == ISAL_BLOCK_NEW_HDR + || state->block_state == ISAL_BLOCK_HDR) { + ret = read_header_stateful(state); + if (ret) + break; + } + + if (state->block_state == ISAL_BLOCK_TYPE0) + ret = decode_literal_block(state); + else + ret = decode_huffman_code_block_stateless(state); + if (ret) + break; + if (state->bfinal != 0 + && state->block_state == ISAL_BLOCK_NEW_HDR) + state->block_state = ISAL_BLOCK_INPUT_DONE; + } + } + + if (state->crc_flag) + state->crc = + crc32_gzip(state->crc, start_out, state->next_out - start_out); + + if (state->block_state != ISAL_BLOCK_INPUT_DONE) { + /* Save decompression history in tmp_out buffer */ + if (state->tmp_out_valid == state->tmp_out_processed + && avail_out - state->avail_out >= ISAL_DEF_HIST_SIZE) { + memcpy(state->tmp_out_buffer, + state->next_out - ISAL_DEF_HIST_SIZE, + ISAL_DEF_HIST_SIZE); + state->tmp_out_valid = ISAL_DEF_HIST_SIZE; + state->tmp_out_processed = ISAL_DEF_HIST_SIZE; + + } else if (state->tmp_out_processed >= ISAL_DEF_HIST_SIZE) { + shift_size = state->tmp_out_valid - ISAL_DEF_HIST_SIZE; + if (shift_size > state->tmp_out_processed) + shift_size = state->tmp_out_processed; + + memmove(state->tmp_out_buffer, + &state->tmp_out_buffer[shift_size], + state->tmp_out_valid - shift_size); + state->tmp_out_valid -= shift_size; + state->tmp_out_processed -= shift_size; + + } + + if (state->copy_overflow_length != 0) { + byte_copy(&state->tmp_out_buffer[state->tmp_out_valid], + state->copy_overflow_distance, + state->copy_overflow_length); + state->tmp_out_valid += state->copy_overflow_length; + state->total_out += state->copy_overflow_length; + state->copy_overflow_distance = 0; + state->copy_overflow_length = 0; + } + + if (ret == ISAL_INVALID_LOOKBACK || ret == ISAL_INVALID_BLOCK + || ret == ISAL_INVALID_SYMBOL) + return ret; + + } else if (state->tmp_out_valid == state->tmp_out_processed) + state->block_state = ISAL_BLOCK_FINISH; + } + + return ISAL_DECOMP_OK; +} diff --git a/ceph/src/isa-l/igzip/igzip_inflate_multibinary.asm b/ceph/src/isa-l/igzip/igzip_inflate_multibinary.asm new file mode 100644 index 000000000..4d6080251 --- /dev/null +++ b/ceph/src/isa-l/igzip/igzip_inflate_multibinary.asm @@ -0,0 +1,51 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2016 Intel Corporation All rights reserved. +; +; 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 Intel Corporation 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 +; 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. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +default rel +[bits 64] + +%ifidn __OUTPUT_FORMAT__, elf64 +%define WRT_OPT wrt ..plt +%else +%define WRT_OPT +%endif + +%include "reg_sizes.asm" + +extern decode_huffman_code_block_stateless_base +extern decode_huffman_code_block_stateless_01 +extern decode_huffman_code_block_stateless_04 + +section .text + +%include "multibinary.asm" + + +mbin_interface decode_huffman_code_block_stateless +mbin_dispatch_init5 decode_huffman_code_block_stateless, decode_huffman_code_block_stateless_base, decode_huffman_code_block_stateless_01, decode_huffman_code_block_stateless_01, decode_huffman_code_block_stateless_04 diff --git a/ceph/src/isa-l/igzip/igzip_inflate_perf.c b/ceph/src/isa-l/igzip/igzip_inflate_perf.c index 930377ebe..70d2af7d3 100644 --- a/ceph/src/isa-l/igzip/igzip_inflate_perf.c +++ b/ceph/src/isa-l/igzip/igzip_inflate_perf.c @@ -29,13 +29,16 @@ #include #include -#include #include "huff_codes.h" -#include "igzip_inflate_ref.h" +#include "igzip_lib.h" #include "test.h" +#if defined(ZLIB_9) || defined(ZLIB_1) || defined(ZLIB_COMPARE) +# include +#endif + #define BUF_SIZE 1024 -#define MIN_TEST_LOOPS 100 +#define MIN_TEST_LOOPS 8 #ifndef RUN_MEM_SIZE # define RUN_MEM_SIZE 1000000000 #endif @@ -60,7 +63,7 @@ int main(int argc, char *argv[]) struct inflate_state state; if (argc > 3 || argc < 2) { - fprintf(stderr, "Usage: igzip_inflate_file_perf infile\n" + fprintf(stderr, "Usage: isal_inflate_file_perf infile\n" "\t - Runs multiple iterations of igzip on a file to " "get more accurate time results.\n"); exit(0); @@ -78,7 +81,7 @@ int main(int argc, char *argv[]) } printf("outfile=%s\n", argv[2]); } - printf("igzip_inflate_perf: \n"); + printf("isal_inflate_perf: \n"); fflush(0); /* Allocate space for entire input file and output * (assuming some possible expansion on output size) @@ -100,49 +103,136 @@ int main(int argc, char *argv[]) fprintf(stderr, "Can't allocate temp buffer memory\n"); exit(0); } - inbuf_size = compressBound(infile_size); + inbuf_size = 2 * infile_size; inbuf = malloc(inbuf_size); if (inbuf == NULL) { fprintf(stderr, "Can't allocate input buffer memory\n"); exit(0); } - outbuf = malloc(infile_size); + outbuf = malloc(outbuf_size); if (outbuf == NULL) { fprintf(stderr, "Can't allocate output buffer memory\n"); exit(0); } + fread(tempbuf, 1, infile_size, in); + +#ifdef ZLIB_9 + printf("Using zlib -9 compression\n"); i = compress2(inbuf, &inbuf_size, tempbuf, infile_size, 9); if (i != Z_OK) { printf("Compression of input file failed\n"); exit(0); } - printf("igzip_inflate_perf: %s %d iterations\n", argv[1], iterations); + + inbuf += 2; + inbuf_size -= 2; +#elif defined(ZLIB_1) + printf("Using zlib -1 compression\n"); + i = compress2(inbuf, &inbuf_size, tempbuf, infile_size, 1); + if (i != Z_OK) { + printf("Compression of input file failed\n"); + exit(0); + } + + inbuf += 2; + inbuf_size -= 2; +#else + printf("Using igzip compression\n"); + struct isal_zstream stream; + isal_deflate_init(&stream); + stream.end_of_stream = 1; /* Do the entire file at once */ + stream.flush = NO_FLUSH; + stream.next_in = tempbuf; + stream.avail_in = infile_size; + stream.next_out = inbuf; + stream.avail_out = inbuf_size; +#ifdef IGZIP_CUSTOM + struct isal_huff_histogram histogram; + struct isal_hufftables hufftables_custom; + + memset(&histogram, 0, sizeof(histogram)); + isal_update_histogram(tempbuf, infile_size, &histogram); + isal_create_hufftables(&hufftables_custom, &histogram); + stream.hufftables = &hufftables_custom; +#endif + isal_deflate(&stream); + if (stream.avail_in != 0) { + printf("Compression of input file failed\n"); + exit(0); + } +#endif + +#ifdef ZLIB_COMPARE + { + printf("igzip_zlib_inflate_perf: %s %d iterations\n", argv[1], iterations); + /* Read complete input file into buffer */ + + struct perf start, stop; + perf_start(&start); + + z_stream gstream; + + for (i = 0; i < iterations; i++) { + gstream.next_in = inbuf; + gstream.avail_in = inbuf_size; + gstream.zalloc = Z_NULL; + gstream.zfree = Z_NULL; + gstream.opaque = Z_NULL; + if (0 != inflateInit2(&gstream, -15)) { + printf("Fail zlib init\n"); + exit(-1); + } + gstream.next_out = outbuf; + gstream.avail_out = outbuf_size; + check = inflate(&gstream, Z_FINISH); + if (check != 1) { + printf("Error in decompression with error %d\n", check); + break; + } + } + perf_stop(&stop); + printf(" file %s - in_size=%d out_size=%lu iter=%d\n", argv[1], + infile_size, gstream.total_out, i); + + printf("igzip_file: "); + perf_print(stop, start, (long long)infile_size * i); + + printf("End of igzip_zlib_inflate_perf\n\n"); + } +#endif + printf("isal_inflate_stateless_perf: %s %d iterations\n", argv[1], iterations); /* Read complete input file into buffer */ fclose(in); struct perf start, stop; perf_start(&start); for (i = 0; i < iterations; i++) { - igzip_inflate_init(&state, inbuf + 2, inbuf_size - 2, outbuf, outbuf_size); + isal_inflate_init(&state); + state.next_in = inbuf; + state.avail_in = inbuf_size; + state.next_out = outbuf; + state.avail_out = outbuf_size; - check = igzip_inflate(&state); + check = isal_inflate(&state); if (check) { printf("Error in decompression with error %d\n", check); break; } } perf_stop(&stop); - printf(" file %s - in_size=%d out_size=%d iter=%d\n", argv[1], - infile_size, state.out_buffer.total_out, i); + infile_size, state.total_out, i); printf("igzip_file: "); perf_print(stop, start, (long long)infile_size * i); - printf("End of igzip_inflate_perf\n\n"); + printf("End of isal_inflate_stateless_perf\n\n"); fflush(0); +#if defined(ZLIB_1) || defined(ZLIB_9) + inbuf -= 2; +#endif free(inbuf); free(outbuf); free(tempbuf); diff --git a/ceph/src/isa-l/igzip/igzip_inflate_ref.c b/ceph/src/isa-l/igzip/igzip_inflate_ref.c deleted file mode 100644 index 46464bcfb..000000000 --- a/ceph/src/isa-l/igzip/igzip_inflate_ref.c +++ /dev/null @@ -1,668 +0,0 @@ -/********************************************************************** - Copyright(c) 2011-2016 Intel Corporation All rights reserved. - - 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 Intel Corporation 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 - 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. -**********************************************************************/ - -#include "igzip_inflate_ref.h" - -void inline byte_copy(uint8_t * dest, uint64_t lookback_distance, int repeat_length) -{ - uint8_t *src = dest - lookback_distance; - - for (; repeat_length > 0; repeat_length--) - *dest++ = *src++; -} - -/* - * Returns integer with first length bits reversed and all higher bits zeroed - */ -uint16_t inline bit_reverse2(uint16_t bits, uint8_t length) -{ - bits = ((bits >> 1) & 0x55555555) | ((bits & 0x55555555) << 1); // swap bits - bits = ((bits >> 2) & 0x33333333) | ((bits & 0x33333333) << 2); // swap pairs - bits = ((bits >> 4) & 0x0F0F0F0F) | ((bits & 0x0F0F0F0F) << 4); // swap nibbles - bits = ((bits >> 8) & 0x00FF00FF) | ((bits & 0x00FF00FF) << 8); // swap bytes - return bits >> (16 - length); -} - -void inline init_inflate_in_buffer(struct inflate_in_buffer *inflate_in) -{ - inflate_in->read_in = 0; - inflate_in->read_in_length = 0; -} - -void inline set_inflate_in_buffer(struct inflate_in_buffer *inflate_in, uint8_t * in_stream, - uint32_t in_size) -{ - inflate_in->next_in = inflate_in->start = in_stream; - inflate_in->avail_in = in_size; -} - -void inline set_inflate_out_buffer(struct inflate_out_buffer *inflate_out, - uint8_t * out_stream, uint32_t out_size) -{ - inflate_out->next_out = out_stream; - inflate_out->avail_out = out_size; - inflate_out->total_out = 0; -} - -void inline inflate_in_clear_bits(struct inflate_in_buffer *inflate_in) -{ - uint8_t bytes; - - bytes = inflate_in->read_in_length / 8; - - inflate_in->read_in = 0; - inflate_in->read_in_length = 0; - inflate_in->next_in -= bytes; - inflate_in->avail_in += bytes; -} - -void inline inflate_in_load(struct inflate_in_buffer *inflate_in, int min_required) -{ - uint64_t temp = 0; - uint8_t new_bytes; - - if (inflate_in->avail_in >= 8) { - /* If there is enough space to load a 64 bits, load the data and use - * that to fill read_in */ - new_bytes = 8 - (inflate_in->read_in_length + 7) / 8; - temp = *(uint64_t *) inflate_in->next_in; - - inflate_in->read_in |= temp << inflate_in->read_in_length; - inflate_in->next_in += new_bytes; - inflate_in->avail_in -= new_bytes; - inflate_in->read_in_length += new_bytes * 8; - - } else { - /* Else fill the read_in buffer 1 byte at a time */ - while (inflate_in->read_in_length < 57 && inflate_in->avail_in > 0) { - temp = *inflate_in->next_in; - inflate_in->read_in |= temp << inflate_in->read_in_length; - inflate_in->next_in++; - inflate_in->avail_in--; - inflate_in->read_in_length += 8; - - } - } - -} - -uint64_t inline inflate_in_peek_bits(struct inflate_in_buffer *inflate_in, uint8_t bit_count) -{ - assert(bit_count < 57); - - /* Load inflate_in if not enough data is in the read_in buffer */ - if (inflate_in->read_in_length < bit_count) - inflate_in_load(inflate_in, 0); - - return (inflate_in->read_in) & ((1 << bit_count) - 1); -} - -void inline inflate_in_shift_bits(struct inflate_in_buffer *inflate_in, uint8_t bit_count) -{ - - inflate_in->read_in >>= bit_count; - inflate_in->read_in_length -= bit_count; -} - -uint64_t inline inflate_in_read_bits(struct inflate_in_buffer *inflate_in, uint8_t bit_count) -{ - uint64_t ret; - assert(bit_count < 57); - - /* Load inflate_in if not enough data is in the read_in buffer */ - if (inflate_in->read_in_length < bit_count) - inflate_in_load(inflate_in, bit_count); - - ret = (inflate_in->read_in) & ((1 << bit_count) - 1); - inflate_in->read_in >>= bit_count; - inflate_in->read_in_length -= bit_count; - - return ret; -} - -int inline setup_static_header(struct inflate_state *state) -{ - /* This could be turned into a memcpy of this functions output for - * higher speed, but then DECODE_LOOKUP_SIZE couldn't be changed without - * regenerating the table. */ - - int i; - struct huff_code lit_code[LIT_LEN + 2]; - struct huff_code dist_code[DIST_LEN + 2]; - - /* These tables are based on the static huffman tree described in RFC - * 1951 */ - uint16_t lit_count[16] = { - 0, 0, 0, 0, 0, 0, 0, 24, 152, 112, 0, 0, 0, 0, 0, 0 - }; - uint16_t dist_count[16] = { - 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - - /* These for loops set the code lengths for the static literal/length - * and distance codes defined in the deflate standard RFC 1951 */ - for (i = 0; i < 144; i++) - lit_code[i].length = 8; - - for (i = 144; i < 256; i++) - lit_code[i].length = 9; - - for (i = 256; i < 280; i++) - lit_code[i].length = 7; - - for (i = 280; i < LIT_LEN + 2; i++) - lit_code[i].length = 8; - - for (i = 0; i < DIST_LEN + 2; i++) - dist_code[i].length = 5; - - make_inflate_huff_code(&state->lit_huff_code, lit_code, LIT_LEN + 2, lit_count); - make_inflate_huff_code(&state->dist_huff_code, dist_code, DIST_LEN + 2, dist_count); - - return 0; -} - -void inline make_inflate_huff_code(struct inflate_huff_code *result, - struct huff_code *huff_code_table, int table_length, - uint16_t * count) -{ - int i, j; - uint16_t code = 0; - uint16_t next_code[MAX_HUFF_TREE_DEPTH + 1]; - uint16_t long_code_list[LIT_LEN]; - uint32_t long_code_length = 0; - uint16_t temp_code_list[1 << (15 - DECODE_LOOKUP_SIZE)]; - uint32_t temp_code_length; - uint32_t long_code_lookup_length = 0; - uint32_t max_length; - uint16_t first_bits; - uint32_t code_length; - uint16_t long_bits; - uint16_t min_increment; - - memset(result, 0, sizeof(struct inflate_huff_code)); - - next_code[0] = code; - - for (i = 1; i < MAX_HUFF_TREE_DEPTH + 1; i++) - next_code[i] = (next_code[i - 1] + count[i - 1]) << 1; - - for (i = 0; i < table_length; i++) { - if (huff_code_table[i].length != 0) { - /* Determine the code for symbol i */ - huff_code_table[i].code = - bit_reverse2(next_code[huff_code_table[i].length], - huff_code_table[i].length); - - next_code[huff_code_table[i].length] += 1; - - if (huff_code_table[i].length <= DECODE_LOOKUP_SIZE) { - /* Set lookup table to return the current symbol - * concatenated with the code length when the - * first DECODE_LENGTH bits of the address are - * the same as the code for the current - * symbol. The first 9 bits are the code, bits - * 14:10 are the code length, bit 15 is a flag - * representing this is a symbol*/ - for (j = 0; j < (1 << (DECODE_LOOKUP_SIZE - - huff_code_table[i].length)); j++) - - result->small_code_lookup[(j << - huff_code_table[i].length) + - huff_code_table[i].code] - = i | (huff_code_table[i].length) << 9; - - } else { - /* Store the element in a list of elements with long codes. */ - long_code_list[long_code_length] = i; - long_code_length++; - } - } - } - - for (i = 0; i < long_code_length; i++) { - /*Set the look up table to point to a hint where the symbol can be found - * in the list of long codes and add the current symbol to the list of - * long codes. */ - if (huff_code_table[long_code_list[i]].code == 0xFFFF) - continue; - - max_length = huff_code_table[long_code_list[i]].length; - first_bits = - huff_code_table[long_code_list[i]].code & ((1 << DECODE_LOOKUP_SIZE) - 1); - - temp_code_list[0] = long_code_list[i]; - temp_code_length = 1; - - for (j = i + 1; j < long_code_length; j++) { - if ((huff_code_table[long_code_list[j]].code & - ((1 << DECODE_LOOKUP_SIZE) - 1)) == first_bits) { - if (max_length < huff_code_table[long_code_list[j]].length) - max_length = huff_code_table[long_code_list[j]].length; - temp_code_list[temp_code_length] = long_code_list[j]; - temp_code_length++; - } - } - - for (j = 0; j < temp_code_length; j++) { - code_length = huff_code_table[temp_code_list[j]].length; - long_bits = - huff_code_table[temp_code_list[j]].code >> DECODE_LOOKUP_SIZE; - min_increment = 1 << (code_length - DECODE_LOOKUP_SIZE); - for (; long_bits < (1 << (max_length - DECODE_LOOKUP_SIZE)); - long_bits += min_increment) { - result->long_code_lookup[long_code_lookup_length + long_bits] = - temp_code_list[j] | (code_length << 9); - } - huff_code_table[temp_code_list[j]].code = 0xFFFF; - } - result->small_code_lookup[first_bits] = - long_code_lookup_length | (max_length << 9) | 0x8000; - long_code_lookup_length += 1 << (max_length - DECODE_LOOKUP_SIZE); - - } -} - -uint16_t inline decode_next(struct inflate_in_buffer *in_buffer, - struct inflate_huff_code *huff_code) -{ - uint16_t next_bits; - uint16_t next_sym; - - next_bits = inflate_in_peek_bits(in_buffer, DECODE_LOOKUP_SIZE); - - /* next_sym is a possible symbol decoded from next_bits. If bit 15 is 0, - * next_code is a symbol. Bits 9:0 represent the symbol, and bits 14:10 - * represent the length of that symbols huffman code. If next_sym is not - * a symbol, it provides a hint of where the large symbols containin - * this code are located. Note the hint is at largest the location the - * first actual symbol in the long code list.*/ - next_sym = huff_code->small_code_lookup[next_bits]; - - if (next_sym < 0x8000) { - /* Return symbol found if next_code is a complete huffman code - * and shift in buffer over by the length of the next_code */ - inflate_in_shift_bits(in_buffer, next_sym >> 9); - - return next_sym & 0x1FF; - - } else { - /* If a symbol is not found, perform a linear search of the long code - * list starting from the hint in next_sym */ - next_bits = inflate_in_peek_bits(in_buffer, (next_sym - 0x8000) >> 9); - next_sym = - huff_code->long_code_lookup[(next_sym & 0x1FF) + - (next_bits >> DECODE_LOOKUP_SIZE)]; - inflate_in_shift_bits(in_buffer, next_sym >> 9); - return next_sym & 0x1FF; - - } -} - -int inline setup_dynamic_header(struct inflate_state *state) -{ - int i, j; - struct huff_code code_huff[CODE_LEN_CODES]; - struct huff_code lit_and_dist_huff[LIT_LEN + DIST_LEN]; - struct huff_code *previous = NULL, *current; - struct inflate_huff_code inflate_code_huff; - uint8_t hclen, hdist, hlit; - uint16_t code_count[16], lit_count[16], dist_count[16]; - uint16_t *count; - uint16_t symbol; - - /* This order is defined in RFC 1951 page 13 */ - const uint8_t code_length_code_order[CODE_LEN_CODES] = { - 0x10, 0x11, 0x12, 0x00, 0x08, 0x07, 0x09, 0x06, - 0x0a, 0x05, 0x0b, 0x04, 0x0c, 0x03, 0x0d, 0x02, - 0x0e, 0x01, 0x0f - }; - - memset(code_count, 0, sizeof(code_count)); - memset(lit_count, 0, sizeof(lit_count)); - memset(dist_count, 0, sizeof(dist_count)); - memset(code_huff, 0, sizeof(code_huff)); - memset(lit_and_dist_huff, 0, sizeof(lit_and_dist_huff)); - - /* These variables are defined in the deflate standard, RFC 1951 */ - hlit = inflate_in_read_bits(&state->in_buffer, 5); - hdist = inflate_in_read_bits(&state->in_buffer, 5); - hclen = inflate_in_read_bits(&state->in_buffer, 4); - - /* Create the code huffman code for decoding the lit/len and dist huffman codes */ - for (i = 0; i < hclen + 4; i++) { - code_huff[code_length_code_order[i]].length = - inflate_in_read_bits(&state->in_buffer, 3); - - code_count[code_huff[code_length_code_order[i]].length] += 1; - } - - if (state->in_buffer.read_in_length < 0) - return END_OF_INPUT; - - make_inflate_huff_code(&inflate_code_huff, code_huff, CODE_LEN_CODES, code_count); - - /* Decode the lit/len and dist huffman codes using the code huffman code */ - count = lit_count; - current = lit_and_dist_huff; - - while (current < lit_and_dist_huff + LIT_LEN + hdist + 1) { - /* If finished decoding the lit/len huffman code, start decoding - * the distance code these decodings are in the same loop - * because the len/lit and dist huffman codes are run length - * encoded together. */ - if (current == lit_and_dist_huff + 257 + hlit) - current = lit_and_dist_huff + LIT_LEN; - - if (current == lit_and_dist_huff + LIT_LEN) - count = dist_count; - - symbol = decode_next(&state->in_buffer, &inflate_code_huff); - - if (state->in_buffer.read_in_length < 0) - return END_OF_INPUT; - - if (symbol < 16) { - /* If a length is found, update the current lit/len/dist - * to have length symbol */ - count[symbol]++; - current->length = symbol; - previous = current; - current++; - - } else if (symbol == 16) { - /* If a repeat length is found, update the next repeat - * length lit/len/dist elements to have the value of the - * repeated length */ - if (previous == NULL) /* No elements available to be repeated */ - return INVALID_BLOCK_HEADER; - - i = 3 + inflate_in_read_bits(&state->in_buffer, 2); - for (j = 0; j < i; j++) { - *current = *previous; - count[current->length]++; - previous = current; - - if (current == lit_and_dist_huff + 256 + hlit) { - current = lit_and_dist_huff + LIT_LEN; - count = dist_count; - - } else - current++; - } - - } else if (symbol == 17) { - /* If a repeat zeroes if found, update then next - * repeated zeroes length lit/len/dist elements to have - * length 0. */ - i = 3 + inflate_in_read_bits(&state->in_buffer, 3); - - for (j = 0; j < i; j++) { - previous = current; - - if (current == lit_and_dist_huff + 256 + hlit) { - current = lit_and_dist_huff + LIT_LEN; - count = dist_count; - - } else - current++; - } - - } else if (symbol == 18) { - /* If a repeat zeroes if found, update then next - * repeated zeroes length lit/len/dist elements to have - * length 0. */ - i = 11 + inflate_in_read_bits(&state->in_buffer, 7); - - for (j = 0; j < i; j++) { - previous = current; - - if (current == lit_and_dist_huff + 256 + hlit) { - current = lit_and_dist_huff + LIT_LEN; - count = dist_count; - - } else - current++; - } - } else - return INVALID_BLOCK_HEADER; - - } - - if (state->in_buffer.read_in_length < 0) - return END_OF_INPUT; - - make_inflate_huff_code(&state->lit_huff_code, lit_and_dist_huff, LIT_LEN, lit_count); - make_inflate_huff_code(&state->dist_huff_code, &lit_and_dist_huff[LIT_LEN], DIST_LEN, - dist_count); - - return 0; -} - -int read_header(struct inflate_state *state) -{ - state->new_block = 0; - - /* btype and bfinal are defined in RFC 1951, bfinal represents whether - * the current block is the end of block, and btype represents the - * encoding method on the current block. */ - state->bfinal = inflate_in_read_bits(&state->in_buffer, 1); - state->btype = inflate_in_read_bits(&state->in_buffer, 2); - - if (state->in_buffer.read_in_length < 0) - return END_OF_INPUT; - - if (state->btype == 0) { - inflate_in_clear_bits(&state->in_buffer); - return 0; - - } else if (state->btype == 1) - return setup_static_header(state); - - else if (state->btype == 2) - return setup_dynamic_header(state); - - return INVALID_BLOCK_HEADER; -} - -void igzip_inflate_init(struct inflate_state *state, uint8_t * in_stream, uint32_t in_size, - uint8_t * out_stream, uint64_t out_size) -{ - - init_inflate_in_buffer(&state->in_buffer); - - set_inflate_in_buffer(&state->in_buffer, in_stream, in_size); - set_inflate_out_buffer(&state->out_buffer, out_stream, out_size); - - state->new_block = 1; - state->bfinal = 0; -} - -int igzip_inflate(struct inflate_state *state) -{ - /* The following tables are based on the tables in the deflate standard, - * RFC 1951 page 11. */ - const uint16_t len_start[29] = { - 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, - 0x0b, 0x0d, 0x0f, 0x11, 0x13, 0x17, 0x1b, 0x1f, - 0x23, 0x2b, 0x33, 0x3b, 0x43, 0x53, 0x63, 0x73, - 0x83, 0xa3, 0xc3, 0xe3, 0x102 - }; - const uint8_t len_extra_bit_count[29] = { - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x1, 0x1, 0x1, 0x2, 0x2, 0x2, 0x2, - 0x3, 0x3, 0x3, 0x3, 0x4, 0x4, 0x4, 0x4, - 0x5, 0x5, 0x5, 0x5, 0x0 - }; - const uint32_t dist_start[30] = { - 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0007, 0x0009, 0x000d, - 0x0011, 0x0019, 0x0021, 0x0031, 0x0041, 0x0061, 0x0081, 0x00c1, - 0x0101, 0x0181, 0x0201, 0x0301, 0x0401, 0x0601, 0x0801, 0x0c01, - 0x1001, 0x1801, 0x2001, 0x3001, 0x4001, 0x6001 - }; - const uint8_t dist_extra_bit_count[30] = { - 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x2, 0x2, - 0x3, 0x3, 0x4, 0x4, 0x5, 0x5, 0x6, 0x6, - 0x7, 0x7, 0x8, 0x8, 0x9, 0x9, 0xa, 0xa, - 0xb, 0xb, 0xc, 0xc, 0xd, 0xd - }; - - uint16_t next_lit, len, nlen; - uint8_t next_dist; - uint32_t repeat_length; - uint32_t look_back_dist; - uint32_t tmp; - - while (state->new_block == 0 || state->bfinal == 0) { - if (state->new_block != 0) { - tmp = read_header(state); - - if (tmp) - return tmp; - } - - if (state->btype == 0) { - /* If the block is uncompressed, perform a memcopy while - * updating state data */ - if (state->in_buffer.avail_in < 4) - return END_OF_INPUT; - - len = *(uint16_t *) state->in_buffer.next_in; - state->in_buffer.next_in += 2; - nlen = *(uint16_t *) state->in_buffer.next_in; - state->in_buffer.next_in += 2; - - /* Check if len and nlen match */ - if (len != (~nlen & 0xffff)) - return INVALID_NON_COMPRESSED_BLOCK_LENGTH; - - if (state->out_buffer.avail_out < len) - return OUT_BUFFER_OVERFLOW; - - if (state->in_buffer.avail_in < len) - len = state->in_buffer.avail_in; - - else - state->new_block = 1; - - memcpy(state->out_buffer.next_out, state->in_buffer.next_in, len); - - state->out_buffer.next_out += len; - state->out_buffer.avail_out -= len; - state->out_buffer.total_out += len; - state->in_buffer.next_in += len; - state->in_buffer.avail_in -= len + 4; - - if (state->in_buffer.avail_in == 0 && state->new_block == 0) - return END_OF_INPUT; - - } else { - /* Else decode a huffman encoded block */ - while (state->new_block == 0) { - /* While not at the end of block, decode the next - * symbol */ - - next_lit = - decode_next(&state->in_buffer, &state->lit_huff_code); - - if (state->in_buffer.read_in_length < 0) - return END_OF_INPUT; - - if (next_lit < 256) { - /* If the next symbol is a literal, - * write out the symbol and update state - * data accordingly. */ - if (state->out_buffer.avail_out < 1) - return OUT_BUFFER_OVERFLOW; - - *state->out_buffer.next_out = next_lit; - state->out_buffer.next_out++; - state->out_buffer.avail_out--; - state->out_buffer.total_out++; - - } else if (next_lit == 256) { - /* If the next symbol is the end of - * block, update the state data - * accordingly */ - state->new_block = 1; - - } else if (next_lit < 286) { - /* Else if the next symbol is a repeat - * length, read in the length extra - * bits, the distance code, the distance - * extra bits. Then write out the - * corresponding data and update the - * state data accordingly*/ - repeat_length = - len_start[next_lit - 257] + - inflate_in_read_bits(&state->in_buffer, - len_extra_bit_count[next_lit - - 257]); - - if (state->out_buffer.avail_out < repeat_length) - return OUT_BUFFER_OVERFLOW; - - next_dist = decode_next(&state->in_buffer, - &state->dist_huff_code); - - look_back_dist = dist_start[next_dist] + - inflate_in_read_bits(&state->in_buffer, - dist_extra_bit_count - [next_dist]); - - if (state->in_buffer.read_in_length < 0) - return END_OF_INPUT; - - if (look_back_dist > state->out_buffer.total_out) - return INVALID_LOOK_BACK_DISTANCE; - - if (look_back_dist > repeat_length) { - memcpy(state->out_buffer.next_out, - state->out_buffer.next_out - - look_back_dist, repeat_length); - } else - byte_copy(state->out_buffer.next_out, - look_back_dist, repeat_length); - - state->out_buffer.next_out += repeat_length; - state->out_buffer.avail_out -= repeat_length; - state->out_buffer.total_out += repeat_length; - - } else - /* Else the read in bits do not - * correspond to any valid symbol */ - return INVALID_SYMBOL; - } - } - } - state->in_buffer.next_in -= state->in_buffer.read_in_length / 8; - state->in_buffer.avail_in += state->in_buffer.read_in_length / 8; - - return DECOMPRESSION_FINISHED; -} diff --git a/ceph/src/isa-l/igzip/igzip_inflate_ref.h b/ceph/src/isa-l/igzip/igzip_inflate_ref.h deleted file mode 100644 index ba1badd66..000000000 --- a/ceph/src/isa-l/igzip/igzip_inflate_ref.h +++ /dev/null @@ -1,150 +0,0 @@ -/********************************************************************** - Copyright(c) 2011-2016 Intel Corporation All rights reserved. - - 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 Intel Corporation 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 - 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. -**********************************************************************/ - -#ifndef INFLATE_H -#define INFLATE_H - -#include -#include "huff_codes.h" - -#define DECOMPRESSION_FINISHED 0 -#define END_OF_INPUT 1 -#define OUT_BUFFER_OVERFLOW 2 -#define INVALID_BLOCK_HEADER 3 -#define INVALID_SYMBOL 4 -#define INVALID_NON_COMPRESSED_BLOCK_LENGTH 5 -#define INVALID_LOOK_BACK_DISTANCE 6 - -#define DECODE_LOOKUP_SIZE 10 - -#if DECODE_LOOKUP_SIZE > 15 -# undef DECODE_LOOKUP_SIZE -# define DECODE_LOOKUP_SIZE 15 -#endif - -#if DECODE_LOOKUP_SIZE > 7 -# define MAX_LONG_CODE ((2 << 8) + 1) * (2 << (15 - DECODE_LOOKUP_SIZE)) + 32 -#else -# define MAX_LONG_CODE (2 << (15 - DECODE_LOOKUP_SIZE)) + (2 << (8 + DECODE_LOOKUP_SIZE)) + 32 -#endif - -/* Buffer used to manage decompressed output */ -struct inflate_out_buffer{ - uint8_t *next_out; - uint32_t avail_out; - uint32_t total_out; -}; - -/* Buffer used to manager compressed input */ -struct inflate_in_buffer{ - uint8_t *start; - uint8_t *next_in; - uint32_t avail_in; - uint64_t read_in; - int32_t read_in_length; -}; - -/* Data structure used to store a huffman code for fast look up */ -struct inflate_huff_code{ - uint16_t small_code_lookup[ 1 << (DECODE_LOOKUP_SIZE)]; - uint16_t long_code_lookup[MAX_LONG_CODE]; -}; - -/* Structure contained current state of decompression of data */ -struct inflate_state { - struct inflate_out_buffer out_buffer; - struct inflate_in_buffer in_buffer; - struct inflate_huff_code lit_huff_code; - struct inflate_huff_code dist_huff_code; - uint8_t new_block; - uint8_t bfinal; - uint8_t btype; -}; - -/*Performs a copy of length repeat_length data starting at dest - - * lookback_distance into dest. This copy copies data previously copied when the - * src buffer and the dest buffer overlap. */ -void byte_copy(uint8_t *dest, uint64_t lookback_distance, int repeat_length); - -/* Initialize a struct in_buffer for use */ -void init_inflate_in_buffer(struct inflate_in_buffer *inflate_in); - -/* Set up the in_stream used for the in_buffer*/ -void set_inflate_in_buffer(struct inflate_in_buffer *inflate_in, uint8_t *in_stream, - uint32_t in_size); - -/* Set up the out_stream used for the out_buffer */ -void set_inflate_out_buffer(struct inflate_out_buffer *inflate_out, uint8_t *out_stream, - uint32_t out_size); - -/* Load data from the in_stream into a buffer to allow for handling unaligned data*/ -void inflate_in_load(struct inflate_in_buffer *inflate_in, int min_load); - -/* Returns the next bit_count bits from the in stream*/ -uint64_t inflate_in_peek_bits(struct inflate_in_buffer *inflate_in, uint8_t bit_count); - -/* Shifts the in stream over by bit-count bits */ -void inflate_in_shift_bits(struct inflate_in_buffer *inflate_in, uint8_t bit_count); - -/* Returns the next bit_count bits from the in stream and shifts the stream over - * by bit-count bits */ -uint64_t inflate_in_read_bits(struct inflate_in_buffer *inflate_in, uint8_t bit_count); - -/* Sets the inflate_huff_codes in state to be the huffcodes corresponding to the - * deflate static header */ -int setup_static_header(struct inflate_state *state); - -/* Sets result to the inflate_huff_code corresponding to the huffcode defined by - * the lengths in huff_code_table,where count is a histogram of the appearance - * of each code length */ -void make_inflate_huff_code(struct inflate_huff_code *result, struct huff_code *huff_code_table, - int table_length, uint16_t * count); - -/* Decodes the next symbol symbol in in_buffer using the huff code defined by - * huff_code */ -uint16_t decode_next(struct inflate_in_buffer *in_buffer, struct inflate_huff_code *huff_code); - -/* Reads data from the in_buffer and sets the huff code corresponding to that - * data */ -int setup_dynamic_header(struct inflate_state *state); - -/* Reads in the header pointed to by in_stream and sets up state to reflect that - * header information*/ -int read_header(struct inflate_state *state); - -/* Initialize a struct inflate_state for deflate compressed input data at in_stream and to output - * data into out_stream */ -void igzip_inflate_init(struct inflate_state *state, uint8_t *in_stream, uint32_t in_size, - uint8_t *out_stream, uint64_t out_size); - -/* Decompress a deflate data. This function assumes a call to igzip_inflate_init - * has been made to set up the state structure to allow for decompression.*/ -int igzip_inflate(struct inflate_state *state); - -#endif //INFLATE_H diff --git a/ceph/src/isa-l/igzip/igzip_inflate_test.c b/ceph/src/isa-l/igzip/igzip_inflate_test.c index 1c745b5e7..a1f9b9a57 100644 --- a/ceph/src/isa-l/igzip/igzip_inflate_test.c +++ b/ceph/src/isa-l/igzip/igzip_inflate_test.c @@ -30,57 +30,158 @@ #include #include #include -#include "igzip_inflate_ref.h" +#include "igzip_lib.h" #include "huff_codes.h" /*Don't use file larger memory can support because compression and decompression * are done in a stateless manner. */ #define MAX_INPUT_FILE_SIZE 2L*1024L*1024L*1024L -int test(uint8_t * compressed_stream, uint64_t * compressed_length, - uint8_t * uncompressed_stream, int uncompressed_length, - uint8_t * uncompressed_test_stream) +int inflate_multi_pass(uint8_t * compress_buf, uint64_t compress_len, + uint8_t * uncompress_buf, uint32_t * uncompress_len) +{ + struct inflate_state *state = NULL; + int ret = 0; + uint8_t *comp_tmp = NULL, *uncomp_tmp = NULL; + uint32_t comp_tmp_size = 0, uncomp_tmp_size = 0; + uint32_t comp_processed = 0, uncomp_processed = 0; + + state = malloc(sizeof(struct inflate_state)); + if (state == NULL) { + printf("Failed to allocate memory\n"); + exit(0); + } + + isal_inflate_init(state); + + state->next_in = NULL; + state->next_out = NULL; + state->avail_in = 0; + state->avail_out = 0; + + while (1) { + if (state->avail_in == 0) { + comp_tmp_size = rand() % (compress_len + 1); + + if (comp_tmp_size >= compress_len - comp_processed) + comp_tmp_size = compress_len - comp_processed; + + if (comp_tmp_size != 0) { + if (comp_tmp != NULL) { + free(comp_tmp); + comp_tmp = NULL; + } + + comp_tmp = malloc(comp_tmp_size); + + if (comp_tmp == NULL) { + printf("Failed to allocate memory\n"); + exit(0); + } + + memcpy(comp_tmp, compress_buf + comp_processed, comp_tmp_size); + comp_processed += comp_tmp_size; + + state->next_in = comp_tmp; + state->avail_in = comp_tmp_size; + } + } + + if (state->avail_out == 0) { + /* Save uncompressed data into uncompress_buf */ + if (uncomp_tmp != NULL) { + memcpy(uncompress_buf + uncomp_processed, uncomp_tmp, + uncomp_tmp_size); + uncomp_processed += uncomp_tmp_size; + } + + uncomp_tmp_size = rand() % (*uncompress_len + 1); + + /* Limit size of buffer to be smaller than maximum */ + if (uncomp_tmp_size > *uncompress_len - uncomp_processed) + uncomp_tmp_size = *uncompress_len - uncomp_processed; + + if (uncomp_tmp_size != 0) { + + if (uncomp_tmp != NULL) { + fflush(0); + free(uncomp_tmp); + uncomp_tmp = NULL; + } + + uncomp_tmp = malloc(uncomp_tmp_size); + if (uncomp_tmp == NULL) { + printf("Failed to allocate memory\n"); + exit(0); + } + + state->avail_out = uncomp_tmp_size; + state->next_out = uncomp_tmp; + } + } + + ret = isal_inflate(state); + + if (state->block_state == ISAL_BLOCK_FINISH || ret != 0) { + memcpy(uncompress_buf + uncomp_processed, uncomp_tmp, uncomp_tmp_size); + *uncompress_len = state->total_out; + break; + } + } + + if (comp_tmp != NULL) { + free(comp_tmp); + comp_tmp = NULL; + } + if (uncomp_tmp != NULL) { + free(uncomp_tmp); + uncomp_tmp = NULL; + } + + free(state); + return ret; +} + +int test(uint8_t * compressed_stream, + uint64_t * compressed_length, + uint8_t * uncompressed_stream, uint32_t uncompressed_length, + uint8_t * uncompressed_test_stream, uint32_t uncompressed_test_stream_length) { - struct inflate_state state; int ret; ret = - compress2(compressed_stream, compressed_length, uncompressed_stream, - uncompressed_length, 9); + compress2(compressed_stream, compressed_length, + uncompressed_stream, uncompressed_length, 6); if (ret) { printf("Failed compressing input with exit code %d", ret); return ret; } - igzip_inflate_init(&state, compressed_stream + 2, *compressed_length - 2, - uncompressed_test_stream, uncompressed_length); - ret = igzip_inflate(&state); - + ret = + inflate_multi_pass(compressed_stream + 2, + *compressed_length - 2 - 4, + uncompressed_test_stream, &uncompressed_test_stream_length); switch (ret) { case 0: break; - case END_OF_INPUT: + case ISAL_END_INPUT: printf(" did not decompress all input\n"); - return END_OF_INPUT; + return ISAL_END_INPUT; break; - case INVALID_BLOCK_HEADER: + case ISAL_INVALID_BLOCK: printf(" invalid header\n"); - return INVALID_BLOCK_HEADER; + return ISAL_INVALID_BLOCK; break; - case INVALID_SYMBOL: + case ISAL_INVALID_SYMBOL: printf(" invalid symbol\n"); - return INVALID_SYMBOL; + return ISAL_INVALID_SYMBOL; break; - case OUT_BUFFER_OVERFLOW: + case ISAL_OUT_OVERFLOW: printf(" out buffer overflow\n"); - return OUT_BUFFER_OVERFLOW; - break; - case INVALID_NON_COMPRESSED_BLOCK_LENGTH: - printf("Invalid length bits in non-compressed block\n"); - return INVALID_NON_COMPRESSED_BLOCK_LENGTH; + return ISAL_OUT_OVERFLOW; break; - case INVALID_LOOK_BACK_DISTANCE: + case ISAL_INVALID_LOOKBACK: printf("Invalid lookback distance"); - return INVALID_LOOK_BACK_DISTANCE; + return ISAL_INVALID_LOOKBACK; break; default: printf(" error\n"); @@ -88,29 +189,39 @@ int test(uint8_t * compressed_stream, uint64_t * compressed_length, break; } - if (state.out_buffer.total_out != uncompressed_length) { + if (uncompressed_test_stream_length != uncompressed_length) { printf("incorrect amount of data was decompressed from compressed data\n"); - printf("%d decompressed of %d compressed", state.out_buffer.total_out, - uncompressed_length); + printf("%d decompressed of %d compressed", + uncompressed_test_stream_length, uncompressed_length); return -1; } if (memcmp(uncompressed_stream, uncompressed_test_stream, uncompressed_length)) { + int i; + for (i = 0; i < uncompressed_length; i++) { + if (uncompressed_stream[i] != uncompressed_test_stream[i]) { + printf("first error at %d, 0x%x != 0x%x\n", i, + uncompressed_stream[i], uncompressed_test_stream[i]); + } + } printf(" decompressed data is not the same as the compressed data\n"); return -1; } + return 0; } int main(int argc, char **argv) { int i, j, ret = 0, fin_ret = 0; - FILE *file; - uint64_t compressed_length, file_length, uncompressed_length; - uint8_t *uncompressed_stream, *compressed_stream, *uncompressed_test_stream; + FILE *file = NULL; + uint64_t compressed_length, file_length; + uint64_t uncompressed_length, uncompressed_test_stream_length; + uint8_t *uncompressed_stream = NULL; + uint8_t *compressed_stream = NULL; + uint8_t *uncompressed_test_stream = NULL; if (argc == 1) printf("Error, no input file\n"); - for (i = 1; i < argc; i++) { file = fopen(argv[i], "r"); if (file == NULL) { @@ -118,7 +229,7 @@ int main(int argc, char **argv) return 1; } else printf("Starting file %s", argv[i]); - + fflush(0); fseek(file, 0, SEEK_END); file_length = ftell(file); fseek(file, 0, SEEK_SET); @@ -128,12 +239,14 @@ int main(int argc, char **argv) fclose(file); continue; } + compressed_length = compressBound(file_length); - uncompressed_stream = malloc(file_length); + if (file_length != 0) { + uncompressed_stream = malloc(file_length); + uncompressed_test_stream = malloc(file_length); + } compressed_stream = malloc(compressed_length); - uncompressed_test_stream = malloc(file_length); - - if (uncompressed_stream == NULL) { + if (uncompressed_stream == NULL && file_length != 0) { printf("Failed to allocate memory\n"); exit(0); } @@ -149,9 +262,11 @@ int main(int argc, char **argv) } uncompressed_length = fread(uncompressed_stream, 1, file_length, file); + uncompressed_test_stream_length = uncompressed_length; ret = test(compressed_stream, &compressed_length, uncompressed_stream, - uncompressed_length, uncompressed_test_stream); + uncompressed_length, uncompressed_test_stream, + uncompressed_test_stream_length); if (ret) { for (j = 0; j < compressed_length; j++) { if ((j & 31) == 0) @@ -159,23 +274,22 @@ int main(int argc, char **argv) else printf(" "); printf("0x%02x,", compressed_stream[j]); - } printf("\n"); - } + fflush(0); fclose(file); free(compressed_stream); - free(uncompressed_stream); - free(uncompressed_test_stream); - + if (uncompressed_stream != NULL) + free(uncompressed_stream); + if (uncompressed_test_stream != NULL) + free(uncompressed_test_stream); if (ret) { printf(" ... Fail with exit code %d\n", ret); return ret; } else printf(" ... Pass\n"); - fin_ret |= ret; } return fin_ret; diff --git a/ceph/src/isa-l/igzip/igzip_level_buf_structs.h b/ceph/src/isa-l/igzip/igzip_level_buf_structs.h new file mode 100644 index 000000000..a408c509d --- /dev/null +++ b/ceph/src/isa-l/igzip/igzip_level_buf_structs.h @@ -0,0 +1,16 @@ +#ifndef IGZIP_LEVEL_BUF_STRUCTS_H +#define IGZIP_LEVEL_BUF_STRUCTS_H + +#include "huff_codes.h" +#include "encode_df.h" + +struct level_2_buf { + struct hufftables_icf encode_tables; + uint32_t deflate_hdr_count; + uint32_t deflate_hdr_extra_bits; + uint8_t deflate_hdr[ISAL_DEF_MAX_HDR_SIZE]; + struct deflate_icf *icf_buf_next; + uint64_t icf_buf_avail_out; + struct deflate_icf icf_buf_start[]; +}; +#endif diff --git a/ceph/src/isa-l/igzip/igzip_multibinary.asm b/ceph/src/isa-l/igzip/igzip_multibinary.asm index 9fb27418d..c95990f6d 100644 --- a/ceph/src/isa-l/igzip/igzip_multibinary.asm +++ b/ceph/src/isa-l/igzip/igzip_multibinary.asm @@ -38,36 +38,50 @@ default rel %include "reg_sizes.asm" -extern isal_deflate_body_stateless_base -extern isal_deflate_body_stateless_01 -extern isal_deflate_body_stateless_04 - extern isal_deflate_body_base extern isal_deflate_body_01 +extern isal_deflate_body_02 extern isal_deflate_body_04 extern isal_deflate_finish_base extern isal_deflate_finish_01 -extern get_crc_base -extern get_crc_01 -extern isal_deflate_init_base -extern isal_deflate_init_01 +extern isal_deflate_icf_body_base +extern isal_deflate_icf_body_01 +extern isal_deflate_icf_body_02 +extern isal_deflate_icf_body_04 +extern isal_deflate_icf_finish_base +extern isal_deflate_icf_finish_01 -section .text +extern isal_update_histogram_base +extern isal_update_histogram_01 +extern isal_update_histogram_04 -%include "multibinary.asm" +extern encode_deflate_icf_base +extern encode_deflate_icf_04 -mbin_interface isal_deflate_init -mbin_dispatch_init5 isal_deflate_init, isal_deflate_init_base, isal_deflate_init_01, isal_deflate_init_01, isal_deflate_init_01 +extern crc32_gzip_base +extern crc32_gzip_01 -mbin_interface isal_deflate_body_stateless -mbin_dispatch_init5 isal_deflate_body_stateless, isal_deflate_body_stateless_base, isal_deflate_body_stateless_01, isal_deflate_body_stateless_01, isal_deflate_body_stateless_04 +section .text + +%include "multibinary.asm" mbin_interface isal_deflate_body -mbin_dispatch_init5 isal_deflate_body, isal_deflate_body_base, isal_deflate_body_01, isal_deflate_body_01, isal_deflate_body_04 +mbin_dispatch_init5 isal_deflate_body, isal_deflate_body_base, isal_deflate_body_01, isal_deflate_body_02, isal_deflate_body_04 mbin_interface isal_deflate_finish mbin_dispatch_init5 isal_deflate_finish, isal_deflate_finish_base, isal_deflate_finish_01, isal_deflate_finish_01, isal_deflate_finish_01 -mbin_interface get_crc -mbin_dispatch_init5 get_crc, get_crc_base, get_crc_01, get_crc_01, get_crc_01 +mbin_interface isal_deflate_icf_body +mbin_dispatch_init5 isal_deflate_icf_body, isal_deflate_icf_body_base, isal_deflate_icf_body_01, isal_deflate_icf_body_02, isal_deflate_icf_body_04 +mbin_interface isal_deflate_icf_finish +mbin_dispatch_init5 isal_deflate_icf_finish, isal_deflate_icf_finish_base, isal_deflate_icf_finish_01, isal_deflate_icf_finish_01, isal_deflate_icf_finish_01 + +mbin_interface isal_update_histogram +mbin_dispatch_init5 isal_update_histogram, isal_update_histogram_base, isal_update_histogram_01, isal_update_histogram_01, isal_update_histogram_04 + +mbin_interface encode_deflate_icf +mbin_dispatch_init5 encode_deflate_icf, encode_deflate_icf_base, encode_deflate_icf_base, encode_deflate_icf_base, encode_deflate_icf_04 + +mbin_interface crc32_gzip +mbin_dispatch_init5 crc32_gzip, crc32_gzip_base, crc32_gzip_base, crc32_gzip_01, crc32_gzip_01 diff --git a/ceph/src/isa-l/igzip/igzip_perf.c b/ceph/src/isa-l/igzip/igzip_perf.c index 1ccd0394a..5292ef39e 100644 --- a/ceph/src/isa-l/igzip/igzip_perf.c +++ b/ceph/src/isa-l/igzip/igzip_perf.c @@ -54,7 +54,7 @@ int main(int argc, char *argv[]) struct isal_zstream stream; unsigned char inbuf[IBUF_SIZE], zbuf[OBUF_SIZE]; - printf("Window Size: %d K\n", HIST_SIZE); + printf("Window Size: %d K\n", IGZIP_HIST_SIZE / 1024); printf("igzip_perf: \n"); fflush(0); create_data(inbuf, TEST_LEN); diff --git a/ceph/src/isa-l/igzip/igzip_rand_test.c b/ceph/src/isa-l/igzip/igzip_rand_test.c index f3d3ff4d1..5ceb53332 100644 --- a/ceph/src/isa-l/igzip/igzip_rand_test.c +++ b/ceph/src/isa-l/igzip/igzip_rand_test.c @@ -30,13 +30,14 @@ #include #include #include +#include #include "igzip_lib.h" -#include "igzip_inflate_ref.h" #include "crc_inflate.h" +#include "inflate_std_vects.h" #include #ifndef RANDOMS -# define RANDOMS 400 +# define RANDOMS 0x40 #endif #ifndef TEST_SEED # define TEST_SEED 0x1234 @@ -44,10 +45,6 @@ #define IBUF_SIZE (1024*1024) -#ifndef IGZIP_USE_GZIP_FORMAT -# define DEFLATE 1 -#endif - #define PAGE_SIZE 4*1024 #define str1 "Short test string" @@ -78,7 +75,6 @@ enum IGZIP_TEST_ERROR_CODES { INFLATE_INVALID_BLOCK_HEADER, INFLATE_INVALID_SYMBOL, INFLATE_OUT_BUFFER_OVERFLOW, - INFLATE_INVALID_NON_COMPRESSED_BLOCK_LENGTH, INFLATE_LEFTOVER_INPUT, INFLATE_INCORRECT_OUTPUT_SIZE, INFLATE_INVALID_LOOK_BACK_DISTANCE, @@ -92,25 +88,19 @@ enum IGZIP_TEST_ERROR_CODES { RESULT_ERROR }; -const int hdr_bytes = 300; +static const int hdr_bytes = 300; -#ifndef DEFLATE -const uint8_t gzip_hdr[10] = { +static const uint8_t gzip_hdr[10] = { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff }; -const uint32_t gzip_hdr_bytes = 10; -const uint32_t gzip_trl_bytes = 8; +static const uint32_t gzip_hdr_bytes = 10; +/* static const uint32_t gzip_trl_bytes = 8; */ -const int trl_bytes = 8; -const int gzip_extra_bytes = 18; +static const int gzip_extra_bytes = 18; /* gzip_hdr_bytes + gzip_trl_bytes */ -#else -const int trl_bytes = 0; -const int gzip_extra_bytes = 0; - -#endif +int inflate_type = 0; struct isal_hufftables *hufftables = NULL; @@ -220,9 +210,6 @@ void print_error(int error_code) case INFLATE_OUT_BUFFER_OVERFLOW: printf("error: output buffer overflow while decompressing data\n"); break; - case INFLATE_INVALID_NON_COMPRESSED_BLOCK_LENGTH: - printf("error: invalid length bits in non-compressed block\n"); - break; case INFLATE_GENERAL_ERROR: printf("error: decompression failed\n"); break; @@ -271,7 +258,6 @@ void print_uint8_t(uint8_t * array, uint64_t length) printf("\n"); } -#ifndef DEFLATE uint32_t check_gzip_header(uint8_t * z_buf) { /* These values are defined in RFC 1952 page 4 */ @@ -305,53 +291,223 @@ uint32_t check_gzip_header(uint8_t * z_buf) return ret; } -uint32_t check_gzip_trl(struct inflate_state * gstream) +uint32_t check_gzip_trl(uint64_t gzip_trl, uint32_t inflate_crc, uint8_t * uncompress_buf, + uint32_t uncompress_len) { - uint8_t *index = NULL; - uint32_t crc, ret = 0; + uint64_t trl, ret = 0; + uint32_t crc; - index = gstream->out_buffer.next_out - gstream->out_buffer.total_out; - crc = find_crc(index, gstream->out_buffer.total_out); + crc = find_crc(uncompress_buf, uncompress_len); + trl = ((uint64_t) uncompress_len << 32) | crc; - if (gstream->out_buffer.total_out != *(uint32_t *) (gstream->in_buffer.next_in + 4) || - crc != *(uint32_t *) gstream->in_buffer.next_in) + if (crc != inflate_crc || trl != gzip_trl) ret = INCORRECT_GZIP_TRAILER; return ret; } -#endif + +int inflate_stateless_pass(uint8_t * compress_buf, uint64_t compress_len, + uint8_t * uncompress_buf, uint32_t * uncompress_len, + uint32_t gzip_flag) +{ + struct inflate_state state; + int ret = 0; + + state.next_in = compress_buf; + state.avail_in = compress_len; + state.next_out = uncompress_buf; + state.avail_out = *uncompress_len; + state.crc_flag = gzip_flag; + + ret = isal_inflate_stateless(&state); + + *uncompress_len = state.total_out; + + if (gzip_flag) { + if (!ret) + ret = + check_gzip_trl(*(uint64_t *) state.next_in, state.crc, + uncompress_buf, *uncompress_len); + state.avail_in -= 8; + } + + if (ret == 0 && state.avail_in != 0) + ret = INFLATE_LEFTOVER_INPUT; + + return ret; +} + +int inflate_multi_pass(uint8_t * compress_buf, uint64_t compress_len, + uint8_t * uncompress_buf, uint32_t * uncompress_len, uint32_t gzip_flag) +{ + struct inflate_state *state = NULL; + int ret = 0; + uint8_t *comp_tmp = NULL, *uncomp_tmp = NULL; + uint32_t comp_tmp_size = 0, uncomp_tmp_size = 0; + uint32_t comp_processed = 0, uncomp_processed = 0; + int32_t read_in_old = 0; + + state = malloc(sizeof(struct inflate_state)); + if (state == NULL) { + printf("Failed to allocate memory\n"); + exit(0); + } + + isal_inflate_init(state); + + state->next_in = NULL; + state->next_out = NULL; + state->avail_in = 0; + state->avail_out = 0; + state->crc_flag = gzip_flag; + + if (gzip_flag) + compress_len -= 8; + + while (1) { + if (state->avail_in == 0) { + comp_tmp_size = rand() % (compress_len + 1); + + if (comp_tmp_size >= compress_len - comp_processed) + comp_tmp_size = compress_len - comp_processed; + + if (comp_tmp_size != 0) { + if (comp_tmp != NULL) { + free(comp_tmp); + comp_tmp = NULL; + } + + comp_tmp = malloc(comp_tmp_size); + + if (comp_tmp == NULL) { + printf("Failed to allocate memory\n"); + return MALLOC_FAILED; + } + + memcpy(comp_tmp, compress_buf + comp_processed, comp_tmp_size); + comp_processed += comp_tmp_size; + + state->next_in = comp_tmp; + state->avail_in = comp_tmp_size; + } + } + + if (state->avail_out == 0) { + /* Save uncompressed data into uncompress_buf */ + if (uncomp_tmp != NULL) { + memcpy(uncompress_buf + uncomp_processed, uncomp_tmp, + uncomp_tmp_size); + uncomp_processed += uncomp_tmp_size; + } + + uncomp_tmp_size = rand() % (*uncompress_len + 1); + + /* Limit size of buffer to be smaller than maximum */ + if (uncomp_tmp_size > *uncompress_len - uncomp_processed) + uncomp_tmp_size = *uncompress_len - uncomp_processed; + + if (uncomp_tmp_size != 0) { + + if (uncomp_tmp != NULL) { + fflush(0); + free(uncomp_tmp); + uncomp_tmp = NULL; + } + + uncomp_tmp = malloc(uncomp_tmp_size); + if (uncomp_tmp == NULL) { + printf("Failed to allocate memory\n"); + return MALLOC_FAILED; + } + + state->avail_out = uncomp_tmp_size; + state->next_out = uncomp_tmp; + } + } + + ret = isal_inflate(state); + + if (state->block_state == ISAL_BLOCK_FINISH || ret != 0) { + memcpy(uncompress_buf + uncomp_processed, uncomp_tmp, uncomp_tmp_size); + *uncompress_len = state->total_out; + break; + } + + if (*uncompress_len - uncomp_processed == 0 && state->avail_out == 0 + && state->tmp_out_valid - state->tmp_out_processed > 0) { + ret = ISAL_OUT_OVERFLOW; + break; + } + + if (compress_len - comp_processed == 0 && state->avail_in == 0 + && (state->block_state != ISAL_BLOCK_INPUT_DONE) + && state->tmp_out_valid - state->tmp_out_processed == 0) { + if (state->read_in_length == read_in_old) { + ret = ISAL_END_INPUT; + break; + } + read_in_old = state->read_in_length; + } + } + + if (gzip_flag) { + if (!ret) + ret = + check_gzip_trl(*(uint64_t *) & compress_buf[compress_len], + state->crc, uncompress_buf, *uncompress_len); + } + if (ret == 0 && state->avail_in != 0) + ret = INFLATE_LEFTOVER_INPUT; + + if (comp_tmp != NULL) { + free(comp_tmp); + comp_tmp = NULL; + } + + if (uncomp_tmp != NULL) { + free(uncomp_tmp); + uncomp_tmp = NULL; + } + + free(state); + return ret; +} /* Inflate the compressed data and check that the decompressed data agrees with the input data */ -int inflate_check(uint8_t * z_buf, int z_size, uint8_t * in_buf, int in_size) +int inflate_check(uint8_t * z_buf, int z_size, uint8_t * in_buf, int in_size, + uint32_t gzip_flag) { /* Test inflate with reference inflate */ int ret = 0; - struct inflate_state gstream; uint32_t test_size = in_size; uint8_t *test_buf = NULL; int mem_result = 0; + int gzip_hdr_result = 0, gzip_trl_result = 0; if (in_size > 0) { assert(in_buf != NULL); test_buf = malloc(test_size); - if (test_buf == NULL) return MALLOC_FAILED; } + if (test_buf != NULL) memset(test_buf, 0xff, test_size); -#ifndef DEFLATE - int gzip_hdr_result, gzip_trl_result; - - gzip_hdr_result = check_gzip_header(z_buf); - z_buf += gzip_hdr_bytes; - z_size -= gzip_hdr_bytes; -#endif + if (gzip_flag == IGZIP_GZIP) { + gzip_hdr_result = check_gzip_header(z_buf); + z_buf += gzip_hdr_bytes; + z_size -= gzip_hdr_bytes; + } - igzip_inflate_init(&gstream, z_buf, z_size, test_buf, test_size); - ret = igzip_inflate(&gstream); + if (inflate_type == 0) { + ret = inflate_stateless_pass(z_buf, z_size, test_buf, &test_size, gzip_flag); + inflate_type = 1; + } else { + ret = inflate_multi_pass(z_buf, z_size, test_buf, &test_size, gzip_flag); + inflate_type = 0; + } if (test_buf != NULL) mem_result = memcmp(in_buf, test_buf, in_size); @@ -361,64 +517,59 @@ int inflate_check(uint8_t * z_buf, int z_size, uint8_t * in_buf, int in_size) if (mem_result) for (i = 0; i < in_size; i++) { if (in_buf[i] != test_buf[i]) { - printf("First incorrect data at 0x%x of 0x%x, 0x%x != 0x%x\n", - i, in_size, in_buf[i], test_buf[i]); + printf + ("First incorrect data at 0x%x of 0x%x, 0x%x != 0x%x\n", + i, in_size, in_buf[i], test_buf[i]); break; } } #endif -#ifndef DEFLATE - gzip_trl_result = check_gzip_trl(&gstream); - gstream.in_buffer.avail_in -= gzip_trl_bytes; - gstream.in_buffer.next_in += gzip_trl_bytes; -#endif - if (test_buf != NULL) free(test_buf); - switch (ret) { case 0: break; - case END_OF_INPUT: + case ISAL_END_INPUT: return INFLATE_END_OF_INPUT; break; - case INVALID_BLOCK_HEADER: + case ISAL_INVALID_BLOCK: return INFLATE_INVALID_BLOCK_HEADER; break; - case INVALID_SYMBOL: + case ISAL_INVALID_SYMBOL: return INFLATE_INVALID_SYMBOL; break; - case OUT_BUFFER_OVERFLOW: + case ISAL_OUT_OVERFLOW: return INFLATE_OUT_BUFFER_OVERFLOW; break; - case INVALID_NON_COMPRESSED_BLOCK_LENGTH: - return INFLATE_INVALID_NON_COMPRESSED_BLOCK_LENGTH; - break; - case INVALID_LOOK_BACK_DISTANCE: + case ISAL_INVALID_LOOKBACK: return INFLATE_INVALID_LOOK_BACK_DISTANCE; break; + case INFLATE_LEFTOVER_INPUT: + return INFLATE_LEFTOVER_INPUT; + break; + case INCORRECT_GZIP_TRAILER: + gzip_trl_result = INCORRECT_GZIP_TRAILER; + break; + default: return INFLATE_GENERAL_ERROR; break; } - if (gstream.in_buffer.avail_in != 0) - return INFLATE_LEFTOVER_INPUT; - - if (gstream.out_buffer.total_out != in_size) + if (test_size != in_size) return INFLATE_INCORRECT_OUTPUT_SIZE; if (mem_result) return RESULT_ERROR; -#ifndef DEFLATE - if (gzip_hdr_result) - return INVALID_GZIP_HEADER; + if (gzip_flag) { + if (gzip_hdr_result) + return INVALID_GZIP_HEADER; - if (gzip_trl_result) - return INCORRECT_GZIP_TRAILER; -#endif + if (gzip_trl_result) + return INCORRECT_GZIP_TRAILER; + } return 0; } @@ -516,11 +667,17 @@ int isal_deflate_with_checks(struct isal_zstream *stream, uint32_t data_size, } +void set_random_hufftable(struct isal_zstream *stream) +{ + isal_deflate_set_hufftables(stream, hufftables, rand() % 4); +} + /* Compress the input data into the output buffer where the input buffer and * output buffer are randomly segmented to test state information for the * compression*/ int compress_multi_pass(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf, - uint32_t * compressed_size, uint32_t flush_type) + uint32_t * compressed_size, uint32_t flush_type, uint32_t gzip_flag, + uint32_t level) { int ret = IGZIP_COMP_OK; uint8_t *in_buf = NULL, *out_buf = NULL; @@ -529,6 +686,8 @@ int compress_multi_pass(uint8_t * data, uint32_t data_size, uint8_t * compressed struct isal_zstream stream; struct isal_zstate *state = &stream.internal_state; uint32_t loop_count = 0; + uint32_t level_buf_size; + uint8_t *level_buf = NULL; #ifdef VERBOSE printf("Starting Compress Multi Pass\n"); @@ -538,9 +697,6 @@ int compress_multi_pass(uint8_t * data, uint32_t data_size, uint8_t * compressed isal_deflate_init(&stream); - if (hufftables != NULL) - stream.hufftables = hufftables; - if (state->state != ZSTATE_NEW_HDR) return COMPRESS_INCORRECT_STATE; @@ -550,6 +706,16 @@ int compress_multi_pass(uint8_t * data, uint32_t data_size, uint8_t * compressed /* These are set here to allow the loop to run correctly */ stream.avail_in = 0; stream.avail_out = 0; + stream.gzip_flag = gzip_flag; + stream.level = level; + + if (level >= 1) { + level_buf_size = rand() % IBUF_SIZE + ISAL_DEF_LVL1_MIN; + level_buf = malloc(level_buf_size); + create_rand_repeat_data(level_buf, level_buf_size); + stream.level_buf = level_buf; + stream.level_buf_size = level_buf_size; + } while (1) { loop_count++; @@ -619,6 +785,9 @@ int compress_multi_pass(uint8_t * data, uint32_t data_size, uint8_t * compressed } } + if (state->state == ZSTATE_NEW_HDR) + set_random_hufftable(&stream); + ret = isal_deflate_with_checks(&stream, data_size, *compressed_size, in_buf, in_size, in_processed, out_buf, out_size, @@ -640,6 +809,8 @@ int compress_multi_pass(uint8_t * data, uint32_t data_size, uint8_t * compressed } + if (level_buf != NULL) + free(level_buf); if (in_buf != NULL) free(in_buf); if (out_buf != NULL) @@ -655,11 +826,14 @@ int compress_multi_pass(uint8_t * data, uint32_t data_size, uint8_t * compressed /* Compress the input data into the outbuffer in one call to isal_deflate */ int compress_single_pass(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf, - uint32_t * compressed_size, uint32_t flush_type) + uint32_t * compressed_size, uint32_t flush_type, uint32_t gzip_flag, + uint32_t level) { int ret = IGZIP_COMP_OK; struct isal_zstream stream; struct isal_zstate *state = &stream.internal_state; + uint32_t level_buf_size; + uint8_t *level_buf = NULL; #ifdef VERBOSE printf("Starting Compress Single Pass\n"); @@ -669,8 +843,7 @@ int compress_single_pass(uint8_t * data, uint32_t data_size, uint8_t * compresse isal_deflate_init(&stream); - if (hufftables != NULL) - stream.hufftables = hufftables; + set_random_hufftable(&stream); if (state->state != ZSTATE_NEW_HDR) return COMPRESS_INCORRECT_STATE; @@ -681,11 +854,24 @@ int compress_single_pass(uint8_t * data, uint32_t data_size, uint8_t * compresse stream.avail_out = *compressed_size; stream.next_out = compressed_buf; stream.end_of_stream = 1; + stream.gzip_flag = gzip_flag; + stream.level = level; + + if (level >= 1) { + level_buf_size = rand() % IBUF_SIZE + ISAL_DEF_LVL1_MIN; + level_buf = malloc(level_buf_size); + create_rand_repeat_data(level_buf, level_buf_size); + stream.level_buf = level_buf; + stream.level_buf_size = level_buf_size; + } ret = isal_deflate_with_checks(&stream, data_size, *compressed_size, data, data_size, data_size, compressed_buf, *compressed_size, 0); + if (level_buf != NULL) + free(level_buf); + /* Check if the compression is completed */ if (state->state == ZSTATE_END) *compressed_size = stream.total_out; @@ -698,40 +884,60 @@ int compress_single_pass(uint8_t * data, uint32_t data_size, uint8_t * compresse /* Statelessly compress the input buffer into the output buffer */ int compress_stateless(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf, - uint32_t * compressed_size) + uint32_t * compressed_size, uint32_t flush_type, uint32_t gzip_flag, + uint32_t level) { int ret = IGZIP_COMP_OK; struct isal_zstream stream; + uint32_t level_buf_size; + uint8_t *level_buf = NULL; create_rand_repeat_data((uint8_t *) & stream, sizeof(stream)); - isal_deflate_init(&stream); + isal_deflate_stateless_init(&stream); - if (hufftables != NULL) - stream.hufftables = hufftables; + set_random_hufftable(&stream); stream.avail_in = data_size; - stream.end_of_stream = 1; stream.next_in = data; - stream.flush = NO_FLUSH; - + stream.flush = flush_type; + if (flush_type != NO_FLUSH) + stream.end_of_stream = 1; stream.avail_out = *compressed_size; stream.next_out = compressed_buf; + stream.gzip_flag = gzip_flag; + stream.level = level; + + if (level >= 1) { + level_buf_size = rand() % IBUF_SIZE; + if (level_buf_size >= ISAL_DEF_LVL1_MIN) { + level_buf = malloc(level_buf_size); + create_rand_repeat_data(level_buf, level_buf_size); + stream.level_buf = level_buf; + stream.level_buf_size = level_buf_size; + } + } ret = isal_deflate_stateless(&stream); + if (level_buf != NULL) + free(level_buf); + /* verify the stream */ if (stream.next_in - data != stream.total_in || stream.total_in + stream.avail_in != data_size) return COMPRESS_INPUT_STREAM_INTEGRITY_ERROR; if (stream.next_out - compressed_buf != stream.total_out || - stream.total_out + stream.avail_out != *compressed_size) + stream.total_out + stream.avail_out != *compressed_size) { return COMPRESS_OUTPUT_STREAM_INTEGRITY_ERROR; + } if (ret != IGZIP_COMP_OK) { if (ret == STATELESS_OVERFLOW) return COMPRESS_OUT_BUFFER_OVERFLOW; + else if (ret == INVALID_FLUSH) + return INVALID_FLUSH_ERROR; else return COMPRESS_GENERAL_ERROR; } @@ -749,15 +955,122 @@ int compress_stateless(uint8_t * data, uint32_t data_size, uint8_t * compressed_ } +/* Statelessly compress the input buffer into the output buffer */ +int compress_stateless_full_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf, + uint32_t * compressed_size, uint32_t level) +{ + int ret = IGZIP_COMP_OK; + uint8_t *in_buf = NULL, *level_buf = NULL, *out_buf = compressed_buf; + uint32_t in_size = 0, level_buf_size; + uint32_t in_processed = 00; + struct isal_zstream stream; + uint32_t loop_count = 0; + +#ifdef VERBOSE + printf("Starting Stateless Compress Full Flush\n"); +#endif + + create_rand_repeat_data((uint8_t *) & stream, sizeof(stream)); + + isal_deflate_stateless_init(&stream); + + stream.flush = FULL_FLUSH; + stream.end_of_stream = 0; + stream.avail_out = *compressed_size; + stream.next_out = compressed_buf; + stream.level = level; + + if (level >= 1) { + level_buf_size = rand() % IBUF_SIZE; + if (level_buf_size >= ISAL_DEF_LVL1_MIN) { + level_buf = malloc(level_buf_size); + create_rand_repeat_data(level_buf, level_buf_size); + stream.level_buf = level_buf; + stream.level_buf_size = level_buf_size; + } + } + + while (1) { + loop_count++; + + /* Randomly choose size of the next out buffer */ + in_size = rand() % (data_size + 1); + + /* Limit size of buffer to be smaller than maximum */ + if (in_size >= data_size - in_processed) { + in_size = data_size - in_processed; + stream.end_of_stream = 1; + } + + stream.avail_in = in_size; + + if (in_size != 0) { + if (in_buf != NULL) { + free(in_buf); + in_buf = NULL; + } + + in_buf = malloc(in_size); + if (in_buf == NULL) { + ret = MALLOC_FAILED; + break; + } + memcpy(in_buf, data + in_processed, in_size); + in_processed += in_size; + + stream.next_in = in_buf; + } + + out_buf = stream.next_out; + + if (stream.internal_state.state == ZSTATE_NEW_HDR) + set_random_hufftable(&stream); + + ret = isal_deflate_stateless(&stream); + assert(stream.internal_state.bitbuf.m_bit_count == 0); + + assert(compressed_buf == stream.next_out - stream.total_out); + if (ret) + break; + + /* Verify that blocks are independent */ + ret = inflate_check(out_buf, stream.next_out - out_buf, in_buf, in_size, 0); + + if (ret == INFLATE_INVALID_LOOK_BACK_DISTANCE) { + break; + } else + ret = 0; + + /* Check if the compression is completed */ + if (in_processed == data_size) { + *compressed_size = stream.total_out; + break; + } + + } + + if (level_buf != NULL) + free(level_buf); + + if (in_buf != NULL) + free(in_buf); + + if (ret == STATELESS_OVERFLOW && loop_count >= MAX_LOOPS) + ret = COMPRESS_LOOP_COUNT_OVERFLOW; + + return ret; + +} + /* Compress the input data into the output buffer where the input buffer and * is randomly segmented to test for independence of blocks in full flush * compression*/ int compress_full_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf, - uint32_t * compressed_size) + uint32_t * compressed_size, uint32_t gzip_flag, uint32_t level) { int ret = IGZIP_COMP_OK; - uint8_t *in_buf = NULL, *out_buf = compressed_buf; - uint32_t in_size = 0; + uint8_t *in_buf = NULL, *out_buf = compressed_buf, *level_buf = NULL; + uint32_t in_size = 0, level_buf_size; uint32_t in_processed = 00; struct isal_zstream stream; struct isal_zstate *state = &stream.internal_state; @@ -771,9 +1084,6 @@ int compress_full_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed isal_deflate_init(&stream); - if (hufftables != NULL) - stream.hufftables = hufftables; - if (state->state != ZSTATE_NEW_HDR) return COMPRESS_INCORRECT_STATE; @@ -782,6 +1092,18 @@ int compress_full_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed stream.avail_out = *compressed_size; stream.next_out = compressed_buf; stream.total_out = 0; + stream.gzip_flag = gzip_flag; + stream.level = level; + + if (level >= 1) { + level_buf_size = rand() % IBUF_SIZE + ISAL_DEF_LVL1_MIN; + if (level_buf_size >= ISAL_DEF_LVL1_MIN) { + level_buf = malloc(level_buf_size); + create_rand_repeat_data(level_buf, level_buf_size); + stream.level_buf = level_buf; + stream.level_buf_size = level_buf_size; + } + } while (1) { loop_count++; @@ -819,6 +1141,9 @@ int compress_full_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed out_buf = stream.next_out; } + if (state->state == ZSTATE_NEW_HDR) + set_random_hufftable(&stream); + ret = isal_deflate(&stream); if (ret) @@ -827,7 +1152,8 @@ int compress_full_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed /* Verify that blocks are independent */ if (state->state == ZSTATE_NEW_HDR || state->state == ZSTATE_END) { ret = - inflate_check(out_buf, stream.next_out - out_buf, in_buf, in_size); + inflate_check(out_buf, stream.next_out - out_buf, in_buf, in_size, + 0); if (ret == INFLATE_INVALID_LOOK_BACK_DISTANCE) break; @@ -843,6 +1169,9 @@ int compress_full_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed } + if (level_buf != NULL) + free(level_buf); + if (in_buf != NULL) free(in_buf); @@ -856,7 +1185,7 @@ int compress_full_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed /*Compress the input buffer into the output buffer, but switch the flush type in * the middle of the compression to test what happens*/ int compress_swap_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf, - uint32_t * compressed_size, uint32_t flush_type) + uint32_t * compressed_size, uint32_t flush_type, uint32_t gzip_flag) { int ret = IGZIP_COMP_OK; struct isal_zstream stream; @@ -869,8 +1198,7 @@ int compress_swap_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed isal_deflate_init(&stream); - if (hufftables != NULL) - stream.hufftables = hufftables; + set_random_hufftable(&stream); if (state->state != ZSTATE_NEW_HDR) return COMPRESS_INCORRECT_STATE; @@ -883,6 +1211,7 @@ int compress_swap_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed stream.avail_out = *compressed_size; stream.next_out = compressed_buf; stream.end_of_stream = 0; + stream.gzip_flag = gzip_flag; ret = isal_deflate_with_checks(&stream, data_size, *compressed_size, data, partial_size, @@ -891,6 +1220,9 @@ int compress_swap_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed if (ret) return ret; + if (state->state == ZSTATE_NEW_HDR) + set_random_hufftable(&stream); + flush_type = rand() % 3; stream.flush = flush_type; @@ -912,13 +1244,16 @@ int compress_swap_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed } /* Test deflate_stateless */ -int test_compress_stateless(uint8_t * in_data, uint32_t in_size) +int test_compress_stateless(uint8_t * in_data, uint32_t in_size, uint32_t flush_type) { int ret = IGZIP_COMP_OK; - uint32_t z_size, overflow; + uint32_t z_size, overflow, gzip_flag, level; uint8_t *z_buf = NULL; uint8_t *in_buf = NULL; + gzip_flag = rand() % 3; + level = rand() % 2; + if (in_size != 0) { in_buf = malloc(in_size); @@ -929,7 +1264,9 @@ int test_compress_stateless(uint8_t * in_data, uint32_t in_size) } /* Test non-overflow case where a type 0 block is not written */ - z_size = 2 * in_size + hdr_bytes + trl_bytes; + z_size = 2 * in_size + hdr_bytes; + if (gzip_flag) + z_size += gzip_extra_bytes; z_buf = malloc(z_size); @@ -938,14 +1275,36 @@ int test_compress_stateless(uint8_t * in_data, uint32_t in_size) create_rand_repeat_data(z_buf, z_size); - ret = compress_stateless(in_buf, in_size, z_buf, &z_size); + /* If flush type is invalid */ + if (flush_type != NO_FLUSH && flush_type != FULL_FLUSH) { + ret = + compress_stateless(in_buf, in_size, z_buf, &z_size, flush_type, gzip_flag, + level); + + if (ret != INVALID_FLUSH_ERROR) + print_error(ret); + else + ret = 0; + + if (z_buf != NULL) + free(z_buf); + + if (in_buf != NULL) + free(in_buf); + + return ret; + } + + /* Else test valid flush type */ + ret = + compress_stateless(in_buf, in_size, z_buf, &z_size, flush_type, gzip_flag, level); if (!ret) - ret = inflate_check(z_buf, z_size, in_buf, in_size); + ret = inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag); #ifdef VERBOSE if (ret) { - printf("Compressed array: "); + printf("Compressed array at level %d with gzip flag %d: ", level, gzip_flag); print_uint8_t(z_buf, z_size); printf("\n"); printf("Data: "); @@ -956,14 +1315,15 @@ int test_compress_stateless(uint8_t * in_data, uint32_t in_size) free(z_buf); z_buf = NULL; } + print_error(ret); if (ret) return ret; /*Test non-overflow case where a type 0 block is possible to be written */ - z_size = - TYPE0_HDR_SIZE * ((in_size + TYPE0_MAX_SIZE - 1) / TYPE0_MAX_SIZE) + in_size + - gzip_extra_bytes; + z_size = TYPE0_HDR_SIZE * ((in_size + TYPE0_MAX_SIZE - 1) / TYPE0_MAX_SIZE) + in_size; + if (gzip_flag) + z_size += gzip_extra_bytes; if (z_size == gzip_extra_bytes) z_size += TYPE0_HDR_SIZE; @@ -978,12 +1338,13 @@ int test_compress_stateless(uint8_t * in_data, uint32_t in_size) create_rand_repeat_data(z_buf, z_size); - ret = compress_stateless(in_buf, in_size, z_buf, &z_size); + ret = + compress_stateless(in_buf, in_size, z_buf, &z_size, flush_type, gzip_flag, level); if (!ret) - ret = inflate_check(z_buf, z_size, in_buf, in_size); + ret = inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag); #ifdef VERBOSE if (ret) { - printf("Compressed array: "); + printf("Compressed array at level %d with gzip flag %d: ", level, gzip_flag); print_uint8_t(z_buf, z_size); printf("\n"); printf("Data: "); @@ -1008,29 +1369,74 @@ int test_compress_stateless(uint8_t * in_data, uint32_t in_size) return MALLOC_FAILED; } - overflow = compress_stateless(in_buf, in_size, z_buf, &z_size); + overflow = + compress_stateless(in_buf, in_size, z_buf, &z_size, flush_type, gzip_flag, + level); if (overflow != COMPRESS_OUT_BUFFER_OVERFLOW) { #ifdef VERBOSE printf("overflow error = %d\n", overflow); print_error(overflow); if (overflow == 0) { - overflow = inflate_check(z_buf, z_size, in_buf, in_size); + overflow = + inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag); printf("inflate ret = %d\n", overflow); print_error(overflow); } - printf("Compressed array: "); + printf("Compressed array at level %d with gzip flag %d: ", level, + gzip_flag); print_uint8_t(z_buf, z_size); printf("\n"); printf("Data: "); print_uint8_t(in_buf, in_size); #endif - ret = OVERFLOW_TEST_ERROR; } } print_error(ret); + if (ret) { + if (z_buf != NULL) { + free(z_buf); + z_buf = NULL; + } + if (in_buf != NULL) + free(in_buf); + return ret; + } + + if (flush_type == FULL_FLUSH) { + if (z_buf != NULL) + free(z_buf); + + z_size = 2 * in_size + MAX_LOOPS * (hdr_bytes + 5); + + z_buf = malloc(z_size); + + if (z_buf == NULL) + return MALLOC_FAILED; + create_rand_repeat_data(z_buf, z_size); + + /* Else test valid flush type */ + ret = compress_stateless_full_flush(in_buf, in_size, z_buf, &z_size, level); + + if (!ret) + ret = inflate_check(z_buf, z_size, in_buf, in_size, 0); + else if (ret == COMPRESS_LOOP_COUNT_OVERFLOW) + ret = 0; + + print_error(ret); +#ifdef VERBOSE + if (ret) { + printf("Compressed array at level %d with gzip flag %d: ", level, + gzip_flag); + print_uint8_t(z_buf, z_size); + printf("\n"); + printf("Data: "); + print_uint8_t(in_buf, in_size); + } +#endif + } if (z_buf != NULL) free(z_buf); @@ -1044,20 +1450,25 @@ int test_compress_stateless(uint8_t * in_data, uint32_t in_size) int test_compress(uint8_t * in_buf, uint32_t in_size, uint32_t flush_type) { int ret = IGZIP_COMP_OK, fin_ret = IGZIP_COMP_OK; - uint32_t overflow = 0; + uint32_t overflow = 0, gzip_flag, level; uint32_t z_size, z_size_max, z_compressed_size; uint8_t *z_buf = NULL; /* Test a non overflow case */ if (flush_type == NO_FLUSH) - z_size_max = 2 * in_size + hdr_bytes + trl_bytes + 2; + z_size_max = 2 * in_size + hdr_bytes + 2; else if (flush_type == SYNC_FLUSH || flush_type == FULL_FLUSH) - z_size_max = 2 * in_size + MAX_LOOPS * (hdr_bytes + trl_bytes + 5); + z_size_max = 2 * in_size + MAX_LOOPS * (hdr_bytes + 5); else { printf("Invalid Flush Parameter\n"); return COMPRESS_GENERAL_ERROR; } + gzip_flag = rand() % 3; + level = rand() % 2; + if (gzip_flag) + z_size_max += gzip_extra_bytes; + z_size = z_size_max; z_buf = malloc(z_size); @@ -1065,16 +1476,17 @@ int test_compress(uint8_t * in_buf, uint32_t in_size, uint32_t flush_type) print_error(MALLOC_FAILED); return MALLOC_FAILED; } - create_rand_repeat_data(z_buf, z_size_max); + create_rand_repeat_data(z_buf, z_size); - ret = compress_single_pass(in_buf, in_size, z_buf, &z_size, flush_type); + ret = compress_single_pass(in_buf, in_size, z_buf, &z_size, flush_type, + gzip_flag, level); if (!ret) - ret = inflate_check(z_buf, z_size, in_buf, in_size); + ret = inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag); if (ret) { #ifdef VERBOSE - printf("Compressed array: "); + printf("Compressed array at level %d with gzip flag %d: ", level, gzip_flag); print_uint8_t(z_buf, z_size); printf("\n"); printf("Data: "); @@ -1090,14 +1502,15 @@ int test_compress(uint8_t * in_buf, uint32_t in_size, uint32_t flush_type) z_size = z_size_max; create_rand_repeat_data(z_buf, z_size_max); - ret = compress_multi_pass(in_buf, in_size, z_buf, &z_size, flush_type); + ret = + compress_multi_pass(in_buf, in_size, z_buf, &z_size, flush_type, gzip_flag, level); if (!ret) - ret = inflate_check(z_buf, z_size, in_buf, in_size); + ret = inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag); if (ret) { #ifdef VERBOSE - printf("Compressed array: "); + printf("Compressed array at level %d with gzip flag %d: ", level, gzip_flag); print_uint8_t(z_buf, z_size); printf("\n"); printf("Data: "); @@ -1118,11 +1531,12 @@ int test_compress(uint8_t * in_buf, uint32_t in_size, uint32_t flush_type) z_size = rand() % z_compressed_size; create_rand_repeat_data(z_buf, z_size_max); - overflow = compress_single_pass(in_buf, in_size, z_buf, &z_size, flush_type); + overflow = compress_single_pass(in_buf, in_size, z_buf, &z_size, flush_type, + gzip_flag, level); if (overflow != COMPRESS_OUT_BUFFER_OVERFLOW) { if (overflow == 0) - ret = inflate_check(z_buf, z_size, in_buf, in_size); + ret = inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag); /* Rarely single pass overflow will compresses data * better than the initial run. This is to stop that @@ -1134,7 +1548,8 @@ int test_compress(uint8_t * in_buf, uint32_t in_size, uint32_t flush_type) printf("inflate ret = %d\n", ret); print_error(overflow); - printf("Compressed array: "); + printf("Compressed array at level %d with gzip flag %d: ", level, + gzip_flag); print_uint8_t(z_buf, z_size); printf("\n"); printf("Data: "); @@ -1151,11 +1566,13 @@ int test_compress(uint8_t * in_buf, uint32_t in_size, uint32_t flush_type) if (flush_type == NO_FLUSH) { create_rand_repeat_data(z_buf, z_size_max); - overflow = compress_multi_pass(in_buf, in_size, z_buf, &z_size, flush_type); + overflow = + compress_multi_pass(in_buf, in_size, z_buf, &z_size, flush_type, + gzip_flag, level); if (overflow != COMPRESS_OUT_BUFFER_OVERFLOW) { if (overflow == 0) - ret = inflate_check(z_buf, z_size, in_buf, in_size); + ret = inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag); /* Rarely multi pass overflow will compresses data * better than the initial run. This is to stop that @@ -1167,7 +1584,8 @@ int test_compress(uint8_t * in_buf, uint32_t in_size, uint32_t flush_type) printf("inflate ret = %d\n", ret); print_error(overflow); - printf("Compressed array: "); + printf("Compressed array at level %d with gzip flag %d: ", + level, gzip_flag); print_uint8_t(z_buf, z_size); printf("\n"); printf("Data: "); @@ -1190,11 +1608,15 @@ int test_compress(uint8_t * in_buf, uint32_t in_size, uint32_t flush_type) int test_flush(uint8_t * in_buf, uint32_t in_size) { int fin_ret = IGZIP_COMP_OK, ret; - uint32_t z_size, flush_type = 0; + uint32_t z_size, flush_type = 0, gzip_flag, level; uint8_t *z_buf = NULL; - z_size = 2 * in_size + 2 * (hdr_bytes + trl_bytes) + 8; + gzip_flag = rand() % 3; + level = rand() % 2; + z_size = 2 * in_size + 2 * hdr_bytes + 8; + if (gzip_flag) + z_size += gzip_extra_bytes; z_buf = malloc(z_size); if (z_buf == NULL) @@ -1206,7 +1628,8 @@ int test_flush(uint8_t * in_buf, uint32_t in_size) flush_type = rand(); /* Test invalid flush */ - ret = compress_single_pass(in_buf, in_size, z_buf, &z_size, flush_type); + ret = compress_single_pass(in_buf, in_size, z_buf, &z_size, flush_type, + gzip_flag, level); if (ret == COMPRESS_GENERAL_ERROR) ret = 0; @@ -1221,14 +1644,14 @@ int test_flush(uint8_t * in_buf, uint32_t in_size) create_rand_repeat_data(z_buf, z_size); /* Test swapping flush type */ - ret = compress_swap_flush(in_buf, in_size, z_buf, &z_size, rand() % 3); + ret = compress_swap_flush(in_buf, in_size, z_buf, &z_size, rand() % 3, gzip_flag); if (!ret) - ret = inflate_check(z_buf, z_size, in_buf, in_size); + ret = inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag); if (ret) { #ifdef VERBOSE - printf("Compressed array: "); + printf("Compressed array at level %d with gzip flag %d: ", level, gzip_flag); print_uint8_t(z_buf, z_size); printf("\n"); printf("Data: "); @@ -1248,10 +1671,15 @@ int test_flush(uint8_t * in_buf, uint32_t in_size) int test_full_flush(uint8_t * in_buf, uint32_t in_size) { int ret = IGZIP_COMP_OK; - uint32_t z_size; + uint32_t z_size, gzip_flag, level; uint8_t *z_buf = NULL; - z_size = 2 * in_size + MAX_LOOPS * (hdr_bytes + trl_bytes + 5); + gzip_flag = rand() % 3; + level = rand() % 2; + z_size = 2 * in_size + MAX_LOOPS * (hdr_bytes + 5); + + if (gzip_flag) + z_size += gzip_extra_bytes; z_buf = malloc(z_size); if (z_buf == NULL) { @@ -1261,10 +1689,10 @@ int test_full_flush(uint8_t * in_buf, uint32_t in_size) create_rand_repeat_data(z_buf, z_size); - ret = compress_full_flush(in_buf, in_size, z_buf, &z_size); + ret = compress_full_flush(in_buf, in_size, z_buf, &z_size, gzip_flag, level); if (!ret) - ret = inflate_check(z_buf, z_size, in_buf, in_size); + ret = inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag); if (ret) { #ifdef VERBOSE @@ -1283,6 +1711,46 @@ int test_full_flush(uint8_t * in_buf, uint32_t in_size) return ret; } +int test_inflate(struct vect_result *in_vector) +{ + int ret = IGZIP_COMP_OK; + uint8_t *compress_buf = in_vector->vector, *out_buf = NULL; + uint64_t compress_len = in_vector->vector_length; + uint32_t out_size = 0; + + out_size = 10 * in_vector->vector_length; + out_buf = malloc(out_size); + if (out_buf == NULL) + return MALLOC_FAILED; + + ret = inflate_stateless_pass(compress_buf, compress_len, out_buf, &out_size, 0); + + if (ret == INFLATE_LEFTOVER_INPUT) + ret = ISAL_DECOMP_OK; + + if (ret != in_vector->expected_error) + printf("Inflate return value incorrect, %d != %d\n", ret, + in_vector->expected_error); + else + ret = IGZIP_COMP_OK; + + if (!ret) { + ret = inflate_multi_pass(compress_buf, compress_len, out_buf, &out_size, 0); + + if (ret == INFLATE_LEFTOVER_INPUT) + ret = ISAL_DECOMP_OK; + + if (ret != in_vector->expected_error) + printf("Inflate return value incorrect, %d != %d\n", ret, + in_vector->expected_error); + else + ret = IGZIP_COMP_OK; + } + + return ret; + +} + int get_filesize(FILE * f) { int curr, end; @@ -1314,7 +1782,9 @@ int test_compress_file(char *file_name) fread(in_buf, 1, in_size, in_file); } - ret |= test_compress_stateless(in_buf, in_size); + ret |= test_compress_stateless(in_buf, in_size, NO_FLUSH); + ret |= test_compress_stateless(in_buf, in_size, SYNC_FLUSH); + ret |= test_compress_stateless(in_buf, in_size, FULL_FLUSH); ret |= test_compress(in_buf, in_size, NO_FLUSH); ret |= test_compress(in_buf, in_size, SYNC_FLUSH); ret |= test_compress(in_buf, in_size, FULL_FLUSH); @@ -1362,9 +1832,10 @@ int create_custom_hufftables(struct isal_hufftables *hufftables_custom, int argc fread(stream, 1, file_length, file); if (ferror(file)) { - printf("Error occurred when reading file"); + printf("Error occurred when reading file\n"); fclose(file); free(stream); + stream = NULL; return 1; } @@ -1373,7 +1844,10 @@ int create_custom_hufftables(struct isal_hufftables *hufftables_custom, int argc isal_update_histogram(stream, file_length, &histogram); fclose(file); - free(stream); + if (stream != NULL) { + free(stream); + stream = NULL; + } argc--; } @@ -1392,7 +1866,7 @@ int main(int argc, char *argv[]) setbuf(stdout, NULL); #endif - printf("Window Size: %d K\n", HIST_SIZE); + printf("Window Size: %d K\n", IGZIP_HIST_SIZE / 1024); printf("Test Seed : %d\n", TEST_SEED); printf("Randoms : %d\n", RANDOMS); srand(TEST_SEED); @@ -1416,7 +1890,7 @@ int main(int argc, char *argv[]) } if (argc > 1) { - printf("igzip_rand_test files: "); + printf("igzip_rand_test files: "); for (i = 1; i < argc; i++) { ret |= test_compress_file(argv[i]); @@ -1429,13 +1903,13 @@ int main(int argc, char *argv[]) fin_ret |= ret; } - printf("igzip_rand_test stateless: "); + printf("igzip_rand_test stateless: "); - ret = test_compress_stateless((uint8_t *) str1, sizeof(str1)); + ret = test_compress_stateless((uint8_t *) str1, sizeof(str1), NO_FLUSH); if (ret) return ret; - ret |= test_compress_stateless((uint8_t *) str2, sizeof(str2)); + ret |= test_compress_stateless((uint8_t *) str2, sizeof(str2), NO_FLUSH); if (ret) return ret; @@ -1446,7 +1920,7 @@ int main(int argc, char *argv[]) create_rand_repeat_data(in_buf, in_size); - ret |= test_compress_stateless(in_buf, in_size); + ret |= test_compress_stateless(in_buf, in_size, NO_FLUSH); in_buf -= offset; @@ -1459,14 +1933,79 @@ int main(int argc, char *argv[]) for (i = 0; i < RANDOMS / 16; i++) { create_rand_repeat_data(in_buf, PAGE_SIZE); - ret |= test_compress_stateless(in_buf, PAGE_SIZE); // good for efence + ret |= test_compress_stateless(in_buf, PAGE_SIZE, NO_FLUSH); // good for efence + if (ret) + return ret; + } + + fin_ret |= ret; + + ret = test_compress_stateless((uint8_t *) str1, sizeof(str1), SYNC_FLUSH); + if (ret) + return ret; + + ret |= test_compress_stateless((uint8_t *) str2, sizeof(str2), SYNC_FLUSH); + if (ret) + return ret; + + for (i = 0; i < 16; i++) { + in_size = rand() % (IBUF_SIZE + 1); + offset = rand() % (IBUF_SIZE + 1 - in_size); + in_buf += offset; + + create_rand_repeat_data(in_buf, in_size); + + ret |= test_compress_stateless(in_buf, in_size, SYNC_FLUSH); + + in_buf -= offset; + + if (ret) + return ret; + } + + fin_ret |= ret; + + printf("%s\n", ret ? "Fail" : "Pass"); + + printf("igzip_rand_test stateless FULL_FLUSH: "); + + ret = test_compress_stateless((uint8_t *) str1, sizeof(str1), FULL_FLUSH); + if (ret) + return ret; + + ret |= test_compress_stateless((uint8_t *) str2, sizeof(str2), FULL_FLUSH); + if (ret) + return ret; + + for (i = 0; i < RANDOMS; i++) { + in_size = rand() % (IBUF_SIZE + 1); + offset = rand() % (IBUF_SIZE + 1 - in_size); + in_buf += offset; + + create_rand_repeat_data(in_buf, in_size); + + ret |= test_compress_stateless(in_buf, in_size, FULL_FLUSH); + + in_buf -= offset; + + if (i % (RANDOMS / 16) == 0) + printf("."); + + if (ret) + return ret; } + for (i = 0; i < RANDOMS / 16; i++) { + create_rand_repeat_data(in_buf, PAGE_SIZE); + ret |= test_compress_stateless(in_buf, PAGE_SIZE, FULL_FLUSH); // good for efence + if (ret) + return ret; + } fin_ret |= ret; printf("%s\n", ret ? "Fail" : "Pass"); - printf("igzip_rand_test NO_FLUSH: "); + printf("igzip_rand_test stateful NO_FLUSH: "); ret = test_compress((uint8_t *) str1, sizeof(str1), NO_FLUSH); if (ret) @@ -1497,7 +2036,7 @@ int main(int argc, char *argv[]) printf("%s\n", ret ? "Fail" : "Pass"); - printf("igzip_rand_test SYNC_FLUSH: "); + printf("igzip_rand_test stateful SYNC_FLUSH: "); ret = test_compress((uint8_t *) str1, sizeof(str1), SYNC_FLUSH); if (ret) @@ -1528,7 +2067,7 @@ int main(int argc, char *argv[]) printf("%s\n", ret ? "Fail" : "Pass"); - printf("igzip_rand_test FULL_FLUSH: "); + printf("igzip_rand_test stateful FULL_FLUSH: "); ret = test_compress((uint8_t *) str1, sizeof(str1), FULL_FLUSH); if (ret) @@ -1555,7 +2094,6 @@ int main(int argc, char *argv[]) return ret; } -#ifdef DEFLATE for (i = 0; i < RANDOMS / 8; i++) { in_size = rand() % (IBUF_SIZE + 1); offset = rand() % (IBUF_SIZE + 1 - in_size); @@ -1570,13 +2108,12 @@ int main(int argc, char *argv[]) if (ret) return ret; } -#endif fin_ret |= ret; printf("%s\n", ret ? "Fail" : "Pass"); - printf("igzip_rand_test Change Flush: "); + printf("igzip_rand_test stateful Change Flush: "); ret = test_flush((uint8_t *) str1, sizeof(str1)); if (ret) @@ -1607,7 +2144,17 @@ int main(int argc, char *argv[]) printf("%s\n", ret ? "Fail" : "Pass"); - printf("igzip rand test finished: %s\n", + printf("igzip_rand_test inflate Std Vectors: "); + + for (i = 0; i < sizeof(std_vect_array) / sizeof(struct vect_result); i++) { + ret = test_inflate(&std_vect_array[i]); + if (ret) + return ret; + } + printf("................"); + printf("%s\n", ret ? "Fail" : "Pass"); + + printf("igzip rand test finished: %s\n", fin_ret ? "Some tests failed" : "All tests passed"); return fin_ret != IGZIP_COMP_OK; diff --git a/ceph/src/isa-l/igzip/igzip_semi_dyn_file_perf.c b/ceph/src/isa-l/igzip/igzip_semi_dyn_file_perf.c new file mode 100644 index 000000000..525d3fe84 --- /dev/null +++ b/ceph/src/isa-l/igzip/igzip_semi_dyn_file_perf.c @@ -0,0 +1,342 @@ +/********************************************************************** + Copyright(c) 2011-2016 Intel Corporation All rights reserved. + + 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 Intel Corporation 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 + 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. +**********************************************************************/ + +#include +#include +#include +#include +#include "igzip_lib.h" +#include "test.h" + +#define MIN_BUF_SIZE (4 * 1024) +#define MIN_TEST_LOOPS 10 +#ifndef RUN_MEM_SIZE +# define RUN_MEM_SIZE 500000000 +#endif + +#define DEFAULT_SEG_SIZE (512 * 1024) +#define DEFAULT_SAMPLE_SIZE (32 * 1024) + +int usage(void) +{ + fprintf(stderr, + "Usage: igzip_semi_dynamic [options] \n" + " -h help\n" + " -v (don't) validate output by inflate and compare\n" + " -i iterations\n" + " -t 1:stateless 0:(default)stateful\n" + " -c chunk size default=%d\n" + " -s sample size default=%d\n" + " -o output file\n", DEFAULT_SEG_SIZE, DEFAULT_SAMPLE_SIZE); + exit(0); +} + +int str_to_i(char *s) +{ +#define ARG_MAX 32 + + int i = atoi(s); + int len = strnlen(s, ARG_MAX); + if (len < 2 || len == ARG_MAX) + return i; + + switch (s[len - 1]) { + case 'k': + i *= 1024; + break; + case 'K': + i *= 1000; + break; + case 'm': + i *= (1024 * 1024); + break; + case 'M': + i *= (1000 * 1000); + break; + case 'g': + i *= (1024 * 1024 * 1024); + break; + case 'G': + i *= (1000 * 1000 * 1000); + break; + } + return i; +} + +int get_filesize(FILE * f) +{ + int curr, end; + + curr = ftell(f); /* Save current position */ + fseek(f, 0L, SEEK_END); + end = ftell(f); + fseek(f, curr, SEEK_SET); /* Restore position */ + return end; +} + +int main(int argc, char *argv[]) +{ + FILE *in = stdin, *out = NULL; + unsigned char *inbuf, *outbuf; + int i = 0, c, infile_size, outbuf_size; + int segment_size = DEFAULT_SEG_SIZE; + int sample_size = DEFAULT_SAMPLE_SIZE; + int check_output = 1; + int iterations = 0, do_stateless = 0, do_stateful = 1; + int ret = 0; + char *out_file_name = NULL; + struct isal_zstream stream; + struct isal_huff_histogram histogram; + struct isal_hufftables hufftable; + + while ((c = getopt(argc, argv, "vht:c:s:o:i:")) != -1) { + switch (c) { + case 'v': + check_output ^= 1; + break; + case 't': + if (atoi(optarg) == 1) { + do_stateful = 0; + do_stateless = 1; + } + break; + case 'c': + segment_size = str_to_i(optarg); + break; + case 's': + sample_size = str_to_i(optarg); + break; + case 'o': + out_file_name = optarg; + break; + case 'i': + iterations = str_to_i(optarg); + break; + case 'h': + default: + usage(); + break; + } + } + + // Open input file + if (optind < argc) { + if (!(in = fopen(argv[optind], "rb"))) { + fprintf(stderr, "Can't open %s for reading\n", argv[optind]); + exit(1); + } + } else + usage(); + + // Optionally open output file + if (out_file_name != NULL) { + if (!(out = fopen(out_file_name, "wb"))) { + fprintf(stderr, "Can't open %s for writing\n", out_file_name); + exit(1); + } + } + + printf("Window Size: %d K\n", IGZIP_HIST_SIZE / 1024); + + /* + * Allocate space for entire input file and output + * (assuming some possible expansion on output size) + */ + infile_size = get_filesize(in); + if (infile_size == 0) { + printf("Input file has zero length\n"); + usage(); + } + + if (iterations == 0) { + iterations = RUN_MEM_SIZE / infile_size; + if (iterations < MIN_TEST_LOOPS) + iterations = MIN_TEST_LOOPS; + } + + outbuf_size = infile_size * 1.30 > MIN_BUF_SIZE ? infile_size * 1.30 : MIN_BUF_SIZE; + + if (NULL == (inbuf = malloc(infile_size))) { + fprintf(stderr, "Can't allocate input buffer memory\n"); + exit(0); + } + if (NULL == (outbuf = malloc(outbuf_size))) { + fprintf(stderr, "Can't allocate output buffer memory\n"); + exit(0); + } + + int hist_size = sample_size > segment_size ? segment_size : sample_size; + + printf("semi-dynamic sample=%d segment=%d %s\n", hist_size, segment_size, + do_stateful ? "stateful" : "stateless"); + printf("igzip_file_perf: %s %d iterations\n", argv[optind], iterations); + + // Read complete input file into buffer + stream.avail_in = (uint32_t) fread(inbuf, 1, infile_size, in); + if (stream.avail_in != infile_size) { + fprintf(stderr, "Couldn't fit all of input file into buffer\n"); + exit(0); + } + + struct perf start, stop; + + if (do_stateful) { + perf_start(&start); + + for (i = 0; i < iterations; i++) { + isal_deflate_init(&stream); + stream.end_of_stream = 0; + stream.flush = SYNC_FLUSH; + stream.next_in = inbuf; + stream.next_out = outbuf; + stream.avail_out = outbuf_size; + int remaining = infile_size; + int chunk_size = segment_size; + + while (remaining > 0) { + // Generate custom hufftables on sample + memset(&histogram, 0, sizeof(struct isal_huff_histogram)); + if (remaining < segment_size * 2) { + chunk_size = remaining; + stream.end_of_stream = 1; + } + int hist_rem = + (hist_size > chunk_size) ? chunk_size : hist_size; + isal_update_histogram(stream.next_in, hist_rem, &histogram); + + if (hist_rem == chunk_size) + isal_create_hufftables_subset(&hufftable, &histogram); + else + isal_create_hufftables(&hufftable, &histogram); + + // Compress with custom table + stream.avail_in = chunk_size; + stream.hufftables = &hufftable; + remaining -= chunk_size; + isal_deflate(&stream); + if (stream.internal_state.state != ZSTATE_NEW_HDR) + break; + } + } + perf_stop(&stop); + } + + if (do_stateless) { + perf_start(&start); + + for (i = 0; i < iterations; i++) { + isal_deflate_stateless_init(&stream); + stream.end_of_stream = 0; + stream.flush = FULL_FLUSH; + stream.next_in = inbuf; + stream.next_out = outbuf; + int remaining = infile_size; + int chunk_size = segment_size; + + while (remaining > 0) { + // Generate custom hufftables on sample + memset(&histogram, 0, sizeof(struct isal_huff_histogram)); + if (remaining < segment_size * 2) { + chunk_size = remaining; + stream.end_of_stream = 1; + } + int hist_rem = + (hist_size > chunk_size) ? chunk_size : hist_size; + isal_update_histogram(stream.next_in, hist_rem, &histogram); + + if (hist_rem == chunk_size) + isal_create_hufftables_subset(&hufftable, &histogram); + else + isal_create_hufftables(&hufftable, &histogram); + + // Compress with custom table + stream.avail_in = chunk_size; + stream.avail_out = chunk_size + 8 * (1 + (chunk_size >> 16)); + stream.hufftables = &hufftable; + remaining -= chunk_size; + isal_deflate_stateless(&stream); + if (stream.avail_in != 0) + break; + } + } + perf_stop(&stop); + } + + if (stream.avail_in != 0) { + printf("Could not compress all of inbuf\n"); + ret = 1; + } + + printf(" file %s - in_size=%d out_size=%d iter=%d ratio=%3.1f%%\n", argv[optind], + infile_size, stream.total_out, i, 100.0 * stream.total_out / infile_size); + + printf("igzip_file: "); + perf_print(stop, start, (long long)infile_size * i); + + if (out != NULL) { + printf("writing %s\n", out_file_name); + fwrite(outbuf, 1, stream.total_out, out); + fclose(out); + } + + fclose(in); + + if (check_output) { + unsigned char *inflate_buf; + struct inflate_state istate; + + if (NULL == (inflate_buf = malloc(infile_size))) { + fprintf(stderr, "Can't allocate reconstruct buffer memory\n"); + exit(0); + } + isal_inflate_init(&istate); + istate.next_in = outbuf; + istate.avail_in = stream.total_out; + istate.next_out = inflate_buf; + istate.avail_out = infile_size; + int check = isal_inflate(&istate); + + if (memcmp(inflate_buf, inbuf, infile_size)) { + printf("inflate check Fail\n"); + printf(" ret %d total_inflate=%d\n", check, istate.total_out); + for (i = 0; i < infile_size; i++) { + if (inbuf[i] != inflate_buf[i]) { + printf(" first diff at offset=%d\n", i); + break; + } + } + ret = 1; + } else + printf("inflate check Pass\n"); + free(inflate_buf); + } + + printf("End of igzip_semi_dyn_file_perf\n\n"); + return ret; +} diff --git a/ceph/src/isa-l/igzip/igzip_stateless.asm b/ceph/src/isa-l/igzip/igzip_stateless.asm deleted file mode 100644 index 594614508..000000000 --- a/ceph/src/isa-l/igzip/igzip_stateless.asm +++ /dev/null @@ -1,644 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Copyright(c) 2011-2016 Intel Corporation All rights reserved. -; -; 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 Intel Corporation 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 -; 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. -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -%include "options.asm" - -%include "lz0a_const.asm" -%include "data_struct2.asm" -%include "bitbuf2.asm" -%include "huffman.asm" -%include "igzip_compare_types.asm" -%include "reg_sizes.asm" - -%include "stdmac.asm" - -%define LAST_BYTES_COUNT 3 ; Bytes to prevent reading out of array bounds -%define LA_STATELESS 264 ; Max number of bytes read in loop2 rounded up to 8 byte boundary - -%ifdef DEBUG -%macro MARK 1 -global %1 -%1: -%endm -%else -%macro MARK 1 -%endm -%endif - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -%define tmp2 rcx -%define hash2 rcx - -%define curr_data rax -%define code rax -%define tmp5 rax - -%define tmp4 rbx -%define dist rbx -%define code2 rbx - -%define hash rdx -%define len rdx -%define code_len3 rdx - -%define tmp1 rsi -%define code_len2 rsi - -%define file_start rdi - -%define m_bit_count rbp - -%define curr_data2 r8 -%define len2 r8 -%define tmp6 r8 - -%define m_bits r9 - -%define f_i r10 - -%define m_out_buf r11 - -%define f_end_i r12 -%define dist2 r12 -%define tmp7 r12 -%define code4 r12 - -%define tmp3 r13 -%define code3 r13 - -%define stream r14 - -%define hufftables r15 - -;; GPR r8 & r15 can be used - -%define xtmp0 xmm0 ; tmp -%define xtmp1 xmm1 ; tmp - -%define ytmp0 ymm0 ; tmp -%define ytmp1 ymm1 ; tmp - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - -blen_mem_offset equ 0 ; local variable (8 bytes) -f_end_i_mem_offset equ 8 -gpr_save_mem_offset equ 16 ; gpr save area (8*8 bytes) -xmm_save_mem_offset equ 16 + 8*8 ; xmm save area (4*16 bytes) (16 byte aligned) -stack_size equ 2*8 + 8*8 + 4*16 + 8 -;;; 8 because stack address is odd multiple of 8 after a function call and -;;; we want it aligned to 16 bytes - -; void isal_deflate_body_stateless ( isal_zstream *stream ) -; arg 1: rcx: addr of stream -global isal_deflate_body_stateless_ %+ ARCH -isal_deflate_body_stateless_ %+ ARCH %+ : -%ifidn __OUTPUT_FORMAT__, elf64 - mov rcx, rdi -%endif - - ;; do nothing if (avail_in == 0) - cmp dword [rcx + _avail_in], 0 - jne skip1 - ret -skip1: - -%ifdef ALIGN_STACK - push rbp - mov rbp, rsp - sub rsp, stack_size - and rsp, ~15 -%else - sub rsp, stack_size -%endif - - mov [rsp + gpr_save_mem_offset + 0*8], rbx - mov [rsp + gpr_save_mem_offset + 1*8], rsi - mov [rsp + gpr_save_mem_offset + 2*8], rdi - mov [rsp + gpr_save_mem_offset + 3*8], rbp - mov [rsp + gpr_save_mem_offset + 4*8], r12 - mov [rsp + gpr_save_mem_offset + 5*8], r13 - mov [rsp + gpr_save_mem_offset + 6*8], r14 - mov [rsp + gpr_save_mem_offset + 7*8], r15 - - mov stream, rcx - mov dword [stream + _internal_state_has_eob], 0 - - ; state->bitbuf.set_buf(stream->next_out, stream->avail_out); - mov m_out_buf, [stream + _next_out] - mov [stream + _internal_state_bitbuf_m_out_start], m_out_buf - mov tmp1 %+ d, [stream + _avail_out] - add tmp1, m_out_buf - sub tmp1, SLOP - -skip_SLOP: - mov [stream + _internal_state_bitbuf_m_out_end], tmp1 - - mov m_bits, [stream + _internal_state_bitbuf_m_bits] - mov m_bit_count %+ d, [stream + _internal_state_bitbuf_m_bit_count] - mov hufftables, [stream + _hufftables] - ; state->b_bytes_valid = stream->avail_in; - mov f_end_i %+ d, [stream + _avail_in] - mov [stream + _internal_state_b_bytes_valid], f_end_i %+ d - - mov f_i, 0 - mov file_start, [stream + _next_in] - mov [stream + _internal_state_file_start], file_start - - ; f_end_i -= LA; - sub f_end_i, LA_STATELESS - mov [rsp + f_end_i_mem_offset], f_end_i - ; if (f_end_i <= 0) continue; - cmp f_end_i, 0 - jle end_loop_2 - - ; for (f_i = f_start_i; f_i < f_end_i; f_i++) { -MARK __stateless_compute_hash_ %+ ARCH - mov curr_data %+ d, [file_start + f_i] - - cmp m_out_buf, [stream + _internal_state_bitbuf_m_out_end] - ja end - - ;; Encode first byte in the stream as a literal - compute_hash hash, curr_data - and hash %+ d, HASH_MASK - mov [stream + _internal_state_head + 2 * hash], f_i %+ w - and curr_data, 0xff - get_lit_code curr_data, code2, code_len2, hufftables - jmp write_lit_bits - - align 16 - -loop2: - shr curr_data2, 8 - xor hash2 %+ d, hash2 %+ d - crc32 hash2 %+ d, curr_data2 %+ d - - ; hash = compute_hash(state->file_start + f_i) & HASH_MASK; - and hash %+ d, HASH_MASK - and hash2 %+ d, HASH_MASK - - ; if (state->bitbuf.is_full()) { - cmp m_out_buf, [stream + _internal_state_bitbuf_m_out_end] - ja end - - xor dist, dist - xor dist2, dist2 - xor tmp3, tmp3 - - lea tmp1, [file_start + f_i] - lea tmp6, [tmp1 - 1] - - mov dist %+ w, f_i %+ w - sub dist %+ w, word [stream + _internal_state_head + 2 * hash] - - ; state->head[hash] = (uint16_t) f_i; - mov [stream + _internal_state_head + 2 * hash], f_i %+ w - - inc f_i - - mov dist2 %+ w, f_i %+ w - sub dist2 %+ w, word [stream + _internal_state_head + 2 * hash2] - dec dist2 - - ; state->head[hash2] = (uint16_t) f_i; - mov [stream + _internal_state_head + 2 * hash2], f_i %+ w - - mov tmp2, tmp1 - sub tmp2, dist - dec dist - - ; if ((dist-1) < (D-1)) { - cmp dist %+ d, (D-1) - cmovae tmp2, tmp6 - cmovae dist, tmp3 - inc dist - - cmp dist2 %+ d, (D-1) - cmovae dist2, tmp3 - inc dist2 - -MARK __stateless_compare_ %+ ARCH - ; len = compare258(state->file_start + f_i, - ; state->file_start + f_i - dist); - - ;; Specutively load distance code (except for when large windows are used) - get_packed_dist_code dist, code2, hufftables - - ;; Check for long len/dist match (>7) with first literal - mov len, [tmp1] - xor len, [tmp2] - jz compare_loop - -%ifdef USE_HSWNI - blsmsk tmp3, len - or tmp3, 0xFFFFFF -%endif - - lea tmp1, [file_start + f_i] - mov tmp2, tmp1 - sub tmp2, dist2 - - ;; Specutively load distance code (except for when large windows are used) - get_packed_dist_code dist2, code4, hufftables - - ;; Check for len/dist match (>7) with second literal - mov len2, [tmp1] - xor len2, [tmp2] - jz compare_loop2 - -%ifdef USE_HSWNI - ;; Check for len/dist match for first literal - test tmp3, len2 - jz len_dist_lit_huffman_pre - - cmp tmp3, 0xFFFFFF - je encode_2_literals - jmp len_dist_huffman_pre - - -MARK __stateless_len_dist_lit_huffman_ %+ ARCH -len_dist_lit_huffman_pre: - movzx tmp1, curr_data %+ b - get_lit_code tmp1, code3, code_len3, hufftables -%else - ;; Specutively load the code for the first literal - movzx tmp1, curr_data %+ b - get_lit_code tmp1, code3, rcx, hufftables - - ;; Check for len/dist match for first literal - test len, 0xFFFFFF - jz len_dist_huffman_pre - - ;; Specutively load the code for the second literal - shr curr_data, 8 - and curr_data, 0xff - get_lit_code curr_data, code2, code_len2, hufftables - - shl code2, cl - or code2, code3 - add code_len2, rcx - - ;; Check for len/dist match for second literal - test len2, 0xFFFFFF - jnz write_lit_bits - -MARK __stateless_len_dist_lit_huffman_ %+ ARCH -len_dist_lit_huffman_pre: - mov code_len3, rcx -%endif - bsf len2, len2 - shr len2, 3 - - -len_dist_lit_huffman: -%ifndef LONGER_HUFFTABLE - mov tmp4, dist2 - get_dist_code tmp4, code4, code_len2, hufftables ;; clobbers dist, rcx -%else - unpack_dist_code code4, code_len2 -%endif - get_len_code len2, code, rcx, hufftables ;; rcx is code_len - -%ifdef USE_HSWNI - shlx code4, code4, rcx -%else - shl code4, cl -%endif - or code4, code - add code_len2, rcx - - mov rcx, code_len3 - -%ifdef USE_HSWNI - shlx code4, code4, rcx -%else - shl code4, cl -%endif - or code4, code3 - add code_len2, rcx - - mov code2, code4 - ;; Setup for updating hash - lea tmp3, [f_i + 1] ; tmp3 <= k - add f_i, len2 - - ; hash = compute_hash(state->file_start + k) & HASH_MASK; - mov tmp5 %+ d, [file_start + tmp3] - mov tmp7, tmp5 - shr tmp7, 8 - - compute_hash hash, tmp5 - and hash %+ d, HASH_MASK - - ; state->head[hash] = k; - mov [stream + _internal_state_head + 2 * hash], tmp3 %+ w - - add tmp3,1 - - jmp update_hash_for_symbol - ;; encode as dist/len - -MARK __stateless_len_dist_huffman_ %+ ARCH -len_dist_huffman_pre: - bsf len, len - shr len, 3 - -len_dist_huffman: - dec f_i - - ; get_dist_code(dist, &code2, &code_len2); -%ifndef LONGER_HUFFTABLE - mov tmp3, dist ; since code2 and dist are rbx - get_dist_code tmp3, code2, code_len2, hufftables ;; clobbers dist, rcx -%else - unpack_dist_code code2, code_len2 -%endif - ; get_len_code(len, &code, &code_len); - get_len_code len, code, rcx, hufftables ;; rcx is code_len - - ; code2 <<= code_len - ; code2 |= code - ; code_len2 += code_len -%ifdef USE_HSWNI - shlx code2, code2, rcx -%else - shl code2, cl -%endif - or code2, code - add code_len2, rcx - - ;; Setup for updateing hash - lea tmp3, [f_i + 2] ; tmp3 <= k - add f_i, len - mov tmp7 %+ d, [file_start + tmp3] - -MARK __stateless_update_hash_for_symbol_ %+ ARCH -update_hash_for_symbol: - mov curr_data %+ d, [file_start + f_i] - mov curr_data2, curr_data - compute_hash hash, curr_data -%ifdef LIMIT_HASH_UPDATE - ; only update hash twice, first hash was already calculated. - - ; hash = compute_hash(state->file_start + k) & HASH_MASK; - compute_hash hash2, tmp7 - and hash2 %+ d, HASH_MASK - ; state->head[hash] = k; - mov [stream + _internal_state_head + 2 * hash2], tmp3 %+ w - -%else -loop3: - ; hash = compute_hash(state->file_start + k) & HASH_MASK; - mov tmp7 %+ d, [file_start + tmp3] - compute_hash hash2, tmp7 - and hash2 %+ d, HASH_MASK - ; state->head[hash] = k; - mov [stream + _internal_state_head + 2 * hash2], tmp3 %+ w - add tmp3,1 - cmp tmp3, f_i - jl loop3 -%endif - - -MARK __stateless_write_len_dist_bits_ %+ ARCH - mov f_end_i, [rsp + f_end_i_mem_offset] - write_bits m_bits, m_bit_count, code2, code_len2, m_out_buf, tmp3 - - ; continue - cmp f_i, f_end_i - jl loop2 - jmp end_loop_2 - - -MARK __stateless_write_lit_bits_ %+ ARCH -%ifdef USE_HSWNI -encode_2_literals: - movzx tmp1, curr_data %+ b - get_lit_code tmp1, code3, rcx, hufftables - - shr curr_data, 8 - and curr_data, 0xff - get_lit_code curr_data, code2, code_len2, hufftables - - ;; Calculate code associated with both literals - shlx code2, code2, rcx - or code2, code3 - add code_len2, rcx -%endif -write_lit_bits: - mov f_end_i, [rsp + f_end_i_mem_offset] - add f_i, 1 - mov curr_data %+ d, [file_start + f_i] - mov curr_data2, curr_data - - compute_hash hash, curr_data - - write_bits m_bits, m_bit_count, code2, code_len2, m_out_buf, tmp3 - - ; continue - cmp f_i, f_end_i - jl loop2 - -MARK __stateless_end_loops_ %+ ARCH -end_loop_2: - ;; Handle the last bytes (at most LA_statless bytes) - add f_end_i, LA_STATELESS - LAST_BYTES_COUNT - cmp f_i, f_end_i - jge end_loop_2_finish - -loop2_finish: - ;; Check for space in out buffer - cmp m_out_buf, [stream + _internal_state_bitbuf_m_out_end] - ja end - - mov curr_data %+ d, [file_start + f_i] - compute_hash hash, curr_data - and hash %+ d, HASH_MASK - - ;; Calculate possible distance for length/dist pair. - xor dist, dist - mov dist %+ w, f_i %+ w - sub dist %+ w, word [stream + _internal_state_head + 2 * hash] - mov [stream + _internal_state_head + 2 * hash], f_i %+ w - - ;; Check if look back distance is valid (the dec is to handle when dist = 0) - dec dist - cmp dist %+ d, (D-1) - jae encode_literal_finish - inc dist - - ;; Check if look back distance is a match - lea tmp6, [f_end_i + LAST_BYTES_COUNT] - sub tmp6, f_i - lea tmp1, [file_start + f_i] - mov tmp2, tmp1 - sub tmp2, dist - compare tmp6, tmp1, tmp2, len, tmp3 - - ;; Limit len to maximum value of 258 - mov tmp2, 258 - cmp len, 258 - cmova len, tmp2 - cmp len, SHORTEST_MATCH - jb encode_literal_finish - - ;; Encode len/dist pair -%ifndef LONGER_HUFFTABLE - mov tmp3, dist - get_dist_code tmp3, code2, code_len2, hufftables ;; clobbers dist, rcx -%else - get_dist_code dist, code2, code_len2, hufftables ;; clobbers dist, rcx -%endif - get_len_code len, code, rcx, hufftables ;; rcx is code_len - - ;; Combine length and distance code for writing it out -%ifdef USE_HSWNI - shlx code2, code2, rcx -%else - shl code2, cl -%endif - or code2, code - add code_len2, rcx - write_bits m_bits, m_bit_count, code2, code_len2, m_out_buf, tmp3 - - ;; Setup for next loop - add f_i, len - cmp f_i, f_end_i - jl loop2_finish - jmp end_loop_2_finish - -encode_literal_finish: - ;; Encode literal - and curr_data %+ d, 0xFF - get_lit_code curr_data, code2, code_len2, hufftables - write_bits m_bits, m_bit_count, code2, code_len2, m_out_buf, tmp3 - - ;; Setup for next loop - add f_i, 1 - cmp f_i, f_end_i - jl loop2_finish -end_loop_2_finish: - cmp m_out_buf, [stream + _internal_state_bitbuf_m_out_end] - ja end - - ;; Check if any bytes left (at most LAST_BYTES_COUNT bytes) - add f_end_i, LAST_BYTES_COUNT - cmp f_i, f_end_i - jz write_eob - - ;; Handle encoding last few bytes by encoding them as literals - xor curr_data, curr_data -final_bytes: - movzx curr_data, byte [file_start + f_i] - get_lit_code curr_data, code2, code_len2, hufftables - write_bits m_bits, m_bit_count, code2, code_len2, m_out_buf, tmp3 - - cmp m_out_buf, [stream + _internal_state_bitbuf_m_out_end] - ja end - - inc f_i - cmp f_i, f_end_i - jl final_bytes - -write_eob: - ;; Write out end of block - get_lit_code 256, code2, code_len2, hufftables - write_bits m_bits, m_bit_count, code2, code_len2, m_out_buf, tmp3 - mov dword [stream + _internal_state_has_eob], 1 - -end: - ;; update input buffer - add [stream + _total_in], f_i %+ d - add [stream + _next_in], f_i - sub [stream + _avail_in], f_i %+ d - - ;; update output buffer - mov [stream + _next_out], m_out_buf - sub m_out_buf, [stream + _internal_state_bitbuf_m_out_start] - sub [stream + _avail_out], m_out_buf %+ d - add [stream + _total_out], m_out_buf %+ d - - mov [stream + _internal_state_bitbuf_m_bits], m_bits - mov [stream + _internal_state_bitbuf_m_bit_count], m_bit_count %+ d - - mov rbx, [rsp + gpr_save_mem_offset + 0*8] - mov rsi, [rsp + gpr_save_mem_offset + 1*8] - mov rdi, [rsp + gpr_save_mem_offset + 2*8] - mov rbp, [rsp + gpr_save_mem_offset + 3*8] - mov r12, [rsp + gpr_save_mem_offset + 4*8] - mov r13, [rsp + gpr_save_mem_offset + 5*8] - mov r14, [rsp + gpr_save_mem_offset + 6*8] - mov r15, [rsp + gpr_save_mem_offset + 7*8] - -%ifndef ALIGN_STACK - add rsp, stack_size -%else - mov rsp, rbp - pop rbp -%endif - ret - -MARK __stateless_compare_loops_ %+ ARCH -compare_loop: -%if (COMPARE_TYPE == 1) - compare250 tmp1, tmp2, len, tmp3 -%elif (COMPARE_TYPE == 2) - compare250_x tmp1, tmp2, len, tmp3, xtmp0, xtmp1 -%elif (COMPARE_TYPE == 3) - compare250_y tmp1, tmp2, len, tmp3, ytmp0, ytmp1 -%else - %error Unknown Compare type COMPARE_TYPE - % error -%endif - jmp len_dist_huffman - -compare_loop2: -%if (COMPARE_TYPE == 1) - compare250 tmp1, tmp2, len2, tmp3 -%elif (COMPARE_TYPE == 2) - compare250_x tmp1, tmp2, len2, tmp3, xtmp0, xtmp1 -%elif (COMPARE_TYPE == 3) - compare250_y tmp1, tmp2, len2, tmp3, ytmp0, ytmp1 -%else -%error Unknown Compare type COMPARE_TYPE - % error -%endif - and curr_data, 0xff - get_lit_code curr_data, code3, code_len3, hufftables - jmp len_dist_lit_huffman - -section .data - align 4 -const_D: dq D diff --git a/ceph/src/isa-l/igzip/igzip_stateless_01.asm b/ceph/src/isa-l/igzip/igzip_stateless_01.asm deleted file mode 100644 index 83ed1bae9..000000000 --- a/ceph/src/isa-l/igzip/igzip_stateless_01.asm +++ /dev/null @@ -1,7 +0,0 @@ -%define ARCH 01 - -%ifndef COMPARE_TYPE -%define COMPARE_TYPE 1 -%endif - -%include "igzip_stateless.asm" diff --git a/ceph/src/isa-l/igzip/igzip_stateless_base.c b/ceph/src/isa-l/igzip/igzip_stateless_base.c deleted file mode 100644 index 63fa57866..000000000 --- a/ceph/src/isa-l/igzip/igzip_stateless_base.c +++ /dev/null @@ -1,151 +0,0 @@ -#include -#include "igzip_lib.h" -#include "huffman.h" -#include "huff_codes.h" -#include "bitbuf2.h" - -static inline void update_state(struct isal_zstream *stream, struct isal_zstate *state, - uint8_t * end_in, uint8_t * start_in) -{ - uint32_t count; - stream->avail_in = end_in - stream->next_in; - stream->total_in += stream->next_in - start_in; - count = buffer_used(&state->bitbuf); - stream->next_out = buffer_ptr(&state->bitbuf); - stream->avail_out -= count; - stream->total_out += count; - -} - -void isal_deflate_body_stateless_base(struct isal_zstream *stream) -{ - uint32_t literal = 0, hash; - uint8_t *start_in, *end_in, *end, *next_hash; - uint16_t match_length; - uint32_t dist; - uint64_t code, code_len, code2, code_len2, i; - struct isal_zstate *state = &stream->internal_state; - uint16_t *last_seen = state->head; - - if (stream->avail_in == 0) - return; - - set_buf(&state->bitbuf, stream->next_out, stream->avail_out); - start_in = stream->next_in; - end_in = stream->next_in + stream->avail_in; - - while (stream->next_in < end_in - 3) { - if (is_full(&state->bitbuf)) { - update_state(stream, state, end_in, start_in); - return; - } - - literal = *(uint32_t *) stream->next_in; - hash = compute_hash(literal) & HASH_MASK; - dist = (uint64_t) (stream->next_in - last_seen[hash]) & 0xFFFF; - last_seen[hash] = (uint64_t) stream->next_in; - - if (dist - 1 < IGZIP_D - 1 && stream->next_in - dist >= start_in) { /* The -1 are to handle the case when dist = 0 */ - match_length = - compare258(stream->next_in - dist, stream->next_in, - end_in - stream->next_in); - - if (match_length >= SHORTEST_MATCH) { - next_hash = stream->next_in; -#ifdef LIMIT_HASH_UPDATE - end = next_hash + 3; -#else - end = next_hash + match_length; -#endif - if (end > end_in - 3) - end = end_in - 3; - next_hash++; - for (; next_hash < end; next_hash++) { - literal = *(uint32_t *) next_hash; - hash = compute_hash(literal) & HASH_MASK; - last_seen[hash] = (uint64_t) next_hash; - } - - get_len_code(stream->hufftables, match_length, &code, - &code_len); - get_dist_code(stream->hufftables, dist, &code2, &code_len2); - - code |= code2 << code_len; - code_len += code_len2; - - write_bits(&state->bitbuf, code, code_len); - - stream->next_in += match_length; - - continue; - } - } - - get_lit_code(stream->hufftables, literal & 0xFF, &code, &code_len); - write_bits(&state->bitbuf, code, code_len); - stream->next_in++; - } - - if (is_full(&state->bitbuf)) { - update_state(stream, state, end_in, start_in); - return; - } - - literal = *(uint32_t *) (end_in - 4); - - for (i = 4; i > end_in - stream->next_in; i--) - literal = literal >> 8; - - hash = compute_hash(literal) & HASH_MASK; - dist = (uint64_t) (stream->next_in - last_seen[hash]) & 0xFFFF; - - if (dist - 1 < IGZIP_D - 1 && stream->next_in - dist >= start_in) { - match_length = - compare258(stream->next_in - dist, stream->next_in, - end_in - stream->next_in); - if (match_length >= SHORTEST_MATCH) { - get_len_code(stream->hufftables, match_length, &code, &code_len); - get_dist_code(stream->hufftables, dist, &code2, &code_len2); - code |= code2 << code_len; - code_len += code_len2; - write_bits(&state->bitbuf, code, code_len); - stream->next_in += 3; - - if (is_full(&state->bitbuf)) { - update_state(stream, state, end_in, start_in); - return; - } - - get_lit_code(stream->hufftables, 256, &code, &code_len); - write_bits(&state->bitbuf, code, code_len); - - if (is_full(&state->bitbuf)) { - update_state(stream, state, end_in, start_in); - return; - } - - state->has_eob = 1; - update_state(stream, state, end_in, start_in); - return; - } - } - - while (stream->next_in < end_in) { - get_lit_code(stream->hufftables, literal & 0xFF, &code, &code_len); - write_bits(&state->bitbuf, code, code_len); - stream->next_in++; - - if (is_full(&state->bitbuf)) { - update_state(stream, state, end_in, start_in); - return; - } - literal >>= 8; - } - - get_lit_code(stream->hufftables, 256, &code, &code_len); - write_bits(&state->bitbuf, code, code_len); - - state->has_eob = 1; - update_state(stream, state, end_in, start_in); - return; -} diff --git a/ceph/src/isa-l/igzip/igzip_stateless_file_perf.c b/ceph/src/isa-l/igzip/igzip_stateless_file_perf.c index d82615a7a..d08e749b0 100644 --- a/ceph/src/isa-l/igzip/igzip_stateless_file_perf.c +++ b/ceph/src/isa-l/igzip/igzip_stateless_file_perf.c @@ -30,17 +30,30 @@ #include #include #include +#include +#include #include "igzip_lib.h" #include "test.h" #define BUF_SIZE 1024 #define MIN_TEST_LOOPS 10 #ifndef RUN_MEM_SIZE -# define RUN_MEM_SIZE 5000000000 +# define RUN_MEM_SIZE 500000000 #endif struct isal_zstream stream; +int usage(void) +{ + fprintf(stderr, + "Usage: igzip_stateless_file_perf [options] \n" + " -h help\n" + " -X use compression level X with 0 <= X <= 1\n" + " -i number of iterations (at least 1)\n" + " -o output file for compresed data\n"); + exit(0); +} + int get_filesize(FILE * f) { int curr, end; @@ -55,29 +68,56 @@ int get_filesize(FILE * f) int main(int argc, char *argv[]) { FILE *in, *out = NULL; - unsigned char *inbuf, *outbuf; - int i, infile_size, iterations, outbuf_size; - - if (argc > 3 || argc < 2) { - fprintf(stderr, "Usage: igzip_file_perf infile [outfile]\n" - "\t - Runs multiple iterations of igzip on a file to " - "get more accurate time results.\n"); - exit(0); + unsigned char *inbuf, *outbuf, *level_buf = NULL; + int i, c, infile_size, iterations = 0, outbuf_size; + struct isal_huff_histogram histogram; + struct isal_hufftables hufftables_custom; + int level = 0, level_size = 0; + char *in_file_name = NULL, *out_file_name = NULL; + + while ((c = getopt(argc, argv, "h01i:o:")) != -1) { + switch (c) { + case 'o': + out_file_name = optarg; + break; + case 'i': + iterations = atoi(optarg); + if (iterations < 1) + usage(); + break; + case '1': + level = 1; + level_size = ISAL_DEF_LVL1_LARGE; + break; + case '0': + break; + case 'h': + default: + usage(); + break; + } } - in = fopen(argv[1], "rb"); + + if (optind < argc) { + in_file_name = argv[optind]; + in = fopen(in_file_name, "rb"); + } else + usage(); + if (!in) { - fprintf(stderr, "Can't open %s for reading\n", argv[1]); + fprintf(stderr, "Can't open %s for reading\n", in_file_name); exit(0); } - if (argc > 2) { - out = fopen(argv[2], "wb"); + if (out_file_name != NULL) { + out = fopen(out_file_name, "wb"); if (!out) { - fprintf(stderr, "Can't open %s for writing\n", argv[2]); + fprintf(stderr, "Can't open %s for writing\n", out_file_name); exit(0); } - printf("outfile=%s\n", argv[2]); + printf("outfile=%s\n", out_file_name); } - printf("Window Size: %d K\n", HIST_SIZE); + + printf("Window Size: %d K\n", IGZIP_HIST_SIZE / 1024); printf("igzip_file_perf: \n"); fflush(0); /* Allocate space for entire input file and output @@ -85,15 +125,13 @@ int main(int argc, char *argv[]) */ infile_size = get_filesize(in); - if (infile_size != 0) { - outbuf_size = infile_size * 1.07; - iterations = RUN_MEM_SIZE / infile_size; - } else { - outbuf_size = BUF_SIZE; - iterations = MIN_TEST_LOOPS; + outbuf_size = infile_size * 1.07 + BUF_SIZE; + + if (iterations == 0) { + iterations = infile_size ? RUN_MEM_SIZE / infile_size : MIN_TEST_LOOPS; + if (iterations < MIN_TEST_LOOPS) + iterations = MIN_TEST_LOOPS; } - if (iterations < MIN_TEST_LOOPS) - iterations = MIN_TEST_LOOPS; inbuf = malloc(infile_size); if (inbuf == NULL) { @@ -106,7 +144,15 @@ int main(int argc, char *argv[]) exit(0); } - printf("igzip_file_perf: %s %d iterations\n", argv[1], iterations); + if (level_size != 0) { + level_buf = malloc(level_size); + if (level_buf == NULL) { + fprintf(stderr, "Can't allocate level buffer memory\n"); + exit(0); + } + } + + printf("igzip_file_perf: %s %d iterations\n", in_file_name, iterations); /* Read complete input file into buffer */ stream.avail_in = (uint32_t) fread(inbuf, 1, infile_size, in); if (stream.avail_in != infile_size) { @@ -125,6 +171,9 @@ int main(int argc, char *argv[]) stream.avail_in = infile_size; stream.next_out = outbuf; stream.avail_out = outbuf_size; + stream.level = level; + stream.level_buf = level_buf; + stream.level_buf_size = level_size; isal_deflate_stateless(&stream); if (stream.avail_in != 0) break; @@ -136,14 +185,37 @@ int main(int argc, char *argv[]) exit(0); } - printf(" file %s - in_size=%d out_size=%d iter=%d ratio=%3.1f%%\n", argv[1], + printf(" file %s - in_size=%d out_size=%d iter=%d ratio=%3.1f%%", in_file_name, infile_size, stream.total_out, i, 100.0 * stream.total_out / infile_size); + if (level == 0) { + memset(&histogram, 0, sizeof(histogram)); + + isal_update_histogram(inbuf, infile_size, &histogram); + isal_create_hufftables(&hufftables_custom, &histogram); + + isal_deflate_init(&stream); + stream.end_of_stream = 1; /* Do the entire file at once */ + stream.flush = NO_FLUSH; + stream.next_in = inbuf; + stream.avail_in = infile_size; + stream.next_out = outbuf; + stream.avail_out = outbuf_size; + stream.level = level; + stream.level_buf = level_buf; + stream.level_buf_size = level_size; + stream.hufftables = &hufftables_custom; + isal_deflate_stateless(&stream); + + printf(" ratio_custom=%3.1f%%", 100.0 * stream.total_out / infile_size); + } + printf("\n"); + printf("igzip_file: "); perf_print(stop, start, (long long)infile_size * i); if (argc > 2 && out) { - printf("writing %s\n", argv[2]); + printf("writing %s\n", out_file_name); fwrite(outbuf, 1, stream.total_out, out); fclose(out); } diff --git a/ceph/src/isa-l/igzip/igzip_sync_flush_example.c b/ceph/src/isa-l/igzip/igzip_sync_flush_example.c index a020c8513..0351d5c01 100644 --- a/ceph/src/isa-l/igzip/igzip_sync_flush_example.c +++ b/ceph/src/isa-l/igzip/igzip_sync_flush_example.c @@ -56,7 +56,7 @@ int main(int argc, char *argv[]) exit(0); } - printf("igzip_sync_flush_example\nWindow Size: %d K\n", HIST_SIZE); + printf("igzip_sync_flush_example\nWindow Size: %d K\n", IGZIP_HIST_SIZE / 1024); fflush(0); isal_deflate_init(&stream); @@ -66,7 +66,7 @@ int main(int argc, char *argv[]) do { if (stream.internal_state.state == ZSTATE_NEW_HDR) { stream.avail_in = (uint32_t) fread(inbuf, 1, BUF_SIZE, in); - stream.end_of_stream = feof(in); + stream.end_of_stream = feof(in) ? 1 : 0; stream.next_in = inbuf; } do { diff --git a/ceph/src/isa-l/igzip/igzip_sync_flush_file_perf.c b/ceph/src/isa-l/igzip/igzip_sync_flush_file_perf.c index 4e256c306..9fceee07d 100644 --- a/ceph/src/isa-l/igzip/igzip_sync_flush_file_perf.c +++ b/ceph/src/isa-l/igzip/igzip_sync_flush_file_perf.c @@ -76,7 +76,7 @@ int main(int argc, char *argv[]) } printf("outfile=%s\n", argv[2]); } - printf("Window Size: %d K\n", HIST_SIZE); + printf("Window Size: %d K\n", IGZIP_HIST_SIZE / 1024); printf("igzip_sync_flush_file_perf: \n"); fflush(0); /* Allocate space for entire input file and diff --git a/ceph/src/isa-l/igzip/igzip_sync_flush_perf.c b/ceph/src/isa-l/igzip/igzip_sync_flush_perf.c index 53a6dbe7a..46d89d675 100644 --- a/ceph/src/isa-l/igzip/igzip_sync_flush_perf.c +++ b/ceph/src/isa-l/igzip/igzip_sync_flush_perf.c @@ -56,7 +56,7 @@ int main(int argc, char *argv[]) struct perf start, stop; create_data(inbuf, TEST_LEN); - printf("Window Size: %d K\n", HIST_SIZE); + printf("Window Size: %d K\n", IGZIP_HIST_SIZE / 1024); printf("igzip_sync_flush_perf: \n"); fflush(0); diff --git a/ceph/src/isa-l/igzip/igzip_update_histogram.asm b/ceph/src/isa-l/igzip/igzip_update_histogram.asm new file mode 100644 index 000000000..4d91f7fbe --- /dev/null +++ b/ceph/src/isa-l/igzip/igzip_update_histogram.asm @@ -0,0 +1,557 @@ + +%include "options.asm" + +%include "lz0a_const.asm" +%include "data_struct2.asm" +%include "bitbuf2.asm" +%include "huffman.asm" +%include "igzip_compare_types.asm" +%include "reg_sizes.asm" + +%include "stdmac.asm" + +extern rfc1951_lookup_table +_len_to_code_offset equ 0 + +%define LAST_BYTES_COUNT 3 ; Bytes to prevent reading out of array bounds +%define LA_STATELESS 280 ; Max number of bytes read in loop2 rounded up to 8 byte boundary +%define LIT_LEN 286 +%define DIST_LEN 30 +%define HIST_ELEM_SIZE 8 + +%ifdef DEBUG +%macro MARK 1 +global %1 +%1: +%endm +%else +%macro MARK 1 +%endm +%endif + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%define file_start rdi +%define file_length rsi +%define histogram rdx +%define rfc_lookup r9 +%define f_i r10 + +%define curr_data rax + +%define tmp2 rcx + +%define dist rbx +%define dist_code2 rbx + +%define dist2 r12 +%define dist_code r12 + +%define len rbp +%define len_code rbp +%define hash3 rbp + +%define curr_data2 r8 +%define len2 r8 +%define tmp4 r8 + +%define tmp1 r11 + +%define tmp3 r13 + +%define hash r14 + +%define hash2 r15 + +%define xtmp0 xmm0 +%define xtmp1 xmm1 +%define xdata xmm2 + +%define ytmp0 ymm0 +%define ytmp1 ymm1 + +%if(ARCH == 01) +%define vtmp0 xtmp0 +%define vtmp1 xtmp1 +%define V_LENGTH 16 +%else +%define vtmp0 ytmp0 +%define vtmp1 ytmp1 +%define V_LENGTH 32 +%endif +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +_eob_count_offset equ 0 ; local variable (8 bytes) +f_end_i_mem_offset equ 8 +gpr_save_mem_offset equ 16 ; gpr save area (8*8 bytes) +xmm_save_mem_offset equ 16 + 8*8 ; xmm save area (4*16 bytes) (16 byte aligned) +stack_size equ 2*8 + 8*8 + 4*16 + 8 +;;; 8 because stack address is odd multiple of 8 after a function call and +;;; we want it aligned to 16 bytes + +%ifidn __OUTPUT_FORMAT__, elf64 +%define arg0 rdi +%define arg1 rsi +%define arg2 rdx + +%macro FUNC_SAVE 0 +%ifdef ALIGN_STACK + push rbp + mov rbp, rsp + sub rsp, stack_size + and rsp, ~15 +%else + sub rsp, stack_size +%endif + + mov [rsp + gpr_save_mem_offset + 0*8], rbx + mov [rsp + gpr_save_mem_offset + 1*8], rbp + mov [rsp + gpr_save_mem_offset + 2*8], r12 + mov [rsp + gpr_save_mem_offset + 3*8], r13 + mov [rsp + gpr_save_mem_offset + 4*8], r14 + mov [rsp + gpr_save_mem_offset + 5*8], r15 +%endm + +%macro FUNC_RESTORE 0 + mov rbx, [rsp + gpr_save_mem_offset + 0*8] + mov rbp, [rsp + gpr_save_mem_offset + 1*8] + mov r12, [rsp + gpr_save_mem_offset + 2*8] + mov r13, [rsp + gpr_save_mem_offset + 3*8] + mov r14, [rsp + gpr_save_mem_offset + 4*8] + mov r15, [rsp + gpr_save_mem_offset + 5*8] + +%ifndef ALIGN_STACK + add rsp, stack_size +%else + mov rsp, rbp + pop rbp +%endif +%endm +%endif + +%ifidn __OUTPUT_FORMAT__, win64 +%define arg0 rcx +%define arg1 rdx +%define arg2 r8 + +%macro FUNC_SAVE 0 +%ifdef ALIGN_STACK + push rbp + mov rbp, rsp + sub rsp, stack_size + and rsp, ~15 +%else + sub rsp, stack_size +%endif + + mov [rsp + gpr_save_mem_offset + 0*8], rbx + mov [rsp + gpr_save_mem_offset + 1*8], rsi + mov [rsp + gpr_save_mem_offset + 2*8], rdi + mov [rsp + gpr_save_mem_offset + 3*8], rbp + mov [rsp + gpr_save_mem_offset + 4*8], r12 + mov [rsp + gpr_save_mem_offset + 5*8], r13 + mov [rsp + gpr_save_mem_offset + 6*8], r14 + mov [rsp + gpr_save_mem_offset + 7*8], r15 +%endm + +%macro FUNC_RESTORE 0 + mov rbx, [rsp + gpr_save_mem_offset + 0*8] + mov rsi, [rsp + gpr_save_mem_offset + 1*8] + mov rdi, [rsp + gpr_save_mem_offset + 2*8] + mov rbp, [rsp + gpr_save_mem_offset + 3*8] + mov r12, [rsp + gpr_save_mem_offset + 4*8] + mov r13, [rsp + gpr_save_mem_offset + 5*8] + mov r14, [rsp + gpr_save_mem_offset + 6*8] + mov r15, [rsp + gpr_save_mem_offset + 7*8] + +%ifndef ALIGN_STACK + add rsp, stack_size +%else + mov rsp, rbp + pop rbp +%endif +%endm +%endif + + +_lit_len_offset equ 0 +_dist_offset equ (8 * LIT_LEN) +_hash_offset equ (_dist_offset + 8 * DIST_LEN) + + +%macro len_to_len_code 3 +%define %%len_code %1 ; Output +%define %%len %2 ; Input +%define %%rfc_lookup %3 + movzx %%len_code, byte [%%rfc_lookup + _len_to_code_offset + %%len] + or %%len_code, 0x100 +%endm + +;;; Clobbers rcx and dist +%macro dist_to_dist_code 2 +%define %%dist_code %1 ; Output code associated with dist +%define %%dist_coded %1d +%define %%dist %2d ; Input dist + dec %%dist + mov %%dist_coded, %%dist + bsr ecx, %%dist_coded + dec ecx + SHRX %%dist_code, %%dist_code, rcx + lea %%dist_coded, [%%dist_coded + 2*ecx] + + cmp %%dist, 1 + cmovle %%dist_coded, %%dist +%endm + +;;; Clobbers rcx and dist +%macro dist_to_dist_code2 2 +%define %%dist_code %1 ; Output code associated with dist +%define %%dist_coded %1d +%define %%dist %2d ; Input -(dist - 1) + neg %%dist + mov %%dist_coded, %%dist + bsr ecx, %%dist_coded + dec ecx + SHRX %%dist_code, %%dist_code, rcx + lea %%dist_coded, [%%dist_coded + 2*ecx] + + cmp %%dist, 1 + cmovle %%dist_coded, %%dist +%endm + +; void isal_update_histogram +global isal_update_histogram_ %+ ARCH +isal_update_histogram_ %+ ARCH %+ : + FUNC_SAVE + +%ifnidn file_start, arg0 + mov file_start, arg0 +%endif +%ifnidn file_length, arg1 + mov file_length, arg1 +%endif +%ifnidn histogram, arg2 + mov histogram, arg2 +%endif + mov f_i, 0 + cmp file_length, 0 + je exit_ret ; If nothing to do then exit + + mov tmp1, qword [histogram + _lit_len_offset + 8*256] + inc tmp1 + mov [rsp + _eob_count_offset], tmp1 + + lea rfc_lookup, [rfc1951_lookup_table] + + ;; Init hash_table + PXOR vtmp0, vtmp0, vtmp0 + mov rcx, (IGZIP_HASH_SIZE - V_LENGTH) +init_hash_table: + MOVDQU [histogram + _hash_offset + 2 * rcx], vtmp0 + MOVDQU [histogram + _hash_offset + 2 * (rcx + V_LENGTH / 2)], vtmp0 + sub rcx, V_LENGTH + jge init_hash_table + + sub file_length, LA_STATELESS + cmp file_length, 0 + jle end_loop_2 + + + ;; Load first literal into histogram + mov curr_data, [file_start + f_i] + compute_hash hash, curr_data + and hash %+ d, HASH_MASK + mov [histogram + _hash_offset + 2 * hash], f_i %+ w + and curr_data, 0xff + inc qword [histogram + _lit_len_offset + HIST_ELEM_SIZE * curr_data] + inc f_i + + ;; Setup to begin loop 2 + MOVDQU xdata, [file_start + f_i] + mov curr_data, [file_start + f_i] + mov curr_data2, curr_data + compute_hash hash, curr_data + shr curr_data2, 8 + compute_hash hash2, curr_data2 + + and hash2 %+ d, HASH_MASK + and hash, HASH_MASK +loop2: + xor dist, dist + xor dist2, dist2 + xor tmp3, tmp3 + + lea tmp1, [file_start + f_i] + + MOVQ curr_data, xdata + PSRLDQ xdata, 1 + + ;; Load possible look back distances and update hash data + mov dist %+ w, f_i %+ w + sub dist, 1 + sub dist %+ w, word [histogram + _hash_offset + 2 * hash] + mov [histogram + _hash_offset + 2 * hash], f_i %+ w + + add f_i, 1 + + mov dist2 %+ w, f_i %+ w + sub dist2, 1 + sub dist2 %+ w, word [histogram + _hash_offset + 2 * hash2] + mov [histogram + _hash_offset + 2 * hash2], f_i %+ w + + ;; Start computing hashes to be used in either the next loop or + ;; for updating the hash if a match is found + MOVQ curr_data2, xdata + MOVQ tmp2, xdata + shr curr_data2, 8 + compute_hash hash, curr_data2 + + ;; Check if look back distances are valid. Load a junk distance of 1 + ;; if the look back distance is too long for speculative lookups. + and dist %+ d, (D-1) + neg dist + + and dist2 %+ d, (D-1) + neg dist2 + + shr tmp2, 16 + compute_hash hash2, tmp2 + + ;; Check for long len/dist matches (>7) + mov len, curr_data + xor len, [tmp1 + dist - 1] + jz compare_loop + + and hash %+ d, HASH_MASK + and hash2 %+ d, HASH_MASK + + MOVQ len2, xdata + xor len2, [tmp1 + dist2] + jz compare_loop2 + + ;; Specutively load the code for the first literal + movzx tmp1, curr_data %+ b + shr curr_data, 8 + + lea tmp3, [f_i + 1] + + ;; Check for len/dist match for first literal + test len %+ d, 0xFFFFFFFF + jz len_dist_huffman_pre + + ;; Store first literal + inc qword [histogram + _lit_len_offset + HIST_ELEM_SIZE * tmp1] + + ;; Check for len/dist match for second literal + test len2 %+ d, 0xFFFFFFFF + jnz lit_lit_huffman +len_dist_lit_huffman_pre: + ;; Calculate repeat length + tzcnt len2, len2 + shr len2, 3 + +len_dist_lit_huffman: + MOVQ curr_data, xdata + shr curr_data, 24 + compute_hash hash3, curr_data + + ;; Store updated hashes + mov [histogram + _hash_offset + 2 * hash], tmp3 %+ w + add tmp3,1 + mov [histogram + _hash_offset + 2 * hash2], tmp3 %+ w + add tmp3, 1 + + add f_i, len2 + + MOVDQU xdata, [file_start + f_i] + mov curr_data, [file_start + f_i] + mov tmp1, curr_data + compute_hash hash, curr_data + + and hash3, HASH_MASK + mov [histogram + _hash_offset + 2 * hash3], tmp3 %+ w + + dist_to_dist_code2 dist_code2, dist2 + + len_to_len_code len_code, len2, rfc_lookup + + shr tmp1, 8 + compute_hash hash2, tmp1 + + inc qword [histogram + _lit_len_offset + HIST_ELEM_SIZE * len_code] + inc qword [histogram + _dist_offset + HIST_ELEM_SIZE * dist_code2] + + and hash2 %+ d, HASH_MASK + and hash, HASH_MASK + + cmp f_i, file_length + jl loop2 + jmp end_loop_2 + ;; encode as dist/len + +len_dist_huffman_pre: + tzcnt len, len + shr len, 3 + +len_dist_huffman: + mov [histogram + _hash_offset + 2 * hash], tmp3 %+ w + add tmp3,1 + mov [histogram + _hash_offset + 2 * hash2], tmp3 %+ w + + dec f_i + add f_i, len + + MOVDQU xdata, [file_start + f_i] + mov curr_data, [file_start + f_i] + mov tmp1, curr_data + compute_hash hash, curr_data + + dist_to_dist_code2 dist_code, dist + + len_to_len_code len_code, len, rfc_lookup + + shr tmp1, 8 + compute_hash hash2, tmp1 + + inc qword [histogram + _lit_len_offset + HIST_ELEM_SIZE * len_code] + inc qword [histogram + _dist_offset + HIST_ELEM_SIZE * dist_code] + + and hash2 %+ d, HASH_MASK + and hash, HASH_MASK + + cmp f_i, file_length + jl loop2 + jmp end_loop_2 + +lit_lit_huffman: + MOVDQU xdata, [file_start + f_i + 1] + and curr_data, 0xff + add f_i, 1 + inc qword [histogram + _lit_len_offset + HIST_ELEM_SIZE * curr_data] + + cmp f_i, file_length + jl loop2 + +end_loop_2: + add file_length, LA_STATELESS - LAST_BYTES_COUNT + cmp f_i, file_length + jge final_bytes + +loop2_finish: + mov curr_data %+ d, dword [file_start + f_i] + compute_hash hash, curr_data + and hash %+ d, HASH_MASK + + ;; Calculate possible distance for length/dist pair. + xor dist, dist + mov dist %+ w, f_i %+ w + sub dist %+ w, word [histogram + _hash_offset + 2 * hash] + mov [histogram + _hash_offset + 2 * hash], f_i %+ w + + ;; Check if look back distance is valid (the dec is to handle when dist = 0) + dec dist + cmp dist %+ d, (D-1) + jae encode_literal_finish + inc dist + + ;; Check if look back distance is a match + lea tmp4, [file_length + LAST_BYTES_COUNT] + sub tmp4, f_i + lea tmp1, [file_start + f_i] + mov tmp2, tmp1 + sub tmp2, dist + compare tmp4, tmp1, tmp2, len, tmp3 + + ;; Limit len to maximum value of 258 + mov tmp2, 258 + cmp len, 258 + cmova len, tmp2 + cmp len, SHORTEST_MATCH + jb encode_literal_finish + + add f_i, len + + len_to_len_code len_code, len, rfc_lookup + dist_to_dist_code dist_code, dist + + inc qword [histogram + _lit_len_offset + HIST_ELEM_SIZE * len_code] + inc qword [histogram + _dist_offset + HIST_ELEM_SIZE * dist_code] + + cmp f_i, file_length + jl loop2_finish + jmp final_bytes + +encode_literal_finish: + ;; Encode literal + and curr_data %+ d, 0xFF + inc qword [histogram + _lit_len_offset + HIST_ELEM_SIZE * curr_data] + + ;; Setup for next loop + add f_i, 1 + cmp f_i, file_length + jl loop2_finish + +final_bytes: + add file_length, LAST_BYTES_COUNT +final_bytes_loop: + cmp f_i, file_length + jge end + movzx curr_data, byte [file_start + f_i] + inc qword [histogram + _lit_len_offset + HIST_ELEM_SIZE * curr_data] + inc f_i + jmp final_bytes_loop + +end: + ;; Handle eob at end of stream + mov tmp1, [rsp + _eob_count_offset] + mov qword [histogram + _lit_len_offset + HIST_ELEM_SIZE * 256], tmp1 + +exit_ret: + FUNC_RESTORE + ret + +compare_loop: + and hash %+ d, HASH_MASK + and hash2 %+ d, HASH_MASK + lea tmp2, [tmp1 + dist - 1] +%if (COMPARE_TYPE == 1) + compare250 tmp1, tmp2, len, tmp3 +%elif (COMPARE_TYPE == 2) + compare250_x tmp1, tmp2, len, tmp3, xtmp0, xtmp1 +%elif (COMPARE_TYPE == 3) + compare250_y tmp1, tmp2, len, tmp3, ytmp0, ytmp1 +%else + %error Unknown Compare type COMPARE_TYPE + % error +%endif + lea tmp3, [f_i + 1] + jmp len_dist_huffman + +compare_loop2: + add tmp1, 1 + lea tmp2, [tmp1 + dist2 - 1] + +%if (COMPARE_TYPE == 1) + compare250 tmp1, tmp2, len2, tmp3 +%elif (COMPARE_TYPE == 2) + compare250_x tmp1, tmp2, len2, tmp3, xtmp0, xtmp1 +%elif (COMPARE_TYPE == 3) + compare250_y tmp1, tmp2, len2, tmp3, ytmp0, ytmp1 +%else +%error Unknown Compare type COMPARE_TYPE + % error +%endif + and curr_data, 0xff + inc qword [histogram + _lit_len_offset + 8 * curr_data] + lea tmp3, [f_i + 1] + jmp len_dist_lit_huffman + +section .data + align 32 +D_vector: + dw -(D + 1) & 0xFFFF, -(D + 1) & 0xFFFF, -(D + 1) & 0xFFFF, -(D + 1) & 0xFFFF + dw -(D + 1) & 0xFFFF, -(D + 1) & 0xFFFF, -(D + 1) & 0xFFFF, -(D + 1) & 0xFFFF + dw -(D + 1) & 0xFFFF, -(D + 1) & 0xFFFF, -(D + 1) & 0xFFFF, -(D + 1) & 0xFFFF + dw -(D + 1) & 0xFFFF, -(D + 1) & 0xFFFF, -(D + 1) & 0xFFFF, -(D + 1) & 0xFFFF diff --git a/ceph/src/isa-l/igzip/igzip_update_histogram_01.asm b/ceph/src/isa-l/igzip/igzip_update_histogram_01.asm new file mode 100644 index 000000000..0705a0774 --- /dev/null +++ b/ceph/src/isa-l/igzip/igzip_update_histogram_01.asm @@ -0,0 +1,7 @@ +%define ARCH 01 + +%ifndef COMPARE_TYPE +%define COMPARE_TYPE 2 +%endif + +%include "igzip_update_histogram.asm" diff --git a/ceph/src/isa-l/igzip/igzip_update_histogram_04.asm b/ceph/src/isa-l/igzip/igzip_update_histogram_04.asm new file mode 100644 index 000000000..18945b2ac --- /dev/null +++ b/ceph/src/isa-l/igzip/igzip_update_histogram_04.asm @@ -0,0 +1,8 @@ +%define ARCH 04 +%define USE_HSWNI + +%ifndef COMPARE_TYPE +%define COMPARE_TYPE 3 +%endif + +%include "igzip_update_histogram.asm" diff --git a/ceph/src/isa-l/igzip/inflate_data_structs.asm b/ceph/src/isa-l/igzip/inflate_data_structs.asm new file mode 100644 index 000000000..3d4d24d4d --- /dev/null +++ b/ceph/src/isa-l/igzip/inflate_data_structs.asm @@ -0,0 +1,117 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2016 Intel Corporation All rights reserved. +; +; 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 Intel Corporation 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 +; 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. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; START_FIELDS +%macro START_FIELDS 0 +%assign _FIELD_OFFSET 0 +%assign _STRUCT_ALIGN 0 +%endm + +;; FIELD name size align +%macro FIELD 3 +%define %%name %1 +%define %%size %2 +%define %%align %3 + +%assign _FIELD_OFFSET (_FIELD_OFFSET + (%%align) - 1) & (~ ((%%align)-1)) +%%name equ _FIELD_OFFSET +%assign _FIELD_OFFSET _FIELD_OFFSET + (%%size) +%if (%%align > _STRUCT_ALIGN) +%assign _STRUCT_ALIGN %%align +%endif +%endm + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +START_FIELDS ;; inflate huff code + +;; name size align +FIELD _short_code_lookup_large, 2 * (1 << (ISAL_DECODE_LONG_BITS)), 2 +FIELD _long_code_lookup_large, 2 * MAX_LONG_CODE_LARGE, 2 + +%assign _inflate_huff_code_large_size _FIELD_OFFSET +%assign _inflate_huff_code_large_align _STRUCT_ALIGN + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +START_FIELDS ;; inflate huff code + +;; name size align +FIELD _short_code_lookup_small, 2 * (1 << (ISAL_DECODE_SHORT_BITS)), 2 +FIELD _long_code_lookup_small, 2 * MAX_LONG_CODE_SMALL, 2 + +%assign _inflate_huff_code_small_size _FIELD_OFFSET +%assign _inflate_huff_code_small_align _STRUCT_ALIGN +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +START_FIELDS ;; inflate state + +;; name size align +FIELD _next_out, 8, 8 +FIELD _avail_out, 4, 4 +FIELD _total_out, 4, 4 +FIELD _next_in, 8, 8 +FIELD _read_in, 8, 8 +FIELD _avail_in, 4, 4 +FIELD _read_in_length,4, 4 +FIELD _lit_huff_code, _inflate_huff_code_large_size, _inflate_huff_code_large_align +FIELD _dist_huff_code,_inflate_huff_code_small_size, _inflate_huff_code_small_align +FIELD _block_state, 4, 4 +FIELD _bfinal, 4, 4 +FIELD _crc_flag, 4, 4 +FIELD _crc, 4, 4 +FIELD _type0_block_len, 4, 4 +FIELD _copy_overflow_len, 4, 4 +FIELD _copy_overflow_dist, 4, 4 + +%assign _inflate_state_size _FIELD_OFFSET +%assign _inflate_state_align _STRUCT_ALIGN + +_lit_huff_code_short_code_lookup equ _lit_huff_code+_short_code_lookup_large +_lit_huff_code_long_code_lookup equ _lit_huff_code+_long_code_lookup_large + +_dist_huff_code_short_code_lookup equ _dist_huff_code+_short_code_lookup_small +_dist_huff_code_long_code_lookup equ _dist_huff_code+_long_code_lookup_small + +ISAL_BLOCK_NEW_HDR equ 0 +ISAL_BLOCK_HDR equ 1 +ISAL_BLOCK_TYPE0 equ 2 +ISAL_BLOCK_CODED equ 3 +ISAL_BLOCK_END equ 4 +ISAL_BLOCK_FINISH equ 5 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + diff --git a/ceph/src/isa-l/igzip/inflate_std_vects.h b/ceph/src/isa-l/igzip/inflate_std_vects.h new file mode 100644 index 000000000..4265c2cd2 --- /dev/null +++ b/ceph/src/isa-l/igzip/inflate_std_vects.h @@ -0,0 +1,1554 @@ +#include +#include "igzip_lib.h" + +uint8_t std_vect_0[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0xb6, 0x6d, 0x20, 0x34, + 0x20, 0x00, 0xc7, 0x7e, 0x06, 0xfb, 0xb1, 0x1f, + 0xcb, 0x7c, 0xec, 0xfb, 0xf1, 0xb2, 0x40, 0xe7, + 0xcb, 0x6a, 0xe8, 0x03, 0x00, 0x00, 0x19, 0xff, + 0xff, 0xbc, 0xec, 0xd9, 0xb6, 0xf3, 0xb2, 0xcd, + 0x4e, 0xcb, 0xb2, 0x2e, 0xc7, 0xb6, 0xad, 0xc7, + 0x7e, 0xbc, 0xbf, 0xee, 0xbc, 0xec, 0xfb, 0x7e, + 0xec, 0x64, 0x7a, 0xec, 0x2f, 0xcc, 0xeb, 0xc5, + 0x1f, 0xbb, 0xfe, 0x72, 0xbc, 0xec, 0xb2, 0x1f +}; + +uint8_t std_vect_1[] = { + 0xed, 0xfd, 0xdb, 0xbc, 0x2d, 0xf3, 0x34, 0x8d, + 0x31, 0xa6, 0x31, 0x7a, 0xf4, 0x18, 0xd3, 0x34, + 0x6d, 0x40, 0x85, 0x42, 0x6d, 0xc7, 0xb6, 0x6d, + 0xd7, 0x34, 0x3d, 0xef, 0xc7, 0x7e, 0xff, 0xff +}; + +uint8_t std_vect_2[] = { + 0xed, 0x83, 0x63, 0x61, 0xeb, 0xbb, 0xff, 0x82, + 0x66, 0xe0, 0xc5, 0xc2, 0xee, 0xc9, 0x8f, 0xf5, + 0xc7, 0xeb, 0x7a, 0x7c, 0xfb, 0x76, 0xec, 0xc7 +}; + +uint8_t std_vect_3[] = { + 0xed, 0xfb, 0xb1, 0x1f, 0x33, 0xee, 0xfb, 0xb1, + 0xbf, 0x1e, 0xc7, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0xa7, 0xec, 0xb2, 0xce, 0xeb, + 0x7a, 0x6c, 0xfb, 0x02, 0xec, 0xc7, 0x88, 0x6c, + 0xcb, 0xb6, 0x6c, 0xc7, 0xb1, 0x6e, 0xeb, 0xb6, + 0x6e, 0xdb, 0x00, 0x7f, 0xfb, 0xb6, 0x6e, 0xdb, + 0x3f, 0x01 +}; + +uint8_t std_vect_4[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0xb6, 0x6d, 0x37, 0xac, + 0x4b, 0x88, 0x4a, 0x2f, 0xb0, 0xa9, 0x10, 0xfc, + 0x31, 0xc8, 0x42, 0xc4, 0x36, 0x50, 0x7b, 0xb2, + 0x5f, 0x37, 0x09, 0x17, 0x65, 0x6b, 0x46, 0xa2, + 0xdb, 0x35, 0xd7, 0x8e, 0x59, 0xd7, 0x34, 0x3d, + 0xef, 0xc7, 0x7e, 0x1c, 0x26, 0xab, 0x48, 0x48, + 0x7c, 0xec, 0xfb, 0xf1, 0xb2, 0x1f, 0xfb, 0xcb, + 0x71, 0xec, 0xc7, 0xbe, 0x1f, 0xc7, 0xb4, 0xce, + 0xfb, 0xb1, 0x6f, 0xcb, 0xbc, 0xec, 0xeb, 0x9f +}; + +uint8_t std_vect_5[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0xb6, 0x6d, 0xd7, 0x4d, + 0x3d, 0xef, 0xc7, 0x8e, 0x35, 0x35, 0x35, 0x35, + 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, + 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, + 0x35, 0x35, 0x35, 0x4c, 0xe5, 0x41, 0x75, 0xab, + 0x69, 0xab, 0x0c, 0xaa, 0x55, 0xec, 0xd8, 0x7e +}; + +uint8_t std_vect_6[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0xfa, 0x00, 0x00, 0xfa, + 0x3d, 0xef, 0xc7, 0x7e, 0x1c, 0xfb, 0xb1, 0x1f, + 0xcb, 0x7c, 0xec, 0xfb, 0xf1, 0xb2, 0x1f, 0x00, + 0x40, 0x71, 0xec, 0x64, 0x25, 0x49, 0x1a, 0x27, + 0x2f, 0x50, 0xcc, 0x76, 0x8e, 0xbc, 0xec, 0xeb, + 0xb2, 0xce, 0xeb, 0x7a, 0x6c, 0xfb, 0x76, 0xec, + 0xc7, 0x71, 0x6c, 0xcb, 0xb6, 0x6c, 0xc7, 0xeb, + 0xb2, 0xce, 0xeb, 0x7a, 0x83, 0xfb, 0x76, 0xec, + 0xb1, 0xaf, 0xf3, 0x3c, 0x2d, 0xcb, 0x32, 0x6f, + 0xdb, 0xbc, 0xcc, 0xf3, 0xb2, 0xcd, 0x2f, 0xcb, + 0xb2, 0x2e, 0xc7, 0xb6, 0xad, 0xc7, 0x7e, 0xbc, + 0xbf, 0xee, 0xfb, 0xb1, 0x8f, 0xc2, 0x3f, 0x01 +}; + +uint8_t std_vect_7[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0xb6, 0x6d, 0xd7, 0xec, + 0xfb, 0xf1, 0xb2, 0x1f, 0x58, 0xf7, 0xc2, 0xb8, + 0x1c, 0xce, 0xcc, 0xcf, 0x44, 0x04, 0x54, 0x29, + 0x34, 0x17, 0xcb, 0xac, 0x36, 0x50, 0x7b, 0xb2, + 0xd8, 0x79, 0xf1, 0x9b, 0xd2, 0x3a, 0xdb, 0x5a, + 0x33, 0xb3, 0x50, 0xca +}; + +uint8_t std_vect_8[] = { + 0xed, 0xfd, 0x1c, 0xfb, 0xaa, 0x12, 0xcb, 0x7c, + 0xec, 0xfb, 0xf1, 0xb2, 0x6e, 0xeb, 0x7f, 0xca, + 0xca, 0xac, 0xca, 0x96, 0x96, 0x96, 0x96, 0xca, + 0xca, 0xca, 0xca, 0xca, 0xb6, 0xed, 0xcb, 0x31, + 0x36, 0x98, 0x79, 0xa6, 0x48, 0xc6, 0x82, 0x8b +}; + +uint8_t std_vect_9[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0xb6, 0x6d, 0xc3, 0xc3, + 0xbb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, + 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0x7f, 0xc3, 0xc3 +}; + +uint8_t std_vect_10[] = { + 0xed, 0xfd, 0x6d, 0xed, 0xaa, 0x9e, 0x1d, 0x01, + 0x4b, 0x86, 0x10, 0x00, 0xfa, 0xf0, 0xf0, 0xf0, + 0xf0, 0xf0, 0xf0, 0xf0, 0xd0, 0xf0, 0xf0, 0x6f +}; + +uint8_t std_vect_11[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0xb6, 0x1e, 0x1e, 0x1e, + 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x6d, 0xbb, 0x34, + 0xec, 0xeb, 0x2f, 0xb0, 0xa9, 0x11, 0x0c, 0x31, + 0xc8, 0xda, 0xda, 0xda, 0xda, 0xda, 0xda, 0xe5, + 0xda, 0xda, 0xda, 0xda, 0xda, 0xda, 0xda, 0xda, + 0xda, 0xda, 0xcc, 0xfb, 0x71, 0x1c, 0xfb, 0x71, + 0xec, 0xfb, 0xf1, 0xbe, 0x1f, 0xc7, 0xbe, 0x1f, + 0xc7, 0xb1, 0xbf, 0x1d, 0x72, 0xfb, 0x7e, 0xbc, + 0xed, 0xaf, 0xc7, 0xb1, 0x05, 0xff, 0xff, 0x05, + 0xfb, 0x31, 0xc6, 0x34, 0xcd, 0xf3, 0x32, 0xbf, + 0x2c, 0xf3, 0xba, 0x6e, 0xeb, 0x7a, 0x6c, 0xc7 +}; + +uint8_t std_vect_12[] = { + 0xed, 0xfd, 0x55, 0xc7, 0xb6, 0x6d, 0xd7, 0x34, + 0x3d, 0xef, 0xc7, 0x7e, 0x1c, 0xfb, 0xb1, 0x1f, + 0xcb, 0x7c, 0xec, 0xfb, 0xf1, 0xb2, 0x1f, 0xfb, + 0xcb, 0x71, 0xec, 0xc7, 0xbe, 0x1f, 0xc7, 0xb4, + 0xce, 0xfb, 0xb1, 0x6f, 0xcb, 0xbc, 0xec, 0xeb, + 0xb2, 0xce, 0xeb, 0x7a, 0x6c, 0xfb, 0x76, 0xec, + 0xc7, 0x71, 0x6c, 0xcb, 0xb6, 0x6c, 0xc7, 0xb1, + 0x6e, 0xeb, 0xb6, 0x6e, 0xdb, 0xba, 0x1d, 0xfb, + 0xb6, 0x6e, 0xdb, 0xb6, 0xaf, 0xeb, 0xb2, 0x6d, + 0xc7, 0x7a, 0xec, 0xdb, 0xb6, 0xed, 0xcb, 0x31, + 0xcd, 0x2f, 0xcb, 0xb2 +}; + +uint8_t std_vect_13[] = { + 0xed, 0xfd, 0x6d, 0x14, 0x81, 0x00, 0x00, 0x34, + 0x52, 0xef, 0xc7, 0x4e, 0x00, 0xfb, 0xb1, 0x1f, + 0xcb, 0x7c, 0xec, 0xf6, 0xf1, 0xb2, 0x1f, 0xfb, + 0xc7, 0xbe, 0x1f, 0xc7, 0xb4, 0xce, 0xfb, 0xb1, + 0x6f, 0xcb, 0xbc, 0xec, 0xeb, 0x1e, 0x0c, 0x31, + 0xc8, 0x42, 0xc4, 0x36, 0x50, 0x40, 0x34, 0x8d, + 0xaf, 0x85, 0x42, 0x81, 0xf4, 0x1d, 0xd1, 0x80, + 0xe8, 0x03, 0x00, 0x00, 0x26, 0xab, 0x75, 0xfe, + 0xb6, 0xbd, 0xeb, 0xb2, 0x6d, 0xc7, 0x7a, 0xec, + 0x82, 0x66, 0xf3, 0xc5 +}; + +uint8_t std_vect_14[] = { + 0xed, 0xf8, 0x6d, 0xc7, 0x00, 0x3c, 0x2d, 0xcb, + 0x32, 0x6f, 0xdb, 0xbc, 0xb6, 0x6d, 0xd7, 0x34, + 0x3d, 0xef, 0xc7, 0x7e, 0x1c, 0xfb, 0xb1, 0x1f, + 0xcb, 0x7c, 0xec, 0xfb, 0xf1, 0xb2, 0x1f, 0xfb, + 0xcb, 0x71, 0xec, 0x80, 0xbe, 0x1f, 0xc7, 0xb4, + 0xce, 0xfb, 0xb1, 0x6f, 0xcb, 0xbc, 0xec, 0xeb +}; + +uint8_t std_vect_15[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0xa9, 0x6d, 0xd7, 0x34, + 0x3d, 0xef, 0xc7, 0x7e, 0x1c, 0xfb, 0xb1, 0x1f, + 0xcb, 0x7c, 0xec, 0xfb, 0xf1, 0xb2, 0x1f, 0xfb, + 0xcb, 0x71, 0xec, 0xc7, 0xbe, 0x1f, 0xc7, 0xb4 +}; + +uint8_t std_vect_16[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0xb6, 0x70, 0xd7, 0x0d, + 0x3d, 0x99, 0xc7, 0x7e, 0x1c, 0x20, 0x00, 0x1f, + 0xcb, 0x71, 0xec, 0xc7, 0xbe, 0x1f, 0xc7, 0xc2 +}; + +uint8_t std_vect_17[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0xb4, 0x6d, 0xd7, 0x34, + 0x3d, 0xef, 0xc7, 0xef, 0xef, 0xef, 0xef, 0xef, + 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0xef, 0xef, 0xef, 0xef, + 0xef, 0xb6, 0x6e, 0xdb, 0xb6, 0xaf, 0xeb, 0xb2, + 0x6d, 0xc7, 0x7a, 0xec, 0xdb, 0xb6, 0xed, 0x10, + 0x31, 0xaf, 0xf3, 0x3c, 0x2d, 0x01, 0x32, 0x6f, + 0xdb, 0xbc, 0xcc, 0xf3, 0xb2, 0xcd, 0x2f, 0xcb, + 0xb2, 0x2e, 0xc7, 0xb6, 0xad, 0xc7, 0x7e, 0xbc, + 0xbf, 0xee, 0xfb, 0xb1, 0xbf, 0x1e, 0xc7, 0xb1, + 0x1f, 0xc7, 0xfe, 0x72, 0xbc, 0xec, 0xfb, 0x7e, + 0xec, 0xfb, 0x71, 0xec, 0x2f, 0xc7, 0xeb, 0xbe, + 0xe0, 0xc5, 0xc2, 0xee, 0x09, 0xc9, 0x8f, 0xf5 +}; + +uint8_t std_vect_18[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0xb6, 0x75, 0xab, 0x69, + 0xb5, 0x0c, 0xaa, 0x55, 0x29, 0x79, 0x81, 0xe2, + 0xab, 0x27, 0x07, 0x23, 0xf2, 0x1f, 0xfb, 0xeb, + 0x7a, 0x6c, 0xfb, 0x76, 0xec, 0xc7, 0x71, 0xb1, + 0x6e, 0xeb, 0xb6, 0xcb, 0x4c, 0xec, 0xc7, 0xbe, + 0x1f, 0xc7, 0xb4, 0xce, 0xfb, 0xb1, 0x6f, 0xcb, + 0xbc, 0xec, 0xeb, 0xb2, 0xce, 0xeb, 0x7a, 0x87, + 0xfb, 0x76, 0xec, 0xc7, 0x71, 0xb1, 0x6e, 0xeb, + 0xb6, 0x6e, 0xdb, 0xba, 0x1d, 0xfb, 0xb6, 0x6e, + 0xdb, 0xb6, 0xaf, 0xeb, 0xca, 0x6d, 0xc7, 0x7a, + 0x6f, 0xdb, 0xbc, 0xcc +}; + +uint8_t std_vect_19[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0xfe, 0x65, 0x65, 0x65, + 0x65, 0x65, 0x72, 0xbc, 0xec, 0x1f, 0xc7, 0xae, + 0x1f, 0x00, 0x00, 0x00, 0x20, 0x71, 0xec, 0xfb, + 0xd0, 0xd2, 0x1f, 0xc7, 0xbe, 0x1f, 0xc7, 0xb1, + 0xbf, 0x1d, 0x6f, 0xfb, 0x7e, 0xbc, 0xed, 0x80, + 0xc7, 0xb1, 0xef, 0xc7, 0xb1, 0x32, 0xf0, 0x11, + 0x52, 0xc6, 0x34, 0xcd, 0xf3, 0x32, 0xbf, 0x2c, + 0x00, 0x01, 0x6e, 0xeb, 0x7a, 0x6c, 0xc7, 0xb1, + 0x6f, 0xe4, 0x7e, 0x1c, 0xfb, 0x00, 0x01, 0x00, + 0xfa, 0x2d, 0xfb, 0x5f, 0x7c, 0xf6, 0x47, 0xde +}; + +uint8_t std_vect_20[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0xb6, 0x6d, 0x09, 0x64, + 0x3d, 0xef, 0xc7, 0x7e, 0x1c, 0xfb, 0xb1, 0x1f, + 0xf1, 0xb2, 0x1f, 0xfb, 0xcb, 0x71, 0xec, 0xc7, + 0xbe, 0x1f, 0xc7, 0xb4, 0xce, 0xfb, 0xb1, 0x6f, + 0xcb, 0xbc, 0xec, 0xeb, 0xb2, 0xce, 0x7a, 0x6c, + 0x7b, 0x76, 0xec, 0xc7, 0x71, 0x6c, 0xcb, 0xb6, + 0x6c, 0xc7, 0xb1, 0x6e, 0xeb, 0xb6, 0x6e, 0xdb, + 0xba, 0x1d, 0xfb, 0xb6 +}; + +uint8_t std_vect_21[] = { + 0xed, 0x0b, 0x84, 0x64, 0x25, 0x49, 0x1a, 0x27, + 0x2d, 0x2d, 0x0a, 0xa8, 0x11, 0x0c, 0x27, 0xc8 +}; + +uint8_t std_vect_22[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0xb6, 0x6d, 0x00, 0x00, + 0x80, 0x00, 0xc7, 0x7e, 0x1c, 0xfb, 0xb1, 0x1f, + 0xcb, 0x7c, 0xec, 0xfb, 0xf1, 0xb2, 0x1f, 0xfb, + 0xcb, 0x71, 0xec, 0xc7, 0xbe, 0x1f, 0xc7, 0xb4, + 0xce, 0xfb, 0xb1, 0x6f, 0xcb, 0xbc, 0xf9, 0xeb, + 0xb2, 0xce, 0xeb, 0xc7, 0x71, 0x6c, 0xcb, 0xb6, + 0x6c, 0xc7, 0xb1, 0x6e, 0xeb, 0xb6, 0x6e, 0xdb, + 0x98, 0x79, 0xa6, 0x48, 0xab, 0x8e, 0x8f, 0xc2, + 0x3f, 0x01 +}; + +uint8_t std_vect_23[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0xb6, 0x6e, 0xd7, 0x50, + 0x3d, 0xef, 0xc7, 0x7e, 0x1c, 0xfb, 0xb1, 0x1f, + 0xcb, 0x7c, 0xec, 0xfb, 0x20, 0xb2, 0x1f, 0xfb, + 0xcb, 0xc7, 0xbe, 0x1f, 0xc7, 0x9f, 0xce, 0xfb, + 0xb1, 0x6f, 0xcb, 0xbc, 0xec, 0xeb, 0xca, 0xce, + 0xeb, 0x7a, 0x6c, 0xfb, 0x76, 0xec, 0xc7, 0x5b, + 0x00, 0x1e, 0x00, 0x00, 0xe2, 0xb1, 0x6e, 0xeb, + 0xb6, 0x6e, 0xf3, 0xba, 0x1d, 0xfb, 0xa6, 0x6e, + 0x40, 0x00, 0xaf, 0xeb, 0xb2, 0x6d, 0xc7, 0x7a, + 0xec, 0xdb, 0xb6, 0x00, 0xfa, 0x00, 0x00, 0xfa, + 0x00, 0x22, 0xff, 0x32, 0x6f, 0xdb, 0x00, 0x00, + 0x03, 0xe8, 0xcd, 0x2f, 0xf1, 0xb2, 0x0f, 0xfb, + 0xcb, 0x71, 0xec, 0xc7, 0xbe, 0x0e, 0xc7, 0xb4, + 0xce, 0xfb, 0xb1, 0x6f, 0x00, 0x00, 0x03, 0xe8, + 0xb2, 0xce, 0xeb, 0x94, 0xab, 0x82, 0x8f, 0xc2 +}; + +uint8_t std_vect_24[] = { + 0xed, 0x44, 0x04, 0x54, 0x29, 0xff, 0xff, 0xff, + 0x80, 0xc7, 0x60, 0x30, 0xeb, 0xbb, 0xff, 0x82, + 0x5b, 0xe0, 0xc5, 0xff, 0xee, 0xfd, 0x80, 0xc7, + 0xff, 0xff, 0xd7, 0x34, 0x3d, 0x00, 0x00, 0x00, + 0x40, 0xf1, 0xb2, 0x0b, 0xfb, 0xcb, 0x71, 0xec, + 0xc7, 0xbe, 0x1f, 0xc7, 0xb4, 0xce, 0xfb, 0xb1, + 0x2f, 0xc7, 0x79, 0xa6, 0x48, 0xab, 0x82, 0x8f, + 0xc2, 0x3f, 0x01 +}; + +uint8_t std_vect_25[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0x1f, 0x21, 0x00, 0x10, + 0x21, 0x0d, 0x21, 0x14, 0x21, 0x35, 0x16, 0xec, + 0xc7, 0x7d, 0x1f, 0xc7, 0x35, 0xce, 0xfb, 0xb1, + 0x6f, 0x7f, 0xbc, 0xec, 0x17, 0x64, 0xbd, 0xeb, + 0x7a, 0x6c, 0xfb, 0x76, 0xec, 0x70, 0x8e, 0x37, + 0xb9, 0x25, 0x9a, 0x0e, 0x65, 0x32, 0x9c, 0xe5, + 0x41, 0x75, 0xab, 0x69, 0x98, 0x0c, 0xc7, 0x71, + 0x6c, 0xcb, 0xb6, 0x6c, 0xc7, 0xb1, 0x6e, 0xf6, + 0x36, 0xe0, 0x27, 0xa9, 0xa6, 0x48, 0xab, 0x82 +}; + +uint8_t std_vect_26[] = { + 0x1c, 0xfb, 0x91, 0xfb, 0xf1, 0xbe, 0x1f, 0xdd, + 0xbe, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, + 0xa7, 0xb9, 0x8f, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7 +}; + +uint8_t std_vect_27[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0xb6, 0xff, 0x00, 0x34, + 0x3d, 0xef, 0xc7, 0x7e, 0x1c, 0xfb, 0xb1, 0x1f, + 0xcb, 0x7c, 0xec, 0xfb, 0xf1, 0xb2, 0x1f, 0xfb, + 0xcb, 0x71, 0xec, 0xc7, 0xbe, 0x1f, 0xc7, 0xb4, + 0xce, 0xfb, 0xb1, 0x6f, 0xcb, 0xbc, 0xec, 0xeb, + 0xb2, 0xce, 0xeb, 0x7a, 0x6c, 0xfb, 0x76, 0xec, + 0xc7, 0x71, 0x6c, 0xcb, 0xb6, 0x6c, 0xc7, 0xb1, + 0x6e, 0xeb, 0xb6, 0x6e, 0xdb, 0xba, 0x1d, 0xfb, + 0xb6, 0x6e, 0xdb, 0xb6, 0xcd, 0x2f, 0xcb, 0xb2 +}; + +uint8_t std_vect_28[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0xb6, 0x6d, 0xd7, 0x34, + 0x3d, 0x00, 0x01, 0x00, 0x00, 0xed, 0xcb, 0x1f, + 0xcb, 0x7c, 0xec, 0xfb, 0xf1, 0xb2, 0x1f, 0xfb, + 0xcb, 0x71, 0xec, 0xc7, 0xbe, 0x3e, 0xc7, 0xb4, + 0xce, 0xfb, 0xb1, 0x6f, 0xcb, 0xd1, 0xec, 0xeb, + 0xb2, 0xdb, 0xeb, 0x7a, 0x6c, 0xfb, 0x76, 0xec, + 0xc7, 0x71, 0x6c, 0xcb, 0xb6, 0x6c, 0xc7, 0x92, + 0x85, 0xeb, 0xa6, 0x6e, 0xdb, 0xba, 0x3c, 0xfb, + 0x3f, 0x01 +}; + +uint8_t std_vect_29[] = { + 0xed, 0xfd, 0x6d, 0x00, 0x00, 0xff, 0x34, 0x3d, + 0xef, 0xc7, 0x94, 0x1c, 0xfb, 0xb1, 0x1f, 0xcb, + 0x7c, 0xec, 0xfb, 0xf1, 0xb2, 0x1f, 0xfb, 0xcb, + 0x71, 0xec, 0xc7, 0xbe, 0x1f, 0xc7, 0xb4, 0xce, + 0xfb, 0xb1, 0x6f, 0xcb, 0xbc, 0xec, 0xeb, 0xb2, + 0xce, 0xeb, 0x7a, 0x6c, 0xfb, 0x76, 0xec, 0xc7, + 0x71, 0x6c, 0xcb, 0xb6, 0x6c, 0xc7, 0xb1, 0x6e, + 0xeb, 0xb6, 0x6e, 0xdb, 0xba, 0x1d, 0xfb, 0x58, + 0xb5, 0x0c, 0xaa, 0x55, 0x29, 0x79, 0x81, 0xe2 +}; + +uint8_t std_vect_30[] = { + 0xed, 0xfd, 0x00, 0x00, 0x7f, 0xff, 0xd7, 0x34, + 0x3d, 0xef, 0xc7, 0x7e, 0x1c, 0xfb, 0xb1, 0x1f +}; + +uint8_t std_vect_31[] = { + 0x0c, 0x8b, 0x8b, 0xc7, 0xb6, 0x65, 0x20, 0x40, + 0x80, 0x00, 0x00, 0x00, 0x1c, 0xfb, 0xb1, 0x1f, + 0xcb, 0x7c, 0xec, 0xfb, 0xf1, 0xb2, 0x1e, 0x00, + 0x12, 0x10, 0x00, 0xc7, 0xbe, 0x00, 0x01, 0xb4, + 0xce, 0xfb, 0xb1, 0x7f, 0xcb, 0xcb, 0x31, 0xff, + 0xff, 0xff, 0x80, 0xcb, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x09, 0x3d, 0x01, 0x89, + 0x7c, 0x7c, 0x7c, 0x7c, 0x43, 0xbb, 0xca, 0xcd, + 0xfa, 0x84, 0x89, 0x89 +}; + +uint8_t std_vect_32[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0xb6, 0x6d, 0xd7, 0x34, + 0x3d, 0xef, 0xc7, 0x7d, 0x1c, 0x00, 0xb1, 0xff, + 0xcb, 0x7c, 0xec, 0xfb, 0xf1, 0xb2, 0x1f, 0x62, + 0xcb, 0x1f, 0xc7, 0xb4, 0xd7, 0xfb, 0xb1, 0x6f, + 0xcb, 0x2c, 0xf3, 0xba, 0x6e, 0xeb, 0x00, 0x04, + 0x00, 0x00, 0x6f, 0xc7, 0x7e, 0x1c, 0xfb, 0xb6, + 0xc2, 0xb8, 0x1c, 0x00, 0x00, 0x04, 0x00, 0xec +}; + +uint8_t std_vect_33[] = { + 0xed, 0xfd, 0xb0, 0xa9, 0x11, 0x0c, 0x31, 0xc8, + 0x42, 0xc4, 0x36, 0x50, 0x1c, 0xfb, 0xb1, 0x1f, + 0xcb, 0x7c, 0xec, 0xfb, 0x6c, 0xcb, 0xb6, 0x6c, + 0xc7, 0xb1, 0x6e, 0xeb +}; + +uint8_t std_vect_34[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0xb6, 0x6d, 0xd7, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0xab, 0x82, 0x8f, 0xc2 +}; + +uint8_t std_vect_35[] = { + 0xed, 0xfd, 0x01, 0x87, 0xb6, 0x6d, 0xd7, 0x34, + 0x3d, 0xef, 0xc7, 0x91, 0xcb, 0x7c, 0xec, 0xfb, + 0x80, 0x00, 0x00, 0x00, 0xcb, 0x71, 0xec, 0xc7, + 0xbe, 0x1f, 0xc7, 0xb4, 0x34, 0x09, 0x17, 0x61, + 0x6b, 0x06, 0x8e, 0x59, 0xdd, 0x45, 0xff, 0xff, + 0x00, 0x00, 0xaa, 0x50, 0x92, 0x31, 0xaf, 0xff, + 0xf3, 0xb2, 0xcd, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, + 0xd8, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, + 0xd0, 0xd0, 0xd0, 0xd0, 0xfb, 0x71, 0xec, 0xfb, + 0xf1, 0xbe, 0x1f, 0xad, 0xdb, 0x99, 0x2c, 0xf3, + 0x34, 0x8d, 0x00, 0x01 +}; + +uint8_t std_vect_36[] = { + 0xed, 0xfd, 0x19, 0xc7, 0xb6, 0x6d, 0xd7, 0x34, + 0x3d, 0xce, 0xfb, 0xff, 0xff, 0xff, 0x7f, 0x9c, + 0xb2, 0xce, 0xeb, 0x7a, 0x6c, 0x91, 0x91, 0x91, + 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, + 0x91, 0x91, 0x91, 0x91, 0xdb, 0xba, 0x3b, 0x3b, + 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, + 0x3b, 0x3b, 0x3b, 0x3b, 0xff, 0x80, 0x3b, 0x3b +}; + +uint8_t std_vect_37[] = { + 0xed, 0xfd, 0xb3, 0x50, 0xca, 0x94, 0x6d, 0xc7, + 0xb6, 0x6d, 0xd7, 0x34, 0x3d, 0xef, 0xc7, 0x7e, + 0x1c, 0xfb, 0xb1, 0x1f, 0xcb, 0x7c, 0xec, 0xfb, + 0xf1, 0xb2, 0x1f, 0xfb, 0xcb, 0x71, 0xec, 0xc7, + 0xbe, 0x1f, 0xc7, 0xb4, 0xce, 0xfb, 0xb1, 0x6f, + 0xcb, 0xbc, 0xec, 0xeb, 0xb2, 0xce, 0xeb, 0x7a, + 0x6c, 0xfb, 0x76, 0xec, 0xc7, 0x71, 0x6c, 0xcb, + 0xb6, 0x6c, 0xc7, 0xb1, 0x6e, 0xeb, 0xb6, 0x6e, + 0xdb, 0xba, 0x1d, 0xfb, 0xb6, 0x6e, 0xdb, 0xb6, + 0xaf, 0xeb, 0xb2, 0x6d, 0xc7, 0x7a, 0xec, 0xdb, + 0xb6, 0xed, 0xcb, 0x31, 0xcb, 0x32, 0x6f, 0xdb, + 0xbc, 0xcc, 0xf3, 0xb2 +}; + +uint8_t std_vect_38[] = { + 0xed, 0xfd, 0x4d, 0xc7, 0xb6, 0x70, 0xd7, 0x34, + 0x3d, 0xef, 0xd6, 0x7f, 0xff, 0xff, 0xff, 0x10, + 0x00, 0x00, 0x64, 0x7e, 0x6c, 0xef, 0xfb, 0x31, + 0xc6, 0x34, 0x08, 0x08, 0x08, 0x08, 0x20, 0x08, + 0x08, 0x01, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xc7, 0x7e, + 0x7c, 0x00, 0x64, 0x00, 0x00, 0xbf, 0x1e, 0xb6, + 0xc2, 0x3f, 0x06 +}; + +uint8_t std_vect_39[] = { + 0xed, 0xfd, 0x8c, 0x8c, 0x97, 0x8c, 0x8c, 0x8c, + 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, + 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0xb4 +}; + +uint8_t std_vect_40[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0xb6, 0x6d, 0xd7, 0x7c, + 0x99, 0x17, 0x34, 0x3d, 0xef, 0xc7, 0x7e, 0x1c, + 0xfb, 0xb1, 0x1f, 0xcb, 0x7c, 0xec, 0xfb, 0xf1, + 0xb2, 0x1f, 0xfb, 0xcb, 0x71, 0xec, 0xc7, 0xbe, + 0x1f, 0xc7, 0xb4, 0xce, 0xfb, 0xb1, 0x6f, 0xcb, + 0xbc, 0xec, 0xeb, 0xb2, 0xce, 0xeb, 0x7a, 0x6c, + 0xfb, 0x76, 0xec, 0xc7, 0x71, 0x6c, 0xcb, 0xb6 +}; + +uint8_t std_vect_41[] = { + 0xed, 0xfd, 0x6d, 0xff, 0xff, 0x80, 0x00, 0x34, + 0x3d, 0xef, 0xc7, 0x7e, 0x1c, 0xfb, 0xb1, 0x1f, + 0xcb, 0x7c, 0xec, 0xfb, 0xf1, 0xb2, 0x1f, 0xfb, + 0xcb, 0x71, 0xec, 0xc7, 0xbe, 0x1f, 0xc7, 0xb4, + 0xce, 0xfb, 0xb1, 0x6f, 0xcb, 0xbc, 0xec, 0xeb, + 0x6c, 0xfb, 0x76, 0xec +}; + +uint8_t std_vect_42[] = { + 0xed, 0xfd, 0x19, 0xc7, 0xb6, 0x6d, 0xd7, 0x34, + 0x3d, 0xef, 0xc7, 0x7e, 0x56, 0x56, 0x56, 0x56, + 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, + 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, + 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x7a, + 0x6c, 0xfb, 0x76, 0xec +}; + +uint8_t std_vect_43[] = { + 0x7c, 0x99, 0x17, 0xed, 0xfd, 0x6d, 0x12, 0x12, + 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, + 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0xb0, 0xa9, + 0x11, 0x0c, 0x31, 0xc8, 0x42, 0xc4, 0x36, 0x50 +}; + +uint8_t std_vect_44[] = { + 0xed, 0xfd, 0xb1, 0xcb, 0xb6, 0x6c, 0xc7, 0xb1, + 0x6e, 0xeb, 0xb6, 0x6e, 0xdb, 0xba, 0x1d, 0xe9, + 0xb6, 0x6e, 0xdb, 0xb4, 0x64, 0x00, 0xb2, 0xb2, + 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, + 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0x6d, + 0xc7, 0x7a, 0xec, 0xdb, 0xe3, 0x6d, 0xd3, 0x31, + 0xaf, 0xf3, 0x3c, 0x2d, 0xbc, 0xcc, 0xf3, 0xb2, + 0xec, 0x2f, 0xcb, 0xb2 +}; + +uint8_t std_vect_45[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0xb6, 0x6d, 0xd7, 0x34, + 0x3d, 0xef, 0xff, 0x7f, 0x1c, 0xfb, 0xb1, 0x1f, + 0xcb, 0x7c, 0x2d, 0x25, 0xd2, 0xf8, 0x0b, 0xf9, + 0x4b, 0x4e, 0x20, 0x8d, 0x10, 0x9c, 0x93, 0x6b, + 0xac, 0x7a, 0xc3, 0xf2, 0x4c, 0x8d, 0xbc, 0xc0, + 0x79, 0x30, 0x17, 0x4a, 0x3a, 0x2f, 0xcc, 0xe1, + 0xbc, 0xec, 0xfb, 0xf1, 0xb2, 0x1f, 0xfb, 0xcb, + 0x71, 0xec, 0xc7, 0xbe, 0x1f, 0xc7, 0xb4, 0xce, + 0x3f, 0x01 +}; + +uint8_t std_vect_46[] = { + 0xed, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, + 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, + 0xcb, 0x71, 0xec, 0xc7, 0xbe, 0x1f, 0xc7, 0xb4 +}; + +uint8_t std_vect_47[] = { + 0xed, 0xfd, 0x1c, 0xfb, 0x71, 0xec, 0xfb, 0xf1, + 0xbe, 0x1f, 0xc7, 0xbe, 0x1f, 0xc7, 0xb1, 0xbf, + 0x1d, 0x6f, 0xfb, 0x7e, 0xbc, 0xed, 0xaf, 0xc7, + 0xb1, 0xef, 0xec, 0xc7, 0xbe, 0x1f, 0xc7, 0xb4, + 0xce, 0xfb, 0xb1, 0x6f, 0xcb, 0xbc, 0xec, 0xeb, + 0xb2, 0xce, 0xeb, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d +}; + +uint8_t std_vect_48[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0xb6, 0x6d, 0xd7, 0x34, + 0x3d, 0xff, 0x80, 0x1f, 0xfb, 0xcb, 0x71, 0xec, + 0xbe, 0xbe, 0x1f, 0xc7, 0x7a, 0xec, 0xdb, 0x9b, + 0x48, 0xab, 0x2d, 0xb5, 0x6f, 0xb3, 0x63, 0x59, + 0x99, 0x59, 0xcb, 0x71, 0xec, 0xbe, 0xbe, 0x1f, + 0xc7, 0x7a, 0xec, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd +}; + +uint8_t std_vect_49[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0xb6, 0x1f, 0xbb, 0xbb, + 0xbb, 0xbb, 0xb9, 0xa9, 0xbb, 0xbb, 0xe3, 0x6d, + 0xd3, 0xbb, 0xe3, 0x6d, 0x01, 0xbb, 0xbb, 0xbb, + 0xbb, 0xaf, 0xf3, 0x3c, 0xb4, 0xc7, 0xb4, 0xb4 +}; + +uint8_t std_vect_50[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0xb6, 0xff, 0x22, 0x80, + 0x00, 0xec, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, + 0x0d, 0x1d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, + 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d +}; + +uint8_t std_vect_51[] = { + 0x7a, 0x7a, 0x7a, 0x7a, 0x71, 0xec, 0xc7, 0xbe, + 0x00, 0x00, 0x1d, 0xfb, 0xb6, 0x6e, 0xdb, 0xb6, + 0xaf, 0xeb, 0xb2, 0x6d, 0xec, 0x00, 0x02, 0xbe +}; + +uint8_t std_vect_52[] = { + 0xed, 0xf2, 0xe8, 0xe8, 0xe8, 0xe8, 0xf6, 0xe8, + 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xcd, + 0x9b, 0xd2, 0x3a, 0xdb, 0x5a, 0x33, 0xb3, 0x50 +}; + +uint8_t std_vect_53[] = { + 0xed, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, + 0xa0, 0xa0, 0xa0, 0x1d, 0xd1, 0x47, 0x46, 0x2d, + 0xec, 0xc7, 0x71, 0x6c, 0xcb, 0xb6, 0x6c, 0xc7 +}; + +uint8_t std_vect_54[] = { + 0xed, 0xfd, 0x1a, 0x1a, 0x2c, 0x1a, 0x1a, 0x16, + 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, + 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, + 0x1f, 0xcb, 0x7c, 0xfd, 0xfb, 0xd0, 0xb2, 0x1f, + 0xfb, 0xcb, 0x71, 0xec, 0xf1, 0xbe, 0x1f, 0xc7 +}; + +uint8_t std_vect_55[] = { + 0xed, 0xfd, 0x1c, 0xfb, 0xb1, 0x1f, 0xcb, 0x7c, + 0xec, 0xfb, 0xf1, 0x00, 0xb3, 0x50, 0xca, 0x94, + 0x01, 0x00, 0x00, 0x71, 0xec, 0xc7, 0xbe, 0x1f, + 0xc7, 0xb4, 0xce, 0xfb, 0xb1, 0x6f, 0xcb, 0xbc, + 0xec, 0xeb, 0xb2, 0xce, 0xeb, 0xe3, 0x6d, 0xd3, + 0x7a, 0x6c, 0xfb, 0x76, 0xec, 0xc7, 0x71, 0x6c +}; + +uint8_t std_vect_56[] = { + 0xf7, 0x4e, 0x00 +}; + +uint8_t std_vect_57[] = { + 0xed, 0xfd, 0x6d, 0x00, 0x00, 0x00, 0x20, 0x39, + 0x3d, 0xef, 0xc7, 0x7e, 0x32, 0x4c, 0xc2, 0x9a, + 0x75, 0xe4, 0x05, 0x8e, 0x37, 0xd5, 0x25, 0x84, + 0x90, 0x9c, 0xfe, 0x47, 0xf2, 0x02, 0x89, 0x7f, + 0x11, 0xb1, 0x1f, 0xcb, 0x7c, 0xec, 0x16, 0x17, + 0x4a, 0x2d, 0xa3, 0xa9, 0x76, 0x96, 0xd1, 0xc1, + 0x3c, 0xbb, 0xca, 0xcd, 0xfa, 0x0a, 0x6c, 0x71, + 0xe1, 0xf7, 0xf1, 0xb2, 0x1f, 0xfb, 0xcb, 0x71, + 0xec, 0xc7, 0xbe, 0x1f, 0xc6, 0xb4, 0xce, 0x40, + 0xb1, 0x6f, 0xcb, 0x99, 0x10, 0xeb, 0x00, 0x00 +}; + +uint8_t std_vect_58[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0xb6, 0x6d, 0xd7, 0x34, + 0x3d, 0xef, 0xc7, 0x7e, 0xff, 0xfb, 0xb1, 0x1f, + 0xcb, 0x7f, 0xec, 0xfb, 0xfa, 0x8e, 0x37, 0xb9, + 0x25, 0x47, 0xa4, 0x0d, 0xfe, 0x47, 0xf2, 0x10, + 0x97, 0x6c, 0x00, 0x00, 0x00, 0xff, 0x00, 0x10, + 0xd9, 0xd9, 0xd9, 0xd9 +}; + +uint8_t std_vect_59[] = { + 0xed, 0xfd, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0xf0, 0xf0, 0x6d, 0xdb, 0x1d, 0xfb, 0xb6, 0x6e +}; + +uint8_t std_vect_60[] = { + 0x64, 0x00, 0x15, 0xbb, 0x2d, 0x18, 0x15, 0xff, + 0xbb, 0x2d +}; + +uint8_t std_vect_61[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0xb6, 0xfa, 0x00, 0x00, + 0xfa, 0xef, 0xc7, 0x7e, 0x1c, 0xfb, 0xb1, 0x1f, + 0xcb, 0x7c, 0xec, 0xfb, 0xf1, 0xb2, 0x1f, 0xfb, + 0xcb, 0x71, 0xec, 0xc7, 0xbe, 0x1f, 0xc7, 0xb4, + 0xce, 0xfb, 0xb1, 0x6f, 0xcb, 0xbc, 0xec, 0xeb, + 0xb2, 0xce, 0xab, 0x7a, 0x6c, 0xfb, 0x76, 0xec, + 0x6e, 0xeb, 0xb6, 0x6e, 0xe5, 0xba, 0x1d, 0xfb +}; + +uint8_t std_vect_62[] = { + 0x6d, 0x2e, 0x98 +}; + +uint8_t std_vect_63[] = { + 0xed, 0xfd, 0x6d, 0xd2, 0xa5, 0x6d, 0x64, 0x7e, + 0xb3, 0x50, 0xca, 0x94, 0x1c, 0xfb, 0xce, 0x1f, + 0xb7, 0x01, 0x09, 0xfb, 0xf1, 0xb2, 0x1f, 0xfb, + 0xcb, 0x71, 0xec, 0xc7, 0xae, 0x1f, 0xc7, 0xb4 +}; + +uint8_t std_vect_64[] = { + 0xed, 0xfd, 0xc1, 0x79, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x7a, 0xf4, 0x18, 0xc1, 0xf7, 0x2a, 0x6d, + 0x7f, 0xff, 0xab, 0xee, 0x64, 0x7f, 0x1d, 0xfb, + 0x00, 0x28, 0x2d, 0xcb, 0x32, 0x6f, 0xdb, 0xbc +}; + +uint8_t std_vect_65[] = { + 0xed, 0x7d, 0x6d, 0xc7, 0xb6, 0x6d, 0xd7, 0x10, + 0x3c, 0xef, 0xc7, 0x7e, 0x1c, 0xfb, 0xb1, 0x1f, + 0xcb, 0x7c, 0xec, 0xfb, 0xf1, 0xb2, 0x1f, 0xfb, + 0xcb, 0x71, 0xec, 0xd1, 0xbe, 0x1f, 0xc7, 0xb4 +}; + +uint8_t std_vect_66[] = { + 0xed, 0xfd, 0x1a, 0xfb, 0x19, 0x1a, 0x1a, 0x1a, + 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, + 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0xff, 0xff, + 0x6f, 0xf6, 0x9c, 0x01, 0xff, 0xff, 0xda, 0x7c, + 0x99, 0x17, 0x10, 0x0d, 0xec, 0x9b, 0xce, 0xeb +}; + +uint8_t std_vect_67[] = { + 0xcc, 0xcc +}; + +uint8_t std_vect_68[] = { + 0xed, 0x30, 0x17, 0xff, 0x7f, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x80, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x7e, 0x1c, 0xfb, 0xe3, + 0xdb, 0x7c, 0x59, 0x99 +}; + +uint8_t std_vect_69[] = { + 0xed, 0xb2, 0x1f, 0xee, 0xcb, 0x5f, 0xec, 0xe8, + 0x03, 0x00, 0x00, 0xd6, 0xce, 0x55, 0xec, 0xcf, + 0xbe, 0x55, 0x55, 0x55, 0x55, 0x01, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x12, 0x55, 0x55, 0x55, + 0x55, 0x50, 0xc7, 0xb1, 0x6a, 0xeb, 0xb6, 0x6e, + 0xdb, 0xb6, 0x1d, 0xfb, 0xb6, 0x6e, 0xdb, 0xb6 +}; + +uint8_t std_vect_70[] = { + 0xed, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, + 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, + 0xe0, 0xe0, 0xe0, 0xfb, 0xcb, 0x71, 0xec, 0xc7, + 0xbe, 0x1f, 0xc7, 0xb4 +}; + +uint8_t std_vect_71[] = { + 0xdd, 0x00, 0x80, 0x01, 0xfa, 0xff +}; + +uint8_t std_vect_72[] = { + 0x05, 0x20, 0x00, 0xff, 0xe5 +}; + +uint8_t std_vect_73[] = { + 0x04, 0x00, 0x04 +}; + +uint8_t std_vect_74[] = { + 0x34 +}; + +uint8_t std_vect_75[] = { + 0x25, 0x28 +}; + +uint8_t std_vect_76[] = { + 0x0a, 0xee, 0x2d, 0x2d, 0x00, 0x01, 0x00, 0x00, + 0x2d, 0xff, 0xff, 0x2d, 0x2d, 0x34 +}; + +uint8_t std_vect_77[] = { + 0x7c, 0x99, 0x17, 0x66, 0x85, 0x17, 0x84, 0x69, + 0x69, 0x00, 0x7f +}; + +uint8_t std_vect_78[] = { + 0x8d, 0x10, 0x7a, 0xf4, 0x18 +}; + +uint8_t std_vect_79[] = { + 0xed, 0xfd, 0x10, 0xae, 0xb6, 0x6c, 0xc7, 0xb1, + 0x6e, 0xeb, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9b, + 0xba, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, + 0x94, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, + 0x88, 0xee, 0x04, 0xbe, 0x03, 0x00, 0x00, 0x10 +}; + +uint8_t std_vect_80[] = { + 0x7c, 0x99, 0x17, 0xfd, 0xfd, 0x6d, 0xc7, 0xb6, + 0xe4, 0x88, 0x34, 0x77, 0x6d, 0xd7, 0x34 +}; + +uint8_t std_vect_81[] = { + 0x15, 0xe7, 0xff, 0x00, 0x23, 0x04, 0x00, 0x04, + 0x6d, 0xd7, 0x34, 0x55, 0xd7, 0x34 +}; + +uint8_t std_vect_82[] = { + 0x9d, 0x00, 0x00, 0xf4, 0x8b +}; + +uint8_t std_vect_83[] = { + 0x6d, 0xfd, 0xfd, 0x55, 0xbe, 0xb6, 0x6d, 0xd7, + 0x35 +}; + +uint8_t std_vect_84[] = { + 0x64, 0xc3, 0xc3, 0x84, 0x84, 0x10, 0x9c, 0x10, + 0x0c, 0x0c, 0x01, 0x9c, 0x20 +}; + +uint8_t std_vect_85[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0x00, 0x00, 0x00, 0x00, + 0x52, 0xef, 0xc7, 0xa3, 0xa3, 0xa3, 0xb3, 0xa3, + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xa3, 0xa3, 0x45, 0x45, 0x45, 0x4e, 0x45, 0x45, + 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, + 0x45, 0xb6, 0xaf, 0xeb, 0xb0, 0x48, 0x4b, 0x69, + 0xa5, 0x4c, 0x9b, 0x48, 0xab, 0x2d, 0xb5, 0x6f, + 0x50, 0x63, 0x59, 0x8a, 0x8d, 0x48, 0xab, 0x82, + 0x8f, 0xc2, 0x3f, 0x01 +}; + +uint8_t std_vect_86[] = { + 0x7c, 0x99, 0x0f, 0x85, 0x42, 0x81, 0xff, 0xff, + 0x80, 0x00, 0xf4, 0x34 +}; + +uint8_t std_vect_87[] = { + 0xe4, 0x2d, 0x2d, 0x2d, 0x2d, 0x51, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x34 +}; + +uint8_t std_vect_88[] = { + 0x65, 0x6c, 0x71, 0xc1, 0x1a, 0x1a, 0x00, 0x6c, + 0x71, 0xc1, 0x1a, 0x00, 0x00, 0x27 +}; + +uint8_t std_vect_89[] = { + 0xdd, 0xed, 0xa3 +}; + +uint8_t std_vect_90[] = { + 0x72, 0x10, 0x00, 0x10 +}; + +uint8_t std_vect_91[] = { + 0xed, 0xfd, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, + 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, + 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, + 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, + 0xff, 0x7f, 0x01 +}; + +uint8_t std_vect_92[] = { + 0xed, 0xfd, 0x6d, 0x00, 0x00, 0x80, 0xff, 0xff, + 0x00, 0x04, 0x84, 0x65, 0x75, 0x7b, 0xff +}; + +uint8_t std_vect_93[] = { + 0x00, 0x00, 0x00, 0xff, 0xff +}; + +uint8_t std_vect_94[] = { + 0x7a, 0x7f, 0x18, 0x20, 0x20, 0x08, 0x08, 0x7a, + 0x7f, 0x18, 0x20, 0x20, 0x08, 0x08, 0x25, 0xfe, + 0x25, 0xfe +}; + +uint8_t std_vect_95[] = { + 0xfa, 0xfd, 0x50, 0xc7, 0x50, 0xc7, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00 +}; + +uint8_t std_vect_96[] = { + 0xed, 0xdd, 0x6d, 0xc7, 0xb6, 0x6d, 0xd7, 0x34, + 0x3d, 0xef, 0xc7, 0x7e, 0x1c, 0xfb, 0xb1, 0x1f, + 0xcb, 0x7c, 0xec, 0xe4, 0xe0, 0xb2, 0x1f, 0xfb, + 0xe4, 0x71, 0xec, 0xc7, 0xa5, 0x42, 0x81, 0x74, + 0xce, 0xfb, 0xb1, 0x6f, 0xcb, 0xbc, 0x65, 0x31, + 0x08, 0xce, 0xeb, 0x7a, 0x6c, 0xfb, 0x76, 0xec, + 0xc7, 0x71, 0x6c, 0xcb, 0xb6, 0xb6, 0x6e, 0xd6, + 0xb6, 0xaf, 0xf8, 0xb2, 0x6d, 0xc7, 0x7a, 0xec, + 0xcb, 0x32, 0x6f, 0xdb, 0xbc, 0xcc, 0xf3, 0xb2, + 0xcd, 0x2f, 0xc9, 0xb2, 0x2e, 0xc7, 0xb6, 0xad, + 0xc7, 0x7e, 0xbc, 0xbf, 0xee, 0xfb, 0x7d, 0xbf, + 0x40, 0xc7, 0xb1, 0x1f, 0xfb, 0x71, 0xec, 0x3d, + 0xc7, 0xeb, 0xbe, 0x1f +}; + +uint8_t std_vect_97[] = { + 0xed, 0xfd, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, + 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, + 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, + 0xd0, 0x6d, 0xc7, 0xb6, 0xd8, 0xd8, 0xd8, 0xd8, + 0xf9, 0xd8, 0xd8, 0xb2 +}; + +uint8_t std_vect_98[] = { + 0x0c, 0x00, 0x00, 0x03, 0xdb, 0xf7, 0xff, 0x00 +}; + +uint8_t std_vect_99[] = { + 0xed, 0xfd, 0xa0, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x0c, + 0x0c, 0x40, 0x0c, 0x0c +}; + +uint8_t std_vect_100[] = { + 0x0c, 0x01, 0x80, 0xb6, 0xc7, 0x89 +}; + +uint8_t std_vect_101[] = { + 0xed, 0xfd, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, + 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, + 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, + 0xb0, 0xb0, 0xb0, 0xb0, 0xab, 0x82, 0x8f, 0xc2, + 0x3f, 0x00 +}; + +uint8_t std_vect_102[] = { + 0xed, 0x22, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x22, + 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0xfd, + 0x4c, 0x4c, 0x4c, 0xec +}; + +uint8_t std_vect_103[] = { + 0xed, 0xb8, 0xb1, 0xe8, 0x03, 0x08, 0x00, 0xc7, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x00, 0xc7, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x80, 0x32, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0xc9 +}; + +uint8_t std_vect_104[] = { + 0xed, 0xfd, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0xf0, 0x1f, 0xc7, 0xb4 +}; + +uint8_t std_vect_105[] = { + 0xed, 0x02, 0x92, 0xc7, 0xb6, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xc7, + 0xdb, 0xba, 0x1d, 0xfb +}; + +uint8_t std_vect_106[] = { + 0xad, 0xfd, 0xcc, 0xcc, 0xff, 0xcc, 0xcc, 0xcc, + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x28, 0x7e, 0x1c, 0xfb, + 0xad, 0xcd, 0xeb, 0xe2 +}; + +uint8_t std_vect_107[] = { + 0x4a, 0xff, 0xff, 0x00, 0x40, 0x00, 0x64, 0x7e, + 0xeb, 0xab, 0xeb, 0xab, 0x82, 0x00, 0x00, 0xd2, + 0x3a, 0x7f, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x40, 0xeb, + 0xd5, 0x82, 0x00, 0x00, 0x39, 0x10 +}; + +uint8_t std_vect_108[] = { + 0x0c, 0x8b, 0x8b, 0xc7, 0xb6, 0x7f, 0x20, 0x40, + 0x80, 0x40, 0x00, 0x00, 0x01, 0x0c, 0x8b, 0x8b, + 0xc7, 0xa4, 0x7f, 0x20, 0x40, 0x80, 0x40, 0x01, + 0x05, 0xff, 0xff, 0x05, 0xcb, 0x31, 0xff, 0xff, + 0xff, 0x04, 0xc3, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0xb1, 0x7f, 0xcb, 0xcb, 0x31, 0xff, + 0xff, 0xff, 0x04, 0xcb, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0xcb, 0x31, 0xff, 0xff, 0xb4, 0xce, + 0xfb, 0xb1, 0x7f, 0x89, 0x7c, 0x7c, 0x7c, 0x7c, + 0x43, 0xbb, 0xca, 0xcd, 0xfa, 0x84, 0x89, 0x89 +}; + +uint8_t std_vect_109[] = { + 0x0c, 0x24, 0x8b, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x18, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x46, 0x89 +}; + +uint8_t std_vect_110[] = { + 0xec, 0xfd, 0x6d, 0xc7, 0xb6, 0x6d, 0xd7, 0x34, + 0x3d, 0xef, 0xc7, 0x7e, 0x6e, 0xeb, 0xb6, 0x6e, + 0xdb, 0xba, 0x1d, 0xfb, 0xb6, 0x6e, 0x40, 0xb6, + 0x6d, 0xb5, 0x7a, 0xec, 0xdb, 0xb6, 0xed, 0xcb, + 0x31, 0xe6, 0xbe, 0x1f, 0x2e, 0x26, 0xab, 0x75, + 0xe3, 0x6d, 0xd3, 0xe3, 0x6d, 0xd3, 0x55, 0xa6, + 0x01, 0x00, 0x21, 0x1f, 0xef, 0xfb, 0xaf, 0xf7, + 0x88, 0x34, 0x77, 0x26, 0x6f, 0xdb, 0xbc, 0xcc, + 0x72, 0xbc, 0xec, 0xfb, 0x7e, 0x64, 0xfb, 0x57, + 0x10, 0x9c, 0xad, 0xdb, 0xbc, 0x2d, 0xf3, 0x34, + 0x8d, 0x24, 0xa6, 0x65, 0x31, 0x08, 0x71, 0x31, + 0x08, 0x0d, 0xd3, 0x34, 0x6d, 0xa3, 0x85, 0x42, + 0x81, 0xf4, 0x1d, 0xe1, 0x47, 0x4a, 0x2d, 0x8d +}; + +uint8_t std_vect_111[] = { + 0xed, 0xfd, 0x6d, 0xc7, 0xb6, 0x6d, 0x98, 0x79, + 0xa6, 0x48, 0xb7, 0x82, 0x8f, 0xfb, 0xb1, 0x1f, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0xb6, 0x6c, 0xc7, 0xb1, 0x6e, 0xeb, 0xb6, 0x6e, + 0xdb, 0xba, 0x1d, 0xfb, 0xb6, 0x6e, 0xdb, 0x99, + 0xaf, 0xeb, 0xc7, 0xeb, 0xbe, 0x1f, 0xc7, 0xfe +}; + +uint8_t std_vect_112[] = { + 0x7c, 0x99, 0x17, 0xfd, 0xfd, 0x6d, 0xc2, 0xef, + 0xff, 0xff, 0x7f, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x59, 0xfb, 0xb6, 0x35, + 0xab, 0x77, 0x8f, 0xc2 +}; + +uint8_t std_vect_113[] = { + 0x4a, 0xff, 0xff, 0x00, 0x40, 0x00, 0xe2, 0x7e, + 0xbd, 0x16, 0xf9, 0xb7, 0x4a, 0xff, 0xff, 0x00, + 0x40, 0x00, 0xe2, 0x7e, 0xbd, 0x16, 0xf9, 0xb7, + 0x13, 0x00, 0x40, 0x00, 0xe2, 0x7e, 0xbd, 0x1d, + 0x00, 0x00, 0xd2, 0x3a, 0xc1, 0x5a, 0x33, 0x00, + 0x00, 0x4f, 0x03, 0xeb, 0xd5, 0x82, 0x00, 0x00 +}; + +uint8_t std_vect_114[] = { + 0xfa, 0xfd, 0x50, 0x00, 0x20, 0xc7, 0x00, 0xcb, + 0xb6, 0x6c, 0x80, 0x00, 0xcb, 0x44, 0x6f, 0xdb, + 0x01 +}; + +uint8_t std_vect_115[] = { + 0x0c, 0x8b, 0x8b, 0xc7, 0xb6, 0x65, 0x20, 0x40, + 0x80, 0x00, 0x00, 0xfb, 0x1a, 0xdc, 0xb5, 0xff, + 0xcb, 0x7a, 0xec, 0xfb, 0xf1, 0xb2, 0x1e, 0x00, + 0x12, 0x10, 0x00, 0xc7, 0xbe, 0x00, 0x01, 0xb4, + 0xad, 0xfb, 0x00, 0x7f, 0xcb, 0xcb, 0x24, 0xff, + 0xff, 0xff, 0x01, 0x01, 0x01, 0x09, 0x01, 0x09, + 0x65, 0x20, 0x40, 0x80, 0x00, 0x50, 0x00, 0x1c, + 0xdc, 0xb5, 0x3f, 0xcb, 0x7e, 0xec, 0xfb, 0xf1, + 0xb2, 0x1e, 0x00, 0x12, 0x10, 0x00, 0xc7, 0xbe, + 0x00, 0x3d, 0x80, 0xcb, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x09, 0x01, 0x00, 0x04, 0x01, 0x85, + 0x89, 0x89 +}; + +uint8_t std_vect_116[] = { + 0x4a, 0xff, 0x66, 0xfd, 0x00, 0x40, 0x0a, 0x05, + 0xff, 0xff, 0x05, 0xf9, 0xff, 0xfb, 0x3f, 0x00, + 0x82, 0x00, 0xff, 0xff, 0x00, 0x00, 0xd2, 0x3a, + 0xcf, 0x5a, 0x33 +}; + +uint8_t std_vect_117[] = { + 0x0c, 0x8b, 0x8b, 0xcb, 0xb6, 0x12, 0x10, 0x00, + 0xc7, 0xbe, 0x00, 0x01, 0xb4, 0xce, 0xfb, 0x00, + 0x7f, 0xcb, 0xcb, 0x31, 0xff, 0xe7, 0xff, 0x80, + 0xcb, 0x01, 0x65, 0x20, 0x40, 0x96, 0x00, 0x00, + 0x00, 0x1c, 0xdc, 0xb1, 0x1f, 0xcb, 0x69, 0xec, + 0x16, 0xf1, 0xb2, 0x1e, 0x00, 0x12, 0x10, 0x00, + 0xc7, 0xbe, 0x00, 0x01, 0xb4, 0xce, 0xfb, 0x00, + 0x7f, 0xcb, 0xcb, 0x31, 0xff, 0xfd, 0xff, 0x80, + 0xcb, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x09, 0x3d, 0x01, 0x89, 0x7c, 0x7c, 0x7c, + 0xfc, 0x43, 0xbb, 0xca, 0xcd, 0xfa, 0x00, 0x00 +}; + +uint8_t std_vect_118[] = { + 0x4a, 0xff, 0xfd, 0x00, 0x40, 0x00, 0x82, 0x00, + 0xbd, 0x1d, 0xf9, 0xff, 0x00, 0x40, 0x00, 0x82, + 0x00, 0xbd, 0x1d, 0xf9, 0x00, 0x40, 0x00, 0x82, + 0x00, 0xbd, 0x1d, 0xb3 +}; + +uint8_t std_vect_119[] = { + 0x0c, 0x8b, 0x8b, 0xc7, 0xb6, 0x6c, 0x20, 0x40, + 0x80, 0x00, 0x00, 0xfb, 0x1a, 0xdc, 0xb5, 0xff, + 0xcb, 0x7a, 0xec, 0xfb, 0xf1, 0xb2, 0x1e, 0x00, + 0x12, 0x10, 0x00, 0xc7, 0xbe, 0x00, 0x01, 0xb4, + 0xad, 0xfb, 0x00, 0x7f, 0xcb, 0xcb, 0x24, 0xff, + 0xff, 0xff, 0x01, 0x01, 0x01, 0x09, 0x01, 0x09, + 0x65, 0x20, 0x40, 0x80, 0x00, 0x50, 0x00, 0x1c, + 0xdc, 0xb5, 0x3f, 0xcb, 0x7e, 0xec, 0xfb, 0x30, + 0x17, 0x4a, 0xf1, 0xb2, 0x1e, 0x00, 0x12, 0x10, + 0x00, 0xc7, 0xbe, 0x00, 0x3d, 0x80, 0xcb, 0x01, + 0x01, 0x2d, 0xf7, 0xa9, 0x01, 0x09, 0x01, 0x00, + 0x04, 0x01, 0x85, 0x89, 0x89 +}; + +uint8_t std_vect_120[] = { + 0x0c, 0x8b, 0x8b, 0xc7, 0xb6, 0x7f, 0x20, 0x40, + 0x80, 0x40, 0x00, 0x00, 0x01, 0x0c, 0x8b, 0x8b, + 0xc7, 0xa4, 0x7f, 0x20, 0x40, 0xb2, 0x1f, 0x62, + 0xcb, 0x1f, 0xc7, 0xb4, 0xd7, 0xfb, 0xb1, 0x6f, + 0xcb, 0x2c, 0xf3, 0xba, 0x6e, 0xeb, 0x00, 0x1d, + 0x00, 0xb3, 0x6f, 0x80, 0xff, 0xff, 0xff, 0xb6, + 0xc2, 0xb8, 0x1c, 0x00, 0x00, 0x04, 0x00, 0xec, + 0x5d, 0x6c, 0xfb, 0x76, 0x25, 0x49, 0x1a, 0x27, + 0x2f, 0x50, 0xcc, 0x10, 0x8e, 0x36, 0xcc, 0x76, + 0x8e, 0x20, 0x0d, 0xfe, 0x47, 0x75, 0xab, 0xca, + 0xcd, 0xfa, 0x02, 0x6c, 0x71, 0x8f, 0xf5, 0x65, + 0x31, 0x08, 0x37, 0x23, 0xfa, 0x86, 0xbc, 0xed, + 0xaf, 0xc7, 0xb1, 0xef, 0x31, 0x31, 0x31, 0x31, + 0x40, 0x00, 0x80, 0xff, 0x89, 0x7d, 0x7c, 0x99 +}; + +uint8_t std_vect_121[] = { + 0x0c, 0x8b, 0x8b, 0xcb, 0xb6, 0x12, 0x10, 0x00, + 0xc7, 0xbe, 0x00, 0x01, 0xb4, 0xce, 0xfb, 0x00, + 0x7f, 0xcb, 0xcb, 0x31, 0x19, 0xe8, 0xff, 0x80, + 0xcb, 0x01, 0x65, 0x20, 0x40, 0x96, 0x00, 0x00, + 0x00, 0x1c, 0xdc, 0xb1, 0x1f, 0xcb, 0x69, 0xec, + 0x16, 0xf1, 0xb2, 0x1e, 0x00, 0x12, 0x10, 0x00, + 0xc7, 0xbe, 0x00, 0x00, 0x10, 0xce, 0xfb, 0x00, + 0x7f, 0xcb, 0xcb, 0x31, 0xff, 0xfd, 0xff, 0x80, + 0xcb, 0x6e, 0xdb, 0xb6, 0xaf, 0xeb, 0xb2, 0x6d, + 0xc7, 0x7a, 0xec, 0xdb, 0xb6, 0xed, 0xcb, 0x31, + 0xaf, 0xf3, 0x3c, 0x2d, 0xcb, 0x32, 0x6f, 0xdb, + 0xbc, 0xcc, 0xf3, 0xb2, 0xcd, 0x2f, 0xcb, 0xb2 +}; + +uint8_t std_vect_122[] = { + 0x4a, 0xff, 0x66, 0xfd, 0x00, 0x40, 0x00, 0x82, + 0x54, 0xb5, 0x1d, 0xf9, 0xff, 0x00, 0x40, 0x00, + 0x82, 0x00, 0xb4, 0xfc, 0xf9, 0x00, 0x40, 0x00, + 0x82, 0x00, 0xb5, 0x54, 0x00, 0x40, 0x00, 0x82, + 0x00, 0xb4, 0xfc, 0xf9, 0x00, 0x40, 0x00, 0x82, + 0x00, 0x40, 0x00, 0xff, 0x7f, 0xbd, 0x1d, 0xfb, + 0x10, 0x00, 0xd2, 0x3a +}; + +uint8_t std_vect_123[] = { + 0x0c, 0x8b, 0x8b, 0xff, 0xff, 0x65, 0x20, 0x40, + 0x80, 0x00, 0xcf, 0xff, 0xc9, 0xcf, 0xcf, 0xcf, + 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, + 0xb6, 0xc2, 0xc2, 0xc2, 0xa3, 0xc2, 0xc2, 0xc2, + 0xc2, 0xc2, 0xc2, 0xc2, 0xaa, 0xef, 0xc7, 0x7e, + 0x10, 0xfb, 0xb1, 0x1f, 0xec, 0xeb, 0xb2, 0x04, + 0x76, 0xec, 0xc7, 0x71, 0x6c, 0xcb, 0xb6, 0x6c, + 0x6e, 0xeb, 0xb6, 0x6e, 0xdb, 0xba, 0x1d, 0xfb, + 0xb6, 0x6e, 0xdb, 0xb6, 0xaf, 0xeb, 0xb2, 0x6d, + 0xc7, 0x7a, 0xec, 0xdb, 0xb6, 0xcb, 0x32, 0xbf, + 0x1e, 0xc7, 0xb1, 0x1f, 0xc7, 0xfe, 0x72, 0xbc, + 0xec, 0xfb, 0x7e, 0xec, 0xfb, 0x71, 0xec, 0x2f, + 0xc7, 0xeb, 0xbe, 0x1f, 0xc7, 0xfe, 0x72, 0xb4 +}; + +uint8_t std_vect_124[] = { + 0xfa, 0xfd, 0x50, 0x08, 0x20, 0xc7, 0x00, 0xcb, + 0xb6, 0x6e, 0x80, 0x00, 0xfa, 0xfd, 0x50, 0x00, + 0x20, 0xc7, 0x00, 0xcb, 0xb6, 0x6c, 0x80, 0x00, + 0xfa, 0xfd, 0x50, 0x00, 0x20, 0xc7, 0x00, 0xcb, + 0xff, 0x7f, 0x00, 0x00, 0xcb, 0xcb, 0x44, 0x6f, + 0xdb, 0x40, 0x00, 0x00, 0x00, 0xcb, 0xcb, 0x44, + 0x6f, 0xdb, 0x01 +}; + +uint8_t std_vect_125[] = { + 0x0c, 0x8b, 0x8b, 0xcb, 0xb6, 0x12, 0x10, 0x00, + 0xc7, 0xbe, 0x00, 0x01, 0xb4, 0xce, 0xfb, 0x00, + 0x7f, 0xcb, 0xcb, 0x31, 0x00, 0x00, 0x00, 0x80, + 0xcb, 0x01, 0x65, 0x20, 0x40, 0x96, 0x00, 0x00, + 0x00, 0x1c, 0xdc, 0xb1, 0x1f, 0xcb, 0x69, 0xec, + 0x16, 0xf1, 0xb2, 0x1e, 0x00, 0x12, 0x10, 0x00, + 0xc7, 0xbe, 0x00, 0x01, 0xb4, 0xce, 0xfb, 0x00, + 0x7f, 0xcb, 0xcb, 0x31, 0xff, 0xfd, 0xff, 0x80, + 0xcb, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x09, 0x3d, 0x01, 0x81, 0x7c, 0x7c, 0x7c, + 0xcd, 0xfa, 0x00, 0x00 +}; + +uint8_t std_vect_126[] = { + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x80, + 0x00, 0x00, 0x00, 0x80, 0xff, 0x80, 0x1c +}; + +uint8_t std_vect_127[] = { + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x20, 0x20, 0x80, 0x00, + 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x1c +}; + +uint8_t std_vect_128[] = { + 0x34, 0x3d, 0xef, 0xc7, 0x7e, 0x1c, 0xfb, 0xe8, + 0x17, 0x00, 0x00, 0xf2, 0xfb, 0xc7, 0x7e, 0xbc, + 0xbf, 0xee, 0xfb, 0xb1, 0xbf, 0x1e, 0xc7, 0xb1, + 0x1f, 0xfb, 0x76, 0xec, 0x0e, 0x0e, 0x0e, 0x0e, + 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, + 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, + 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, + 0x0e, 0x0e, 0x0e, 0xc7, 0x71, 0x6c, 0xcb, 0xb6, + 0x6c, 0xc7, 0xb1, 0x6e, 0xeb, 0xb6, 0x6e, 0xdb, + 0xba, 0x1d, 0xbc, 0xcc, 0xf3, 0xb2, 0xe3, 0x2f, + 0xcb, 0x84, 0x11, 0x9c, 0xb2, 0x2e, 0xc7, 0xb6, + 0xad, 0xc7, 0x7e, 0xbc, 0xbf, 0xee, 0xfb, 0xb1, + 0xbf, 0x1e, 0xc7, 0xb1, 0x1f, 0xfb, 0x76, 0xec, + 0x2f, 0xc7, 0xeb, 0xd6, 0x1f +}; + +uint8_t std_vect_129[] = { + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x39, 0x39, 0x52, 0x39, 0x39, 0x39, + 0x39, 0x39, 0x39, 0x7c, 0xb1, 0x17, 0x39, 0xff, + 0x7f, 0xf9 +}; + +uint8_t std_vect_130[] = { + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x80, 0x1c, 0x7f, 0xff +}; + +uint8_t std_vect_131[] = { + 0x0c, 0x8b, 0x8b, 0xc7, 0xb6, 0x41, 0x20, 0x4a, + 0x80, 0x00, 0x23, 0xeb, 0x20, 0xd3, 0x55, 0xa6, + 0x16, 0x7a, 0x2e, 0xab, 0xeb, 0x7a, 0x6c, 0xc7, + 0xb1, 0x6f, 0xc7, 0x7e, 0x1c, 0xfb, 0x5e, 0xb7, + 0x1e, 0x00, 0x12, 0x10, 0x00, 0xc7, 0xbe, 0x00, + 0x01, 0xb4, 0xce, 0xfb, 0x00, 0x80, 0xff, 0xff, + 0x31, 0xff, 0xff, 0xa3, 0xa9, 0x76, 0x96, 0xd1, + 0xbe, 0x41, 0xbb, 0xca, 0xcd, 0xfa, 0x02, 0x6c, + 0x00, 0x89, 0x88, 0x00, 0x00, 0x10, 0xff, 0xff, + 0x00, 0xd9, 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0xfb, 0x91, 0xec, 0xfb, 0xd3, 0xbe, 0x1f, + 0x00, 0x00, 0x80, 0x00, 0x63, 0x2e, 0xc7, 0xa6, + 0xad, 0xc7, 0x7e, 0xbc, 0xbf, 0xeb, 0x04, 0x00, + 0x63, 0x2e, 0xc7, 0xa6, 0xad, 0xc7, 0x7e, 0xbc, + 0xbf, 0xeb, 0xf5, 0xfb, 0x72, 0xbc, 0xec, 0xfb +}; + +uint8_t std_vect_132[] = { + 0xfa, 0xfd, 0x50, 0x08, 0x20, 0xc7, 0x00, 0xcb, + 0xb6, 0x6c, 0x80, 0x00, 0xfa, 0xfd, 0x50, 0x00, + 0x20, 0xc7, 0x00, 0xcb, 0xb6, 0xb6, 0x6c, 0x80, + 0x00, 0xfa, 0xfd, 0x50, 0x00, 0x20, 0xc7, 0x00, + 0xcb, 0xb6, 0x6c, 0xb6, 0x6c, 0x80, 0x00, 0xfa, + 0xfd, 0x50, 0x00, 0x20, 0x80, 0x00, 0xfa, 0xfd, + 0x50, 0x00, 0x20, 0xc7, 0x00, 0xcd, 0xb6, 0x6c, + 0x80, 0xf6, 0x80, 0xff +}; + +uint8_t std_vect_133[] = { + 0x4a, 0xff, 0x66, 0xfd, 0x00, 0x40, 0x00, 0x82, + 0x54, 0xb5, 0x1d, 0xf9, 0xf8, 0x00, 0x40, 0x00, + 0x82, 0x00, 0xb4, 0xfc, 0x00, 0x40, 0x00, 0x82, + 0x00, 0xb4, 0xfc, 0xf9, 0xff, 0x66, 0xfd, 0x00, + 0x40, 0x00, 0x82, 0x54, 0xb5, 0x1d, 0xf9, 0xf8, + 0x00, 0x40, 0x00, 0x82, 0x00, 0xb4, 0xf9, 0xf8, + 0x00, 0x40, 0x00, 0x82, 0x00, 0xb4, 0xfc, 0xf9, + 0x00, 0xb5, 0x54, 0x00, 0x40, 0x00, 0x82, 0x00, + 0xb4, 0xfc, 0xf9, 0xff, 0x66, 0xfd, 0x00, 0x40, + 0x00, 0x82, 0x54, 0xb5, 0x1d, 0xf9, 0xf8, 0x00, + 0x40, 0x00, 0x82, 0x00, 0xb4, 0xfc, 0xf9, 0x00, + 0x40, 0x00, 0x82, 0x00, 0xb5, 0x54, 0x00, 0x40, + 0x00, 0x82, 0x00, 0x40, 0xfc, 0xf9, 0x00, 0x40, + 0x00, 0x82, 0x00, 0xb5, 0x54, 0x00, 0x40, 0x00, + 0x82, 0x00, 0x40, 0x00, 0x82, 0x00, 0x40, 0x00, + 0xff, 0x7f, 0xbd, 0x1d, 0xfb, 0x10 +}; + +uint8_t std_vect_134[] = { + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, + 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x20, 0xff, 0xff, 0x7f, 0x18, 0xff +}; + +uint8_t std_vect_135[] = { + 0x4a, 0xff, 0xff, 0x00, 0x40, 0x00, 0xe2, 0x7e, + 0xff, 0x00, 0x40, 0x00, 0xe2, 0x7e, 0xff, 0xff, + 0x00, 0x40, 0x00, 0xe2, 0x7f, 0xfd, 0x00, 0x40, + 0x00, 0xe2, 0x7e, 0xbd, 0x00, 0x40, 0x00, 0xe2, + 0x7e, 0xff, 0x00, 0x40, 0x00, 0xe2, 0x7e, 0xff, + 0xff, 0x00, 0x40, 0x00, 0xe2, 0x7f, 0xfd, 0x00, + 0x40, 0x00, 0xe2, 0x7e, 0xbd, 0x1d, 0x1d, 0xff, + 0x82, 0x00, 0x00, 0xd2, 0x3a, 0x39, 0xd2, 0x3a, + 0x7f, 0x10 +}; + +uint8_t std_vect_136[] = { + 0xed, 0xfd, 0x51, 0xc7, 0xb6, 0x6d, 0xdb, 0x5a, + 0x33, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f +}; + +uint8_t std_vect_137[] = { + 0xfa, 0xfd, 0x50, 0x08, 0x20, 0xc7, 0x00, 0xcb, + 0xb6, 0x6c, 0x80, 0x00, 0xfa, 0xfd, 0x50, 0x00, + 0x20, 0xc7, 0x00, 0xcb, 0xb6, 0xb6, 0x6c, 0x80, + 0x00, 0xfa, 0xfd, 0x50, 0x00, 0x20, 0xc7, 0x00, + 0xcb, 0xb6, 0x6c, 0xb6, 0x6c, 0x80, 0x00, 0xfa, + 0xfd, 0x50, 0x00, 0x20, 0x80, 0x00, 0xfa, 0xfd, + 0x50, 0x08, 0x20, 0xc7, 0x00, 0xcb, 0xb6, 0x6c, + 0x80, 0x00, 0xfa, 0xfd, 0x50, 0x00, 0x20, 0xc7, + 0x20, 0xc7, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0d, + 0x80, 0xff +}; + +uint8_t std_vect_138[] = { + 0xfa, 0xfd, 0x50, 0x08, 0x20, 0xc7, 0x00, 0xcb, + 0xb6, 0xb6, 0x6c, 0x80, 0x00, 0xfa, 0xfd, 0x50, + 0x00, 0x20, 0xc7, 0x00, 0x80, 0x00, 0xfa, 0xfd, + 0x50, 0x00, 0x20, 0xc7, 0xb6, 0x6c, 0x80, 0x00, + 0xfa, 0xfd, 0x50, 0x00, 0x20, 0x80, 0x00, 0xfa, + 0xfd, 0x50, 0x00, 0x20, 0xc7, 0x00, 0x6c, 0x80, + 0x00, 0xfa, 0xfd, 0x50, 0x00, 0x20, 0xc7, 0x00, + 0x80, 0x00, 0xfa, 0xfd, 0x50, 0x00, 0x20, 0xc7, + 0xb6, 0x6c, 0x80, 0x00, 0xfa, 0xfd, 0x50, 0x00, + 0x20, 0x80, 0x00, 0xfa, 0xfd, 0x50, 0x00, 0x20, + 0xc7, 0x00, 0xcd, 0xb6, 0x6c, 0x80, 0xf6, 0x80, + 0xff +}; + +uint8_t std_vect_139[] = { + 0xfa, 0xfd, 0x50, 0x08, 0x20, 0xc7, 0x00, 0xcb, + 0xb6, 0x6c, 0x80, 0x00, 0xfa, 0xfd, 0x50, 0x00, + 0x20, 0xd6, 0x00, 0xcb, 0xb6, 0xb6, 0x6c, 0x80, + 0x00, 0xfa, 0xfd, 0x50, 0x00, 0x20, 0xc7, 0x00, + 0xcb, 0xb6, 0x6c, 0xb6, 0x6c, 0x80, 0x00, 0xfa, + 0xfd, 0x50, 0x00, 0x20, 0x80, 0x00, 0xfa, 0xfd, + 0x50, 0x00, 0x20, 0xc7, 0x00, 0xcd, 0xb6, 0x6c, + 0x80, 0x00, 0xfa, 0xfd, 0x50, 0x00, 0x20, 0xc7, + 0xb6, 0x6c, 0x80, 0x00, 0xfa, 0xfd, 0x50, 0x00, + 0x20, 0x80, 0x00, 0xfa, 0x80, 0xf6, 0x80, 0xff +}; + +uint8_t std_vect_140[] = { + 0x4a, 0xff, 0xff, 0x00, 0x40, 0x00, 0xe2, 0x7e, + 0xff, 0x00, 0x40, 0x00, 0xe2, 0xb6, 0xff, 0x00, + 0x40, 0x00, 0xe2, 0xc7, 0xb1, 0x6e, 0xeb, 0x32, + 0x7e, 0xff, 0x00, 0x40, 0x00, 0xe2, 0xb6, 0xff, + 0x00, 0x40, 0x00, 0xe2, 0xc7, 0xb1, 0x6e, 0xeb, + 0xff, 0x00, 0x40, 0x00, 0xe2, 0xb6, 0xff, 0x00, + 0x40, 0x00, 0xe2, 0xc7, 0xb1, 0x6e, 0xeb, 0x32, + 0x7e, 0xff, 0x00, 0x40, 0x00, 0xe2, 0xb6, 0xff, + 0x00, 0x40, 0x00, 0x00, 0x10, 0xb1, 0x6e, 0xeb, + 0xb6, 0xed, 0x85, 0x84, 0x84, 0x84, 0x84, 0x84 +}; + +uint8_t std_vect_141[] = { + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, + 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, + 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff +}; + +uint8_t std_vect_142[] = { + 0x4a, 0xff, 0xff, 0x00, 0x40, 0x00, 0xe2, 0x7e, + 0xbd, 0x1d, 0xf9, 0xff, 0x00, 0x40, 0x00, 0xe2, + 0xb6, 0xff, 0x00, 0x40, 0x00, 0xe2, 0x7e, 0xf9, + 0xff, 0x00, 0x40, 0x00, 0xe2, 0xd0, 0xff, 0x00, + 0x40, 0x00, 0xe2, 0x7e, 0xf9, 0xff, 0x00, 0x40, + 0x00, 0xe2, 0xd0, 0xff, 0x00, 0x40, 0x00, 0xe2, + 0x7e, 0x00, 0xe2, 0xb6, 0x7f, 0xc5, 0xa4, 0xee, + 0x11, 0xff, 0x8f, 0xf5 +}; + +uint8_t std_vect_143[] = { + 0x1c, 0xa7, 0x51, 0x20, 0xf8, 0xf8, 0xf8, 0xf8, + 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, + 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, + 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0x96, 0x96, + 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, + 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, + 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, + 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, + 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, + 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, + 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0xf8, 0xf8, + 0xb6, 0x6e, 0xdb, 0xba, 0x1d, 0xfb, 0xb6, 0x6f, + 0x10, 0x00, 0x6f, 0xdb, 0x00, 0x01, 0x00, 0x00 +}; + +uint8_t std_vect_144[] = { + 0x1c, 0xa7, 0x51, 0x20, 0xf8, 0xf8, 0xf8, 0xf8, + 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, + 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, + 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0x96, 0x96, + 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, + 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, + 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, + 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, + 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, + 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, + 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0xf8, 0xf8, + 0xb6, 0x6e, 0xdb, 0xba, 0x1d, 0xfb, 0xb6, 0x6f, + 0x10, 0x00, 0x6f, 0xdb, 0x00, 0x01, 0x00, 0xdb, + 0x00, 0x01, 0x00 +}; + +uint8_t std_vect_145[] = { + 0x4a, 0xff, 0x66, 0xfd, 0x01, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x80, + 0xff +}; + +uint8_t std_vect_146[] = { + 0x4a, 0xff, 0xff, 0x00, 0x40, 0x00, 0xe2, 0x7e, + 0xbd, 0x1d, 0x40, 0x00, 0xf9, 0xff, 0x00, 0x40, + 0x00, 0xe2, 0xb6, 0xff, 0x00, 0x40, 0x00, 0xe2, + 0x7e, 0xf9, 0xff, 0x00, 0x40, 0x00, 0xe2, 0xd0, + 0xff, 0xff, 0x00, 0x40, 0x00, 0xe2, 0x7e, 0xbd, + 0x1d, 0xf9, 0xff, 0x00, 0x40, 0x00, 0xe2, 0xb6, + 0xff, 0x00, 0x40, 0x00, 0xe2, 0x7e, 0xf9, 0xff, + 0x00, 0x40, 0x00, 0xe2, 0xd0, 0xff, 0x00, 0x40, + 0x00, 0xe2, 0x7e, 0xf9, 0xff, 0x00, 0x40, 0x00, + 0xe2, 0xd0, 0xff, 0x00, 0xff, 0x00, 0x40, 0x00, + 0xe2, 0x7e, 0xf9, 0xff, 0x00, 0x40, 0x00, 0xe2, + 0x7e, 0x00, 0xe2, 0xb6, 0x7f, 0xc5, 0xa4, 0xee, + 0x11, 0xff, 0xa9, 0xf5 +}; + +uint8_t std_vect_147[] = { + 0x32, 0x6c, 0x71, 0xb3, 0x00, 0x10, 0xd7, 0x34, + 0x3d, 0xef, 0xc7, 0x7e, 0x1c, 0xfb, 0xb1, 0x1f, + 0xb3, 0x00, 0x10, 0xd7, 0x34, 0x3d, 0xef, 0xc7, + 0x7e, 0x1c, 0xfb, 0xb1, 0xb3, 0x00, 0x10, 0xd7, + 0x34, 0x3d, 0x1f, 0xc7, 0x6c, 0x71, 0xb3, 0x00, + 0x10, 0xd7, 0x34, 0x3d, 0xef, 0xc7, 0x7e, 0x1c +}; + +uint8_t std_vect_148[] = { + 0x32, 0x6c, 0x71, 0xb3, 0x00, 0x10, 0xd7, 0x34, + 0x7e, 0x1c, 0xef, 0xb1, 0x1f, 0x9f, 0x00, 0x10, + 0xd7, 0x34, 0x3d, 0xe2, 0xc7, 0x7e, 0x1c, 0x1f, + 0xb3, 0x00, 0x10, 0xd7, 0x34, 0x3d, 0xe2, 0xc7, + 0x7e, 0x1c, 0x1f, 0xb3, 0x00, 0x10, 0xd7, 0x34, + 0x3d, 0xe2, 0xc7, 0x7e, 0x1c, 0xfb, 0xb1, 0xb3, + 0x00, 0x96, 0x96, 0x96 +}; + +uint8_t std_vect_149[] = { + 0x4a, 0xff, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x02, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x80, + 0xff +}; + +uint8_t std_vect_150[] = { + 0x1c ,0xe5 ,0x03 ,0x97 ,0x00 ,0x80 ,0xff ,0xff, + 0xa5 ,0xa5 ,0xa5 ,0xa5 ,0xa5 ,0xa5 ,0xa5 ,0x10, + 0xf3 ,0x1d ,0x1d ,0x09 ,0x1d ,0x09 ,0xa5 ,0x00, + 0x00 ,0x08 ,0xa5 ,0x30 ,0x11 ,0x11 ,0x11 ,0xa5, + 0xa5 ,0xa5 ,0xa5 ,0xa5 ,0x80 ,0xa8 ,0x7a ,0x11, + 0x11 ,0x09 ,0x01 ,0x09 ,0x1d ,0x1d ,0x09 ,0x05, + 0x1d ,0xa7 ,0x11 ,0x11 ,0x11 ,0x11 ,0x6d ,0x10, + 0x6d ,0x6d ,0xa5 ,0xa5 ,0x30 ,0x30 ,0x30 ,0x30, + 0x30 ,0x30 ,0x30 ,0x30 ,0x30 ,0x30 ,0x30 ,0x30, + 0x30 ,0x30 +}; + +struct vect_result { + uint8_t *vector; + int vector_length; + int expected_error; +}; + +struct vect_result std_vect_array[] = { + {std_vect_0, sizeof(std_vect_0), ISAL_INVALID_LOOKBACK}, + {std_vect_1, sizeof(std_vect_1), ISAL_INVALID_BLOCK}, + {std_vect_2, sizeof(std_vect_2), ISAL_INVALID_BLOCK}, + {std_vect_3, sizeof(std_vect_3), ISAL_INVALID_BLOCK}, + {std_vect_4, sizeof(std_vect_4), ISAL_INVALID_SYMBOL}, + {std_vect_5, sizeof(std_vect_5), ISAL_INVALID_BLOCK}, + {std_vect_6, sizeof(std_vect_6), ISAL_INVALID_LOOKBACK}, + {std_vect_7, sizeof(std_vect_7), ISAL_INVALID_BLOCK}, + {std_vect_8, sizeof(std_vect_8), ISAL_INVALID_BLOCK}, + {std_vect_9, sizeof(std_vect_9), ISAL_INVALID_BLOCK}, + {std_vect_10, sizeof(std_vect_10), ISAL_INVALID_BLOCK}, + {std_vect_11, sizeof(std_vect_11), ISAL_INVALID_LOOKBACK}, + {std_vect_12, sizeof(std_vect_12), ISAL_DECOMP_OK}, + {std_vect_13, sizeof(std_vect_13), ISAL_INVALID_LOOKBACK}, + {std_vect_14, sizeof(std_vect_14), ISAL_INVALID_LOOKBACK}, + {std_vect_15, sizeof(std_vect_15), ISAL_INVALID_BLOCK}, + {std_vect_16, sizeof(std_vect_16), ISAL_INVALID_BLOCK}, + {std_vect_17, sizeof(std_vect_17), ISAL_DECOMP_OK}, + {std_vect_18, sizeof(std_vect_18), ISAL_INVALID_LOOKBACK}, + {std_vect_19, sizeof(std_vect_19), ISAL_INVALID_SYMBOL}, + {std_vect_20, sizeof(std_vect_20), ISAL_INVALID_BLOCK}, + {std_vect_21, sizeof(std_vect_21), ISAL_INVALID_BLOCK}, + {std_vect_22, sizeof(std_vect_22), ISAL_INVALID_SYMBOL}, + {std_vect_23, sizeof(std_vect_23), ISAL_INVALID_LOOKBACK}, + {std_vect_24, sizeof(std_vect_24), ISAL_INVALID_SYMBOL}, + {std_vect_25, sizeof(std_vect_25), ISAL_INVALID_LOOKBACK}, + {std_vect_26, sizeof(std_vect_26), ISAL_INVALID_BLOCK}, + {std_vect_27, sizeof(std_vect_27), ISAL_INVALID_LOOKBACK}, + {std_vect_28, sizeof(std_vect_28), ISAL_INVALID_LOOKBACK}, + {std_vect_29, sizeof(std_vect_29), ISAL_INVALID_SYMBOL}, + {std_vect_30, sizeof(std_vect_30), ISAL_INVALID_BLOCK}, + {std_vect_31, sizeof(std_vect_31), ISAL_INVALID_BLOCK}, + {std_vect_32, sizeof(std_vect_32), ISAL_INVALID_SYMBOL}, + {std_vect_33, sizeof(std_vect_33), ISAL_INVALID_BLOCK}, + {std_vect_34, sizeof(std_vect_34), ISAL_INVALID_BLOCK}, + {std_vect_35, sizeof(std_vect_35), ISAL_INVALID_BLOCK}, + {std_vect_36, sizeof(std_vect_36), ISAL_INVALID_BLOCK}, + {std_vect_37, sizeof(std_vect_37), ISAL_INVALID_LOOKBACK}, + {std_vect_38, sizeof(std_vect_38), ISAL_INVALID_BLOCK}, + {std_vect_39, sizeof(std_vect_39), ISAL_INVALID_BLOCK}, + {std_vect_40, sizeof(std_vect_40), ISAL_INVALID_LOOKBACK}, + {std_vect_41, sizeof(std_vect_41), ISAL_END_INPUT}, + {std_vect_42, sizeof(std_vect_42), ISAL_INVALID_BLOCK}, + {std_vect_43, sizeof(std_vect_43), ISAL_INVALID_BLOCK}, + {std_vect_44, sizeof(std_vect_44), ISAL_INVALID_BLOCK}, + {std_vect_45, sizeof(std_vect_45), ISAL_INVALID_LOOKBACK}, + {std_vect_46, sizeof(std_vect_46), ISAL_INVALID_BLOCK}, + {std_vect_47, sizeof(std_vect_47), ISAL_INVALID_BLOCK}, + {std_vect_48, sizeof(std_vect_48), ISAL_INVALID_SYMBOL}, + {std_vect_49, sizeof(std_vect_49), ISAL_DECOMP_OK}, + {std_vect_50, sizeof(std_vect_50), ISAL_INVALID_BLOCK}, + {std_vect_51, sizeof(std_vect_51), ISAL_INVALID_BLOCK}, + {std_vect_52, sizeof(std_vect_52), ISAL_INVALID_BLOCK}, + {std_vect_53, sizeof(std_vect_53), ISAL_INVALID_BLOCK}, + {std_vect_54, sizeof(std_vect_54), ISAL_INVALID_BLOCK}, + {std_vect_55, sizeof(std_vect_55), ISAL_INVALID_SYMBOL}, + {std_vect_56, sizeof(std_vect_56), ISAL_INVALID_BLOCK}, + {std_vect_57, sizeof(std_vect_57), ISAL_INVALID_LOOKBACK}, + {std_vect_58, sizeof(std_vect_58), ISAL_INVALID_LOOKBACK}, + {std_vect_59, sizeof(std_vect_59), ISAL_INVALID_BLOCK}, + {std_vect_60, sizeof(std_vect_60), ISAL_END_INPUT}, + {std_vect_61, sizeof(std_vect_61), ISAL_INVALID_SYMBOL}, + {std_vect_62, sizeof(std_vect_62), ISAL_END_INPUT}, + {std_vect_63, sizeof(std_vect_63), ISAL_INVALID_SYMBOL}, + {std_vect_64, sizeof(std_vect_64), ISAL_INVALID_SYMBOL}, + {std_vect_65, sizeof(std_vect_65), ISAL_INVALID_BLOCK}, + {std_vect_66, sizeof(std_vect_66), ISAL_INVALID_BLOCK}, + {std_vect_67, sizeof(std_vect_67), ISAL_END_INPUT}, + {std_vect_68, sizeof(std_vect_68), ISAL_INVALID_BLOCK}, + {std_vect_69, sizeof(std_vect_69), ISAL_INVALID_BLOCK}, + {std_vect_70, sizeof(std_vect_70), ISAL_INVALID_BLOCK}, + {std_vect_71, sizeof(std_vect_71), ISAL_INVALID_BLOCK}, + {std_vect_72, sizeof(std_vect_72), ISAL_INVALID_BLOCK}, + {std_vect_73, sizeof(std_vect_73), ISAL_END_INPUT}, + {std_vect_74, sizeof(std_vect_74), ISAL_END_INPUT}, + {std_vect_75, sizeof(std_vect_75), ISAL_END_INPUT}, + {std_vect_76, sizeof(std_vect_76), ISAL_INVALID_BLOCK}, + {std_vect_77, sizeof(std_vect_77), ISAL_END_INPUT}, + {std_vect_78, sizeof(std_vect_78), ISAL_INVALID_BLOCK}, + {std_vect_79, sizeof(std_vect_79), ISAL_INVALID_BLOCK}, + {std_vect_80, sizeof(std_vect_80), ISAL_END_INPUT}, + {std_vect_81, sizeof(std_vect_81), ISAL_END_INPUT}, + {std_vect_82, sizeof(std_vect_82), ISAL_INVALID_BLOCK}, + {std_vect_83, sizeof(std_vect_83), ISAL_END_INPUT}, + {std_vect_84, sizeof(std_vect_84), ISAL_END_INPUT}, + {std_vect_85, sizeof(std_vect_85), ISAL_INVALID_SYMBOL}, + {std_vect_86, sizeof(std_vect_86), ISAL_END_INPUT}, + {std_vect_87, sizeof(std_vect_87), ISAL_INVALID_BLOCK}, + {std_vect_88, sizeof(std_vect_88), ISAL_END_INPUT}, + {std_vect_89, sizeof(std_vect_89), ISAL_END_INPUT}, + {std_vect_90, sizeof(std_vect_90), ISAL_END_INPUT}, + {std_vect_91, sizeof(std_vect_91), ISAL_INVALID_BLOCK}, + {std_vect_92, sizeof(std_vect_92), ISAL_INVALID_BLOCK}, + {std_vect_93, sizeof(std_vect_93), ISAL_END_INPUT}, + {std_vect_94, sizeof(std_vect_94), ISAL_INVALID_SYMBOL}, + {std_vect_95, sizeof(std_vect_95), ISAL_END_INPUT}, + {std_vect_96, sizeof(std_vect_96), ISAL_END_INPUT}, + {std_vect_97, sizeof(std_vect_97), ISAL_INVALID_BLOCK}, + {std_vect_98, sizeof(std_vect_98), ISAL_INVALID_BLOCK}, + {std_vect_99, sizeof(std_vect_99), ISAL_INVALID_BLOCK}, + {std_vect_100, sizeof(std_vect_100), ISAL_INVALID_BLOCK}, + {std_vect_101, sizeof(std_vect_101), ISAL_INVALID_BLOCK}, + {std_vect_102, sizeof(std_vect_102), ISAL_INVALID_BLOCK}, + {std_vect_103, sizeof(std_vect_103), ISAL_END_INPUT}, + {std_vect_104, sizeof(std_vect_104), ISAL_INVALID_BLOCK}, + {std_vect_105, sizeof(std_vect_105), ISAL_INVALID_BLOCK}, + {std_vect_106, sizeof(std_vect_106), ISAL_INVALID_BLOCK}, + {std_vect_107, sizeof(std_vect_107), ISAL_INVALID_BLOCK}, + {std_vect_108, sizeof(std_vect_108), ISAL_END_INPUT}, + {std_vect_109, sizeof(std_vect_109), ISAL_INVALID_BLOCK}, + {std_vect_110, sizeof(std_vect_110), ISAL_INVALID_BLOCK}, + {std_vect_111, sizeof(std_vect_111), ISAL_END_INPUT}, + {std_vect_112, sizeof(std_vect_112), ISAL_INVALID_BLOCK}, + {std_vect_113, sizeof(std_vect_113), ISAL_INVALID_BLOCK}, + {std_vect_114, sizeof(std_vect_114), ISAL_INVALID_LOOKBACK}, + {std_vect_115, sizeof(std_vect_115), ISAL_END_INPUT}, + {std_vect_116, sizeof(std_vect_116), ISAL_INVALID_BLOCK}, + {std_vect_117, sizeof(std_vect_117), ISAL_INVALID_BLOCK}, + {std_vect_118, sizeof(std_vect_118), ISAL_INVALID_BLOCK}, + {std_vect_119, sizeof(std_vect_119), ISAL_END_INPUT}, + {std_vect_120, sizeof(std_vect_120), ISAL_INVALID_SYMBOL}, + {std_vect_121, sizeof(std_vect_121), ISAL_INVALID_BLOCK}, + {std_vect_122, sizeof(std_vect_122), ISAL_INVALID_BLOCK}, + {std_vect_123, sizeof(std_vect_123), ISAL_INVALID_BLOCK}, + {std_vect_124, sizeof(std_vect_124), ISAL_INVALID_BLOCK}, + {std_vect_125, sizeof(std_vect_125), ISAL_INVALID_BLOCK}, + {std_vect_126, sizeof(std_vect_126), ISAL_INVALID_BLOCK}, + {std_vect_127, sizeof(std_vect_127), ISAL_INVALID_BLOCK}, + {std_vect_128, sizeof(std_vect_128), ISAL_INVALID_BLOCK}, + {std_vect_129, sizeof(std_vect_129), ISAL_INVALID_BLOCK}, + {std_vect_130, sizeof(std_vect_130), ISAL_END_INPUT}, + {std_vect_131, sizeof(std_vect_131), ISAL_INVALID_BLOCK}, + {std_vect_132, sizeof(std_vect_132), ISAL_INVALID_SYMBOL}, + {std_vect_133, sizeof(std_vect_133), ISAL_INVALID_BLOCK}, + {std_vect_134, sizeof(std_vect_134), ISAL_INVALID_BLOCK}, + {std_vect_135, sizeof(std_vect_135), ISAL_INVALID_BLOCK}, + {std_vect_136, sizeof(std_vect_136), ISAL_INVALID_BLOCK}, + {std_vect_137, sizeof(std_vect_137), ISAL_INVALID_BLOCK}, + {std_vect_138, sizeof(std_vect_138), ISAL_INVALID_SYMBOL}, + {std_vect_139, sizeof(std_vect_139), ISAL_INVALID_SYMBOL}, + {std_vect_140, sizeof(std_vect_140), ISAL_INVALID_BLOCK}, + {std_vect_141, sizeof(std_vect_141), ISAL_END_INPUT}, + {std_vect_142, sizeof(std_vect_142), ISAL_INVALID_BLOCK}, + {std_vect_143, sizeof(std_vect_143), ISAL_INVALID_BLOCK}, + {std_vect_144, sizeof(std_vect_144), ISAL_INVALID_BLOCK}, + {std_vect_145, sizeof(std_vect_145), ISAL_END_INPUT}, + {std_vect_146, sizeof(std_vect_146), ISAL_INVALID_BLOCK}, + {std_vect_147, sizeof(std_vect_147), ISAL_INVALID_BLOCK}, + {std_vect_148, sizeof(std_vect_148), ISAL_INVALID_BLOCK}, + {std_vect_149, sizeof(std_vect_149), ISAL_INVALID_BLOCK}, + {std_vect_150, sizeof(std_vect_150), ISAL_INVALID_SYMBOL} +}; diff --git a/ceph/src/isa-l/igzip/lz0a_const.asm b/ceph/src/isa-l/igzip/lz0a_const.asm index 4d9573958..a37abc0b7 100644 --- a/ceph/src/isa-l/igzip/lz0a_const.asm +++ b/ceph/src/isa-l/igzip/lz0a_const.asm @@ -27,18 +27,30 @@ ; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%include "options.asm" + %assign K 1024 -%assign D HIST_SIZE * K ;; Amount of history -%assign LA 17 * 16 ;; Max look-ahead, rounded up to 32 byte boundary -%assign BSIZE 2*HIST_SIZE*K + LA ;; Nominal buffer size +%assign D IGZIP_HIST_SIZE ;; Amount of history +%assign LA 18 * 16 ;; Max look-ahead, rounded up to 32 byte boundary +%assign BSIZE 2*IGZIP_HIST_SIZE + LA ;; Nominal buffer size ;; Constants for stateless compression %define LAST_BYTES_COUNT 3 ;; Bytes to prevent reading out of array bounds %define LA_STATELESS 258 ;; No round up since no data is copied to a buffer -%assign HASH_SIZE D -%assign HASH_MASK (HASH_SIZE - 1) +%ifndef IGZIP_HASH_SIZE +%assign IGZIP_HASH_SIZE (8 * K) +%endif + +%assign HASH_MASK (IGZIP_HASH_SIZE - 1) -%assign SHORTEST_MATCH 3 +%assign SHORTEST_MATCH 4 %assign SLOP 8 + +%define LIT_LEN_BIT_COUNT 10 +%define DIST_LIT_BIT_COUNT 9 + +%define DIST_OFFSET LIT_LEN_BIT_COUNT +%define EXTRA_BITS_OFFSET (DIST_OFFSET + DIST_LIT_BIT_COUNT) +%define LIT (0x1E << DIST_OFFSET) diff --git a/ceph/src/isa-l/igzip/options.asm b/ceph/src/isa-l/igzip/options.asm index d86a41f3d..69e9e9d70 100644 --- a/ceph/src/isa-l/igzip/options.asm +++ b/ceph/src/isa-l/igzip/options.asm @@ -32,10 +32,6 @@ default rel %ifndef __OPTIONS_ASM__ %define __OPTIONS_ASM__ -%ifndef IGZIP_USE_GZIP_FORMAT -%define DEFLATE -%endif - ; Options:dir ; m - reschedule mem reads ; e b - bitbuff style @@ -44,10 +40,20 @@ default rel ; l - use longer huffman table ; f - fix cache read -%ifdef LARGE_WINDOW -%define HIST_SIZE 32 -%else -%define HIST_SIZE 8 +%ifndef IGZIP_HIST_SIZE +%define IGZIP_HIST_SIZE (32 * 1024) +%endif + +%if (IGZIP_HIST_SIZE > (32 * 1024)) +%undef IGZIP_HIST_SIZE +%define IGZIP_HIST_SIZE (32 * 1024) +%endif + +%ifdef LONGER_HUFFTABLE +%if (IGZIP_HIST_SIZE > 8 * 1024) +%undef IGZIP_HIST_SIZE +%define IGZIP_HIST_SIZE (8 * 1024) +%endif %endif %ifdef USE_BITBUFB @@ -62,17 +68,10 @@ default rel ; (h) limit hash update %define LIMIT_HASH_UPDATE -; (l) longer huffman table -%define LONGER_HUFFTABLE - ; (f) fix cache read problem %define FIX_CACHE_READ -%if (HIST_SIZE > 8) -%undef LONGER_HUFFTABLE -%endif - -%define IGZIP_MAX_DEF_HDR_SIZE 328 +%define ISAL_DEF_MAX_HDR_SIZE 328 %ifidn __OUTPUT_FORMAT__, elf64 %ifndef __NASM_VER__ diff --git a/ceph/src/isa-l/igzip/proc_heap.asm b/ceph/src/isa-l/igzip/proc_heap.asm new file mode 100644 index 000000000..75238e729 --- /dev/null +++ b/ceph/src/isa-l/igzip/proc_heap.asm @@ -0,0 +1,97 @@ +; returns modified node_ptr +; uint32_t proc_heap(uint64_t *heap, uint32_t heap_size); + +%include "reg_sizes.asm" +%include "heap_macros.asm" + +%ifidn __OUTPUT_FORMAT__, win64 +%define heap rcx ; pointer, 64-bit +%define heap_size rdx +%define arg3 r8 +%define child rsi +%define tmp32 rdi +%else +%define heap rdi +%define heap_size rsi +%define arg3 rdx +%define child rcx +%define tmp32 rdx +%endif + +%define node_ptr rax +%define h1 r8 +%define h2 r9 +%define h3 r10 +%define i r11 +%define tmp2 r12 + + global build_huff_tree +build_huff_tree: +%ifidn __OUTPUT_FORMAT__, win64 + push rsi + push rdi +%endif + push r12 + + mov node_ptr, arg3 +.main_loop: + ; REMOVE_MIN64(heap, heap_size, h1); + mov h2, [heap + heap_size*8] + mov h1, [heap + 1*8] + mov qword [heap + heap_size*8], -1 + dec heap_size + mov [heap + 1*8], h2 + + mov i, 1 + heapify heap, heap_size, i, child, h2, h3, tmp32, tmp2 + + mov h2, [heap + 1*8] + lea h3, [h1 + h2] + mov [heap + node_ptr*8], h1 %+ w + mov [heap + node_ptr*8 - 8], h2 %+ w + + and h3, ~0xffff + or h3, node_ptr + sub node_ptr, 2 + + ; replace_min64(heap, heap_size, h3) + mov [heap + 1*8], h3 + mov i, 1 + heapify heap, heap_size, i, child, h2, h3, tmp32, tmp2 + + cmp heap_size, 1 + ja .main_loop + + mov h1, [heap + 1*8] + mov [heap + node_ptr*8], h1 %+ w + + pop r12 +%ifidn __OUTPUT_FORMAT__, win64 + pop rdi + pop rsi +%endif + ret + +align 32 + global build_heap +build_heap: +%ifidn __OUTPUT_FORMAT__, win64 + push rsi + push rdi +%endif + push r12 + mov qword [heap + heap_size*8 + 8], -1 + mov i, heap_size + shr i, 1 +.loop: + mov h1, i + heapify heap, heap_size, h1, child, h2, h3, tmp32, tmp2 + dec i + jnz .loop + + pop r12 +%ifidn __OUTPUT_FORMAT__, win64 + pop rdi + pop rsi +%endif + ret diff --git a/ceph/src/isa-l/igzip/proc_heap_base.c b/ceph/src/isa-l/igzip/proc_heap_base.c new file mode 100644 index 000000000..8794d209b --- /dev/null +++ b/ceph/src/isa-l/igzip/proc_heap_base.c @@ -0,0 +1,84 @@ +/********************************************************************** + Copyright(c) 2011-2017 Intel Corporation All rights reserved. + + 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 Intel Corporation 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 + 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. +**********************************************************************/ + +#include "igzip_lib.h" +#include "huff_codes.h" + +void inline heapify(uint64_t * heap, uint64_t heap_size, uint64_t index) +{ + uint64_t child = 2 * index, tmp; + while (child <= heap_size) { + child = (heap[child] <= heap[child + 1]) ? child : child + 1; + + if (heap[index] > heap[child]) { + tmp = heap[index]; + heap[index] = heap[child]; + heap[child] = tmp; + index = child; + child = 2 * index; + } else + break; + } +} + +void build_heap(uint64_t * heap, uint64_t heap_size) +{ + uint64_t i; + heap[heap_size + 1] = -1; + for (i = heap_size / 2; i > 0; i--) + heapify(heap, heap_size, i); + +} + +uint32_t build_huff_tree(struct heap_tree *heap_space, uint64_t heap_size, uint64_t node_ptr) +{ + uint64_t *heap = (uint64_t *) heap_space; + uint64_t h1, h2; + + while (heap_size > 1) { + h1 = heap[1]; + heap[1] = heap[heap_size]; + heap[heap_size--] = -1; + + heapify(heap, heap_size, 1); + + h2 = heap[1]; + heap[1] = ((h1 + h2) & ~0xFFFFull) | node_ptr; + + heapify(heap, heap_size, 1); + + *(uint16_t *) (&heap[node_ptr]) = h1; + *(uint16_t *) (&heap[node_ptr - 1]) = h2; + node_ptr -= 2; + + } + h1 = heap[1]; + *(uint16_t *) (&heap[node_ptr]) = h1; + return node_ptr; +} diff --git a/ceph/src/isa-l/igzip/rfc1951_lookup.asm b/ceph/src/isa-l/igzip/rfc1951_lookup.asm new file mode 100644 index 000000000..d6fc695d1 --- /dev/null +++ b/ceph/src/isa-l/igzip/rfc1951_lookup.asm @@ -0,0 +1,89 @@ +%include "reg_sizes.asm" + +%ifndef RFC1951_LOOKUP +%define RFC1951_LOOKUP + +section .data + + align 8 + +;; /* Structure contain lookup data based on RFC 1951 */ +;; struct rfc1951_tables { +;; uint8_t len_to_code[264]; +;; uint8_t dist_extra_bit_count[32]; +;; uint32_t dist_start[32]; +;; uint8_t len_extra_bit_count[32]; +;; uint16_t len_start[32]; +;; }; + +global rfc1951_lookup_table:data internal +rfc1951_lookup_table: +len_to_code: + db 0x00, 0x00, 0x00 + db 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 + db 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c + db 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0e, 0x0e + db 0x0f, 0x0f, 0x0f, 0x0f, 0x10, 0x10, 0x10, 0x10 + db 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 + db 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12 + db 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 + db 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14 + db 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15 + db 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15 + db 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16 + db 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16 + db 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17 + db 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17 + db 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 + db 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 + db 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 + db 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 + db 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 + db 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 + db 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a + db 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a + db 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a + db 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a + db 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b + db 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b + db 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b + db 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b + db 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c + db 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c + db 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c + db 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1d + db 0x00, 0x00, 0x00, 0x00, 0x00 + +dist_extra_bit_count: + db 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02 + db 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06 + db 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a + db 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x00, 0x00 + +dist_start: + dd 0x00000001, 0x00000002, 0x00000003, 0x00000004 + dd 0x00000005, 0x00000007, 0x00000009, 0x0000000d + dd 0x00000011, 0x00000019, 0x00000021, 0x00000031 + dd 0x00000041, 0x00000061, 0x00000081, 0x000000c1 + dd 0x00000101, 0x00000181, 0x00000201, 0x00000301 + dd 0x00000401, 0x00000601, 0x00000801, 0x00000c01 + dd 0x00001001, 0x00001801, 0x00002001, 0x00003001 + dd 0x00004001, 0x00006001, 0x00000000, 0x00000000 + +len_extra_bit_count: + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + db 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02 + db 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04 + db 0x05, 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00 + +len_start: + dw 0x0003, 0x0004, 0x0005, 0x0006 + dw 000007, 0x0008, 0x0009, 0x000a + dw 0x000b, 0x000d, 0x000f, 0x0011 + dw 0x0013, 0x0017, 0x001b, 0x001f + dw 0x0023, 0x002b, 0x0033, 0x003b + dw 0x0043, 0x0053, 0x0063, 0x0073 + dw 0x0083, 0x00a3, 0x00c3, 0x00e3 + dw 0x0102, 0x0000, 0x0000, 0x0000 + +%endif ; RFC1951_LOOKUP diff --git a/ceph/src/isa-l/igzip/stdmac.asm b/ceph/src/isa-l/igzip/stdmac.asm index a4c2b6fe2..500ee7fd8 100644 --- a/ceph/src/isa-l/igzip/stdmac.asm +++ b/ceph/src/isa-l/igzip/stdmac.asm @@ -27,7 +27,8 @@ ; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - +%ifndef STDMAC_ASM +%define STDMAC_ASM ;; internal macro used by push_all ;; push args L to R %macro push_all_ 1-* @@ -205,3 +206,184 @@ ssc: mov rbx, rax ret %endm + +;; Implement BZHI instruction on older architectures +;; Clobbers rcx, unless rcx is %%index +%macro BZHI 4 +%define %%dest %1 +%define %%src %2 +%define %%index %3 +%define %%tmp1 %4 + +%ifdef USE_HSWNI + bzhi %%dest, %%src, %%index +%else +%ifnidn %%index, rcx + mov rcx, %%index +%endif + mov %%tmp1, 1 + shl %%tmp1, cl + sub %%tmp1, 1 + +%ifnidn %%src, %%dest + mov %%dest, %%src +%endif + + and %%dest, %%tmp1 +%endif +%endm + +;; Implement shrx instruction on older architectures +;; Clobbers rcx, unless rcx is %%index +%macro SHRX 3 +%define %%dest %1 +%define %%src %2 +%define %%index %3 + +%ifdef USE_HSWNI + shrx %%dest, %%src, %%index +%else +%ifnidn %%src, %%dest + mov %%dest, %%src +%endif +%ifnidn %%index, rcx + mov rcx, %%index +%endif + shr %%dest, cl +%endif +%endm + +;; Implement shlx instruction on older architectures +;; Clobbers rcx, unless rcx is %%index +%macro SHLX 3 +%define %%dest %1 +%define %%src %2 +%define %%index %3 + +%ifdef USE_HSWNI + shlx %%dest, %%src, %%index +%else +%ifnidn %%src, %%dest + mov %%dest, %%src +%endif +%ifnidn %%index, rcx + mov rcx, %%index +%endif + shl %%dest, cl +%endif +%endm + +%macro MOVDQU 2 +%define %%dest %1 +%define %%src %2 +%if ((ARCH == 02) || (ARCH == 03) || (ARCH == 04)) + vmovdqu %%dest, %%src +%else + movdqu %%dest, %%src +%endif +%endm + +%macro MOVD 2 +%define %%dest %1 +%define %%src %2 +%if (ARCH == 02 || ARCH == 03 || ARCH == 04) + vmovd %%dest, %%src +%else + movd %%dest, %%src +%endif +%endm + +%macro MOVQ 2 +%define %%dest %1 +%define %%src %2 +%if (ARCH == 02 || ARCH == 03 || ARCH == 04) + vmovq %%dest, %%src +%else + movq %%dest, %%src +%endif +%endm + +%macro PINSRD 3 +%define %%dest %1 +%define %%src %2 +%define %%offset %3 +%if ((ARCH == 02) || (ARCH == 03) || (ARCH == 04)) + vpinsrd %%dest, %%src, %%offset +%else + pinsrd %%dest, %%src, %%offset +%endif +%endm + +%macro PEXTRD 3 +%define %%dest %1 +%define %%src %2 +%define %%offset %3 +%if ((ARCH == 02) || (ARCH == 03) || (ARCH == 04)) + vpextrd %%dest, %%src, %%offset +%else + pextrd %%dest, %%src, %%offset +%endif +%endm + +%macro PSRLDQ 2 +%define %%dest %1 +%define %%offset %2 +%if ((ARCH == 02) || (ARCH == 03) || (ARCH == 04)) + vpsrldq %%dest, %%offset +%else + psrldq %%dest, %%offset +%endif +%endm + +%macro PAND 3 +%define %%dest %1 +%define %%src1 %2 +%define %%src2 %3 +%if (ARCH == 02 || ARCH == 03 || ARCH == 04) + vpand %%dest, %%src1, %%src2 +%else +%ifnidn %%dest, %%src1 + movdqa %%dest, %%src1 +%endif + pand %%dest, %%src2 +%endif +%endm + +%macro PCMPEQB 3 +%define %%dest %1 +%define %%src1 %2 +%define %%src2 %3 +%if ((ARCH == 02) || (ARCH == 03) || (ARCH == 04)) + vpcmpeqb %%dest, %%src1, %%src2 +%else +%ifnidn %%dest, %%src1 + movdqa %%dest, %%src1 +%endif + pcmpeqb %%dest, %%src2 +%endif +%endm + +%macro PMOVMSKB 2 +%define %%dest %1 +%define %%src %2 +%if ((ARCH == 02) || (ARCH == 03) || (ARCH == 04)) + vpmovmskb %%dest, %%src +%else + pmovmskb %%dest, %%src +%endif +%endm + +%macro PXOR 3 +%define %%dest %1 +%define %%src1 %2 +%define %%src2 %3 +%if ((ARCH == 02) || (ARCH == 03) || (ARCH == 04)) + vpxor %%dest, %%src1, %%src2 +%else +%ifnidn %%dest, %%src1 + movdqa %%dest, %%src1 +%endif + pxor %%dest, %%src2 +%endif +%endm +%endif ;; ifndef STDMAC_ASM diff --git a/ceph/src/isa-l/include/crc64.h b/ceph/src/isa-l/include/crc64.h new file mode 100644 index 000000000..8d7d81f9b --- /dev/null +++ b/ceph/src/isa-l/include/crc64.h @@ -0,0 +1,277 @@ +/********************************************************************** + Copyright(c) 2011-2016 Intel Corporation All rights reserved. + + 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 Intel Corporation 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 + 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. +**********************************************************************/ + + +/** + * @file crc64.h + * @brief CRC64 functions. + */ + + +#ifndef _CRC64_H_ +#define _CRC64_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Multi-binary functions */ + +/** + * @brief Generate CRC from ECMA-182 standard in reflected format, runs + * appropriate version. + * + * This function determines what instruction sets are enabled and + * selects the appropriate version at runtime. + * @returns 64 bit CRC + */ +uint64_t crc64_ecma_refl( + uint64_t init_crc, //!< initial CRC value, 64 bits + const unsigned char *buf, //!< buffer to calculate CRC on + uint64_t len //!< buffer length in bytes (64-bit data) + ); + +/** + * @brief Generate CRC from ECMA-182 standard in normal format, runs + * appropriate version. + * + * This function determines what instruction sets are enabled and + * selects the appropriate version at runtime. + * @returns 64 bit CRC + */ +uint64_t crc64_ecma_norm( + uint64_t init_crc, //!< initial CRC value, 64 bits + const unsigned char *buf, //!< buffer to calculate CRC on + uint64_t len //!< buffer length in bytes (64-bit data) + ); + +/** + * @brief Generate CRC from ISO standard in reflected format, runs + * appropriate version. + * + * This function determines what instruction sets are enabled and + * selects the appropriate version at runtime. + * @returns 64 bit CRC + */ +uint64_t crc64_iso_refl( + uint64_t init_crc, //!< initial CRC value, 64 bits + const unsigned char *buf, //!< buffer to calculate CRC on + uint64_t len //!< buffer length in bytes (64-bit data) + ); + +/** + * @brief Generate CRC from ISO standard in normal format, runs + * appropriate version. + * + * This function determines what instruction sets are enabled and + * selects the appropriate version at runtime. + * @returns 64 bit CRC + */ +uint64_t crc64_iso_norm( + uint64_t init_crc, //!< initial CRC value, 64 bits + const unsigned char *buf, //!< buffer to calculate CRC on + uint64_t len //!< buffer length in bytes (64-bit data) + ); + +/** + * @brief Generate CRC from "Jones" coefficients in reflected format, runs + * appropriate version. + * + * This function determines what instruction sets are enabled and + * selects the appropriate version at runtime. + * @returns 64 bit CRC + */ +uint64_t crc64_jones_refl( + uint64_t init_crc, //!< initial CRC value, 64 bits + const unsigned char *buf, //!< buffer to calculate CRC on + uint64_t len //!< buffer length in bytes (64-bit data) + ); + +/** + * @brief Generate CRC from "Jones" coefficients in normal format, runs + * appropriate version. + * + * This function determines what instruction sets are enabled and + * selects the appropriate version at runtime. + * @returns 64 bit CRC + */ +uint64_t crc64_jones_norm( + uint64_t init_crc, //!< initial CRC value, 64 bits + const unsigned char *buf, //!< buffer to calculate CRC on + uint64_t len //!< buffer length in bytes (64-bit data) + ); + +/* Arch specific versions */ + +/** + * @brief Generate CRC from ECMA-182 standard in reflected format. + * @requires SSE3, CLMUL + * + * @returns 64 bit CRC + */ + +uint64_t crc64_ecma_refl_by8( + uint64_t init_crc, //!< initial CRC value, 64 bits + const unsigned char *buf, //!< buffer to calculate CRC on + uint64_t len //!< buffer length in bytes (64-bit data) + ); + +/** + * @brief Generate CRC from ECMA-182 standard in normal format. + * @requires SSE3, CLMUL + * + * @returns 64 bit CRC + */ + +uint64_t crc64_ecma_norm_by8( + uint64_t init_crc, //!< initial CRC value, 64 bits + const unsigned char *buf, //!< buffer to calculate CRC on + uint64_t len //!< buffer length in bytes (64-bit data) + ); + +/** + * @brief Generate CRC from ECMA-182 standard in reflected format, runs baseline version + * @returns 64 bit CRC + */ +uint64_t crc64_ecma_refl_base( + uint64_t init_crc, //!< initial CRC value, 64 bits + const unsigned char *buf, //!< buffer to calculate CRC on + uint64_t len //!< buffer length in bytes (64-bit data) + ); + +/** + * @brief Generate CRC from ECMA-182 standard in normal format, runs baseline version + * @returns 64 bit CRC + */ +uint64_t crc64_ecma_norm_base( + uint64_t init_crc, //!< initial CRC value, 64 bits + const unsigned char *buf, //!< buffer to calculate CRC on + uint64_t len //!< buffer length in bytes (64-bit data) + ); + +/** + * @brief Generate CRC from ISO standard in reflected format. + * @requires SSE3, CLMUL + * + * @returns 64 bit CRC + */ + +uint64_t crc64_iso_refl_by8( + uint64_t init_crc, //!< initial CRC value, 64 bits + const unsigned char *buf, //!< buffer to calculate CRC on + uint64_t len //!< buffer length in bytes (64-bit data) + ); + +/** + * @brief Generate CRC from ISO standard in normal format. + * @requires SSE3, CLMUL + * + * @returns 64 bit CRC + */ + +uint64_t crc64_iso_norm_by8( + uint64_t init_crc, //!< initial CRC value, 64 bits + const unsigned char *buf, //!< buffer to calculate CRC on + uint64_t len //!< buffer length in bytes (64-bit data) + ); + +/** + * @brief Generate CRC from ISO standard in reflected format, runs baseline version + * @returns 64 bit CRC + */ +uint64_t crc64_iso_refl_base( + uint64_t init_crc, //!< initial CRC value, 64 bits + const unsigned char *buf, //!< buffer to calculate CRC on + uint64_t len //!< buffer length in bytes (64-bit data) + ); + +/** + * @brief Generate CRC from ISO standard in normal format, runs baseline version + * @returns 64 bit CRC + */ +uint64_t crc64_iso_norm_base( + uint64_t init_crc, //!< initial CRC value, 64 bits + const unsigned char *buf, //!< buffer to calculate CRC on + uint64_t len //!< buffer length in bytes (64-bit data) + ); + +/** + * @brief Generate CRC from "Jones" coefficients in reflected format. + * @requires SSE3, CLMUL + * + * @returns 64 bit CRC + */ + +uint64_t crc64_jones_refl_by8( + uint64_t init_crc, //!< initial CRC value, 64 bits + const unsigned char *buf, //!< buffer to calculate CRC on + uint64_t len //!< buffer length in bytes (64-bit data) + ); + +/** + * @brief Generate CRC from "Jones" coefficients in normal format. + * @requires SSE3, CLMUL + * + * @returns 64 bit CRC + */ + +uint64_t crc64_jones_norm_by8( + uint64_t init_crc, //!< initial CRC value, 64 bits + const unsigned char *buf, //!< buffer to calculate CRC on + uint64_t len //!< buffer length in bytes (64-bit data) + ); + +/** + * @brief Generate CRC from "Jones" coefficients in reflected format, runs baseline version + * @returns 64 bit CRC + */ +uint64_t crc64_jones_refl_base( + uint64_t init_crc, //!< initial CRC value, 64 bits + const unsigned char *buf, //!< buffer to calculate CRC on + uint64_t len //!< buffer length in bytes (64-bit data) + ); + +/** + * @brief Generate CRC from "Jones" coefficients in normal format, runs baseline version + * @returns 64 bit CRC + */ +uint64_t crc64_jones_norm_base( + uint64_t init_crc, //!< initial CRC value, 64 bits + const unsigned char *buf, //!< buffer to calculate CRC on + uint64_t len //!< buffer length in bytes (64-bit data) + ); + +#ifdef __cplusplus +} +#endif + +#endif // _CRC64_H_ diff --git a/ceph/src/isa-l/include/igzip_lib.h b/ceph/src/isa-l/include/igzip_lib.h index 1dd930c2b..3cba3fafa 100644 --- a/ceph/src/isa-l/include/igzip_lib.h +++ b/ceph/src/isa-l/include/igzip_lib.h @@ -33,14 +33,14 @@ /** * @file igzip_lib.h * - * @brief This file defines the igzip compression interface, a high performance - * deflate compression interface for storage applications. + * @brief This file defines the igzip compression and decompression interface, a + * high performance deflate compression interface for storage applications. * * Deflate is a widely used compression standard that can be used standalone, it * also forms the basis of gzip and zlib compression formats. Igzip supports the * following flush features: * - * - No Flush: The default method where no flush is performed. + * - No Flush: The default method where no special flush is performed. * * - Sync flush: whereby isal_deflate() finishes the current deflate block at * the end of each input buffer. The deflate block is byte aligned by @@ -50,22 +50,25 @@ * in sync flush but also ensures that subsequent block's history does not * look back beyond this point and new blocks are fully independent. * - * Igzip's default configuration is: + * Igzip also supports compression levels from ISAL_DEF_MIN_LEVEL to + * ISAL_DEF_MAX_LEVEL. * - * - 8K window size + * Igzip contains some behaviour configurable at compile time. These + * configureable options are: * - * This option can be overridden to enable: + * - IGZIP_HIST_SIZE - Defines the window size. The default value is 32K (note K + * represents 1024), but 8K is also supported. Powers of 2 which are at most + * 32K may also work. * - * - 32K window size, by adding \#define LARGE_WINDOW 1 in igzip_lib.h and - * \%define LARGE_WINDOW in options.asm, or via the command line with - * @verbatim gmake D="-D LARGE_WINDOW" @endverbatim on Linux and FreeBSD, or - * with @verbatim nmake -f Makefile.nmake D="-D LARGE_WINDOW" @endverbatim on - * Windows. + * - LONGER_HUFFTABLES - Defines whether to use a larger hufftables structure + * which may increase performance with smaller IGZIP_HIST_SIZE values. By + * default this optoin is not defined. This define sets IGZIP_HIST_SIZE to be + * 8 if IGZIP_HIST_SIZE > 8K. * - * KNOWN ISSUES: - * - If building the code on Windows with the 32K window enabled, the - * /LARGEADDRESSAWARE:NO link option must be added. - * - The 32K window isn't supported when used in a shared library. + * As an example, to compile gzip with an 8K window size, in a terminal run + * @verbatim gmake D="-D IGZIP_HIST_SIZE=8*1024" @endverbatim on Linux and + * FreeBSD, or with @verbatim nmake -f Makefile.nmake D="-D + * IGZIP_HIST_SIZE=8*1024" @endverbatim on Windows. * */ #include @@ -75,74 +78,63 @@ extern "C" { #endif -// Options:dir -// m - reschedule mem reads -// e b - bitbuff style -// t s x - compare style -// h - limit hash updates -// l - use longer huffman table -// f - fix cache read - -#if defined(LARGE_WINDOW) -# define HIST_SIZE 32 -#else -# define HIST_SIZE 8 +/******************************************************************************/ +/* Deflate Compression Standard Defines */ +/******************************************************************************/ +#define IGZIP_K 1024 +#define ISAL_DEF_MAX_HDR_SIZE 328 +#define ISAL_DEF_MAX_CODE_LEN 15 +#define ISAL_DEF_HIST_SIZE (32*IGZIP_K) + +#define ISAL_DEF_LIT_SYMBOLS 257 +#define ISAL_DEF_LEN_SYMBOLS 29 +#define ISAL_DEF_DIST_SYMBOLS 30 +#define ISAL_DEF_LIT_LEN_SYMBOLS (ISAL_DEF_LIT_SYMBOLS + ISAL_DEF_LEN_SYMBOLS) + +#define ISAL_LOOK_AHEAD (18 * 16) /* Max repeat length, rounded up to 32 byte boundary */ + +/******************************************************************************/ +/* Deflate Implemenation Specific Defines */ +/******************************************************************************/ +/* Note IGZIP_HIST_SIZE must be a power of two */ +#ifndef IGZIP_HIST_SIZE +#define IGZIP_HIST_SIZE ISAL_DEF_HIST_SIZE #endif -/* bit buffer types - * BITBUF8: (e) Always write 8 bytes of data - * BITBUFB: (b) Always write data - */ -#if !(defined(USE_BITBUFB) || defined(USE_BITBUF8) || defined(USE_BITBUF_ELSE)) -# define USE_BITBUFB +#if (IGZIP_HIST_SIZE > ISAL_DEF_HIST_SIZE) +#undef IGZIP_HIST_SIZE +#define IGZIP_HIST_SIZE ISAL_DEF_HIST_SIZE #endif -/* compare types - * 1: ( ) original - * 2: (t) with CMOV - * 3: (s) with sttni - * 4: (x) with xmm / pmovbmsk - * 5: (y) with ymm / pmovbmsk (32-bytes at a time) - */ -# define LIMIT_HASH_UPDATE - -/* (l) longer huffman table */ -#define LONGER_HUFFTABLE - -/* (f) fix cache read problem */ -#define FIX_CACHE_READ - -#if (HIST_SIZE > 8) -# undef LONGER_HUFFTABLE +#ifdef LONGER_HUFFTABLE +#if (IGZIP_HIST_SIZE > 8 * IGZIP_K) +#undef IGZIP_HIST_SIZE +#define IGZIP_HIST_SIZE (8 * IGZIP_K) +#endif #endif -#define IGZIP_K 1024 -#define IGZIP_D (HIST_SIZE * IGZIP_K) /* Amount of history */ -#define IGZIP_LA (17 * 16) /* Max look-ahead, rounded up to 32 byte boundary */ -#define BSIZE (2*IGZIP_D + IGZIP_LA) /* Nominal buffer size */ - -#define HASH_SIZE IGZIP_D -#define HASH_MASK (HASH_SIZE - 1) - -#define SHORTEST_MATCH 3 +#define ISAL_LIMIT_HASH_UPDATE -#define IGZIP_MAX_DEF_HDR_SIZE 328 +#ifndef IGZIP_HASH_SIZE +#define IGZIP_HASH_SIZE (8 * IGZIP_K) +#endif #ifdef LONGER_HUFFTABLE -enum {DIST_TABLE_SIZE = 8*1024}; +enum {IGZIP_DIST_TABLE_SIZE = 8*1024}; /* DECODE_OFFSET is dist code index corresponding to DIST_TABLE_SIZE + 1 */ -enum { DECODE_OFFSET = 26 }; +enum { IGZIP_DECODE_OFFSET = 26 }; #else -enum {DIST_TABLE_SIZE = 1024}; +enum {IGZIP_DIST_TABLE_SIZE = 2}; /* DECODE_OFFSET is dist code index corresponding to DIST_TABLE_SIZE + 1 */ -enum { DECODE_OFFSET = 20 }; +enum { IGZIP_DECODE_OFFSET = 0 }; #endif -enum {LEN_TABLE_SIZE = 256}; -enum {LIT_TABLE_SIZE = 257}; +enum {IGZIP_LEN_TABLE_SIZE = 256}; +enum {IGZIP_LIT_TABLE_SIZE = ISAL_DEF_LIT_SYMBOLS}; -#define IGZIP_LIT_LEN 286 -#define IGZIP_DIST_LEN 30 +#define IGZIP_HUFFTABLE_CUSTOM 0 +#define IGZIP_HUFFTABLE_DEFAULT 1 +#define IGZIP_HUFFTABLE_STATIC 2 /* Flush Flags */ #define NO_FLUSH 0 /* Default */ @@ -150,14 +142,21 @@ enum {LIT_TABLE_SIZE = 257}; #define FULL_FLUSH 2 #define FINISH_FLUSH 0 /* Deprecated */ -/* Return values */ +/* Gzip Flags */ +#define IGZIP_DEFLATE 0 /* Default */ +#define IGZIP_GZIP 1 +#define IGZIP_GZIP_NO_HDR 2 + +/* Compression Return values */ #define COMP_OK 0 #define INVALID_FLUSH -7 #define INVALID_PARAM -8 #define STATELESS_OVERFLOW -1 -#define DEFLATE_HDR_LEN 3 +#define ISAL_INVALID_OPERATION -9 +#define ISAL_INVALID_LEVEL -4 /* Invalid Compression level set */ + /** - * @enum isal_zstate + * @enum isal_zstate_state * @brief Compression State please note ZSTATE_TRL only applies for GZIP compression */ @@ -168,16 +167,20 @@ enum {LIT_TABLE_SIZE = 257}; enum isal_zstate_state { ZSTATE_NEW_HDR, //!< Header to be written ZSTATE_HDR, //!< Header state + ZSTATE_CREATE_HDR, //!< Header to be created ZSTATE_BODY, //!< Body state ZSTATE_FLUSH_READ_BUFFER, //!< Flush buffer + ZSTATE_FLUSH_ICF_BUFFER, ZSTATE_SYNC_FLUSH, //!< Write sync flush block ZSTATE_FLUSH_WRITE_BUFFER, //!< Flush bitbuf ZSTATE_TRL, //!< Trailer state ZSTATE_END, //!< End state ZSTATE_TMP_NEW_HDR, //!< Temporary Header to be written ZSTATE_TMP_HDR, //!< Temporary Header state + ZSTATE_TMP_CREATE_HDR, //!< Temporary Header to be created state ZSTATE_TMP_BODY, //!< Temporary Body state ZSTATE_TMP_FLUSH_READ_BUFFER, //!< Flush buffer + ZSTATE_TMP_FLUSH_ICF_BUFFER, ZSTATE_TMP_SYNC_FLUSH, //!< Write sync flush block ZSTATE_TMP_FLUSH_WRITE_BUFFER, //!< Flush bitbuf ZSTATE_TMP_TRL, //!< Temporary Trailer state @@ -185,13 +188,70 @@ enum isal_zstate_state { }; /* Offset used to switch between TMP states and non-tmp states */ -#define TMP_OFFSET_SIZE ZSTATE_TMP_HDR - ZSTATE_HDR +#define ZSTATE_TMP_OFFSET ZSTATE_TMP_HDR - ZSTATE_HDR + +/******************************************************************************/ +/* Inflate Implementation Specific Defines */ +/******************************************************************************/ +#define ISAL_DECODE_LONG_BITS 12 +#define ISAL_DECODE_SHORT_BITS 10 + +/* Current state of decompression */ +enum isal_block_state { + ISAL_BLOCK_NEW_HDR, /* Just starting a new block */ + ISAL_BLOCK_HDR, /* In the middle of reading in a block header */ + ISAL_BLOCK_TYPE0, /* Decoding a type 0 block */ + ISAL_BLOCK_CODED, /* Decoding a huffman coded block */ + ISAL_BLOCK_INPUT_DONE, /* Decompression of input is completed */ + ISAL_BLOCK_FINISH /* Decompression of input is completed and all data has been flushed to output */ +}; +/* Inflate Return values */ +#define ISAL_DECOMP_OK 0 /* No errors encountered while decompressing */ +#define ISAL_END_INPUT 1 /* End of input reached */ +#define ISAL_OUT_OVERFLOW 2 /* End of output reached */ +#define ISAL_INVALID_BLOCK -1 /* Invalid deflate block found */ +#define ISAL_INVALID_SYMBOL -2 /* Invalid deflate symbol found */ +#define ISAL_INVALID_LOOKBACK -3 /* Invalid lookback distance found */ + +/******************************************************************************/ +/* Compression structures */ +/******************************************************************************/ +/** @brief Holds histogram of deflate symbols*/ struct isal_huff_histogram { - uint64_t lit_len_histogram[IGZIP_LIT_LEN]; - uint64_t dist_histogram[IGZIP_DIST_LEN]; + uint64_t lit_len_histogram[ISAL_DEF_LIT_LEN_SYMBOLS]; //!< Histogram of Literal/Len symbols seen + uint64_t dist_histogram[ISAL_DEF_DIST_SYMBOLS]; //!< Histogram of Distance Symbols seen + uint16_t hash_table[IGZIP_HASH_SIZE]; //!< Tmp space used as a hash table +}; + +struct isal_mod_hist { + uint32_t d_hist[30]; + uint32_t ll_hist[513]; }; +#define ISAL_DEF_MIN_LEVEL 0 +#define ISAL_DEF_MAX_LEVEL 1 + +/* Defines used set level data sizes */ +#define ISAL_DEF_LVL0_REQ 0 +#define ISAL_DEF_LVL1_REQ 4 * IGZIP_K /* has to be at least sizeof(struct level_2_buf) */ +#define ISAL_DEF_LVL1_TOKEN_SIZE 4 + +/* Data sizes for level specific data options */ +#define ISAL_DEF_LVL0_MIN ISAL_DEF_LVL0_REQ +#define ISAL_DEF_LVL0_SMALL ISAL_DEF_LVL0_REQ +#define ISAL_DEF_LVL0_MEDIUM ISAL_DEF_LVL0_REQ +#define ISAL_DEF_LVL0_LARGE ISAL_DEF_LVL0_REQ +#define ISAL_DEF_LVL0_EXTRA_LARGE ISAL_DEF_LVL0_REQ +#define ISAL_DEF_LVL0_DEFAULT ISAL_DEF_LVL0_REQ + +#define ISAL_DEF_LVL1_MIN (ISAL_DEF_LVL1_REQ + ISAL_DEF_LVL1_TOKEN_SIZE * 1 * IGZIP_K) +#define ISAL_DEF_LVL1_SMALL (ISAL_DEF_LVL1_REQ + ISAL_DEF_LVL1_TOKEN_SIZE * 16 * IGZIP_K) +#define ISAL_DEF_LVL1_MEDIUM (ISAL_DEF_LVL1_REQ + ISAL_DEF_LVL1_TOKEN_SIZE * 32 * IGZIP_K) +#define ISAL_DEF_LVL1_LARGE (ISAL_DEF_LVL1_REQ + ISAL_DEF_LVL1_TOKEN_SIZE * 64 * IGZIP_K) +#define ISAL_DEF_LVL1_EXTRA_LARGE (ISAL_DEF_LVL1_REQ + ISAL_DEF_LVL1_TOKEN_SIZE * 128 * IGZIP_K) +#define ISAL_DEF_LVL1_DEFAULT ISAL_DEF_LVL1_LARGE + /** @brief Holds Bit Buffer information*/ struct BitBuf2 { uint64_t m_bits; //!< bits in the bit buffer @@ -211,39 +271,36 @@ struct isal_zstate { uint32_t b_bytes_valid; //!< number of bytes of valid data in buffer uint32_t b_bytes_processed; //!< keeps track of the number of bytes processed in isal_zstate.buffer uint8_t *file_start; //!< pointer to where file would logically start - DECLARE_ALIGNED(uint32_t crc[16], 16); //!< actually 4 128-bit integers + uint32_t crc; //!< Current crc struct BitBuf2 bitbuf; //!< Bit Buffer enum isal_zstate_state state; //!< Current state in processing the data stream uint32_t count; //!< used for partial header/trailer writes uint8_t tmp_out_buff[16]; //!< temporary array uint32_t tmp_out_start; //!< temporary variable uint32_t tmp_out_end; //!< temporary variable - uint32_t last_flush; //!< keeps track of last submitted flush - uint32_t has_gzip_hdr; //!< keeps track of if the gzip header has been written. uint32_t has_eob; //!< keeps track of eob on the last deflate block uint32_t has_eob_hdr; //!< keeps track of eob hdr (with BFINAL set) - uint32_t left_over; //!< keeps track of overflow bytes - + uint32_t has_hist; //!< flag to track if there is match history + struct isal_mod_hist hist; - DECLARE_ALIGNED(uint8_t buffer[BSIZE + 16], 32); //!< Internal buffer - - DECLARE_ALIGNED(uint16_t head[HASH_SIZE], 16); //!< Hash array + DECLARE_ALIGNED(uint8_t buffer[2 * IGZIP_HIST_SIZE + ISAL_LOOK_AHEAD], 32); //!< Internal buffer + DECLARE_ALIGNED(uint16_t head[IGZIP_HASH_SIZE], 16); //!< Hash array }; /** @brief Holds the huffman tree used to huffman encode the input stream **/ struct isal_hufftables { - uint8_t deflate_hdr[IGZIP_MAX_DEF_HDR_SIZE]; //!< deflate huffman tree header + uint8_t deflate_hdr[ISAL_DEF_MAX_HDR_SIZE]; //!< deflate huffman tree header uint32_t deflate_hdr_count; //!< Number of whole bytes in deflate_huff_hdr uint32_t deflate_hdr_extra_bits; //!< Number of bits in the partial byte in header - uint32_t dist_table[DIST_TABLE_SIZE]; //!< bits 4:0 are the code length, bits 31:5 are the code - uint32_t len_table[LEN_TABLE_SIZE]; //!< bits 4:0 are the code length, bits 31:5 are the code - uint16_t lit_table[LIT_TABLE_SIZE]; //!< literal code - uint8_t lit_table_sizes[LIT_TABLE_SIZE]; //!< literal code length - uint16_t dcodes[30 - DECODE_OFFSET]; //!< distance code - uint8_t dcodes_sizes[30 - DECODE_OFFSET]; //!< distance code length + uint32_t dist_table[IGZIP_DIST_TABLE_SIZE]; //!< bits 4:0 are the code length, bits 31:5 are the code + uint32_t len_table[IGZIP_LEN_TABLE_SIZE]; //!< bits 4:0 are the code length, bits 31:5 are the code + uint16_t lit_table[IGZIP_LIT_TABLE_SIZE]; //!< literal code + uint8_t lit_table_sizes[IGZIP_LIT_TABLE_SIZE]; //!< literal code length + uint16_t dcodes[30 - IGZIP_DECODE_OFFSET]; //!< distance code + uint8_t dcodes_sizes[30 - IGZIP_DECODE_OFFSET]; //!< distance code length }; @@ -258,13 +315,105 @@ struct isal_zstream { uint32_t total_out; //!< total number of bytes written so far struct isal_hufftables *hufftables; //!< Huffman encoding used when compressing + uint32_t level; //!< Compression level to use + uint32_t level_buf_size; //!< Size of level_buf + uint8_t * level_buf; //!< User allocated buffer required for different compression levels uint32_t end_of_stream; //!< non-zero if this is the last input buffer - uint32_t flush; //!< Flush type can be NO_FLUSH or SYNC_FLUSH + uint32_t flush; //!< Flush type can be NO_FLUSH, SYNC_FLUSH or FULL_FLUSH + uint32_t gzip_flag; //!< Indicate if gzip compression is to be performed struct isal_zstate internal_state; //!< Internal state for this stream }; +/******************************************************************************/ +/* Inflate structures */ +/******************************************************************************/ +/* + * Inflate_huff_code data structures are used to store a Huffman code for fast + * lookup. It works by performing a lookup in small_code_lookup that hopefully + * yields the correct symbol. Otherwise a lookup into long_code_lookup is + * performed to find the correct symbol. The details of how this works follows: + * + * Let i be some index into small_code_lookup and let e be the associated + * element. Bit 15 in e is a flag. If bit 15 is not set, then index i contains + * a Huffman code for a symbol which has length at most DECODE_LOOKUP_SIZE. Bits + * 0 through 8 are the symbol associated with that code and bits 9 through 12 of + * e represent the number of bits in the code. If bit 15 is set, the i + * corresponds to the first DECODE_LOOKUP_SIZE bits of a Huffman code which has + * length longer than DECODE_LOOKUP_SIZE. In this case, bits 0 through 8 + * represent an offset into long_code_lookup table and bits 9 through 12 + * represent the maximum length of a Huffman code starting with the bits in the + * index i. The offset into long_code_lookup is for an array associated with all + * codes which start with the bits in i. + * + * The elements of long_code_lookup are in the same format as small_code_lookup, + * except bit 15 is never set. Let i be a number made up of DECODE_LOOKUP_SIZE + * bits. Then all Huffman codes which start with DECODE_LOOKUP_SIZE bits are + * stored in an array starting at index h in long_code_lookup. This index h is + * stored in bits 0 through 9 at index i in small_code_lookup. The index j is an + * index of this array if the number of bits contained in j and i is the number + * of bits in the longest huff_code starting with the bits of i. The symbol + * stored at index j is the symbol whose huffcode can be found in (j << + * DECODE_LOOKUP_SIZE) | i. Note these arrays will be stored sorted in order of + * maximum Huffman code length. + * + * The following are explanations for sizes of the tables: + * + * Since small_code_lookup is a lookup on DECODE_LOOKUP_SIZE bits, it must have + * size 2^DECODE_LOOKUP_SIZE. + * + * Since deflate Huffman are stored such that the code size and the code value + * form an increasing function, At most 2^(15 - DECODE_LOOKUP_SIZE) - 1 elements + * of long_code_lookup duplicate an existing symbol. Since there are at most 285 + * - DECODE_LOOKUP_SIZE possible symbols contained in long_code lookup. Rounding + * this to the nearest 16 byte boundary yields the size of long_code_lookup of + * 288 + 2^(15 - DECODE_LOOKUP_SIZE). + * + * Note that DECODE_LOOKUP_SIZE can be any length even though the offset in + * small_lookup_code is 9 bits long because the increasing relationship between + * code length and code value forces the maximum offset to be less than 288. + */ +/* Large lookup table for decoding huffman codes */ +struct inflate_huff_code_large { + uint16_t short_code_lookup[1 << (ISAL_DECODE_LONG_BITS)]; + uint16_t long_code_lookup[288 + (1 << (15 - ISAL_DECODE_LONG_BITS))]; +}; + +/* Small lookup table for decoding huffman codes */ +struct inflate_huff_code_small { + uint16_t short_code_lookup[1 << (ISAL_DECODE_SHORT_BITS)]; + uint16_t long_code_lookup[32 + (1 << (15 - ISAL_DECODE_SHORT_BITS))]; +}; + +/** @brief Holds decompression state information*/ +struct inflate_state { + uint8_t *next_out; //!< Next output Byte + uint32_t avail_out; //!< Number of bytes available at next_out + uint32_t total_out; //!< Total bytes written out so far + uint8_t *next_in; //!< Next input byte + uint64_t read_in; //!< Bits buffered to handle unaligned streams + uint32_t avail_in; //!< Number of bytes available at next_in + int32_t read_in_length; //!< Bits in read_in + struct inflate_huff_code_large lit_huff_code; //!< Structure for decoding lit/len symbols + struct inflate_huff_code_small dist_huff_code; //!< Structure for decoding dist symbols + enum isal_block_state block_state; //!< Current decompression state + uint32_t bfinal; //!< Flag identifying final block + uint32_t crc_flag; //!< Flag identifying whether to track of crc + uint32_t crc; //!< Contains crc of output if crc_flag is set + int32_t type0_block_len; //!< Length left to read of type 0 block when outbuffer overflow occured + int32_t copy_overflow_length; //!< Length left to copy when outbuffer overflow occured + int32_t copy_overflow_distance; //!< Lookback distance when outbuffer overlow occured + int32_t tmp_in_size; //!< Number of bytes in tmp_in_buffer + int32_t tmp_out_valid; //!< Number of bytes in tmp_out_buffer + int32_t tmp_out_processed; //!< Number of bytes processed in tmp_out_buffer + uint8_t tmp_in_buffer[ISAL_DEF_MAX_HDR_SIZE]; //!< Temporary buffer containing data from the input stream + uint8_t tmp_out_buffer[2 * ISAL_DEF_HIST_SIZE + ISAL_LOOK_AHEAD]; //!< Temporary buffer containing data from the output stream +}; + +/******************************************************************************/ +/* Compression functions */ +/******************************************************************************/ /** * @brief Updates histograms to include the symbols found in the input * stream. Since this function only updates the histograms, it can be called on @@ -285,9 +434,8 @@ void isal_update_histogram(uint8_t * in_stream, int length, struct isal_huff_his * distances are assigned a code. * * @param hufftables: the output structure containing the huffman code - * @param lit_histogram: histogram containing frequency of literal symbols and - * repeat lengths - * @param dist_histogram: histogram containing frequency of of lookback distances + * @param histogram: histogram containing frequency of literal symbols, + * repeat lengths and lookback distances * @returns Returns a non zero value if an invalid huffman code was created. */ int isal_create_hufftables(struct isal_hufftables * hufftables, @@ -299,9 +447,8 @@ int isal_create_hufftables(struct isal_hufftables * hufftables, * are not assigned a code * * @param hufftables: the output structure containing the huffman code - * @param lit_histogram: histogram containing frequency of literal symbols and - * repeat lengths - * @param dist_histogram: histogram containing frequency of of lookback distances + * @param histogram: histogram containing frequency of literal symbols, + * repeat lengths and lookback distances * @returns Returns a non zero value if an invalid huffman code was created. */ int isal_create_hufftables_subset(struct isal_hufftables * hufftables, @@ -315,10 +462,46 @@ int isal_create_hufftables_subset(struct isal_hufftables * hufftables, */ void isal_deflate_init(struct isal_zstream *stream); +/** + * @brief Set stream to use a new Huffman code + * + * Sets the Huffman code to be used in compression before compression start or + * after the sucessful completion of a SYNC_FLUSH or FULL_FLUSH. If type has + * value IGZIP_HUFFTABLE_DEFAULT, the stream is set to use the default Huffman + * code. If type has value IGZIP_HUFFTABLE_STATIC, the stream is set to use the + * deflate standard static Huffman code, or if type has value + * IGZIP_HUFFTABLE_CUSTOM, the stream is set to sue the isal_hufftables + * structure input to isal_deflate_set_hufftables. + * + * @param stream: Structure holding state information on the compression stream. + * @param hufftables: new huffman code to use if type is set to + * IGZIP_HUFFTABLE_CUSTOM. + * @param type: Flag specifying what hufftable to use. + * + * @returns Returns INVALID_OPERATION if the stream was unmodified. This may be + * due to the stream being in a state where changing the huffman code is not + * allowed or an invalid input is provided. + */ +int isal_deflate_set_hufftables(struct isal_zstream *stream, + struct isal_hufftables *hufftables, int type); + +/** + * @brief Initialize compression stream data structure + * + * @param stream Structure holding state information on the compression streams. + * @returns none + */ +void isal_deflate_stateless_init(struct isal_zstream *stream); + /** * @brief Fast data (deflate) compression for storage applications. * + * The call to isal_deflate() will take data from the input buffer (updating + * next_in, avail_in and write a compressed stream to the output buffer + * (updating next_out and avail_out). The function returns when either the input + * buffer is empty or the output buffer is full. + * * On entry to isal_deflate(), next_in points to an input buffer and avail_in * indicates the length of that buffer. Similarly next_out points to an empty * output buffer and avail_out indicates the size of that buffer. @@ -326,25 +509,39 @@ void isal_deflate_init(struct isal_zstream *stream); * The fields total_in and total_out start at 0 and are updated by * isal_deflate(). These reflect the total number of bytes read or written so far. * - * The call to isal_deflate() will take data from the input buffer (updating - * next_in, avail_in and write a compressed stream to the output buffer - * (updating next_out and avail_out). The function returns when either the input - * buffer is empty or the output buffer is full. - * * When the last input buffer is passed in, signaled by setting the * end_of_stream, the routine will complete compression at the end of the input * buffer, as long as the output buffer is big enough. * + * The compression level can be set by setting level to any value between + * ISAL_DEF_MIN_LEVEL and ISAL_DEF_MAX_LEVEL. When the compression level is + * ISAL_DEF_MIN_LEVEL, hufftables can be set to a table trained for the the + * specific data type being compressed to achieve better compression. When a + * higher compression level is desired, a larger generic memory buffer needs to + * be supplied by setting level_buf and level_buf_size to represent the chunk of + * memory. For level x, the suggest size for this buffer this buffer is + * ISAL_DEFL_LVLx_DEFAULT. The defines ISAL_DEFL_LVLx_MIN, ISAL_DEFL_LVLx_SMALL, + * ISAL_DEFL_LVLx_MEDIUM, ISAL_DEFL_LVLx_LARGE, and ISAL_DEFL_LVLx_EXTRA_LARGE + * are also provided as other suggested sizes. + * * The equivalent of the zlib FLUSH_SYNC operation is currently supported. - * Flush types can be NO_FLUSH or SYNC_FLUSH. Default flush type is NO_FLUSH. - * If SYNC_FLUSH is selected each input buffer is compressed and byte aligned - * with a type 0 block appended to the end. Switching between NO_FLUSH and - * SYNC_FLUSH is supported to select after which input buffer a SYNC_FLUSH is - * performed. + * Flush types can be NO_FLUSH, SYNC_FLUSH or FULL_FLUSH. Default flush type is + * NO_FLUSH. A SYNC_ OR FULL_ flush will byte align the deflate block by + * appending an empty stored block once all input has been compressed, including + * the buffered input. Checking that the out_buffer is not empty or that + * internal_state.state = ZSTATE_NEW_HDR is sufficient to guarantee all input + * has been flushed. Additionally FULL_FLUSH will ensure look back history does + * not include previous blocks so new blocks are fully independent. Switching + * between flush types is supported. + * + * If the gzip_flag is set to IGZIP_GZIP, a generic gzip header and the gzip + * trailer are written around the deflate compressed data. If gzip_flag is set + * to IGZIP_GZIP_NO_HDR, then only the gzip trailer is written. * * @param stream Structure holding state information on the compression streams. * @return COMP_OK (if everything is ok), * INVALID_FLUSH (if an invalid FLUSH is selected), + * ISAL_INVALID_LEVEL (if an invalid compression level is selected). */ int isal_deflate(struct isal_zstream *stream); @@ -358,13 +555,81 @@ int isal_deflate(struct isal_zstream *stream); * expansion is limited to the input size plus the header size of a stored/raw * block. * + * When the compression level is set to 1, unlike in isal_deflate(), level_buf + * may be optionally set depending on what what permormance is desired. + * + * For stateless the flush types NO_FLUSH and FULL_FLUSH are supported. + * FULL_FLUSH will byte align the output deflate block so additional blocks can + * be easily appended. + * + * If the gzip_flag is set to IGZIP_GZIP, a generic gzip header and the gzip + * trailer are written around the deflate compressed data. If gzip_flag is set + * to IGZIP_GZIP_NO_HDR, then only the gzip trailer is written. + * * @param stream Structure holding state information on the compression streams. * @return COMP_OK (if everything is ok), + * INVALID_FLUSH (if an invalid FLUSH is selected), + * ISAL_INVALID_LEVEL (if an invalid compression level is selected), * STATELESS_OVERFLOW (if output buffer will not fit output). */ int isal_deflate_stateless(struct isal_zstream *stream); +/******************************************************************************/ +/* Inflate functions */ +/******************************************************************************/ +/** + * @brief Initialize decompression state data structure + * + * @param state Structure holding state information on the compression streams. + * @returns none + */ +void isal_inflate_init(struct inflate_state *state); + +/** + * @brief Fast data (deflate) decompression for storage applications. + * + * On entry to isal_inflate(), next_in points to an input buffer and avail_in + * indicates the length of that buffer. Similarly next_out points to an empty + * output buffer and avail_out indicates the size of that buffer. + * + * The field total_out starts at 0 and is updated by isal_inflate(). This + * reflects the total number of bytes written so far. + * + * The call to isal_inflate() will take data from the input buffer (updating + * next_in, avail_in and write a decompressed stream to the output buffer + * (updating next_out and avail_out). The function returns when the input buffer + * is empty, the output buffer is full or invalid data is found. The current + * state of the decompression on exit can be read from state->block-state. If + * the crc_flag is set, the gzip crc of the output is stored in state->crc. + * + * @param state Structure holding state information on the compression streams. + * @return ISAL_DECOMP_OK (if everything is ok), + * ISAL_END_INPUT (if all input was decompressed), + * ISAL_OUT_OVERFLOW (if output buffer ran out of space), + * ISAL_INVALID_BLOCK, + * ISAL_INVALID_SYMBOL, + * ISAL_INVALID_LOOKBACK. + */ +int isal_inflate(struct inflate_state *state); + +/** + * @brief Fast data (deflate) stateless decompression for storage applications. + * + * Stateless (one shot) decompression routine with a similar interface to + * isal_inflate() but operates on entire input buffer at one time. Parameter + * avail_out must be large enough to fit the entire decompressed output. + * + * @param state Structure holding state information on the compression streams. + * @return ISAL_DECOMP_OK (if everything is ok), + * ISAL_END_INPUT (if all input was decompressed), + * ISAL_OUT_OVERFLOW (if output buffer ran out of space), + * ISAL_INVALID_BLOCK, + * ISAL_INVALID_SYMBOL, + * ISAL_INVALID_LOOKBACK. + */ +int isal_inflate_stateless(struct inflate_state *state); + #ifdef __cplusplus } #endif diff --git a/ceph/src/isa-l/include/multibinary.asm b/ceph/src/isa-l/include/multibinary.asm index 8bc777c6e..7fca3a146 100644 --- a/ceph/src/isa-l/include/multibinary.asm +++ b/ceph/src/isa-l/include/multibinary.asm @@ -142,11 +142,47 @@ ret %endmacro +;;;;; +; mbin_dispatch_init_clmul 3 parameters +; Use this case for CRC which needs both SSE4_1 and CLMUL +; 1-> function name +; 2-> base function +; 3-> SSE4_1 and CLMUL optimized function +;;;;; +%macro mbin_dispatch_init_clmul 3 + section .text + %1_dispatch_init: + push mbin_rsi + push mbin_rax + push mbin_rbx + push mbin_rcx + push mbin_rdx + lea mbin_rsi, [%2 WRT_OPT] ; Default - use base function + + mov eax, 1 + cpuid + lea mbin_rbx, [%3 WRT_OPT] ; SSE opt func + + ; Test for SSE4.2 + test ecx, FLAG_CPUID1_ECX_SSE4_1 + jz _%1_init_done + test ecx, FLAG_CPUID1_ECX_CLMUL + cmovne mbin_rsi, mbin_rbx + _%1_init_done: + pop mbin_rdx + pop mbin_rcx + pop mbin_rbx + pop mbin_rax + mov [%1_dispatched], mbin_rsi + pop mbin_rsi + ret +%endmacro + ;;;;; ; mbin_dispatch_init5 parameters ; 1-> function name ; 2-> base function -; 3-> SSE4_1 or 00/01 optimized function +; 3-> SSE4_2 or 00/01 optimized function ; 4-> AVX/02 opt func ; 5-> AVX2/04 opt func ;;;;; @@ -162,8 +198,8 @@ mov eax, 1 cpuid - ; Test for SSE4.1 - test ecx, FLAG_CPUID1_ECX_SSE4_1 + ; Test for SSE4.2 + test ecx, FLAG_CPUID1_ECX_SSE4_2 lea mbin_rbx, [%3 WRT_OPT] ; SSE opt func cmovne mbin_rsi, mbin_rbx @@ -203,7 +239,7 @@ ; mbin_dispatch_init6 parameters ; 1-> function name ; 2-> base function -; 3-> SSE4_1 or 00/01 optimized function +; 3-> SSE4_2 or 00/01 optimized function ; 4-> AVX/02 opt func ; 5-> AVX2/04 opt func ; 6-> AVX512/06 opt func @@ -222,8 +258,8 @@ mov eax, 1 cpuid mov ebx, ecx ; save cpuid1.ecx - test ecx, FLAG_CPUID1_ECX_SSE4_1 - je _%1_init_done ; Use base function if no SSE4_1 + test ecx, FLAG_CPUID1_ECX_SSE4_2 + je _%1_init_done ; Use base function if no SSE4_2 lea mbin_rsi, [%3 WRT_OPT] ; SSE possible so use 00/01 opt ;; Test for XMM_YMM support/AVX diff --git a/ceph/src/isa-l/isa-l.def b/ceph/src/isa-l/isa-l.def index 4cd1fa2d1..4708f6d52 100644 --- a/ceph/src/isa-l/isa-l.def +++ b/ceph/src/isa-l/isa-l.def @@ -81,3 +81,20 @@ isal_deflate_init @77 isal_update_histogram @78 isal_create_hufftables @79 isal_create_hufftables_subset @80 +isal_deflate_stateless_init @81 +isal_deflate_set_hufftables @82 +isal_inflate @83 +isal_inflate_stateless @84 +isal_inflate_init @85 +crc64_jones_norm_base @86 +crc64_jones_refl_base @87 +crc64_iso_norm_base @88 +crc64_iso_refl_base @89 +crc64_ecma_norm_base @90 +crc64_ecma_refl_base @91 +crc64_ecma_refl @92 +crc64_ecma_norm @93 +crc64_iso_refl @94 +crc64_iso_norm @95 +crc64_jones_refl @96 +crc64_jones_norm @97 diff --git a/ceph/src/isa-l/make.inc b/ceph/src/isa-l/make.inc index a5a7a02ee..1afe97b97 100644 --- a/ceph/src/isa-l/make.inc +++ b/ceph/src/isa-l/make.inc @@ -39,18 +39,21 @@ # trace - get simulator trace # clean - remove object files -version ?= #auto filled on release +version ?= 2.18.0 +host_cpu ?= $(shell uname -m | sed -e 's/amd/x86_/') +arch ?= $(shell uname | grep -v -e Linux -e BSD ) CC = gcc AS = yasm SIM = sde $(SIMFLAGS) -- +AWK = awk DEBUG = -g DEBUG_yasm = -g dwarf2 DEBUG_nasm = -g # Default arch= build options -CFLAGS_gcc = -Wall +CFLAGS_ = -Wall ASFLAGS_ = -f elf64 ARFLAGS_ = cr $@ STRIP_gcc = strip -d -R .comment $@ @@ -68,17 +71,27 @@ ARFLAGS_win64 = -out:$@ # arch=mingw build options ASFLAGS_mingw = -f win64 ARFLAGS_mingw = cr $@ -lsrcmingw = $(lsrc) -unit_testsmingw = $(unit_tests) -examplesmingw = $(examples) -perf_testsmingw = $(perf_tests) +LDFLAGS_mingw = -Wl,--force-exe-suffix + +LDFLAGS_so = -Wl,-soname,$(soname) ifeq ($(arch),mingw) CC=x86_64-w64-mingw32-gcc AR=x86_64-w64-mingw32-ar - LDFLAGS = -Wl,--force-exe-suffix endif +# arch=noarch build options +ARFLAGS_noarch = cr $@ +ifeq ($(arch),noarch) + host_cpu=base_aliases +endif + +ASFLAGS_Darwin = -f macho64 --prefix=_ +ARFLAGS_Darwin = -r $@ +ifeq ($(arch),Darwin) + LDFLAGS_so = + STRIP_gcc = +endif INCLUDE = $(patsubst %,-I%/,$(subst :, ,$(VPATH))) CFLAGS = $(CFLAGS_$(arch)) $(CFLAGS_$(CC)) $(DEBUG) -O2 $(DEFINES) $(INCLUDE) @@ -86,8 +99,9 @@ ASFLAGS = $(ASFLAGS_$(arch)) $(ASFLAGS_$(CC)) $(DEBUG_$(AS)) $(DEFINES) $(INCLU ARFLAGS = $(ARFLAGS_$(arch)) DEFINES += $(addprefix -D , $D) +lsrc += $(lsrc_$(host_cpu)) O = bin -lobj += $(patsubst %.c,%.o,$(patsubst %.asm,%.o,$(lsrc$(arch)) $(lsrc_intrinsic))) +lobj += $(patsubst %.c,%.o,$(patsubst %.asm,%.o,$(lsrc) $(lsrc_intrinsic))) objs = $(addprefix $(O)/,$(notdir $(lobj))) @@ -108,22 +122,25 @@ exampleswin64 = $(examples) perf_testswin64 = $(perf_tests) # Build and run unit tests, performance tests, etc. -all_tests = $(notdir $(sort $(perf_tests$(arch)) $(check_tests$(arch)) $(unit_tests$(arch)) $(examples$(arch)) $(other_tests))) -all_unit_tests = $(notdir $(sort $(check_tests$(arch)) $(unit_tests$(arch)))) -all_perf_tests = $(notdir $(sort $(perf_tests$(arch)))) +all_tests = $(notdir $(sort $(perf_tests) $(check_tests) $(unit_tests) $(examples) $(other_tests))) +all_unit_tests = $(notdir $(sort $(check_tests) $(unit_tests))) +all_perf_tests = $(notdir $(sort $(perf_tests))) +all_check_tests = $(notdir $(sort $(check_tests))) $(all_unit_tests): % : %.c $(lib_name) $(all_perf_tests): % : %.c $(lib_name) -$(sort $(notdir $(examples$(arch)))): % : %.c $(lib_name) +$(sort $(notdir $(examples))): % : %.c $(lib_name) $(sort $(notdir $(other_tests))): % : %.c $(lib_name) sim test trace: $(addsuffix .run,$(all_unit_tests)) perf: $(addsuffix .run,$(all_perf_tests)) -ex: $(notdir $(examples$(arch))) +check: $(addsuffix .run,$(all_check_tests)) +ex: $(notdir $(examples)) all: lib $(all_tests) other: $(notdir $(other_tests)) tests: $(all_unit_tests) perfs: $(all_perf_tests) +checks: $(all_check_tests) check test perf: SIM= trace: SIMFLAGS = -debugtrace check test sim: @@ -138,7 +155,7 @@ $(addsuffix .run,$(all_tests)): %.run : % @echo Completed run: $< # Other build rules -msg = $(if $(DEBUG),DEBUG) $(patsubst 32,32-bit,$(arch)) $D +msg = $(if $(DEBUG),DEBUG) $(patsubst 32,32-bit,$(host_cpu)) $D $(O)/%.o: %.asm @echo " ---> Building $< $(msg)" @@ -178,8 +195,8 @@ so_lib_ver = $(so_lib_inst).$(version) soname = $(so_lib_inst).$(word 1, $(subst ., ,$(version))) slib: $(so_lib_name) -aobjs += $(addprefix $(O)/,$(patsubst %.asm,%.o,$(filter %.asm,$(notdir $(lsrc$(arch)) $(lsrc_intrinsic))))) -shared_objs += $(addprefix $(O)/shared_ver_,$(patsubst %.c,%.o,$(filter %.c,$(notdir $(lsrc$(arch)) $(lsrc_intrinsic))))) +aobjs += $(addprefix $(O)/,$(patsubst %.asm,%.o,$(filter %.asm,$(notdir $(lsrc) $(lsrc_intrinsic))))) +shared_objs += $(addprefix $(O)/shared_ver_,$(patsubst %.c,%.o,$(filter %.c,$(notdir $(lsrc) $(lsrc_intrinsic))))) $(O)/shared_ver_%.o: %.c @echo " ---> Building shared $< $(msg)" @@ -193,12 +210,29 @@ endif $(shared_objs): CFLAGS += -fPIC $(shared_objs) $(aobjs): | $(O) -$(so_lib_name): LDFLAGS+=-Wl,-soname,$(soname) +$(so_lib_name): LDFLAGS+=$(LDFLAGS_so) $(so_lib_name): $(shared_objs) $(aobjs) @echo " ---> Creating Shared Lib $@" @$(CC) $(CFLAGS) --shared $(LDFLAGS) -o $@ $^ @(cd $(@D); ln -f -s $(so_lib_inst) $(soname)) + +isa-l.h: + @echo 'Building $@' + @echo '' >> $@ + @echo '#ifndef _ISAL_H_' >> $@ + @echo '#define _ISAL_H_' >> $@ + @echo '' >> $@ + @echo '#define.ISAL_MAJOR_VERSION.${version}' | ${AWK} -F . '{print $$1, $$2, $$3}' >> $@ + @echo '#define.ISAL_MINOR_VERSION.${version}' | ${AWK} -F . '{print $$1, $$2, $$4}' >> $@ + @echo '#define.ISAL_PATCH_VERSION.${version}' | ${AWK} -F . '{print $$1, $$2, $$5}' >> $@ + @echo '#define ISAL_MAKE_VERSION(maj, min, patch) ((maj) * 0x10000 + (min) * 0x100 + (patch))' >> $@ + @echo '#define ISAL_VERSION ISAL_MAKE_VERSION(ISAL_MAJOR_VERSION, ISAL_MINOR_VERSION, ISAL_PATCH_VERSION)' >> $@ + @echo '' >> $@ + @for unit in $(sort $(extern_hdrs)); do echo "#include " | sed -e 's;include/;;' >> $@; done + @echo '#endif //_ISAL_H_' >> $@ + + # Target for install prefix = /usr/local install_dirs = $(prefix)/lib $(prefix)/include/isa-l @@ -206,14 +240,17 @@ $(install_dirs): ; mkdir -p $@ install: $(sort $(extern_hdrs)) | $(install_dirs) $(lib_name) $(so_lib_name) isa-l.h install -m 644 $(lib_name) $(prefix)/lib/libisal.a install -m 644 $^ $(prefix)/include/isa-l/. - install -m 664 include/isa-l.h $(prefix)/include/. + install -m 664 isa-l.h $(prefix)/include/. + install -m 664 include/types.h $(prefix)/include/isa-l/. install -m 664 $(so_lib_name) $(prefix)/lib/$(so_lib_ver) (cd $(prefix)/lib && ln -f -s $(so_lib_ver) $(soname) && ln -f -s $(so_lib_ver) $(so_lib_inst)) ifeq ($(shell uname),Darwin) (cd $(prefix)/lib && ln -f -s $(so_lib_ver) $(basename $(so_lib_inst)).dylib) -endif + which glibtool && glibtool --mode=finish $(prefix)/lib +else which libtool && libtool --mode=finish $(prefix)/lib || \ echo 'Lib installed at $(prefix)/lib. Run system-dependent programs to add shared lib path.' +endif uninstall: $(RM) $(prefix)/lib/libisal.a @@ -239,4 +276,8 @@ clean: @$(RM) -r $(O) *.o *.a $(all_tests) $(lib_name) $(so_lib_name) +doc: isa-l.h + (cat Doxyfile; echo 'PROJECT_NUMBER=$(version)') | doxygen - + $(MAKE) -C generated_doc/latex &> generated_doc/latex_build_api.log + cp generated_doc/latex/refman.pdf isa-l_api_$(version).pdf diff --git a/ceph/src/isa-l/raid/Makefile.am b/ceph/src/isa-l/raid/Makefile.am index 7f9d6cfe6..95490e2c3 100644 --- a/ceph/src/isa-l/raid/Makefile.am +++ b/ceph/src/isa-l/raid/Makefile.am @@ -27,10 +27,29 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ######################################################################## -lsrc += raid/xor_gen_sse.asm raid/pq_gen_sse.asm raid/xor_check_sse.asm \ - raid/pq_check_sse.asm raid/pq_gen_avx.asm \ - raid/xor_gen_avx.asm raid/pq_gen_avx2.asm \ - raid/raid_base.c raid/raid_multibinary.asm +lsrc += raid/raid_base.c + +lsrc_base_aliases += raid/raid_base_aliases.c + +lsrc_x86_64 += \ + raid/xor_gen_sse.asm \ + raid/pq_gen_sse.asm \ + raid/xor_check_sse.asm \ + raid/pq_check_sse.asm \ + raid/pq_gen_avx.asm \ + raid/xor_gen_avx.asm \ + raid/pq_gen_avx2.asm \ + raid/xor_gen_avx512.asm \ + raid/pq_gen_avx512.asm \ + raid/raid_multibinary.asm + +lsrc_x86_32 += \ + raid/xor_gen_sse.asm \ + raid/pq_gen_sse_i32.asm \ + raid/xor_check_sse.asm \ + raid/pq_check_sse_i32.asm \ + raid/raid_multibinary_i32.asm + extern_hdrs += include/raid.h diff --git a/ceph/src/isa-l/raid/pq_gen_avx512.asm b/ceph/src/isa-l/raid/pq_gen_avx512.asm new file mode 100644 index 000000000..ac7b29f96 --- /dev/null +++ b/ceph/src/isa-l/raid/pq_gen_avx512.asm @@ -0,0 +1,235 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2017 Intel Corporation All rights reserved. +; +; 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 Intel Corporation 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 +; 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. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; Optimized pq of N source vectors using AVX512 +;;; int pq_gen_avx512(int vects, int len, void **array) + +;;; Generates P+Q parity vector from N (vects-2) sources in array of pointers +;;; (**array). Last two pointers are the P and Q destinations respectively. +;;; Vectors must be aligned to 64 bytes if NO_NT_LDST is not defined. +;;; Length must be 32 byte multiple. + +%include "reg_sizes.asm" + +%ifdef HAVE_AS_KNOWS_AVX512 + +%ifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define tmp3 arg4 + %define return rax + %define func(x) x: + %define FUNC_SAVE + %define FUNC_RESTORE +%endif + +%ifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + %define tmp r11 + %define tmp3 r10 + %define return rax + %define stack_size 4*16 + 8 ; must be an odd multiple of 8 + %define func(x) proc_frame x + %macro FUNC_SAVE 0 + alloc_stack stack_size + vmovdqu [rsp + 0*16], xmm6 + vmovdqu [rsp + 1*16], xmm7 + vmovdqu [rsp + 2*16], xmm8 + vmovdqu [rsp + 3*16], xmm9 + end_prolog + %endmacro + + %macro FUNC_RESTORE 0 + vmovdqu xmm6, [rsp + 0*16] + vmovdqu xmm7, [rsp + 1*16] + vmovdqu xmm8, [rsp + 2*16] + vmovdqu xmm9, [rsp + 3*16] + add rsp, stack_size + %endmacro +%endif + +%define vec arg0 +%define len arg1 +%define ptr arg3 +%define pos rax + +%define xp1 zmm0 +%define xq1 zmm1 +%define xtmp1 zmm2 +%define xs1 zmm3 + +%define xp2 zmm4 +%define xq2 zmm5 +%define xtmp2 zmm6 +%define xs2 zmm7 + +%define xzero zmm8 +%define xpoly zmm9 + +%define xp1y ymm0 +%define xq1y ymm1 +%define xtmp1y ymm2 +%define xs1y ymm3 +%define xzeroy ymm8 +%define xpolyy ymm9 + +%define NO_NT_LDST +;;; Use Non-temporal load/stor +%ifdef NO_NT_LDST + %define XLDR vmovdqu8 ;u8 + %define XSTR vmovdqu8 +%else + %define XLDR vmovntdqa + %define XSTR vmovntdq +%endif + +default rel + +[bits 64] +section .text + +align 16 +global pq_gen_avx512:function +func(pq_gen_avx512) + FUNC_SAVE + sub vec, 3 ;Keep as offset to last source + jng return_fail ;Must have at least 2 sources + cmp len, 0 + je return_pass + test len, (32-1) ;Check alignment of length + jnz return_fail + mov pos, 0 + mov tmp, 0x1d + vpbroadcastb xpoly, tmp + vpxorq xzero, xzero, xzero + cmp len, 128 + jl loop32 + +len_aligned_32bytes: + sub len, 2*64 ;Len points to last block + +loop128: + mov ptr, [arg2+vec*8] ;Fetch last source pointer + mov tmp, vec ;Set tmp to point back to last vector + XLDR xs1, [ptr+pos] ;Preload last vector (source) + XLDR xs2, [ptr+pos+64] ;Preload last vector (source) + vpxorq xp1, xp1, xp1 ;p1 = 0 + vpxorq xp2, xp2, xp2 ;p2 = 0 + vpxorq xq1, xq1, xq1 ;q1 = 0 + vpxorq xq2, xq2, xq2 ;q2 = 0 + +next_vect: + sub tmp, 1 ;Inner loop for each source vector + mov ptr, [arg2+tmp*8] ; get pointer to next vect + vpxorq xq1, xq1, xs1 ; q1 ^= s1 + vpxorq xq2, xq2, xs2 ; q2 ^= s2 + vpxorq xp1, xp1, xs1 ; p1 ^= s1 + vpxorq xp2, xp2, xs2 ; p2 ^= s2 + vpcmpb k1, xq1, xzero, 1 + vpcmpb k2, xq2, xzero, 1 + vpblendmb xtmp1 {k1}, xzero, xpoly + vpblendmb xtmp2 {k2}, xzero, xpoly + XLDR xs1, [ptr+pos] ; Get next vector (source data1) + XLDR xs2, [ptr+pos+64] ; Get next vector (source data2) + vpaddb xq1, xq1, xq1 ; q1 = q1<<1 + vpaddb xq2, xq2, xq2 ; q2 = q2<<1 + vpxorq xq1, xq1, xtmp1 ; q1 = q1<<1 ^ poly_masked + vpxorq xq2, xq2, xtmp2 ; q2 = q2<<1 ^ poly_masked + jg next_vect ; Loop for each vect except 0 + + mov ptr, [arg2+8+vec*8] ;Get address of P parity vector + mov tmp, [arg2+(2*8)+vec*8] ;Get address of Q parity vector + vpxorq xp1, xp1, xs1 ;p1 ^= s1[0] - last source is already loaded + vpxorq xq1, xq1, xs1 ;q1 ^= 1 * s1[0] + vpxorq xp2, xp2, xs2 ;p2 ^= s2[0] + vpxorq xq2, xq2, xs2 ;q2 ^= 1 * s2[0] + XSTR [ptr+pos], xp1 ;Write parity P1 vector + XSTR [ptr+pos+64], xp2 ;Write parity P2 vector + XSTR [tmp+pos], xq1 ;Write parity Q1 vector + XSTR [tmp+pos+64], xq2 ;Write parity Q2 vector + add pos, 2*64 + cmp pos, len + jle loop128 + + ;; ------------------------------ + ;; Do last 32 or 64 Bytes remaining + add len, 2*64 + cmp pos, len + je return_pass + +loop32: + mov ptr, [arg2+vec*8] ;Fetch last source pointer + mov tmp, vec ;Set tmp to point back to last vector + XLDR xs1y, [ptr+pos] ;Preload last vector (source) + vpxorq xp1y, xp1y, xp1y ;p = 0 + vpxorq xq1y, xq1y, xq1y ;q = 0 + +next_vect32: + sub tmp, 1 ;Inner loop for each source vector + mov ptr, [arg2+tmp*8] ; get pointer to next vect + vpxorq xq1y, xq1y, xs1y ; q1 ^= s1 + vpblendvb xtmp1y, xzeroy, xpolyy, xq1y ; xtmp1 = poly or 0x00 + vpxorq xp1y, xp1y, xs1y ; p ^= s + vpaddb xq1y, xq1y, xq1y ; q = q<<1 + vpxorq xq1y, xq1y, xtmp1y ; q = q<<1 ^ poly_masked + XLDR xs1y, [ptr+pos] ; Get next vector (source data) + jg next_vect32 ; Loop for each vect except 0 + + mov ptr, [arg2+8+vec*8] ;Get address of P parity vector + mov tmp, [arg2+(2*8)+vec*8] ;Get address of Q parity vector + vpxorq xp1y, xp1y, xs1y ;p ^= s[0] - last source is already loaded + vpxorq xq1y, xq1y, xs1y ;q ^= 1 * s[0] + XSTR [ptr+pos], xp1y ;Write parity P vector + XSTR [tmp+pos], xq1y ;Write parity Q vector + add pos, 32 + cmp pos, len + jl loop32 + + +return_pass: + mov return, 0 + FUNC_RESTORE + ret + +return_fail: + mov return, 1 + FUNC_RESTORE + ret + +endproc_frame + +%endif ; ifdef HAVE_AS_KNOWS_AVX512 diff --git a/ceph/src/isa-l/raid/pq_gen_perf.c b/ceph/src/isa-l/raid/pq_gen_perf.c index 7d9289ba3..194f26048 100644 --- a/ceph/src/isa-l/raid/pq_gen_perf.c +++ b/ceph/src/isa-l/raid/pq_gen_perf.c @@ -40,7 +40,7 @@ // Cached test, loop many times over small dataset # define TEST_SOURCES 10 # define TEST_LEN 8*1024 -# define TEST_LOOPS 40000 +# define TEST_LOOPS 800000 # define TEST_TYPE_STR "_warm" #else # ifndef TEST_CUSTOM @@ -72,7 +72,7 @@ int main(int argc, char *argv[]) for (i = 0; i < TEST_SOURCES + 2; i++) { int ret; void *buf; - ret = posix_memalign(&buf, 32, TEST_LEN); + ret = posix_memalign(&buf, 64, TEST_LEN); if (ret) { printf("alloc error: Fail"); return 1; diff --git a/ceph/src/isa-l/raid/raid_base_aliases.c b/ceph/src/isa-l/raid/raid_base_aliases.c new file mode 100644 index 000000000..f81792a00 --- /dev/null +++ b/ceph/src/isa-l/raid/raid_base_aliases.c @@ -0,0 +1,50 @@ +/********************************************************************** + Copyright(c) 2011-2017 Intel Corporation All rights reserved. + + 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 Intel Corporation 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 + 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. +**********************************************************************/ + +#include "raid.h" + +int pq_gen(int vects, int len, void **array) +{ + return pq_gen_base(vects, len, array); +} + +int pq_check(int vects, int len, void **array) +{ + return pq_check_base(vects, len, array); +} + +int xor_gen(int vects, int len, void **array) +{ + return xor_gen_base(vects, len, array); +} + +int xor_check(int vects, int len, void **array) +{ + return xor_check_base(vects, len, array); +} diff --git a/ceph/src/isa-l/raid/raid_multibinary.asm b/ceph/src/isa-l/raid/raid_multibinary.asm index f079656e0..72ef5d40d 100644 --- a/ceph/src/isa-l/raid/raid_multibinary.asm +++ b/ceph/src/isa-l/raid/raid_multibinary.asm @@ -54,12 +54,21 @@ extern pq_check_sse extern xor_check_base extern xor_check_sse +%ifdef HAVE_AS_KNOWS_AVX512 + extern xor_gen_avx512 + extern pq_gen_avx512 +%endif + mbin_interface xor_gen mbin_interface pq_gen -mbin_dispatch_init5 xor_gen, xor_gen_base, xor_gen_sse, xor_gen_avx, xor_gen_avx -mbin_dispatch_init5 pq_gen, pq_gen_base, pq_gen_sse, pq_gen_avx, pq_gen_avx2 - +%ifdef HAVE_AS_KNOWS_AVX512 + mbin_dispatch_init6 xor_gen, xor_gen_base, xor_gen_sse, xor_gen_avx, xor_gen_avx, xor_gen_avx512 + mbin_dispatch_init6 pq_gen, pq_gen_base, pq_gen_sse, pq_gen_avx, pq_gen_avx2, pq_gen_avx512 +%else + mbin_dispatch_init5 xor_gen, xor_gen_base, xor_gen_sse, xor_gen_avx, xor_gen_avx + mbin_dispatch_init5 pq_gen, pq_gen_base, pq_gen_sse, pq_gen_avx, pq_gen_avx2 +%endif section .data diff --git a/ceph/src/isa-l/raid/raid_multibinary_i32.asm b/ceph/src/isa-l/raid/raid_multibinary_i32.asm new file mode 100644 index 000000000..6da4c9dc0 --- /dev/null +++ b/ceph/src/isa-l/raid/raid_multibinary_i32.asm @@ -0,0 +1,58 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2017 Intel Corporation All rights reserved. +; +; 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 Intel Corporation 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 +; 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. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +%ifidn __OUTPUT_FORMAT__, elf64 +%define WRT_OPT wrt ..plt +%else +%define WRT_OPT +%endif + +%include "reg_sizes.asm" +%include "multibinary.asm" + +[bits 32] + +extern xor_gen_base +extern xor_gen_sse +extern pq_gen_base +extern pq_gen_sse +extern xor_check_base +extern xor_check_sse +extern pq_check_base +extern pq_check_sse + +mbin_interface xor_gen +mbin_interface pq_gen +mbin_interface xor_check +mbin_interface pq_check + +mbin_dispatch_init5 xor_gen, xor_gen_base, xor_gen_sse, xor_gen_sse, xor_gen_sse +mbin_dispatch_init5 pq_gen, pq_gen_base, pq_gen_sse, pq_gen_sse, pq_gen_sse +mbin_dispatch_init5 xor_check, xor_check_base, xor_check_sse, xor_check_sse, xor_check_sse +mbin_dispatch_init5 pq_check, pq_check_base, pq_check_sse, pq_check_sse, pq_check_sse diff --git a/ceph/src/isa-l/raid/xor_gen_avx512.asm b/ceph/src/isa-l/raid/xor_gen_avx512.asm new file mode 100644 index 000000000..6892f85c7 --- /dev/null +++ b/ceph/src/isa-l/raid/xor_gen_avx512.asm @@ -0,0 +1,217 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright(c) 2011-2017 Intel Corporation All rights reserved. +; +; 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 Intel Corporation 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 +; 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. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; Optimized xor of N source vectors using AVX512 +;;; int xor_gen_avx512(int vects, int len, void **array) + +;;; Generates xor parity vector from N (vects-1) sources in array of pointers +;;; (**array). Last pointer is the dest. +;;; Vectors must be aligned to 32 bytes. Length can be any value. + +%include "reg_sizes.asm" + +%ifdef HAVE_AS_KNOWS_AVX512 + +%ifidn __OUTPUT_FORMAT__, elf64 + %define arg0 rdi + %define arg1 rsi + %define arg2 rdx + %define arg3 rcx + %define arg4 r8 + %define arg5 r9 + %define tmp r11 + %define tmp3 arg4 + %define func(x) x: + %define return rax + %define FUNC_SAVE + %define FUNC_RESTORE + +%elifidn __OUTPUT_FORMAT__, win64 + %define arg0 rcx + %define arg1 rdx + %define arg2 r8 + %define arg3 r9 + %define tmp r11 + %define tmp3 r10 + %define func(x) proc_frame x + %define return rax + %define stack_size 2*16 + 8 ;must be an odd multiple of 8 + + %macro FUNC_SAVE 0 + alloc_stack stack_size + vmovdqu [rsp + 0*16], xmm6 + vmovdqu [rsp + 1*16], xmm7 + end_prolog + %endmacro + %macro FUNC_RESTORE 0 + vmovdqu xmm6, [rsp + 0*16] + vmovdqu xmm7, [rsp + 1*316] + add rsp, stack_size + %endmacro + +%endif ;output formats + + +%define vec arg0 +%define len arg1 +%define ptr arg3 +%define tmp2 rax +%define tmp2.b al +%define pos tmp3 +%define PS 8 + +%define NO_NT_LDST +;;; Use Non-temporal load/stor +%ifdef NO_NT_LDST + %define XLDR vmovdqu8 + %define XSTR vmovdqu8 +%else + %define XLDR vmovntdqa + %define XSTR vmovntdq +%endif + + +default rel +[bits 64] + +section .text + +align 16 +global xor_gen_avx512:function +func(xor_gen_avx512) + FUNC_SAVE + sub vec, 2 ;Keep as offset to last source + jng return_fail ;Must have at least 2 sources + cmp len, 0 + je return_pass + test len, (128-1) ;Check alignment of length + jnz len_not_aligned + +len_aligned_128bytes: + sub len, 128 + mov pos, 0 + +loop128: + mov tmp, vec ;Back to last vector + mov tmp2, [arg2+vec*PS] ;Fetch last pointer in array + sub tmp, 1 ;Next vect + XLDR zmm0, [tmp2+pos] ;Start with end of array in last vector + XLDR zmm1, [tmp2+pos+64] ;Keep xor parity in xmm0-7 + +next_vect: + mov ptr, [arg2+tmp*PS] + sub tmp, 1 + XLDR zmm4, [ptr+pos] ;Get next vector (source) + XLDR zmm5, [ptr+pos+64] + vpxorq zmm0, zmm0, zmm4 ;Add to xor parity + vpxorq zmm1, zmm1, zmm5 + jge next_vect ;Loop for each source + + mov ptr, [arg2+PS+vec*PS] ;Address of parity vector + XSTR [ptr+pos], zmm0 ;Write parity xor vector + XSTR [ptr+pos+64], zmm1 + add pos, 128 + cmp pos, len + jle loop128 + +return_pass: + FUNC_RESTORE + mov return, 0 + ret + + +;;; Do one byte at a time for no alignment case +loop_1byte: + mov tmp, vec ;Back to last vector + mov ptr, [arg2+vec*PS] ;Fetch last pointer in array + mov tmp2.b, [ptr+len-1] ;Get array n + sub tmp, 1 +nextvect_1byte: + mov ptr, [arg2+tmp*PS] + xor tmp2.b, [ptr+len-1] + sub tmp, 1 + jge nextvect_1byte + + mov tmp, vec + add tmp, 1 ;Add back to point to last vec + mov ptr, [arg2+tmp*PS] + mov [ptr+len-1], tmp2.b ;Write parity + sub len, 1 + test len, (PS-1) + jnz loop_1byte + + cmp len, 0 + je return_pass + test len, (128-1) ;If not 0 and 128bit aligned + jz len_aligned_128bytes ; then do aligned case. len = y * 128 + + ;; else we are 8-byte aligned so fall through to recheck + + + ;; Unaligned length cases +len_not_aligned: + test len, (PS-1) + jne loop_1byte + mov tmp3, len + and tmp3, (128-1) ;Do the unaligned bytes 8 at a time + + ;; Run backwards 8 bytes at a time for (tmp3) bytes +loop8_bytes: + mov tmp, vec ;Back to last vector + mov ptr, [arg2+vec*PS] ;Fetch last pointer in array + mov tmp2, [ptr+len-PS] ;Get array n + sub tmp, 1 +nextvect_8bytes: + mov ptr, [arg2+tmp*PS] ;Get pointer to next vector + xor tmp2, [ptr+len-PS] + sub tmp, 1 + jge nextvect_8bytes ;Loop for each source + + mov tmp, vec + add tmp, 1 ;Add back to point to last vec + mov ptr, [arg2+tmp*PS] + mov [ptr+len-PS], tmp2 ;Write parity + sub len, PS + sub tmp3, PS + jg loop8_bytes + + cmp len, 128 ;Now len is aligned to 128B + jge len_aligned_128bytes ;We can do the rest aligned + + cmp len, 0 + je return_pass + +return_fail: + FUNC_RESTORE + mov return, 1 + ret + +endproc_frame + +%endif ; ifdef HAVE_AS_KNOWS_AVX512 diff --git a/ceph/src/isa-l/raid/xor_gen_perf.c b/ceph/src/isa-l/raid/xor_gen_perf.c index 53a963d22..25b33cb6f 100644 --- a/ceph/src/isa-l/raid/xor_gen_perf.c +++ b/ceph/src/isa-l/raid/xor_gen_perf.c @@ -40,7 +40,7 @@ // Loop many times over same # define TEST_SOURCES 10 # define TEST_LEN 8*1024 -# define TEST_LOOPS 400000 +# define TEST_LOOPS 2000000 # define TEST_TYPE_STR "_warm" #else // Uncached test. Pull from large mem base. @@ -72,7 +72,7 @@ int main(int argc, char *argv[]) // Allocate the arrays for (i = 0; i < TEST_SOURCES + 1; i++) { void *buf; - ret = posix_memalign(&buf, 32, TEST_LEN); + ret = posix_memalign(&buf, 64, TEST_LEN); if (ret) { printf("alloc error: Fail"); return 1; diff --git a/ceph/src/isa-l/tools/iindent b/ceph/src/isa-l/tools/iindent new file mode 100755 index 000000000..b447b2fb5 --- /dev/null +++ b/ceph/src/isa-l/tools/iindent @@ -0,0 +1,2 @@ +#!/bin/sh +indent -npro -kr -i8 -ts8 -sob -l95 -ss -ncs -cp1 -lps "$@" diff --git a/ceph/src/jobs/alc.tp b/ceph/src/jobs/alc.tp deleted file mode 100644 index c600850c5..000000000 --- a/ceph/src/jobs/alc.tp +++ /dev/null @@ -1,38 +0,0 @@ -#PSUB -s /bin/bash # Sets your shell in batch -#PSUB -c alc # Where to run the job - -#PSUB -eo # Send std error & std out to the same file - -#PSUB -ln $NUM # Number of nodes to use -#PSUB -g $NUM # Total Number of tasks to use -#PSUB -cpn 1 # cpus per node - -####PSUB -c 1024Mb # memory limit -#PSUB -lc 1500 # Core file size per process -#PSUB -nr # Do not automatically resubmit job -#PSUB -tM 20m # Select time limit. The default time limit - # is only 30 minutes! Time can be HH:MM:SS or HH:MM - -#PSUB -o $CWD/$OUT # filename for output - -# Put your commands here. Remember to 'cd' to the appropriate -# directory, because the job will initially be in your home directory. -# To run a parallel job, you need to use the srun. - - - -echo job $PSUB_JOBID nodes $NUM name $NAME - -# environment -cd $CWD -export LD_LIBRARY_PATH=/usr/lib/mpi/mpi_gnu/lib - -# create fakestore dirs -srun -l -N $NUM -ppbatch bash -c "test -d tmp/osddata || mkdir tmp/osddata || echo cant make osddata ; uptime" - -# go -srun -l -N $NUM -ppbatch $CMD && touch $DONE - -# clean up fakestore -srun -l -N $NUM -ppbatch bash -c 'uptime ; rm -r tmp/osddata/*' - diff --git a/ceph/src/jobs/alcdat/makedirs b/ceph/src/jobs/alcdat/makedirs deleted file mode 100644 index af5a098a2..000000000 --- a/ceph/src/jobs/alcdat/makedirs +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/perl - -# hi there -{ - 'sleep' => 3, - - #'nummds' => [1, 2, 4, 8, 16, 32, 48, 64, 80, 96, 128, 160, 192], - 'nummds' => [1, 2, 8, 16, 32, 48, 64, 80, 96, 112, 128],#144, 160, 192, 208], - - 'cper' => [15,20], - '_dep' => [ 'cnode' => '$nummds',# / 4 + 1', - 'numclient' => '$nummds * $cper', - 'numosd' => '$nummds > 1 ? $nummds:2', - 'n' => '1 + $cnode + $nummds + $numosd' ], - - # parameters - 'fs' => 'ebofs', - #'fs' => 'fakestore', - - 'mds_bal_rep' => 10000, # none of that! - 'mds_decay_halflife' => 30, - - 'mds_bal_interval' => 45, - 'mds_bal_max' => [2], - - 'until' => 300, # --syn until $n ... when to stop clients - 'kill_after' => 400, - 'start' => 100, - 'end' => 300, - - 'makedirs' => 1, - 'makedirs_dirs' => 10, - 'makedirs_files' => 10, - 'makedirs_depth' => 4, - - # --meta_log_layout_scount 32 --meta_log_layout_ssize 256 - # --osd_pg_layout linear - 'custom' => '--tcp_skip_rank0 --meta_log_layout_num_rep 1 --meta_dir_layout_num_rep 1 --mds_shutdown_check 60', - #'custom' => '--debug_after 110 --debug_osd 15 --debug_filer 15 --debug 5', - - 'comb' => { - 'x' => 'nummds', - 'vars' => [ 'mds.req' ] - } -}; diff --git a/ceph/src/jobs/alcdat/makedirs.big b/ceph/src/jobs/alcdat/makedirs.big deleted file mode 100644 index c67b2b93d..000000000 --- a/ceph/src/jobs/alcdat/makedirs.big +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/perl - -# hi there -{ - 'sleep' => 3, - - #'nummds' => [1, 2, 4, 8, 16, 32, 48, 64, 80, 96, 128, 160, 192], - 'nummds' => [160, 200],#[1, 2, 8, 16, 32, 48, 64, 80, 96, 112, 128],#144, 160, 192, 208], - - 'cper' => [15,20], - '_dep' => [ 'cnode' => '40',#$nummds',# / 4 + 1', - 'numclient' => '$nummds * $cper', - 'numosd' => '$nummds * .8', - 'n' => '415'],#1 + $cnode + $nummds + $numosd' ], - - # parameters - 'fs' => 'ebofs', - #'fs' => 'fakestore', - - 'mds_bal_rep' => 10000, # none of that! - 'mds_decay_halflife' => 30, - - 'mds_bal_interval' => 45, - 'mds_bal_max' => 2, - - 'until' => 300, # --syn until $n ... when to stop clients - 'kill_after' => 400, - 'start' => 100, - 'end' => 300, - - 'makedirs' => 1, - 'makedirs_dirs' => 10, - 'makedirs_files' => 10, - 'makedirs_depth' => 4, - - # --meta_log_layout_scount 32 --meta_log_layout_ssize 256 - # --osd_pg_layout linear - 'custom' => '--tcp_skip_rank0 --meta_log_layout_num_rep 1 --meta_dir_layout_num_rep 1 --mds_shutdown_check 60', - #'custom' => '--debug_after 110 --debug_osd 15 --debug_filer 15 --debug 5', - - 'comb' => { - 'x' => 'nummds', - 'vars' => [ 'mds.req' ] - } -}; diff --git a/ceph/src/jobs/alcdat/makedirs.tput b/ceph/src/jobs/alcdat/makedirs.tput deleted file mode 100644 index 8dd5ae4c4..000000000 --- a/ceph/src/jobs/alcdat/makedirs.tput +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/perl - -# hi there -{ - 'sleep' => 3, - - #'nummds' => [1, 2, 4, 8, 16, 32, 48, 64, 80, 96, 128, 160, 192], - 'nummds' => [4, 16, 64],#[1, 16, 64, 128],#144, 160, 192, 208], - - #'cper' => [2, 5, 7, 10, 13, 16, 20, 30, 40, 50, 100, 150], - 'cper' => [13, 30, 40], # just for final run... - '_dep' => [ 'cnode' => '$nummds',# / 4 + 1', - 'numclient' => '$nummds * $cper', - 'numosd' => '$nummds', - 'n' => '1 + $cnode + $nummds + $numosd' ], - - # parameters - 'fs' => 'ebofs', - #'fs' => 'fakestore', - - 'mds_bal_rep' => 10000, # none of that! - 'mds_decay_halflife' => 30, - - 'mds_bal_interval' => 45, - 'mds_bal_max' => 2, - - 'until' => 300, # --syn until $n ... when to stop clients - 'kill_after' => 400, - 'start' => 100, - 'end' => 300, - - 'makedirs' => 1, - 'makedirs_dirs' => 10, - 'makedirs_files' => 10, - 'makedirs_depth' => 4, - - # --meta_log_layout_scount 32 --meta_log_layout_ssize 256 - # --osd_pg_layout linear - 'custom' => '--tcp_skip_rank0 --meta_log_layout_num_rep 1 --meta_dir_layout_num_rep 1 --mds_shutdown_check 60', - #'custom' => '--debug_after 110 --debug_osd 15 --debug_filer 15 --debug 5', - - 'comb' => { - 'x' => 'cper',#nummds', - 'vars' => [ 'mds.req', 'cl.lat' ] - } -}; diff --git a/ceph/src/jobs/alcdat/makefiles.shared b/ceph/src/jobs/alcdat/makefiles.shared deleted file mode 100644 index ab96702c7..000000000 --- a/ceph/src/jobs/alcdat/makefiles.shared +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/perl - -# hi there -{ - 'sleep' => 3, - - 'nummds' => [1, 2, 4, 8, 16, 32, 64, 96, 128], #2, 4, 8, 16, 32, 48, 64, 80, 96], - - 'cper' => [25, 50, 100, 150],# 100, 150, 200], - - '_dep' => [ 'cnode' => '$nummds', - 'numclient' => '$nummds * $cper', - 'numosd' => '$nummds', - 'n' => '1 + $cnode + $nummds + $numosd' ], - - # parameters - 'fs' => 'ebofs', - - 'mds_bal_hash_wr' => 1000, - - 'until' => 180, # --syn until $n ... when to stop clients - 'kill_after' => 250, - 'start' => 30, - 'end' => 180, - - 'custom' => '--tcp_skip_rank0 --meta_log_layout_num_rep 1 --meta_dir_layout_num_rep 1 --mds_shutdown_check 60 --syn makefiles 100000 1000 0', - - 'comb' => { - 'x' => 'nummds', - 'vars' => [ 'mds.req', 'cl.lat' ] - } -}; diff --git a/ceph/src/jobs/alcdat/openshared b/ceph/src/jobs/alcdat/openshared deleted file mode 100644 index 5ed7ba958..000000000 --- a/ceph/src/jobs/alcdat/openshared +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/perl - -# hi there -{ - 'sleep' => 3, - - 'nummds' => [1, 4, 16, 64, 128, 192 ], - - 'cper' => [10, 50, 100, 150], - '_dep' => [ 'cnode' => '$nummds',# > 30 ? 30:$nummds', - 'numclient' => '$nummds*$cper', - 'numosd' => '$nummds > 30 ? 30:$nummds', - 'n' => '1 + $cnode + $nummds + $numosd' ], - - # parameters - 'fs' => 'ebofs', - - 'mds_bal_interval' => 10000, - 'mds_bal_hash_wr' => 1000, - - 'until' => 120, # --syn until $n ... when to stop clients - 'kill_after' => 180, - 'start' => 10, - 'end' => 120, - - 'custom' => '--tcp_skip_rank0 --debug_mds_balancer 10 --mds_shutdown_check 60 --syn only 0 --syn createshared 10 --syn sleep 5 --syn openshared 10 10000', - - 'comb' => { - 'x' => 'nummds', - 'vars' => [ 'mds.req', 'cl.lat' ] - } -}; diff --git a/ceph/src/jobs/alcdat/ossh.include b/ceph/src/jobs/alcdat/ossh.include deleted file mode 100644 index c9a368ba5..000000000 --- a/ceph/src/jobs/alcdat/ossh.include +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/perl - -# hi there -{ - 'sleep' => 10, - - #'nummds' => [2, 4, 8, 16, 32, 48, 64, 80, 96, 128], - #'nummds' => [1, 2, 4, 6, 7], # googoo - 'nummds' => [ 2, 4, 8, 16, 32, 48, 64, 80, 96, 128 ], - - #'trace' => ['make.lib', 'make.include'], - - 'mds_bal_interval' => 45, - 'mds_bal_max' => 2,#6, #[ 2,4,6 ], - 'mds_decay_halflife' => 30, - 'mds_bal_rep' => 1500, - 'mds_bal_hash_rd' => 100000, - - 'cper' => [15, 20],#25, 50, 100], #50,#[25, 50, 75, 100],#50,# [ 50, 100 ], - #'cper' => 125, #[30, 50, 75, 100, 125, 150], #50, #[10,50,100],# [ 50, 75, 100 ], - - '_dep' => [ 'cnode' => '$nummds', - 'numclient' => '$nummds * $cper', - 'numosd' => '$nummds', - 'n' => '1 + $cnode + $nummds + $numosd' ], - - 'custom' => '--tcp_skip_rank0 --mds_shutdown_check 60 --syn only 0 --syn trace traces/openssh/untar.include 1 --syn sleep 30 --syn trace traces/openssh/make.include 1000', - - # parameters - 'fs' => 'ebofs', - - #'until' => 500, - #'kill_after' => 600, - #'start' => 200, - #'end' => 500, - 'until' => 300, # --syn until $n ... when to stop clients - 'kill_after' => 400, - 'start' => 200, - 'end' => 300, - - 'comb' => { - 'x' => 'nummds', - 'vars' => [ 'mds.req' ] - } -}; diff --git a/ceph/src/jobs/alcdat/ossh.include.big b/ceph/src/jobs/alcdat/ossh.include.big deleted file mode 100644 index b92895a53..000000000 --- a/ceph/src/jobs/alcdat/ossh.include.big +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/perl - -# hi there -{ - 'sleep' => 10, - - #'nummds' => [2, 4, 8, 16, 32, 48, 64, 80, 96, 128], - #'nummds' => [1, 2, 4, 6, 7], # googoo - #'nummds' => [ 2, 4, 8, 16, 32, 48, 64, 80, 96, 128 ], - 'nummds' => [160,200], - - #'trace' => ['make.lib', 'make.include'], - - 'mds_bal_interval' => 45, - 'mds_bal_max' => 2,#6, #[ 2,4,6 ], - 'mds_decay_halflife' => 30, - 'mds_bal_rep' => 1500, - 'mds_bal_hash_rd' => 100000, - - 'cper' => [25, 50], #50,#[25, 50, 75, 100],#50,# [ 50, 100 ], - #'cper' => 125, #[30, 50, 75, 100, 125, 150], #50, #[10,50,100],# [ 50, 75, 100 ], - - '_dep' => [ 'cnode' => '$nummds', - 'numclient' => '$nummds * $cper', - 'numosd' => '$nummds * .6', - 'n' => '415'],#1 + $cnode + $nummds + $numosd' ], - - 'custom' => '--tcp_skip_rank0 --tcp_overlay_clients --mds_shutdown_check 60 --syn only 0 --syn trace traces/openssh/untar.include 1 --syn sleep 30 --syn trace traces/openssh/make.include 1000', - - # parameters - 'fs' => 'ebofs', - - #'until' => 500, - #'kill_after' => 600, - #'start' => 200, - #'end' => 500, - 'until' => 300, # --syn until $n ... when to stop clients - 'kill_after' => 400, - 'start' => 200, - 'end' => 300, - - 'comb' => { - 'x' => 'nummds', - 'vars' => [ 'mds.req' ] - } -}; diff --git a/ceph/src/jobs/alcdat/ossh.lib b/ceph/src/jobs/alcdat/ossh.lib deleted file mode 100644 index 73372866f..000000000 --- a/ceph/src/jobs/alcdat/ossh.lib +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/perl - -# hi there -{ - 'sleep' => 10, - - #'nummds' => [1, 2, 4, 8, 16, 32, 48, 64, 80, 96, 128], - 'nummds' => [2, 4, 8, 16, 32, 48, 64, 80, 96, 128], - - #'nummds' => [1, 2, 4, 6, 7], # googoo - #'trace' => ['make.lib', 'make.include'], - - 'mds_bal_interval' => 90, #[30, 60, 90], #$[60,90], #[60,90],#[30, 60, 90], - #'mds_bal_max' => [4, 10],#6,#[2,4,6,8], - - 'mds_decay_halflife' => 30, - 'mds_bal_rep' => 1500, - 'cper' => [10, 16], #50,#[25, 50, 75, 100],#50,# [ 50, 100 ], - - '_dep' => [ 'cnode' => '$nummds', - 'numclient' => '$nummds * $cper', - 'numosd' => '$nummds', - 'n' => '1 + $cnode + $nummds + $numosd' ], - - - 'custom' => '--tcp_skip_rank0 --debug_mds_balancer 1 --mds_shutdown_check 60 --syn only 0 --syn trace traces/openssh/untar.lib 1 --syn sleep 10 --syn trace traces/openssh/make.lib 1000', - - # parameters - #'fs' => ['fakestore'], - 'fs' => 'ebofs', - - #'until' => 500, - #'kill_after' => 600, - #'start' => 200, - #'end' => 500, - 'until' => 300, # --syn until $n ... when to stop clients - 'kill_after' => 400, - 'start' => 150, - 'end' => 300, - - 'comb' => { - 'x' => 'nummds', - 'vars' => [ 'mds.req' ] - } -}; diff --git a/ceph/src/jobs/alcdat/ossh.lib.big b/ceph/src/jobs/alcdat/ossh.lib.big deleted file mode 100644 index b9e0dd1ff..000000000 --- a/ceph/src/jobs/alcdat/ossh.lib.big +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/perl - -# hi there -{ - 'sleep' => 10, - - #'nummds' => [1, 2, 4, 8, 16, 32, 48, 64, 80, 96, 128], - #'nummds' => [2, 4, 8, 16, 32, 48, 64, 80, 96, 128], - 'nummds' => [160,200], - - #'nummds' => [1, 2, 4, 6, 7], # googoo - #'trace' => ['make.lib', 'make.include'], - - 'mds_bal_interval' => 90, #[30, 60, 90], #$[60,90], #[60,90],#[30, 60, 90], - #'mds_bal_max' => [4, 10],#6,#[2,4,6,8], - - 'mds_decay_halflife' => 30, - 'mds_bal_rep' => 1500, - 'cper' => [25, 50, 100], #50,#[25, 50, 75, 100],#50,# [ 50, 100 ], - - '_dep' => [ 'cnode' => 0,#'30', - 'numclient' => '$nummds * $cper', - 'numosd' => '$nummds * .6', - 'n' => '415'],#'1 + $cnode + $nummds + $numosd' ], - - - 'custom' => '--tcp_skip_rank0 --debug_mds_balancer 1 --mds_shutdown_check 60 --syn only 0 --syn trace traces/openssh/untar.lib 1 --syn sleep 10 --syn trace traces/openssh/make.lib 1000', - - # parameters - #'fs' => ['fakestore'], - 'fs' => 'ebofs', - - #'until' => 500, - #'kill_after' => 600, - #'start' => 200, - #'end' => 500, - 'until' => 300, # --syn until $n ... when to stop clients - 'kill_after' => 400, - 'start' => 150, - 'end' => 300, - - 'comb' => { - 'x' => 'nummds', - 'vars' => [ 'mds.req' ] - } -}; diff --git a/ceph/src/jobs/alcdat/striping b/ceph/src/jobs/alcdat/striping deleted file mode 100644 index de71828d1..000000000 --- a/ceph/src/jobs/alcdat/striping +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/perl - -# hi there -{ - 'sleep' => 3, - - 'nummds' => 1, - 'numosd' => 10, - - 'cnode' => 10, - 'cper' => [ 10, 25, 50, 100 ], - - '_dep' => [ 'numclient' => '$cper * $cnode', - 'n' => '1 + $cnode + $nummds + $numosd', - 'file_layout_osize' => '$writefile_size' ], - - # parameters - 'fs' => 'ebofs', - #'fs' => 'fakestore', - - 'until' => 160, # --syn until $n ... when to stop clients - 'kill_after' => 200, - 'start' => 100, - 'end' => 160, - - 'writefile' => 1, - 'writefile_size' => [ -# 4*1024*1024, - 1024*1024 ], -# 256*1024, -# 64*1024 - 'writefile_mb' => 100000, - - 'osd_pg_bits' => 10,#16, - #'osd_pg_bits' => [ 16, 20 ], - - #'osd_object_layout' => [ 'hash', 'hashino', 'linear' ], - 'osd_pg_layout' => [ 'crush', -# 'hash', - 'linear' ], - - 'custom' => '--tcp_skip_rank0 --file_layout_num_rep 1 --mds_shutdown_check 60', - - 'comb' => { - 'x' => 'cper',#writefile_size', - 'vars' => [ 'osd.c_wrb', 'osd.c_wr' ], - } -}; diff --git a/ceph/src/jobs/example b/ceph/src/jobs/example deleted file mode 100644 index 802a8b66e..000000000 --- a/ceph/src/jobs/example +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/perl -# hi there -{ - # startup - 'n' => 30, # number of mpi nodes - 'sleep' => 3, # seconds to sleep between runs (so you have time to control-c out) - 'nummds' => 1, - 'numosd' => 6, - 'numclient' => 100, - - 'until' => 100, # --syn until $n ... synthetic client will stop itself after this many seconds. - 'kill_after' => 300, # seconds before everything commits suicide (in case something hangs) - - # stuff i want to vary - # here's a simple example: - - # do --syn writefile command - 'writefile' => 1, - # and very the write size - 'writefile_size' => [ # vary -# 2048*1024, - 1024*1024, - 512*1024, - 256*1024, - 128*1024, - 64*1024, - 48*1024, - 32*1024, - 28*1024, - 24*1024, - 16*1024, - 12*1024, - 8*1024, - 4096, -# 256, -# 16, -# 1 - ], - 'writefile_mb' => 1000, # each client shoudl write 1GB (or more likely, keep going until time runs out) - - 'file_layout_num_rep'=> [1,2], # also vary the replication level - - # pass some other random things to newsyn - 'custom' => '--', - - # for final summation (script/sum.pl) - # specify time period to look at the results - 'start' => 30, # skip first 30 seconds, so that caches are full etc. - 'end' => 90, # go for 60 seconds - - # what should i parse/plot? - 'comb' => { - 'x' => 'writefile_size', - 'vars' => [ 'osd.c_wrb', 'osd.r_wrb' ], - } -}; diff --git a/ceph/src/jobs/mds/log_striping b/ceph/src/jobs/mds/log_striping deleted file mode 100644 index 4bdd4b253..000000000 --- a/ceph/src/jobs/mds/log_striping +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/perl - -# hi there -{ - 'sleep' => 3, - 'kill_after' => 300, - - 'nummds' => 1, - 'numosd' => 8, - 'numclient' => 100, - 'n' => 16, - - # parameters - 'fs' => ['fakestore'], - 'meta_log_ssize' => [ 128, 256, 1024, 1 << 15, 1 << 20 ], - 'meta_log_scount' => 4,#[ 1, 2, 4, 8 ], - - 'until' => 200, # --syn until $n ... when to stop clients - - 'makedirs' => 1, - 'makedirs_dirs' => 10, - 'makedirs_files' => 10, - 'makedirs_depth' => 4, - - 'custom' => '--tcp_skip_rank0', - #'custom' => '--debug_after 110 --debug_osd 15 --debug_filer 15 --debug 5', - - # for final summation (script/sum.pl) - 'start' => 100, - 'end' => 550, - - 'comb' => { - 'x' => 'nummds', - 'vars' => [ 'mds.req' ] - } -}; diff --git a/ceph/src/jobs/mds/makedir_lat b/ceph/src/jobs/mds/makedir_lat deleted file mode 100644 index 63374f52a..000000000 --- a/ceph/src/jobs/mds/makedir_lat +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/perl - -# hi there -{ - 'sleep' => 3, - - 'nummds' => 1, - 'numosd' => 8, - 'numclient' => [1],#, 40, 80, 160 ], - 'n' => 20, - - 'fs' => 'ebofs', - - 'start' => 20, - 'end' => 40, - 'until' => 40, - 'kill_after' => 60, - - 'makedirs' => 1, - 'makedirs_dirs' => 10, - 'makedirs_files' => 10, - 'makedirs_depth' => 5, - - 'mds_local_osd' => [ 0, 1 ], - 'meta_log_layout_num_rep' => [ 0, 1, 2, 3, 4], - - 'custom' => '--tcp_skip_rank0', - - 'comb' => { - 'x' => 'meta_log_layout_num_rep', - 'vars' => [ 'mds.log.lat', 'cl.lat', 'osd.rlat' ] - } -}; diff --git a/ceph/src/jobs/mds/makedirs b/ceph/src/jobs/mds/makedirs deleted file mode 100644 index 0ba474a15..000000000 --- a/ceph/src/jobs/mds/makedirs +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/perl - -# hi there -{ - '_psub' => 'jobs/alc.tp', - - 'sleep' => 3, - - 'nummds' => [1, 2, 4, 6, 8, 12, 16, 24, 32, 40, 48, 64], - - 'cper' => 50, - '_dep' => [ 'cnode' => '$nummds', - 'numclient' => '$cnode * $cper', - 'numosd' => '$nummds * 2', - 'n' => '1 + $cnode + $nummds + $numosd' ], - - # parameters - 'fs' => 'fakestore', - - 'until' => 300, # --syn until $n ... when to stop clients - 'kill_after' => 400, - - 'makedirs' => 1, - 'makedirs_dirs' => 10, - 'makedirs_files' => 10, - 'makedirs_depth' => 3, - - 'custom' => '--tcp_skip_rank0', - #'custom' => '--debug_after 110 --debug_osd 15 --debug_filer 15 --debug 5', - - # for final summation (script/sum.pl) - 'start' => 100, - 'end' => 550, - - 'comb' => { - 'x' => 'nummds', - 'vars' => [ 'mds.req' ] - } -}; diff --git a/ceph/src/jobs/mds/opensshlib b/ceph/src/jobs/mds/opensshlib deleted file mode 100644 index d8b61ae52..000000000 --- a/ceph/src/jobs/mds/opensshlib +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/perl - -# hi there -{ - 'sleep' => 3, - - 'nummds' => [1, 2, 4, 7], # googoo - #'nummds' => [1, 2, 4, 6, 8, 12, 16, 24, 32, 40, 48, 64], # alc - - - # parameters - 'fs' => 'ebofs', - #'fs' => 'fakestore', - - 'until' => 300, # --syn until $n ... when to stop clients - 'kill_after' => 400, - 'start' => 150, - 'end' => 300, - - 'mds_bal_interval' => 90,#[60, 90], - #'mds_bal_max' => [3,4,5], - 'mds_bal_max' => 4, - 'mds_decay_halflife' => 30,#[15, 25, 30, 45, 60], - 'mds_bal_rep' => 1500,#[1000, 1500, 2000], - - 'decay_hl' => 100,#[ 25, 50, 100, 150 ], - - 'cper' => 100, #[50, 75, 100, 125, 150, 200], - '_dep' => [ 'cnode' => '$nummds', - 'numclient' => '$nummds * $cper', - 'numosd' => '$nummds * 2', - 'n' => '1 + $cnode + $nummds + $numosd', - 'mds_bal_rep' => '$mds_decay_halflife * $decay_hl'], - - 'custom' => '--tcp_skip_rank0 --syn only 0 --syn trace traces/openssh/untar.lib 1 --syn sleep 10 --syn randomsleep 30 --syn trace traces/openssh/make.lib 100 --debug_mds_balancer 1 --mds_shutdown_check 60', - #'custom' => '--debug_after 110 --debug_osd 15 --debug_filer 15 --debug 5', - - # for final summation (script/sum.pl) - - 'comb' => { - 'x' => 'nummds',#decay_hl',#'nummds', - 'vars' => [ 'mds.req' ] - } -}; diff --git a/ceph/src/jobs/meta1 b/ceph/src/jobs/meta1 deleted file mode 100644 index 743212f1c..000000000 --- a/ceph/src/jobs/meta1 +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh - -# makedirs for 300 seconds -# first bit in memory -# second bit is commiting from journal too -# then walk fs for 300 seconds -# this should all be in memory. - -JOB="meta1" -ARGS="--numosd 10 --fullmkfs --syn until 180 --syn makedirs 10 10 4 --syn until 360 --syn repeatwalk --mds_bal_max 1 --osd_fsync 0 --mds_log_max_len 200000 --mds_cache_size 500000" - -#rm core* ; make tcpsyn && mpiexec -l -n 17 ./tcpsyn $ARGS --nummds 1 --log_name $JOB/1 --numclient 25 > log/$JOB/o.1 -#rm core* ; make tcpsyn && mpiexec -l -n 18 ./tcpsyn $ARGS --nummds 2 --log_name $JOB/2 --numclient 50 > log/$JOB/o.2 -#rm core* ; make tcpsyn && mpiexec -l -n 20 ./tcpsyn $ARGS --nummds 4 --log_name $JOB/4 --numclient 100 > log/$JOB/o.4 -#rm core* ; make tcpsyn && mpiexec -l -n 24 ./tcpsyn $ARGS --nummds 8 --log_name $JOB/8 --numclient 200 > log/$JOB/o.8 -#rm core* ; make tcpsyn && mpiexec -l -n 28 ./tcpsyn $ARGS --nummds 12 --log_name $JOB/12 --numclient 300 > log/$JOB/o.12 -rm core* ; make tcpsyn && mpiexec -l -n 32 ./tcpsyn $ARGS --nummds 16 --log_name $JOB/16 --numclient 300 > log/$JOB/o.16 - - diff --git a/ceph/src/jobs/meta1.proc.sh b/ceph/src/jobs/meta1.proc.sh deleted file mode 100755 index 616acbeff..000000000 --- a/ceph/src/jobs/meta1.proc.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -for d in 1 2 4 8 12 -do - echo $d - cd $d - ../../../script/sum.pl mds? mds?? > mds.sum - ../../../script/sum.pl -avg mds? mds?? > mds.avg - - ../../../script/sum.pl -start 90 -end 180 mds? mds?? > mds.sum.makedirs - ../../../script/sum.pl -start 200 -end 300 mds? mds?? > mds.sum.walk - - cd .. -done diff --git a/ceph/src/jobs/osd/ebofs b/ceph/src/jobs/osd/ebofs deleted file mode 100644 index 81c601a82..000000000 --- a/ceph/src/jobs/osd/ebofs +++ /dev/null @@ -1,48 +0,0 @@ -# hi there -{ - # startup - 'n' => 30, # mpi nodes - 'sleep' => 3, # seconds between runs - 'nummds' => 1, - 'numosd' => 8, - 'numclient' => 100,#[10, 50, 100, 200, 400], - -'kill_after' => 200, - - # parameters - 'fs' => 'ebofs',#[ -# 'obfs', -# 'fakestore', -# 'ebofs' -# ], - 'until' => 100, # --syn until $n ... when to stop clients - 'writefile' => 1, - 'writefile_size' => [ -# 2560000, - 1024000, - 262144, -# 131072, -# 98304, - 65536, -# 16384, -# 4096, - 256, -# 16, -# 1 - ], - 'writefile_mb' => 1000, - -# 'custom' => '--tcp_skip_rank0',# --osd_maxthreads 0', - 'custom' => '--debug_after 110 --debug_osd 15 --debug_filer 15 --debug 5', - - # for final summation (script/sum.pl) - 'start' => 30, - 'end' => 90, - -'comb' => { - 'x' => 'writefile_size', - 'vars' => [ 'osd.c_wrb' ], -# 'maptitle' => { 'osd_object_layout=' => '', -# ',osd_pg_layout=' => ' + '} - } -}; diff --git a/ceph/src/jobs/osd/mds_log b/ceph/src/jobs/osd/mds_log deleted file mode 100644 index 9ff89c0ba..000000000 --- a/ceph/src/jobs/osd/mds_log +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/perl - -# hi there -{ - #'_psub' => 'jobs/alc.tp', - 'sleep' => 3, - - 'nummds' => 1, - 'numclient' => [5, 10, 15, 25, 50, 100, 200, 300, 400], - #'numclient' => [ 50, 100, 200 ], - 'numosd' => [2,4],#[ 4, 8, 12, 16, 20, 24 ], - 'n' => 12, - - # parameters - 'fs' => 'fakestore',#['fakestore','obfs'], - #'fs' => 'ebofs', - #'osd_maxthreads' => [ 0, 1, 2, 4, 8 ], - - 'until' => 100, # --syn until $n ... when to stop clients - 'kill_after' => 300, - 'start' => 20, - 'end' => 90, - - 'makedirs' => 1, - 'makedirs_dirs' => 10, - 'makedirs_files' => 10, - 'makedirs_depth' => 3, - - - #'meta_log_layout_ssize' => [256, 512, 1024, 4096, 16384, 65536, 262400], - #'meta_log_layout_scount' => [2, 4, 8], - #'meta_log_layout_num_rep' => [1, 2], - #'meta_log_layout_num_rep' => 1, - - 'custom' => '--tcp_skip_rank0 --mds_shutdown_check 60', - #'custom' => '--debug_after 110 --debug_osd 15 --debug_filer 15 --debug 5', - - 'comb' => { - 'x' => 'numclient',#'meta_log_layout_ssize', - 'vars' => [ 'mds.req' ] - } -}; diff --git a/ceph/src/jobs/osd/osd_threads b/ceph/src/jobs/osd/osd_threads deleted file mode 100644 index ef271f9e8..000000000 --- a/ceph/src/jobs/osd/osd_threads +++ /dev/null @@ -1,33 +0,0 @@ -# hi there -{ - # startup - 'n' => 30, # mpi nodes - 'sleep' => 10, # seconds between runs - 'nummds' => 1, - 'numosd' => 8, - 'numclient' => 50, - - # parameters - 'fs' => [ -# 'obfs', - 'fakestore', - 'ebofs' - ], - 'until' => 100, # --syn until $n ... when to stop clients - 'writefile' => 1, - 'writefile_size' => [ - 1024000, - 131072, - 65536, - 16 - ], - 'writefile_mb' => 1000, - - 'osd_maxthreads' => [0, 1, 2, 4, 8], - - 'custom' => '--tcp_skip_rank0', - - # for final summation (script/sum.pl) - 'start' => 30, - 'end' => 90 -}; diff --git a/ceph/src/jobs/osd/striping b/ceph/src/jobs/osd/striping deleted file mode 100644 index ea8cabe64..000000000 --- a/ceph/src/jobs/osd/striping +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/perl -# hi there -{ - # startup - #'n' => 28, # mpi nodes - - 'sleep' => 3, # seconds between runs - 'nummds' => 1, - - 'numosd' => [2,3,4,5,6,7,8,10,12], #[6, 8, 10, 12, 16], - 'numosd' => [14], - #'cper' => [4, 5, 6, 7, 8, 9, 10, 11, 12], #[1, 4, 6, 8, 16, 32, 64], - #'cper' => [4, 6, 8, 10, 12, 16, 24, 32 ], #[1, 4, 6, 8, 16, 32, 64], - 'cper' => [30], - - '_dep' => [ 'cnode' => '$numosd', - 'numclient' => '$cnode * $cper', - 'n' => 38],#'$nummds + $numosd + $cnode'], - #'numclient' => [5, 10, 20, 50, 75, 100, 150 ], - - 'start' => 30, - 'end' => 90, - 'until' => 100, # --syn until $n ... when to stop clients - 'kill_after' => 260, - - # parameters - 'fs' => 'ebofs', - 'writefile' => 1, - - 'writefile_size' => [# 4096, - # 16*1024, - # 64*1024, - # 256*1024, - 1024*1024 ], -# 'writefile_size' => [ -# 2048*1024, -# 1048576, -# 512*1024, -# 262144, -# 65536, -# 16384 -# ], - 'writefile_mb' => 1000, - - 'file_layout_num_rep'=> [1,2,3], - - 'osd_pg_bits' => 12,#[6, 8, 10, 12, 14], - - 'osd_object_layout' => [ 'hashino' ],#'hash', 'hashino', 'linear' ], - 'osd_pg_layout' => [ 'crush', 'linear' ],#, 'linear'],#, 'hash' ],#, 'linear' ],#, 'hash' ], - - #'custom' => '--tcp_skip_rank0', # --osd_maxthreads 0', - #'custom' => '--debug_after 110 --debug_osd 15 --debug_filer 15 --debug 5', - - # for final summation (script/sum.pl) - - 'comb' => { - 'x' => 'numosd',#'writefile_size', - 'vars' => [ 'osd.c_wrb', 'cl.wrlat' ], -# 'maptitle' => { 'osd_object_layout=' => '', -# ',osd_pg_layout=' => ' + '} - } -}; - - -=item some googoo notes - -for 1mb 1x writes, - - with numosd=6, min cper=6 to saturate (cper_saturate) - googoo saturates at numosd=8. (osd_saturate) - - -> so, numosd=6 or 7 is a safe size! - - - - -=cut diff --git a/ceph/src/jobs/osd/wr_lat2 b/ceph/src/jobs/osd/wr_lat2 deleted file mode 100644 index 47053dd61..000000000 --- a/ceph/src/jobs/osd/wr_lat2 +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/perl - -# hi there -{ - 'sleep' => 3, - - 'nummds' => 1, - 'numosd' => [12], - 'numclient' => [1],#, 40, 80, 160 ], - 'n' => 16, - - 'fs' => 'ebofs', - - 'start' => 10, - 'end' => 40, - 'until' => 40, - 'kill_after' => 90, - - 'writefile' => 1, - 'writefile_size' => [4096, - 8*1024, - 16*1024, - 32*1024, - 64*1024, - 128*1024, - 256*1024, - 512*1024, - 1024*1024], - 'writefile_mb' => 10000, - - #'tcp_multi_out' => [0,1], - -# 'mds_local_osd' => [ 0, 1 ], - 'file_layout_num_rep' => [1,2,3],#, 2, 3, 4], - - 'client_oc' => [0,1], - - 'custom' => '--tcp_skip_rank0', - - 'comb' => { - 'x' => 'writefile_size',#'file_layout_num_rep', - 'vars' => [ 'osd.c_wrb','cl.wrlat' ] - } -}; diff --git a/ceph/src/jobs/osd/write_sizes b/ceph/src/jobs/osd/write_sizes deleted file mode 100644 index 656f6a63f..000000000 --- a/ceph/src/jobs/osd/write_sizes +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/perl -# hi there -{ - # startup - 'n' => 30, # mpi nodes - 'sleep' => 3, # seconds between runs - 'nummds' => 1, - 'numosd' => 6, - 'numclient' => 100,#[25,50,100,300],#100,#[10, 50, 100, 200, 400], - - 'until' => 100, # --syn until $n ... when to stop clients - 'kill_after' => 300, - - # parameters - 'fs' => [ -# 'obfs', - 'fakestore', -# 'ebofs' - ], - 'writefile' => 1, - 'writefile_size' => [ -# 2048*1024, - 1024*1024, - 512*1024, - 256*1024, - 128*1024, - 64*1024, - 48*1024, - 32*1024, - 28*1024, - 24*1024, - 16*1024, - 12*1024, - 8*1024, - 4096, -# 256, -# 16, -# 1 - ], - 'writefile_mb' => 1000, - - 'file_layout_num_rep'=> 1,#[1,2], - - 'custom' => '--debug_after 110 --debug_mds 15 --debug 5 --mds_shutdown_check 60', - - # for final summation (script/sum.pl) - 'start' => 30, - 'end' => 90, - - 'comb' => { - 'x' => 'writefile_size', - 'vars' => [ 'osd.c_wrb' ], -# 'maptitle' => { 'osd_object_layout=' => '', -# ',osd_pg_layout=' => ' + '} - } -}; diff --git a/ceph/src/jobs/rados/map_dist b/ceph/src/jobs/rados/map_dist deleted file mode 100644 index 39f16daa1..000000000 --- a/ceph/src/jobs/rados/map_dist +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/perl - -# hi there -{ - 'sleep' => 3, - - 'osdbits' => [6,7,8],#,9],10,11], - 'pgperbits' => [3],#,4,5],#[4,6,8], - - 'nummds' => 1, - - '_dep' => [ 'numosd' => '1 << $osdbits', - 'osd_pg_bits' => '$pgperbits + $osdbits', - 'n' => '3 + $numosd / 32'], - 'numclient' => 0, - - 'fake_osdmap_updates' => [30], - - 'fs' => 'ebofs', - - 'start' => 30, - 'end' => 300, - 'kill_after' => 300, - - 'custom' => '--bdev_lock 0 --ms_stripe_osds --osd_maxthreads 0', - #'custom' => '--tcp_skip_rank0', - - 'comb' => { - 'x' => 'osdbits', - 'vars' => [ 'osd.sum=mapi', 'osd.sum=mapidup', 'osd.numpg', 'osd.pingset' ] - } -}; diff --git a/ceph/src/jobs/rados/rep_lat b/ceph/src/jobs/rados/rep_lat deleted file mode 100644 index 3f5ab0c8a..000000000 --- a/ceph/src/jobs/rados/rep_lat +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/perl - -# hi there -{ - 'sleep' => 3, - - 'nummds' => 1, - 'numosd' => 8, #[6], - 'numclient' => 1,#, 40, 80, 160 ], - 'n' => 10, - - 'fs' => 'ebofs', - - 'start' => 10, - 'end' => 40, - 'until' => 40, - 'kill_after' => 45, - - 'writefile' => 1, - 'writefile_size' => [4096, -# 8*1024, -# 16*1024, -# 32*1024, - 64*1024, -# 128*1024, -# 256*1024, -# 512*1024, -# 1024*1024 -], - 'writefile_mb' => 10000, - - 'osd_rep' => [0,1,2], - - 'file_layout_num_rep' => [1,2,3,4,5,6],#, 2, 3, 4], - - 'osd_pg_bits' => 4, - 'custom' => '--osd_max_rep 8', - - 'comb' => { - 'x' => 'file_layout_num_rep', - 'vars' => [ 'cl.wrlat' ] - } -}; diff --git a/ceph/src/jobs/rados/wr_sizes b/ceph/src/jobs/rados/wr_sizes deleted file mode 100644 index 9b979dcc9..000000000 --- a/ceph/src/jobs/rados/wr_sizes +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/perl - -# hi there -{ - '_sleep' => 3, - - 'nummds' => 1, - 'numosd' => 8, #[8],#10,14,16], - 'numclient' => 40, #[10*16], - '_n' => 32, - - '_start' => 20, - '_end' => 50, - '_kill_after' => 190, - - '_subst' => ['size'], - 'size' => [4096, -# 8*1024, - 16*1024, -# 32*1024, - 64*1024, -# 128*1024, - 256*1024, - # 512*1024, - 1024*1024 -# 2*1024*1024, - #4*1024*1024, - ], - - 'osd_pg_bits' => [4, 6], - - '_custom' => '--syn until 55 --syn createobjects 1000000 $size 5', - - #'custom' => '--tcp_skip_rank0', - - '_comb' => { - 'x' => 'size', - 'vars' => [ 'osd.c_wrb' ] - } -}; diff --git a/ceph/src/jobs/runjobsample b/ceph/src/jobs/runjobsample deleted file mode 100644 index 590be2077..000000000 --- a/ceph/src/jobs/runjobsample +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/perl - -# hi there -{ - '_sleep' => 3, - - 'nummds' => 1, - 'numosd' => 16, #[8],#10,14,16], - 'numclient' => 32,#,4,10,20,40], #[10*16], - '_n' => 32, - - '_start' => 15, - '_end' => 45, - '_kill_after' => 190, - - 'osd_pg_bits' => [4, 6], - 'osd_auto_weight' => [0,1], - 'file_layout_pg_size' => [1,2], - - '_custom' => '--syn createobjects 1000000 1048576 2', - - '_comb' => { - 'x' => 'osd_pg_bits', - 'vars' => [ 'osd.c_wrb' ] - } -}; diff --git a/ceph/src/krbd.cc b/ceph/src/krbd.cc index bf7e25583..4f8b671b4 100644 --- a/ceph/src/krbd.cc +++ b/ceph/src/krbd.cc @@ -133,13 +133,15 @@ static int build_map_buf(CephContext *cct, const char *pool, const char *image, oss << " name=" << cct->_conf->name.get_id(); KeyRing keyring; - r = keyring.from_ceph_context(cct); - if (r == -ENOENT && !(cct->_conf->keyfile.length() || - cct->_conf->key.length())) - r = 0; - if (r < 0) { - cerr << "rbd: failed to get secret" << std::endl; - return r; + if (cct->_conf->auth_client_required != "none") { + r = keyring.from_ceph_context(cct); + if (r == -ENOENT && !(cct->_conf->keyfile.length() || + cct->_conf->key.length())) + r = 0; + if (r < 0) { + cerr << "rbd: failed to get secret" << std::endl; + return r; + } } CryptoKey secret; diff --git a/ceph/src/kv/RocksDBStore.cc b/ceph/src/kv/RocksDBStore.cc index 0ea96ca12..01c2369ca 100644 --- a/ceph/src/kv/RocksDBStore.cc +++ b/ceph/src/kv/RocksDBStore.cc @@ -298,27 +298,36 @@ int RocksDBStore::do_open(ostream &out, bool create_if_missing) } // caches - if (!cache_size) { + if (!set_cache_flag) { cache_size = g_conf->rocksdb_cache_size; } uint64_t row_cache_size = cache_size * g_conf->rocksdb_cache_row_ratio; uint64_t block_cache_size = cache_size - row_cache_size; - if (g_conf->rocksdb_cache_type == "lru") { - bbt_opts.block_cache = rocksdb::NewLRUCache( - block_cache_size, - g_conf->rocksdb_cache_shard_bits); - } else if (g_conf->rocksdb_cache_type == "clock") { - bbt_opts.block_cache = rocksdb::NewClockCache( - block_cache_size, - g_conf->rocksdb_cache_shard_bits); + + if (block_cache_size == 0) { + // disable block cache + dout(10) << __func__ << " block_cache_size " << block_cache_size + << ", setting no_block_cache " << dendl; + bbt_opts.no_block_cache = true; } else { - derr << "unrecognized rocksdb_cache_type '" << g_conf->rocksdb_cache_type - << "'" << dendl; - return -EINVAL; + if (g_conf->rocksdb_cache_type == "lru") { + bbt_opts.block_cache = rocksdb::NewLRUCache( + block_cache_size, + g_conf->rocksdb_cache_shard_bits); + } else if (g_conf->rocksdb_cache_type == "clock") { + bbt_opts.block_cache = rocksdb::NewClockCache( + block_cache_size, + g_conf->rocksdb_cache_shard_bits); + } else { + derr << "unrecognized rocksdb_cache_type '" << g_conf->rocksdb_cache_type + << "'" << dendl; + return -EINVAL; + } } bbt_opts.block_size = g_conf->rocksdb_block_size; - opt.row_cache = rocksdb::NewLRUCache(row_cache_size, + if (row_cache_size > 0) + opt.row_cache = rocksdb::NewLRUCache(row_cache_size, g_conf->rocksdb_cache_shard_bits); if (g_conf->kstore_rocksdb_bloom_bits_per_key > 0) { @@ -716,8 +725,12 @@ int RocksDBStore::get( std::string value; std::string bound = combine_strings(prefix, *i); auto status = db->Get(rocksdb::ReadOptions(), rocksdb::Slice(bound), &value); - if (status.ok()) + if (status.ok()) { (*out)[*i].append(value); + } else if (status.IsIOError()) { + ceph_abort_msg(cct, status.ToString()); + } + } utime_t lat = ceph_clock_now() - start; logger->inc(l_rocksdb_gets); @@ -739,8 +752,10 @@ int RocksDBStore::get( s = db->Get(rocksdb::ReadOptions(), rocksdb::Slice(k), &value); if (s.ok()) { out->append(value); - } else { + } else if (s.IsNotFound()) { r = -ENOENT; + } else { + ceph_abort_msg(cct, s.ToString()); } utime_t lat = ceph_clock_now() - start; logger->inc(l_rocksdb_gets); @@ -763,8 +778,10 @@ int RocksDBStore::get( s = db->Get(rocksdb::ReadOptions(), rocksdb::Slice(k), &value); if (s.ok()) { out->append(value); - } else { + } else if (s.IsNotFound()) { r = -ENOENT; + } else { + ceph_abort_msg(cct, s.ToString()); } utime_t lat = ceph_clock_now() - start; logger->inc(l_rocksdb_gets); @@ -882,17 +899,20 @@ RocksDBStore::RocksDBWholeSpaceIteratorImpl::~RocksDBWholeSpaceIteratorImpl() int RocksDBStore::RocksDBWholeSpaceIteratorImpl::seek_to_first() { dbiter->SeekToFirst(); + assert(!dbiter->status().IsIOError()); return dbiter->status().ok() ? 0 : -1; } int RocksDBStore::RocksDBWholeSpaceIteratorImpl::seek_to_first(const string &prefix) { rocksdb::Slice slice_prefix(prefix); dbiter->Seek(slice_prefix); + assert(!dbiter->status().IsIOError()); return dbiter->status().ok() ? 0 : -1; } int RocksDBStore::RocksDBWholeSpaceIteratorImpl::seek_to_last() { dbiter->SeekToLast(); + assert(!dbiter->status().IsIOError()); return dbiter->status().ok() ? 0 : -1; } int RocksDBStore::RocksDBWholeSpaceIteratorImpl::seek_to_last(const string &prefix) @@ -934,6 +954,7 @@ int RocksDBStore::RocksDBWholeSpaceIteratorImpl::next() if (valid()) { dbiter->Next(); } + assert(!dbiter->status().IsIOError()); return dbiter->status().ok() ? 0 : -1; } int RocksDBStore::RocksDBWholeSpaceIteratorImpl::prev() @@ -941,6 +962,7 @@ int RocksDBStore::RocksDBWholeSpaceIteratorImpl::prev() if (valid()) { dbiter->Prev(); } + assert(!dbiter->status().IsIOError()); return dbiter->status().ok() ? 0 : -1; } string RocksDBStore::RocksDBWholeSpaceIteratorImpl::key() diff --git a/ceph/src/kv/RocksDBStore.h b/ceph/src/kv/RocksDBStore.h index c437badeb..321653448 100644 --- a/ceph/src/kv/RocksDBStore.h +++ b/ceph/src/kv/RocksDBStore.h @@ -76,6 +76,7 @@ class RocksDBStore : public KeyValueDB { string options_str; uint64_t cache_size = 0; + bool set_cache_flag = false; int do_open(ostream &out, bool create_if_missing); @@ -439,6 +440,7 @@ err: int set_cache_size(uint64_t s) override { cache_size = s; + set_cache_flag = true; return 0; } diff --git a/ceph/src/librados/RadosClient.cc b/ceph/src/librados/RadosClient.cc index e3215c96a..c90f3c129 100644 --- a/ceph/src/librados/RadosClient.cc +++ b/ceph/src/librados/RadosClient.cc @@ -28,6 +28,7 @@ #include "common/errno.h" #include "include/buffer.h" #include "include/stringify.h" +#include "include/util.h" #include "messages/MLog.h" #include "msg/Messenger.h" @@ -307,6 +308,12 @@ int librados::RadosClient::connect() monclient.sub_want("mgrmap", 0, 0); monclient.renew_subs(); + if (service_daemon) { + ldout(cct, 10) << __func__ << " registering as " << service_name << "." + << daemon_name << dendl; + mgrclient.service_daemon_register(service_name, daemon_name, + daemon_metadata); + } mgrclient.init(); objecter->set_client_incarnation(0); @@ -1001,7 +1008,9 @@ void librados::RadosClient::handle_log(MLog *m) stamp.tv_sec, stamp.tv_nsec, e.seq, level.c_str(), e.msg.c_str()); if (log_cb2) - log_cb2(log_cb_arg, line.c_str(), who.c_str(), name.c_str(), + log_cb2(log_cb_arg, line.c_str(), + e.channel.c_str(), + who.c_str(), name.c_str(), stamp.tv_sec, stamp.tv_nsec, e.seq, level.c_str(), e.msg.c_str()); } @@ -1012,3 +1021,51 @@ void librados::RadosClient::handle_log(MLog *m) m->put(); } + +int librados::RadosClient::service_daemon_register( + const std::string& service, ///< service name (e.g., 'rgw') + const std::string& name, ///< daemon name (e.g., 'gwfoo') + const std::map& metadata) +{ + if (service_daemon) { + return -EEXIST; + } + if (service == "osd" || + service == "mds" || + service == "client" || + service == "mon" || + service == "mgr") { + // normal ceph entity types are not allowed! + return -EINVAL; + } + if (service.empty() || name.empty()) { + return -EINVAL; + } + + collect_sys_info(&daemon_metadata, cct); + + ldout(cct,10) << __func__ << " " << service << "." << name << dendl; + service_daemon = true; + service_name = service; + daemon_name = name; + daemon_metadata.insert(metadata.begin(), metadata.end()); + + if (state == DISCONNECTED) { + return 0; + } + if (state == CONNECTING) { + return -EBUSY; + } + mgrclient.service_daemon_register(service_name, daemon_name, + daemon_metadata); + return 0; +} + +int librados::RadosClient::service_daemon_update_status( + const std::map& status) +{ + if (state != CONNECTED) { + return -ENOTCONN; + } + return mgrclient.service_daemon_update_status(status); +} diff --git a/ceph/src/librados/RadosClient.h b/ceph/src/librados/RadosClient.h index b3f301631..6c61c7f3f 100644 --- a/ceph/src/librados/RadosClient.h +++ b/ceph/src/librados/RadosClient.h @@ -78,6 +78,10 @@ private: void *log_cb_arg; string log_watch; + bool service_daemon = false; + string daemon_name, service_name; + map daemon_metadata; + int wait_for_osdmap(); public: @@ -151,6 +155,13 @@ public: void get(); bool put(); void blacklist_self(bool set); + + int service_daemon_register( + const std::string& service, ///< service name (e.g., 'rgw') + const std::string& name, ///< daemon name (e.g., 'gwfoo') + const std::map& metadata); ///< static metadata about daemon + int service_daemon_update_status( + const std::map& status); }; #endif diff --git a/ceph/src/librados/librados.cc b/ceph/src/librados/librados.cc index 1438952f8..b1002194a 100644 --- a/ceph/src/librados/librados.cc +++ b/ceph/src/librados/librados.cc @@ -2346,6 +2346,20 @@ int librados::Rados::conf_get(const char *option, std::string &val) return 0; } +int librados::Rados::service_daemon_register( + const std::string& service, ///< service name (e.g., 'rgw') + const std::string& name, ///< daemon name (e.g., 'gwfoo') + const std::map& metadata) ///< static metadata about daemon +{ + return client->service_daemon_register(service, name, metadata); +} + +int librados::Rados::service_daemon_update_status( + const std::map& status) +{ + return client->service_daemon_update_status(status); +} + int librados::Rados::pool_create(const char *name) { string str(name); diff --git a/ceph/src/libradosstriper/MultiAioCompletionImpl.cc b/ceph/src/libradosstriper/MultiAioCompletionImpl.cc index 270182918..7bb21bc0e 100644 --- a/ceph/src/libradosstriper/MultiAioCompletionImpl.cc +++ b/ceph/src/libradosstriper/MultiAioCompletionImpl.cc @@ -59,3 +59,13 @@ void libradosstriper::MultiAioCompletionImpl::finish_adding_requests() safe(); lock.Unlock(); } + +void intrusive_ptr_add_ref(libradosstriper::MultiAioCompletionImpl* ptr) +{ + ptr->get(); +} + +void intrusive_ptr_release(libradosstriper::MultiAioCompletionImpl* ptr) +{ + ptr->put(); +} diff --git a/ceph/src/libradosstriper/MultiAioCompletionImpl.h b/ceph/src/libradosstriper/MultiAioCompletionImpl.h index a7d8ed4eb..696f3def9 100644 --- a/ceph/src/libradosstriper/MultiAioCompletionImpl.h +++ b/ceph/src/libradosstriper/MultiAioCompletionImpl.h @@ -177,4 +177,7 @@ struct libradosstriper::MultiAioCompletionImpl { }; +void intrusive_ptr_add_ref(libradosstriper::MultiAioCompletionImpl*); +void intrusive_ptr_release(libradosstriper::MultiAioCompletionImpl*); + #endif // CEPH_LIBRADOSSTRIPERSTRIPER_MULTIAIOCOMPLETIONIMPL_H diff --git a/ceph/src/libradosstriper/RadosStriperImpl.cc b/ceph/src/libradosstriper/RadosStriperImpl.cc index fd5f13f00..52783b53c 100644 --- a/ceph/src/libradosstriper/RadosStriperImpl.cc +++ b/ceph/src/libradosstriper/RadosStriperImpl.cc @@ -26,7 +26,6 @@ #include "common/dout.h" #include "common/strtol.h" #include "osdc/Striper.h" -#include "libradosstriper/MultiAioCompletionImpl.h" #include "librados/AioCompletionImpl.h" #include @@ -112,10 +111,38 @@ struct ceph_file_layout default_file_layout = { init_le32(-1), // fl_pg_pool }; +using libradosstriper::MultiAioCompletionImplPtr; + +namespace { ///////////////////////// CompletionData ///////////////////////////// -libradosstriper::RadosStriperImpl::CompletionData::CompletionData +/** + * struct handling the data needed to pass to the call back + * function in asynchronous operations + */ +struct CompletionData : RefCountedObject { + /// constructor + CompletionData(libradosstriper::RadosStriperImpl * striper, + const std::string& soid, + const std::string& lockCookie, + librados::AioCompletionImpl *userCompletion = 0, + int n = 1); + /// destructor + ~CompletionData() override; + /// complete method + void complete(int r); + /// striper to be used to handle the write completion + libradosstriper::RadosStriperImpl *m_striper; + /// striped object concerned by the write operation + std::string m_soid; + /// shared lock to be released at completion + std::string m_lockCookie; + /// completion handler + librados::IoCtxImpl::C_aio_Complete *m_ack; +}; + +CompletionData::CompletionData (libradosstriper::RadosStriperImpl* striper, const std::string& soid, const std::string& lockCookie, @@ -130,16 +157,48 @@ libradosstriper::RadosStriperImpl::CompletionData::CompletionData } } -libradosstriper::RadosStriperImpl::CompletionData::~CompletionData() { +CompletionData::~CompletionData() { if (m_ack) delete m_ack; m_striper->put(); } -void libradosstriper::RadosStriperImpl::CompletionData::complete(int r) { +void CompletionData::complete(int r) { if (m_ack) m_ack->finish(r); } -libradosstriper::RadosStriperImpl::ReadCompletionData::ReadCompletionData +/** + * struct handling the data needed to pass to the call back + * function in asynchronous read operations + */ +struct ReadCompletionData : CompletionData { + /// bufferlist containing final result + bufferlist* m_bl; + /// extents that will be read + std::vector* m_extents; + /// intermediate results + std::vector* m_resultbl; + /// return code of read completion, to be remembered until unlocking happened + int m_readRc; + /// completion object for the unlocking of the striped object at the end of the read + librados::AioCompletion *m_unlockCompletion; + /// constructor + ReadCompletionData(libradosstriper::RadosStriperImpl * striper, + const std::string& soid, + const std::string& lockCookie, + librados::AioCompletionImpl *userCompletion, + bufferlist* bl, + std::vector* extents, + std::vector* resultbl, + int n); + /// destructor + ~ReadCompletionData() override; + /// complete method for when reading is over + void complete_read(int r); + /// complete method for when object is unlocked + void complete_unlock(int r); +}; + +ReadCompletionData::ReadCompletionData (libradosstriper::RadosStriperImpl* striper, const std::string& soid, const std::string& lockCookie, @@ -152,13 +211,13 @@ libradosstriper::RadosStriperImpl::ReadCompletionData::ReadCompletionData m_bl(bl), m_extents(extents), m_resultbl(resultbl), m_readRc(0), m_unlockCompletion(0) {} -libradosstriper::RadosStriperImpl::ReadCompletionData::~ReadCompletionData() { +ReadCompletionData::~ReadCompletionData() { m_unlockCompletion->release(); delete m_extents; delete m_resultbl; } -void libradosstriper::RadosStriperImpl::ReadCompletionData::complete_read(int r) { +void ReadCompletionData::complete_read(int r) { // gather data into final buffer Striper::StripedReadResult readResult; vector::iterator bit = m_resultbl->begin(); @@ -173,13 +232,40 @@ void libradosstriper::RadosStriperImpl::ReadCompletionData::complete_read(int r) m_readRc = r; } -void libradosstriper::RadosStriperImpl::ReadCompletionData::complete_unlock(int r) { +void ReadCompletionData::complete_unlock(int r) { // call parent's completion method // Note that we ignore the return code of the unlock as we cannot do much about it CompletionData::complete(m_readRc?m_readRc:m_bl->length()); } -libradosstriper::RadosStriperImpl::WriteCompletionData::WriteCompletionData +/** + * struct handling the data needed to pass to the call back + * function in asynchronous write operations + */ +struct WriteCompletionData : CompletionData { + /// safe completion handler + librados::IoCtxImpl::C_aio_Complete *m_safe; + /// return code of write completion, to be remembered until unlocking happened + int m_writeRc; + /// completion object for the unlocking of the striped object at the end of the write + librados::AioCompletion *m_unlockCompletion; + /// constructor + WriteCompletionData(libradosstriper::RadosStriperImpl * striper, + const std::string& soid, + const std::string& lockCookie, + librados::AioCompletionImpl *userCompletion, + int n); + /// destructor + ~WriteCompletionData() override; + /// complete method for when writing is over + void complete_write(int r); + /// complete method for when object is unlocked + void complete_unlock(int r); + /// safe method + void safe(int r); +}; + +WriteCompletionData::WriteCompletionData (libradosstriper::RadosStriperImpl* striper, const std::string& soid, const std::string& lockCookie, @@ -192,46 +278,160 @@ libradosstriper::RadosStriperImpl::WriteCompletionData::WriteCompletionData } } -libradosstriper::RadosStriperImpl::WriteCompletionData::~WriteCompletionData() { +WriteCompletionData::~WriteCompletionData() { m_unlockCompletion->release(); if (m_safe) delete m_safe; } -void libradosstriper::RadosStriperImpl::WriteCompletionData::complete_unlock(int r) { +void WriteCompletionData::complete_unlock(int r) { // call parent's completion method // Note that we ignore the return code of the unlock as we cannot do much about it CompletionData::complete(m_writeRc); } -void libradosstriper::RadosStriperImpl::WriteCompletionData::complete_write(int r) { +void WriteCompletionData::complete_write(int r) { // Remember return code m_writeRc = r; } -void libradosstriper::RadosStriperImpl::WriteCompletionData::safe(int r) { +void WriteCompletionData::safe(int r) { if (m_safe) m_safe->finish(r); } -libradosstriper::RadosStriperImpl::RemoveCompletionData::RemoveCompletionData -(libradosstriper::RadosStriperImpl* striper, - const std::string& soid, - const std::string& lockCookie, - librados::AioCompletionImpl *userCompletion, - int flags) : +struct RemoveCompletionData : CompletionData { + /// removal flags + int flags; + /** + * constructor + * note that the constructed object will take ownership of the lock + */ + RemoveCompletionData(libradosstriper::RadosStriperImpl * striper, + const std::string& soid, + const std::string& lockCookie, + librados::AioCompletionImpl *userCompletion, + int flags = 0) : CompletionData(striper, soid, lockCookie, userCompletion), flags(flags) {} +}; -libradosstriper::RadosStriperImpl::TruncateCompletionData::TruncateCompletionData -(libradosstriper::RadosStriperImpl* striper, - const std::string& soid, - uint64_t size) : - RefCountedObject(striper->cct()), - m_striper(striper), m_soid(soid), m_size(size) { - m_striper->get(); -} +/** + * struct handling the data needed to pass to the call back + * function in asynchronous truncate operations + */ +struct TruncateCompletionData : RefCountedObject { + /// constructor + TruncateCompletionData(libradosstriper::RadosStriperImpl* striper, + const std::string& soid, + uint64_t size) : + RefCountedObject(striper->cct()), + m_striper(striper), m_soid(soid), m_size(size) { + m_striper->get(); + } + /// destructor + ~TruncateCompletionData() override { + m_striper->put(); + } + /// striper to be used + libradosstriper::RadosStriperImpl *m_striper; + /// striped object concerned by the truncate operation + std::string m_soid; + /// the final size of the truncated object + uint64_t m_size; +}; -libradosstriper::RadosStriperImpl::TruncateCompletionData::~TruncateCompletionData() { - m_striper->put(); -} +/** + * struct handling the data needed to pass to the call back + * function in asynchronous read operations of a Rados File + */ +struct RadosReadCompletionData : RefCountedObject { + /// constructor + RadosReadCompletionData(MultiAioCompletionImplPtr multiAioCompl, + uint64_t expectedBytes, + bufferlist *bl, + CephContext *context, + int n = 1) : + RefCountedObject(context, n), + m_multiAioCompl(multiAioCompl), m_expectedBytes(expectedBytes), m_bl(bl) {} + /// the multi asynch io completion object to be used + MultiAioCompletionImplPtr m_multiAioCompl; + /// the expected number of bytes + uint64_t m_expectedBytes; + /// the bufferlist object where data have been written + bufferlist *m_bl; +}; + +/** + * struct handling (most of) the data needed to pass to the call back + * function in asynchronous stat operations. + * Inherited by the actual type for adding time information in different + * versions (time_t or struct timespec) + */ +struct BasicStatCompletionData : CompletionData { + /// constructor + BasicStatCompletionData(libradosstriper::RadosStriperImpl* striper, + const std::string& soid, + librados::AioCompletionImpl *userCompletion, + libradosstriper::MultiAioCompletionImpl *multiCompletion, + uint64_t *psize, + int n = 1) : + CompletionData(striper, soid, "", userCompletion, n), + m_multiCompletion(multiCompletion), m_psize(psize), + m_statRC(0), m_getxattrRC(0) {}; + // MultiAioCompletionImpl used to handle the double aysnc + // call in the back (stat + getxattr) + libradosstriper::MultiAioCompletionImpl *m_multiCompletion; + // where to store the size of first objct + // this will be ignored but we need a place to store it when + // async stat is called + uint64_t m_objectSize; + // where to store the file size + uint64_t *m_psize; + /// the bufferlist object used for the getxattr call + bufferlist m_bl; + /// return code of the stat + int m_statRC; + /// return code of the getxattr + int m_getxattrRC; +}; + +/** + * struct handling the data needed to pass to the call back + * function in asynchronous stat operations. + * Simple templated extension of BasicStatCompletionData. + * The template parameter is the type of the time information + * (used with time_t for stat and struct timespec for stat2) + */ +template +struct StatCompletionData : BasicStatCompletionData { + /// constructor + StatCompletionData(libradosstriper::RadosStriperImpl* striper, + const std::string& soid, + librados::AioCompletionImpl *userCompletion, + libradosstriper::MultiAioCompletionImpl *multiCompletion, + uint64_t *psize, + TimeType *pmtime, + int n = 1) : + BasicStatCompletionData(striper, soid, userCompletion, multiCompletion, psize, n), + m_pmtime(pmtime) {}; + // where to store the file time + TimeType *m_pmtime; +}; + +/** + * struct handling the data needed to pass to the call back + * function in asynchronous remove operations of a Rados File + */ +struct RadosRemoveCompletionData : RefCountedObject { + /// constructor + RadosRemoveCompletionData(MultiAioCompletionImplPtr multiAioCompl, + CephContext *context) : + RefCountedObject(context, 2), + m_multiAioCompl(multiAioCompl) {}; + /// the multi asynch io completion object to be used + MultiAioCompletionImplPtr m_multiAioCompl; +}; + + +} // namespace { ///////////////////////// constructor ///////////////////////////// @@ -412,8 +612,7 @@ int libradosstriper::RadosStriperImpl::aio_write_full(const std::string& soid, static void rados_read_aio_unlock_complete(rados_striper_multi_completion_t c, void *arg) { - libradosstriper::RadosStriperImpl::ReadCompletionData *cdata = - reinterpret_cast(arg); + auto cdata = reinterpret_cast(arg); libradosstriper::MultiAioCompletionImpl *comp = reinterpret_cast(c); cdata->complete_unlock(comp->rval); @@ -422,8 +621,7 @@ static void rados_read_aio_unlock_complete(rados_striper_multi_completion_t c, v static void striper_read_aio_req_complete(rados_striper_multi_completion_t c, void *arg) { - libradosstriper::RadosStriperImpl::ReadCompletionData *cdata = - reinterpret_cast(arg); + auto cdata = reinterpret_cast(arg); // launch the async unlocking of the object cdata->m_striper->aio_unlockObject(cdata->m_soid, cdata->m_lockCookie, cdata->m_unlockCompletion); // complete the read part in parallel @@ -434,21 +632,19 @@ static void striper_read_aio_req_complete(rados_striper_multi_completion_t c, vo static void rados_req_read_safe(rados_completion_t c, void *arg) { - libradosstriper::RadosStriperImpl::RadosReadCompletionData *data = - reinterpret_cast(arg); + auto data = reinterpret_cast(arg); int rc = rados_aio_get_return_value(c); // ENOENT means that we are dealing with a sparse file. This is fine, // data (0s) will be created on the fly by the rados_req_read_complete method if (rc == -ENOENT) rc = 0; - libradosstriper::MultiAioCompletionImpl *multiAioComp = data->m_multiAioCompl; + auto multiAioComp = data->m_multiAioCompl; multiAioComp->safe_request(rc); data->put(); } static void rados_req_read_complete(rados_completion_t c, void *arg) { - libradosstriper::RadosStriperImpl::RadosReadCompletionData *data = - reinterpret_cast(arg); + auto data = reinterpret_cast(arg); int rc = rados_aio_get_return_value(c); // We need to handle the case of sparse files here if (rc == -ENOENT) { @@ -472,7 +668,7 @@ static void rados_req_read_complete(rados_completion_t c, void *arg) } rc = data->m_expectedBytes; } - libradosstriper::MultiAioCompletionImpl * multiAioComp = data->m_multiAioCompl; + auto multiAioComp = data->m_multiAioCompl; multiAioComp->complete_request(rc); data->put(); } @@ -519,7 +715,8 @@ int libradosstriper::RadosStriperImpl::aio_read(const std::string& soid, librados::Rados::aio_create_completion(cdata, rados_read_aio_unlock_complete, 0); cdata->m_unlockCompletion = unlock_completion; // create the multiCompletion object handling the reads - libradosstriper::MultiAioCompletionImpl *nc = new libradosstriper::MultiAioCompletionImpl; + MultiAioCompletionImplPtr nc{new libradosstriper::MultiAioCompletionImpl, + false}; nc->set_complete_callback(cdata, striper_read_aio_req_complete); // go through the extents int r = 0, i = 0; @@ -546,7 +743,6 @@ int libradosstriper::RadosStriperImpl::aio_read(const std::string& soid, break; } nc->finish_adding_requests(); - nc->put(); return r; } @@ -596,8 +792,7 @@ int libradosstriper::RadosStriperImpl::stat(const std::string& soid, uint64_t *p } static void striper_stat_aio_stat_complete(rados_completion_t c, void *arg) { - libradosstriper::RadosStriperImpl::BasicStatCompletionData *data = - reinterpret_cast(arg); + auto data = reinterpret_cast(arg); int rc = rados_aio_get_return_value(c); if (rc == -ENOENT) { // remember this has failed @@ -608,8 +803,7 @@ static void striper_stat_aio_stat_complete(rados_completion_t c, void *arg) { } static void striper_stat_aio_getxattr_complete(rados_completion_t c, void *arg) { - libradosstriper::RadosStriperImpl::BasicStatCompletionData *data = - reinterpret_cast(arg); + auto data = reinterpret_cast(arg); int rc = rados_aio_get_return_value(c); // We need to handle the case of sparse files here if (rc < 0) { @@ -632,8 +826,7 @@ static void striper_stat_aio_getxattr_complete(rados_completion_t c, void *arg) static void striper_stat_aio_req_complete(rados_striper_multi_completion_t c, void *arg) { - libradosstriper::RadosStriperImpl::BasicStatCompletionData *data = - reinterpret_cast(arg); + auto data = reinterpret_cast(arg); if (data->m_statRC) { data->complete(data->m_statRC); } else { @@ -656,13 +849,13 @@ int libradosstriper::RadosStriperImpl::aio_generic_stat { // use a MultiAioCompletion object for dealing with the fact // that we'll do 2 asynchronous calls in parallel - libradosstriper::MultiAioCompletionImpl *multi_completion = - new libradosstriper::MultiAioCompletionImpl; + MultiAioCompletionImplPtr multi_completion{ + new libradosstriper::MultiAioCompletionImpl, false}; // Data object used for passing context to asynchronous calls std::string firstObjOid = getObjectId(soid, 0); StatCompletionData *cdata = new StatCompletionData(this, firstObjOid, c, - multi_completion, psize, pmtime, 4); + multi_completion.get(), psize, pmtime, 4); multi_completion->set_complete_callback(cdata, striper_stat_aio_req_complete); // use a regular AioCompletion for the stat async call librados::AioCompletion *stat_completion = @@ -674,7 +867,6 @@ int libradosstriper::RadosStriperImpl::aio_generic_stat stat_completion->release(); if (rc < 0) { // nothing is really started so cancel everything - delete multi_completion; delete cdata; return rc; } @@ -692,11 +884,9 @@ int libradosstriper::RadosStriperImpl::aio_generic_stat // we mark the getxattr as failed in the data object cdata->m_getxattrRC = rc; multi_completion->complete_request(rc); - multi_completion->put(); return rc; } cdata->put(); - multi_completion->put(); return 0; } @@ -733,8 +923,7 @@ int libradosstriper::RadosStriperImpl::aio_stat2(const std::string& soid, static void rados_req_remove_complete(rados_completion_t c, void *arg) { - libradosstriper::RadosStriperImpl::RadosRemoveCompletionData *cdata = - reinterpret_cast(arg); + auto cdata = reinterpret_cast(arg); int rc = rados_aio_get_return_value(c); // in case the object did not exist, it means we had a sparse file, all is fine if (rc == -ENOENT) { @@ -746,8 +935,7 @@ static void rados_req_remove_complete(rados_completion_t c, void *arg) static void rados_req_remove_safe(rados_completion_t c, void *arg) { - libradosstriper::RadosStriperImpl::RadosRemoveCompletionData *cdata = - reinterpret_cast(arg); + auto cdata = reinterpret_cast(arg); int rc = rados_aio_get_return_value(c); // in case the object did not exist, it means we had a sparse file, all is fine if (rc == -ENOENT) { @@ -759,8 +947,7 @@ static void rados_req_remove_safe(rados_completion_t c, void *arg) static void striper_remove_aio_req_complete(rados_striper_multi_completion_t c, void *arg) { - libradosstriper::RadosStriperImpl::RemoveCompletionData *cdata = - reinterpret_cast(arg); + auto cdata = reinterpret_cast(arg); libradosstriper::MultiAioCompletionImpl *comp = reinterpret_cast(c); ldout(cdata->m_striper->cct(), 10) @@ -808,21 +995,20 @@ int libradosstriper::RadosStriperImpl::aio_remove(const std::string& soid, if (rc) return rc; // create CompletionData for the async remove call RemoveCompletionData *cdata = new RemoveCompletionData(this, soid, lockCookie, c, flags); - libradosstriper::MultiAioCompletionImpl *multi_completion = - new libradosstriper::MultiAioCompletionImpl; + MultiAioCompletionImplPtr multi_completion{ + new libradosstriper::MultiAioCompletionImpl, false}; multi_completion->set_complete_callback(cdata, striper_remove_aio_req_complete); // call asynchronous internal version of remove ldout(cct(), 10) << "RadosStriperImpl : Aio_remove starting for " << soid << dendl; rc = internal_aio_remove(soid, multi_completion); - multi_completion->put(); return rc; } -int libradosstriper::RadosStriperImpl::internal_aio_remove -(const std::string& soid, - libradosstriper::MultiAioCompletionImpl *multi_completion, +int libradosstriper::RadosStriperImpl::internal_aio_remove( + const std::string& soid, + MultiAioCompletionImplPtr multi_completion, int flags) { std::string firstObjOid = getObjectId(soid, 0); @@ -954,8 +1140,7 @@ void libradosstriper::RadosStriperImpl::aio_unlockObject(const std::string& soid static void rados_write_aio_unlock_complete(rados_striper_multi_completion_t c, void *arg) { - libradosstriper::RadosStriperImpl::WriteCompletionData *cdata = - reinterpret_cast(arg); + auto cdata = reinterpret_cast(arg); libradosstriper::MultiAioCompletionImpl *comp = reinterpret_cast(c); cdata->complete_unlock(comp->rval); @@ -964,8 +1149,7 @@ static void rados_write_aio_unlock_complete(rados_striper_multi_completion_t c, static void striper_write_aio_req_complete(rados_striper_multi_completion_t c, void *arg) { - libradosstriper::RadosStriperImpl::WriteCompletionData *cdata = - reinterpret_cast(arg); + auto cdata = reinterpret_cast(arg); // launch the async unlocking of the object cdata->m_striper->aio_unlockObject(cdata->m_soid, cdata->m_lockCookie, cdata->m_unlockCompletion); // complete the write part in parallel @@ -977,8 +1161,7 @@ static void striper_write_aio_req_complete(rados_striper_multi_completion_t c, v static void striper_write_aio_req_safe(rados_striper_multi_completion_t c, void *arg) { - libradosstriper::RadosStriperImpl::WriteCompletionData *cdata = - reinterpret_cast(arg); + auto cdata = reinterpret_cast(arg); libradosstriper::MultiAioCompletionImpl *comp = reinterpret_cast(c); cdata->safe(comp->rval); @@ -1001,7 +1184,8 @@ int libradosstriper::RadosStriperImpl::write_in_open_object(const std::string& s librados::Rados::aio_create_completion(cdata, rados_write_aio_unlock_complete, 0); cdata->m_unlockCompletion = unlock_completion; // create the multicompletion that will handle the write completion - libradosstriper::MultiAioCompletionImpl *c = new libradosstriper::MultiAioCompletionImpl; + MultiAioCompletionImplPtr c{new libradosstriper::MultiAioCompletionImpl, + false}; c->set_complete_callback(cdata, striper_write_aio_req_complete); c->set_safe_callback(cdata, striper_write_aio_req_safe); // call the asynchronous API @@ -1015,7 +1199,6 @@ int libradosstriper::RadosStriperImpl::write_in_open_object(const std::string& s // return result rc = c->get_return_value(); } - c->put(); cdata->put(); return rc; } @@ -1039,12 +1222,12 @@ int libradosstriper::RadosStriperImpl::aio_write_in_open_object(const std::strin librados::Rados::aio_create_completion(cdata, rados_write_aio_unlock_complete, 0); cdata->m_unlockCompletion = unlock_completion; // create the multicompletion that will handle the write completion - libradosstriper::MultiAioCompletionImpl *nc = new libradosstriper::MultiAioCompletionImpl; + libradosstriper::MultiAioCompletionImplPtr nc{ + new libradosstriper::MultiAioCompletionImpl, false}; nc->set_complete_callback(cdata, striper_write_aio_req_complete); nc->set_safe_callback(cdata, striper_write_aio_req_safe); // internal asynchronous API int rc = internal_aio_write(soid, nc, bl, len, off, layout); - nc->put(); cdata->put(); return rc; } @@ -1065,7 +1248,7 @@ static void rados_req_write_complete(rados_completion_t c, void *arg) int libradosstriper::RadosStriperImpl::internal_aio_write(const std::string& soid, - libradosstriper::MultiAioCompletionImpl *c, + libradosstriper::MultiAioCompletionImplPtr c, const bufferlist& bl, size_t len, uint64_t off, @@ -1095,8 +1278,11 @@ libradosstriper::RadosStriperImpl::internal_aio_write(const std::string& soid, // and write the object c->add_request(); librados::AioCompletion *rados_completion = - librados::Rados::aio_create_completion(c, rados_req_write_complete, rados_req_write_safe); - r = m_ioCtx.aio_write(p->oid.name, rados_completion, oid_bl, p->length, p->offset); + librados::Rados::aio_create_completion(c.get(), + rados_req_write_complete, + rados_req_write_safe); + r = m_ioCtx.aio_write(p->oid.name, rados_completion, oid_bl, + p->length, p->offset); rados_completion->release(); if (r < 0) break; @@ -1313,8 +1499,7 @@ int libradosstriper::RadosStriperImpl::createAndOpenStripedObject(const std::str static void striper_truncate_aio_req_complete(rados_striper_multi_completion_t c, void *arg) { - libradosstriper::RadosStriperImpl::TruncateCompletionData *cdata = - reinterpret_cast(arg); + auto cdata = reinterpret_cast(arg); libradosstriper::MultiAioCompletionImpl *comp = reinterpret_cast(c); if (0 == comp->rval) { @@ -1334,8 +1519,8 @@ int libradosstriper::RadosStriperImpl::truncate(const std::string& soid, ceph_file_layout &layout) { TruncateCompletionData *cdata = new TruncateCompletionData(this, soid, size); - libradosstriper::MultiAioCompletionImpl *multi_completion = - new libradosstriper::MultiAioCompletionImpl; + libradosstriper::MultiAioCompletionImplPtr multi_completion{ + new libradosstriper::MultiAioCompletionImpl, false}; multi_completion->set_complete_callback(cdata, striper_truncate_aio_req_complete); // call asynchrous version of truncate int rc = aio_truncate(soid, multi_completion, original_size, size, layout); @@ -1346,13 +1531,12 @@ int libradosstriper::RadosStriperImpl::truncate(const std::string& soid, if (rc == 0) { rc = multi_completion->get_return_value(); } - multi_completion->put(); return rc; } int libradosstriper::RadosStriperImpl::aio_truncate (const std::string& soid, - libradosstriper::MultiAioCompletionImpl *multi_completion, + libradosstriper::MultiAioCompletionImplPtr multi_completion, uint64_t original_size, uint64_t size, ceph_file_layout &layout) diff --git a/ceph/src/libradosstriper/RadosStriperImpl.h b/ceph/src/libradosstriper/RadosStriperImpl.h index 332c37536..6622471ed 100644 --- a/ceph/src/libradosstriper/RadosStriperImpl.h +++ b/ceph/src/libradosstriper/RadosStriperImpl.h @@ -21,221 +21,18 @@ #include "include/rados/librados.hpp" #include "include/radosstriper/libradosstriper.h" #include "include/radosstriper/libradosstriper.hpp" +#include "MultiAioCompletionImpl.h" #include "librados/IoCtxImpl.h" #include "librados/AioCompletionImpl.h" #include "common/RefCountedObj.h" -struct libradosstriper::RadosStriperImpl { +namespace libradosstriper { - /** - * struct handling the data needed to pass to the call back - * function in asynchronous operations - */ - struct CompletionData : RefCountedObject { - /// constructor - CompletionData(libradosstriper::RadosStriperImpl * striper, - const std::string& soid, - const std::string& lockCookie, - librados::AioCompletionImpl *userCompletion = 0, - int n = 1); - /// destructor - ~CompletionData() override; - /// complete method - void complete(int r); - /// striper to be used to handle the write completion - libradosstriper::RadosStriperImpl *m_striper; - /// striped object concerned by the write operation - std::string m_soid; - /// shared lock to be released at completion - std::string m_lockCookie; - /// completion handler - librados::IoCtxImpl::C_aio_Complete *m_ack; - }; - - /** - * struct handling the data needed to pass to the call back - * function in asynchronous read operations - */ - struct ReadCompletionData : CompletionData { - /// bufferlist containing final result - bufferlist* m_bl; - /// extents that will be read - std::vector* m_extents; - /// intermediate results - std::vector* m_resultbl; - /// return code of read completion, to be remembered until unlocking happened - int m_readRc; - /// completion object for the unlocking of the striped object at the end of the read - librados::AioCompletion *m_unlockCompletion; - /// constructor - ReadCompletionData(libradosstriper::RadosStriperImpl * striper, - const std::string& soid, - const std::string& lockCookie, - librados::AioCompletionImpl *userCompletion, - bufferlist* bl, - std::vector* extents, - std::vector* resultbl, - int n); - /// destructor - ~ReadCompletionData() override; - /// complete method for when reading is over - void complete_read(int r); - /// complete method for when object is unlocked - void complete_unlock(int r); - }; - - /** - * struct handling the data needed to pass to the call back - * function in asynchronous write operations - */ - struct WriteCompletionData : CompletionData { - /// safe completion handler - librados::IoCtxImpl::C_aio_Complete *m_safe; - /// return code of write completion, to be remembered until unlocking happened - int m_writeRc; - /// completion object for the unlocking of the striped object at the end of the write - librados::AioCompletion *m_unlockCompletion; - /// constructor - WriteCompletionData(libradosstriper::RadosStriperImpl * striper, - const std::string& soid, - const std::string& lockCookie, - librados::AioCompletionImpl *userCompletion, - int n); - /// destructor - ~WriteCompletionData() override; - /// complete method for when writing is over - void complete_write(int r); - /// complete method for when object is unlocked - void complete_unlock(int r); - /// safe method - void safe(int r); - }; - - /** - * struct handling the data needed to pass to the call back - * function in asynchronous read operations of a Rados File - */ - struct RadosReadCompletionData : RefCountedObject { - /// constructor - RadosReadCompletionData(MultiAioCompletionImpl *multiAioCompl, - uint64_t expectedBytes, - bufferlist *bl, - CephContext *context, - int n = 1) : - RefCountedObject(context, n), - m_multiAioCompl(multiAioCompl), m_expectedBytes(expectedBytes), m_bl(bl) {}; - /// the multi asynch io completion object to be used - MultiAioCompletionImpl *m_multiAioCompl; - /// the expected number of bytes - uint64_t m_expectedBytes; - /// the bufferlist object where data have been written - bufferlist *m_bl; - }; - - /** - * struct handling (most of) the data needed to pass to the call back - * function in asynchronous stat operations. - * Inherited by the actual type for adding time information in different - * versions (time_t or struct timespec) - */ - struct BasicStatCompletionData : CompletionData { - /// constructor - BasicStatCompletionData(libradosstriper::RadosStriperImpl* striper, - const std::string& soid, - librados::AioCompletionImpl *userCompletion, - libradosstriper::MultiAioCompletionImpl *multiCompletion, - uint64_t *psize, - int n = 1) : - CompletionData(striper, soid, "", userCompletion, n), - m_multiCompletion(multiCompletion), m_psize(psize), - m_statRC(0), m_getxattrRC(0) {}; - // MultiAioCompletionImpl used to handle the double aysnc - // call in the back (stat + getxattr) - libradosstriper::MultiAioCompletionImpl *m_multiCompletion; - // where to store the size of first objct - // this will be ignored but we need a place to store it when - // async stat is called - uint64_t m_objectSize; - // where to store the file size - uint64_t *m_psize; - /// the bufferlist object used for the getxattr call - bufferlist m_bl; - /// return code of the stat - int m_statRC; - /// return code of the getxattr - int m_getxattrRC; - }; +using MultiAioCompletionImplPtr = + boost::intrusive_ptr; - /** - * struct handling the data needed to pass to the call back - * function in asynchronous stat operations. - * Simple templated extension of BasicStatCompletionData. - * The template parameter is the type of the time information - * (used with time_t for stat and struct timespec for stat2) - */ - template - struct StatCompletionData : BasicStatCompletionData { - /// constructor - StatCompletionData(libradosstriper::RadosStriperImpl* striper, - const std::string& soid, - librados::AioCompletionImpl *userCompletion, - libradosstriper::MultiAioCompletionImpl *multiCompletion, - uint64_t *psize, - TimeType *pmtime, - int n = 1) : - BasicStatCompletionData(striper, soid, userCompletion, multiCompletion, psize, n), - m_pmtime(pmtime) {}; - // where to store the file time - TimeType *m_pmtime; - }; - - /** - * struct handling the data needed to pass to the call back - * function in asynchronous remove operations of a Rados File - */ - struct RadosRemoveCompletionData : RefCountedObject { - /// constructor - RadosRemoveCompletionData(MultiAioCompletionImpl *multiAioCompl, - CephContext *context) : - RefCountedObject(context, 2), - m_multiAioCompl(multiAioCompl) {}; - /// the multi asynch io completion object to be used - MultiAioCompletionImpl *m_multiAioCompl; - }; - - struct RemoveCompletionData : CompletionData { - /// removal flags - int flags; - /** - * constructor - * note that the constructed object will take ownership of the lock - */ - RemoveCompletionData(libradosstriper::RadosStriperImpl * striper, - const std::string& soid, - const std::string& lockCookie, - librados::AioCompletionImpl *userCompletion, - int flags = 0); - }; - - /** - * struct handling the data needed to pass to the call back - * function in asynchronous truncate operations - */ - struct TruncateCompletionData : RefCountedObject { - /// constructor - TruncateCompletionData(libradosstriper::RadosStriperImpl* striper, - const std::string& soid, - uint64_t size); - /// destructor - ~TruncateCompletionData() override; - /// striper to be used - libradosstriper::RadosStriperImpl *m_striper; - /// striped object concerned by the truncate operation - std::string m_soid; - /// the final size of the truncated object - uint64_t m_size; - }; +struct RadosStriperImpl { /** * exception wrapper around an error code @@ -355,7 +152,7 @@ struct libradosstriper::RadosStriperImpl { size_t len, uint64_t off); int internal_aio_write(const std::string& soid, - libradosstriper::MultiAioCompletionImpl *c, + MultiAioCompletionImplPtr c, const bufferlist& bl, size_t len, uint64_t off, @@ -374,7 +171,7 @@ struct libradosstriper::RadosStriperImpl { uint64_t *size); int internal_aio_remove(const std::string& soid, - libradosstriper::MultiAioCompletionImpl *multi_completion, + MultiAioCompletionImplPtr multi_completion, int flags=0); /** @@ -437,7 +234,7 @@ struct libradosstriper::RadosStriperImpl { * point is synchronous for lack of asynchronous truncation in the rados layer */ int aio_truncate(const std::string& soid, - libradosstriper::MultiAioCompletionImpl *c, + MultiAioCompletionImplPtr c, uint64_t original_size, uint64_t size, ceph_file_layout &layout); @@ -473,5 +270,5 @@ struct libradosstriper::RadosStriperImpl { // Default layout ceph_file_layout m_layout; }; - +} #endif diff --git a/ceph/src/libradosstriper/libradosstriper.cc b/ceph/src/libradosstriper/libradosstriper.cc index c72899a5f..193ee16c0 100644 --- a/ceph/src/libradosstriper/libradosstriper.cc +++ b/ceph/src/libradosstriper/libradosstriper.cc @@ -34,7 +34,8 @@ libradosstriper::MultiAioCompletion::~MultiAioCompletion() { - delete pc; + assert(pc->ref == 1); + pc->put(); } int libradosstriper::MultiAioCompletion::set_complete_callback diff --git a/ceph/src/librbd/ExclusiveLock.cc b/ceph/src/librbd/ExclusiveLock.cc index a3d69fce8..8436bad87 100644 --- a/ceph/src/librbd/ExclusiveLock.cc +++ b/ceph/src/librbd/ExclusiveLock.cc @@ -147,8 +147,14 @@ template void ExclusiveLock::handle_init_complete(uint64_t features) { ldout(m_image_ctx.cct, 10) << ": features=" << features << dendl; - if ((features & RBD_FEATURE_JOURNALING) != 0) { - m_image_ctx.io_work_queue->set_require_lock_on_read(); + { + RWLock::RLocker owner_locker(m_image_ctx.owner_lock); + if (m_image_ctx.clone_copy_on_read || + (features & RBD_FEATURE_JOURNALING) != 0) { + m_image_ctx.io_work_queue->set_require_lock(io::DIRECTION_BOTH, true); + } else { + m_image_ctx.io_work_queue->set_require_lock(io::DIRECTION_WRITE, true); + } } Mutex::Locker locker(ML::m_lock); @@ -161,7 +167,7 @@ void ExclusiveLock::shutdown_handler(int r, Context *on_finish) { { RWLock::WLocker owner_locker(m_image_ctx.owner_lock); - m_image_ctx.io_work_queue->clear_require_lock_on_read(); + m_image_ctx.io_work_queue->set_require_lock(io::DIRECTION_BOTH, false); m_image_ctx.exclusive_lock = nullptr; } @@ -269,7 +275,7 @@ void ExclusiveLock::handle_post_acquired_lock(int r) { if (r >= 0) { m_image_ctx.image_watcher->notify_acquired_lock(); - m_image_ctx.io_work_queue->clear_require_lock_on_read(); + m_image_ctx.io_work_queue->set_require_lock(io::DIRECTION_BOTH, false); m_image_ctx.io_work_queue->unblock_writes(); } @@ -302,16 +308,11 @@ void ExclusiveLock::post_release_lock_handler(bool shutting_down, int r, if (r >= 0) { m_image_ctx.image_watcher->notify_released_lock(); - if (m_image_ctx.io_work_queue->is_lock_request_needed()) { - // if we have blocked IO -- re-request the lock - RWLock::RLocker owner_locker(m_image_ctx.owner_lock); - ML::acquire_lock(nullptr); - } } } else { { RWLock::WLocker owner_locker(m_image_ctx.owner_lock); - m_image_ctx.io_work_queue->clear_require_lock_on_read(); + m_image_ctx.io_work_queue->set_require_lock(io::DIRECTION_BOTH, false); m_image_ctx.exclusive_lock = nullptr; } diff --git a/ceph/src/librbd/ImageCtx.cc b/ceph/src/librbd/ImageCtx.cc index fd2333ee1..ed27beda2 100644 --- a/ceph/src/librbd/ImageCtx.cc +++ b/ceph/src/librbd/ImageCtx.cc @@ -210,7 +210,7 @@ struct C_InvalidateCache : public Context { ThreadPool *thread_pool; get_thread_pool_instance(cct, &thread_pool, &op_work_queue); - io_work_queue = new io::ImageRequestWQ( + io_work_queue = new io::ImageRequestWQ<>( this, "librbd::io_work_queue", cct->_conf->rbd_op_thread_timeout, thread_pool); diff --git a/ceph/src/librbd/ImageCtx.h b/ceph/src/librbd/ImageCtx.h index 99a02748e..2bda521f1 100644 --- a/ceph/src/librbd/ImageCtx.h +++ b/ceph/src/librbd/ImageCtx.h @@ -52,7 +52,7 @@ namespace librbd { namespace io { class AioCompletion; class AsyncOperation; - class ImageRequestWQ; + template class ImageRequestWQ; class CopyupRequest; } namespace journal { struct Policy; } @@ -154,7 +154,7 @@ namespace librbd { xlist*> resize_reqs; - io::ImageRequestWQ *io_work_queue; + io::ImageRequestWQ *io_work_queue; xlist completed_reqs; EventSocket event_socket; diff --git a/ceph/src/librbd/exclusive_lock/PreReleaseRequest.cc b/ceph/src/librbd/exclusive_lock/PreReleaseRequest.cc index 5a37acc96..504de0f0b 100644 --- a/ceph/src/librbd/exclusive_lock/PreReleaseRequest.cc +++ b/ceph/src/librbd/exclusive_lock/PreReleaseRequest.cc @@ -109,8 +109,13 @@ void PreReleaseRequest::send_block_writes() { { RWLock::RLocker owner_locker(m_image_ctx.owner_lock); - if (m_image_ctx.test_features(RBD_FEATURE_JOURNALING)) { - m_image_ctx.io_work_queue->set_require_lock_on_read(); + // setting the lock as required will automatically cause the IO + // queue to re-request the lock if any IO is queued + if (m_image_ctx.clone_copy_on_read || + m_image_ctx.test_features(RBD_FEATURE_JOURNALING)) { + m_image_ctx.io_work_queue->set_require_lock(io::DIRECTION_BOTH, true); + } else { + m_image_ctx.io_work_queue->set_require_lock(io::DIRECTION_WRITE, true); } m_image_ctx.io_work_queue->block_writes(ctx); } diff --git a/ceph/src/librbd/image/RefreshRequest.cc b/ceph/src/librbd/image/RefreshRequest.cc index 7397b681a..f8448dc0e 100644 --- a/ceph/src/librbd/image/RefreshRequest.cc +++ b/ceph/src/librbd/image/RefreshRequest.cc @@ -644,7 +644,8 @@ void RefreshRequest::send_v2_open_journal() { !journal_disabled_by_policy && m_image_ctx.exclusive_lock != nullptr && m_image_ctx.journal == nullptr) { - m_image_ctx.io_work_queue->set_require_lock_on_read(); + m_image_ctx.io_work_queue->set_require_lock(librbd::io::DIRECTION_BOTH, + true); } send_v2_block_writes(); return; @@ -1077,7 +1078,6 @@ void RefreshRequest::apply() { // object map and journaling assert(m_exclusive_lock == nullptr); m_exclusive_lock = m_image_ctx.exclusive_lock; - m_image_ctx.io_work_queue->clear_require_lock_on_read(); } else { if (m_exclusive_lock != nullptr) { assert(m_image_ctx.exclusive_lock == nullptr); @@ -1085,8 +1085,9 @@ void RefreshRequest::apply() { } if (!m_image_ctx.test_features(RBD_FEATURE_JOURNALING, m_image_ctx.snap_lock)) { - if (m_image_ctx.journal != nullptr) { - m_image_ctx.io_work_queue->clear_require_lock_on_read(); + if (!m_image_ctx.clone_copy_on_read && m_image_ctx.journal != nullptr) { + m_image_ctx.io_work_queue->set_require_lock(io::DIRECTION_READ, + false); } std::swap(m_journal, m_image_ctx.journal); } else if (m_journal != nullptr) { @@ -1097,10 +1098,6 @@ void RefreshRequest::apply() { m_object_map != nullptr) { std::swap(m_object_map, m_image_ctx.object_map); } - if (m_image_ctx.clone_copy_on_read && - m_image_ctx.io_work_queue->is_lock_required()) { - m_image_ctx.io_work_queue->set_require_lock_on_read(); - } } } } diff --git a/ceph/src/librbd/io/ImageRequest.cc b/ceph/src/librbd/io/ImageRequest.cc index 80c7208a1..8afd6556a 100644 --- a/ceph/src/librbd/io/ImageRequest.cc +++ b/ceph/src/librbd/io/ImageRequest.cc @@ -108,6 +108,48 @@ private: } // anonymous namespace +template +ImageRequest* ImageRequest::create_read_request( + I &image_ctx, AioCompletion *aio_comp, Extents &&image_extents, + ReadResult &&read_result, int op_flags, + const ZTracer::Trace &parent_trace) { + return new ImageReadRequest(image_ctx, aio_comp, + std::move(image_extents), + std::move(read_result), op_flags, + parent_trace); +} + +template +ImageRequest* ImageRequest::create_write_request( + I &image_ctx, AioCompletion *aio_comp, Extents &&image_extents, + bufferlist &&bl, int op_flags, const ZTracer::Trace &parent_trace) { + return new ImageWriteRequest(image_ctx, aio_comp, std::move(image_extents), + std::move(bl), op_flags, parent_trace); +} + +template +ImageRequest* ImageRequest::create_discard_request( + I &image_ctx, AioCompletion *aio_comp, uint64_t off, uint64_t len, + bool skip_partial_discard, const ZTracer::Trace &parent_trace) { + return new ImageDiscardRequest(image_ctx, aio_comp, off, len, + skip_partial_discard, parent_trace); +} + +template +ImageRequest* ImageRequest::create_flush_request( + I &image_ctx, AioCompletion *aio_comp, + const ZTracer::Trace &parent_trace) { + return new ImageFlushRequest(image_ctx, aio_comp, parent_trace); +} + +template +ImageRequest* ImageRequest::create_writesame_request( + I &image_ctx, AioCompletion *aio_comp, uint64_t off, uint64_t len, + bufferlist &&bl, int op_flags, const ZTracer::Trace &parent_trace) { + return new ImageWriteSameRequest(image_ctx, aio_comp, off, len, + std::move(bl), op_flags, parent_trace); +} + template void ImageRequest::aio_read(I *ictx, AioCompletion *c, Extents &&image_extents, diff --git a/ceph/src/librbd/io/ImageRequest.h b/ceph/src/librbd/io/ImageRequest.h index 21b88b098..de19f490c 100644 --- a/ceph/src/librbd/io/ImageRequest.h +++ b/ceph/src/librbd/io/ImageRequest.h @@ -33,6 +33,31 @@ public: m_trace.event("finish"); } + static ImageRequest* create_read_request(ImageCtxT &image_ctx, + AioCompletion *aio_comp, + Extents &&image_extents, + ReadResult &&read_result, + int op_flags, + const ZTracer::Trace &parent_trace); + static ImageRequest* create_write_request(ImageCtxT &image_ctx, + AioCompletion *aio_comp, + Extents &&image_extents, + bufferlist &&bl, int op_flags, + const ZTracer::Trace &parent_trace); + static ImageRequest* create_discard_request(ImageCtxT &image_ctx, + AioCompletion *aio_comp, + uint64_t off, uint64_t len, + bool skip_partial_discard, + const ZTracer::Trace &parent_trace); + static ImageRequest* create_flush_request(ImageCtxT &image_ctx, + AioCompletion *aio_comp, + const ZTracer::Trace &parent_trace); + static ImageRequest* create_writesame_request(ImageCtxT &image_ctx, + AioCompletion *aio_comp, + uint64_t off, uint64_t len, + bufferlist &&bl, int op_flags, + const ZTracer::Trace &parent_trace); + static void aio_read(ImageCtxT *ictx, AioCompletion *c, Extents &&image_extents, ReadResult &&read_result, int op_flags, const ZTracer::Trace &parent_trace); diff --git a/ceph/src/librbd/io/ImageRequestWQ.cc b/ceph/src/librbd/io/ImageRequestWQ.cc index 2758790eb..e80e90088 100644 --- a/ceph/src/librbd/io/ImageRequestWQ.cc +++ b/ceph/src/librbd/io/ImageRequestWQ.cc @@ -21,21 +21,60 @@ namespace librbd { namespace io { -ImageRequestWQ::ImageRequestWQ(ImageCtx *image_ctx, const string &name, - time_t ti, ThreadPool *tp) - : ThreadPool::PointerWQ >(name, ti, 0, tp), +template +struct ImageRequestWQ::C_AcquireLock : public Context { + ImageRequestWQ *work_queue; + ImageRequest *image_request; + + C_AcquireLock(ImageRequestWQ *work_queue, ImageRequest *image_request) + : work_queue(work_queue), image_request(image_request) { + } + + void finish(int r) override { + work_queue->handle_acquire_lock(r, image_request); + } +}; + +template +struct ImageRequestWQ::C_BlockedWrites : public Context { + ImageRequestWQ *work_queue; + C_BlockedWrites(ImageRequestWQ *_work_queue) + : work_queue(_work_queue) { + } + + void finish(int r) override { + work_queue->handle_blocked_writes(r); + } +}; + +template +struct ImageRequestWQ::C_RefreshFinish : public Context { + ImageRequestWQ *work_queue; + ImageRequest *image_request; + + C_RefreshFinish(ImageRequestWQ *work_queue, + ImageRequest *image_request) + : work_queue(work_queue), image_request(image_request) { + } + void finish(int r) override { + work_queue->handle_refreshed(r, image_request); + } +}; + +template +ImageRequestWQ::ImageRequestWQ(I *image_ctx, const string &name, + time_t ti, ThreadPool *tp) + : ThreadPool::PointerWQ >(name, ti, 0, tp), m_image_ctx(*image_ctx), - m_lock(util::unique_lock_name("ImageRequestWQ::m_lock", this)), - 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) { + m_lock(util::unique_lock_name("ImageRequestWQ::m_lock", this)) { CephContext *cct = m_image_ctx.cct; ldout(cct, 5) << "ictx=" << image_ctx << dendl; - tp->add_work_queue(this); + this->register_work_queue(); } -ssize_t ImageRequestWQ::read(uint64_t off, uint64_t len, - ReadResult &&read_result, int op_flags) { +template +ssize_t ImageRequestWQ::read(uint64_t off, uint64_t len, + ReadResult &&read_result, int op_flags) { CephContext *cct = m_image_ctx.cct; ldout(cct, 20) << "ictx=" << &m_image_ctx << ", off=" << off << ", " << "len = " << len << dendl; @@ -46,8 +85,9 @@ ssize_t ImageRequestWQ::read(uint64_t off, uint64_t len, return cond.wait(); } -ssize_t ImageRequestWQ::write(uint64_t off, uint64_t len, - bufferlist &&bl, int op_flags) { +template +ssize_t ImageRequestWQ::write(uint64_t off, uint64_t len, + bufferlist &&bl, int op_flags) { CephContext *cct = m_image_ctx.cct; ldout(cct, 20) << "ictx=" << &m_image_ctx << ", off=" << off << ", " << "len = " << len << dendl; @@ -71,7 +111,9 @@ ssize_t ImageRequestWQ::write(uint64_t off, uint64_t len, return len; } -ssize_t ImageRequestWQ::discard(uint64_t off, uint64_t len, bool skip_partial_discard) { +template +ssize_t ImageRequestWQ::discard(uint64_t off, uint64_t len, + bool skip_partial_discard) { CephContext *cct = m_image_ctx.cct; ldout(cct, 20) << "ictx=" << &m_image_ctx << ", off=" << off << ", " << "len = " << len << dendl; @@ -95,8 +137,9 @@ ssize_t ImageRequestWQ::discard(uint64_t off, uint64_t len, bool skip_partial_di return len; } -ssize_t ImageRequestWQ::writesame(uint64_t off, uint64_t len, bufferlist &&bl, - int op_flags) { +template +ssize_t ImageRequestWQ::writesame(uint64_t off, uint64_t len, + bufferlist &&bl, int op_flags) { CephContext *cct = m_image_ctx.cct; ldout(cct, 20) << "ictx=" << &m_image_ctx << ", off=" << off << ", " << "len = " << len << ", data_len " << bl.length() << dendl; @@ -120,9 +163,10 @@ ssize_t ImageRequestWQ::writesame(uint64_t off, uint64_t len, bufferlist &&bl, return len; } -void ImageRequestWQ::aio_read(AioCompletion *c, uint64_t off, uint64_t len, - ReadResult &&read_result, int op_flags, - bool native_async) { +template +void ImageRequestWQ::aio_read(AioCompletion *c, uint64_t off, uint64_t len, + ReadResult &&read_result, int op_flags, + bool native_async) { CephContext *cct = m_image_ctx.cct; ZTracer::Trace trace; if (cct->_conf->rbd_blkin_trace_all) { @@ -130,7 +174,7 @@ void ImageRequestWQ::aio_read(AioCompletion *c, uint64_t off, uint64_t len, trace.event("start"); } - c->init_time(&m_image_ctx, AIO_TYPE_READ); + c->init_time(util::get_image_ctx(&m_image_ctx), AIO_TYPE_READ); ldout(cct, 20) << "ictx=" << &m_image_ctx << ", " << "completion=" << c << ", off=" << off << ", " << "len=" << len << ", " << "flags=" << op_flags << dendl; @@ -139,36 +183,31 @@ void ImageRequestWQ::aio_read(AioCompletion *c, uint64_t off, uint64_t len, c->set_event_notify(true); } - if (!start_in_flight_op(c)) { + if (!start_in_flight_io(c)) { return; } - RWLock::RLocker owner_locker(m_image_ctx.owner_lock); - // 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; - } - + RWLock::RLocker owner_locker(m_image_ctx.owner_lock); if (m_image_ctx.non_blocking_aio || writes_blocked() || !writes_empty() || - lock_required) { - queue(new ImageReadRequest<>(m_image_ctx, c, {{off, len}}, - std::move(read_result), op_flags, trace)); + require_lock_on_read()) { + queue(ImageRequest::create_read_request( + m_image_ctx, c, {{off, len}}, std::move(read_result), op_flags, + trace)); } else { c->start_op(); - ImageRequest<>::aio_read(&m_image_ctx, c, {{off, len}}, - std::move(read_result), op_flags, trace); - finish_in_flight_op(); + ImageRequest::aio_read(&m_image_ctx, c, {{off, len}}, + std::move(read_result), op_flags, trace); + finish_in_flight_io(); } trace.event("finish"); } -void ImageRequestWQ::aio_write(AioCompletion *c, uint64_t off, uint64_t len, - bufferlist &&bl, int op_flags, - bool native_async) { +template +void ImageRequestWQ::aio_write(AioCompletion *c, uint64_t off, uint64_t len, + bufferlist &&bl, int op_flags, + bool native_async) { CephContext *cct = m_image_ctx.cct; ZTracer::Trace trace; if (cct->_conf->rbd_blkin_trace_all) { @@ -176,7 +215,7 @@ void ImageRequestWQ::aio_write(AioCompletion *c, uint64_t off, uint64_t len, trace.event("init"); } - c->init_time(&m_image_ctx, AIO_TYPE_WRITE); + c->init_time(util::get_image_ctx(&m_image_ctx), AIO_TYPE_WRITE); ldout(cct, 20) << "ictx=" << &m_image_ctx << ", " << "completion=" << c << ", off=" << off << ", " << "len=" << len << ", flags=" << op_flags << dendl; @@ -185,26 +224,27 @@ void ImageRequestWQ::aio_write(AioCompletion *c, uint64_t off, uint64_t len, c->set_event_notify(true); } - if (!start_in_flight_op(c)) { + if (!start_in_flight_io(c)) { return; } RWLock::RLocker owner_locker(m_image_ctx.owner_lock); if (m_image_ctx.non_blocking_aio || writes_blocked()) { - queue(new ImageWriteRequest<>(m_image_ctx, c, {{off, len}}, - std::move(bl), op_flags, trace)); + queue(ImageRequest::create_write_request( + m_image_ctx, c, {{off, len}}, std::move(bl), op_flags, trace)); } else { c->start_op(); - ImageRequest<>::aio_write(&m_image_ctx, c, {{off, len}}, - std::move(bl), op_flags, trace); - finish_in_flight_op(); + ImageRequest::aio_write(&m_image_ctx, c, {{off, len}}, + std::move(bl), op_flags, trace); + finish_in_flight_io(); } trace.event("finish"); } -void ImageRequestWQ::aio_discard(AioCompletion *c, uint64_t off, - uint64_t len, bool skip_partial_discard, - bool native_async) { +template +void ImageRequestWQ::aio_discard(AioCompletion *c, uint64_t off, + uint64_t len, bool skip_partial_discard, + bool native_async) { CephContext *cct = m_image_ctx.cct; ZTracer::Trace trace; if (cct->_conf->rbd_blkin_trace_all) { @@ -212,7 +252,7 @@ void ImageRequestWQ::aio_discard(AioCompletion *c, uint64_t off, trace.event("init"); } - c->init_time(&m_image_ctx, AIO_TYPE_DISCARD); + c->init_time(util::get_image_ctx(&m_image_ctx), AIO_TYPE_DISCARD); ldout(cct, 20) << "ictx=" << &m_image_ctx << ", " << "completion=" << c << ", off=" << off << ", len=" << len << dendl; @@ -221,24 +261,25 @@ void ImageRequestWQ::aio_discard(AioCompletion *c, uint64_t off, c->set_event_notify(true); } - if (!start_in_flight_op(c)) { + if (!start_in_flight_io(c)) { return; } RWLock::RLocker owner_locker(m_image_ctx.owner_lock); if (m_image_ctx.non_blocking_aio || writes_blocked()) { - queue(new ImageDiscardRequest<>(m_image_ctx, c, off, len, - skip_partial_discard, trace)); + queue(ImageRequest::create_discard_request( + m_image_ctx, c, off, len, skip_partial_discard, trace)); } else { c->start_op(); - ImageRequest<>::aio_discard(&m_image_ctx, c, off, len, - skip_partial_discard, trace); - finish_in_flight_op(); + ImageRequest::aio_discard(&m_image_ctx, c, off, len, + skip_partial_discard, trace); + finish_in_flight_io(); } trace.event("finish"); } -void ImageRequestWQ::aio_flush(AioCompletion *c, bool native_async) { +template +void ImageRequestWQ::aio_flush(AioCompletion *c, bool native_async) { CephContext *cct = m_image_ctx.cct; ZTracer::Trace trace; if (cct->_conf->rbd_blkin_trace_all) { @@ -246,7 +287,7 @@ void ImageRequestWQ::aio_flush(AioCompletion *c, bool native_async) { trace.event("init"); } - c->init_time(&m_image_ctx, AIO_TYPE_FLUSH); + c->init_time(util::get_image_ctx(&m_image_ctx), AIO_TYPE_FLUSH); ldout(cct, 20) << "ictx=" << &m_image_ctx << ", " << "completion=" << c << dendl; @@ -254,23 +295,24 @@ void ImageRequestWQ::aio_flush(AioCompletion *c, bool native_async) { c->set_event_notify(true); } - if (!start_in_flight_op(c)) { + if (!start_in_flight_io(c)) { return; } RWLock::RLocker owner_locker(m_image_ctx.owner_lock); if (m_image_ctx.non_blocking_aio || writes_blocked() || !writes_empty()) { - queue(new ImageFlushRequest<>(m_image_ctx, c, trace)); + queue(ImageRequest::create_flush_request(m_image_ctx, c, trace)); } else { - ImageRequest<>::aio_flush(&m_image_ctx, c, trace); - finish_in_flight_op(); + ImageRequest::aio_flush(&m_image_ctx, c, trace); + finish_in_flight_io(); } trace.event("finish"); } -void ImageRequestWQ::aio_writesame(AioCompletion *c, uint64_t off, uint64_t len, - bufferlist &&bl, int op_flags, - bool native_async) { +template +void ImageRequestWQ::aio_writesame(AioCompletion *c, uint64_t off, + uint64_t len, bufferlist &&bl, + int op_flags, bool native_async) { CephContext *cct = m_image_ctx.cct; ZTracer::Trace trace; if (cct->_conf->rbd_blkin_trace_all) { @@ -278,7 +320,7 @@ void ImageRequestWQ::aio_writesame(AioCompletion *c, uint64_t off, uint64_t len, trace.event("init"); } - c->init_time(&m_image_ctx, AIO_TYPE_WRITESAME); + c->init_time(util::get_image_ctx(&m_image_ctx), AIO_TYPE_WRITESAME); ldout(cct, 20) << "ictx=" << &m_image_ctx << ", " << "completion=" << c << ", off=" << off << ", " << "len=" << len << ", data_len = " << bl.length() << ", " @@ -288,24 +330,25 @@ void ImageRequestWQ::aio_writesame(AioCompletion *c, uint64_t off, uint64_t len, c->set_event_notify(true); } - if (!start_in_flight_op(c)) { + if (!start_in_flight_io(c)) { return; } RWLock::RLocker owner_locker(m_image_ctx.owner_lock); if (m_image_ctx.non_blocking_aio || writes_blocked()) { - queue(new ImageWriteSameRequest<>(m_image_ctx, c, off, len, std::move(bl), - op_flags, trace)); + queue(ImageRequest::create_writesame_request( + m_image_ctx, c, off, len, std::move(bl), op_flags, trace)); } else { c->start_op(); - ImageRequest<>::aio_writesame(&m_image_ctx, c, off, len, std::move(bl), - op_flags, trace); - finish_in_flight_op(); + ImageRequest::aio_writesame(&m_image_ctx, c, off, len, std::move(bl), + op_flags, trace); + finish_in_flight_io(); } trace.event("finish"); } -void ImageRequestWQ::shut_down(Context *on_shutdown) { +template +void ImageRequestWQ::shut_down(Context *on_shutdown) { assert(m_image_ctx.owner_lock.is_locked()); { @@ -314,9 +357,9 @@ void ImageRequestWQ::shut_down(Context *on_shutdown) { m_shutdown = true; CephContext *cct = m_image_ctx.cct; - ldout(cct, 5) << __func__ << ": in_flight=" << m_in_flight_ops.load() + ldout(cct, 5) << __func__ << ": in_flight=" << m_in_flight_ios.load() << dendl; - if (m_in_flight_ops > 0) { + if (m_in_flight_ios > 0) { m_on_shutdown = on_shutdown; return; } @@ -326,19 +369,15 @@ void ImageRequestWQ::shut_down(Context *on_shutdown) { m_image_ctx.flush(on_shutdown); } -bool ImageRequestWQ::is_lock_request_needed() const { - RWLock::RLocker locker(m_lock); - return (m_queued_writes > 0 || - (m_require_lock_on_read && m_queued_reads > 0)); -} - -int ImageRequestWQ::block_writes() { +template +int ImageRequestWQ::block_writes() { C_SaferCond cond_ctx; block_writes(&cond_ctx); return cond_ctx.wait(); } -void ImageRequestWQ::block_writes(Context *on_blocked) { +template +void ImageRequestWQ::block_writes(Context *on_blocked) { assert(m_image_ctx.owner_lock.is_locked()); CephContext *cct = m_image_ctx.cct; @@ -347,7 +386,7 @@ void ImageRequestWQ::block_writes(Context *on_blocked) { ++m_write_blockers; ldout(cct, 5) << &m_image_ctx << ", " << "num=" << m_write_blockers << dendl; - if (!m_write_blocker_contexts.empty() || m_in_progress_writes > 0) { + if (!m_write_blocker_contexts.empty() || m_in_flight_writes > 0) { m_write_blocker_contexts.push_back(on_blocked); return; } @@ -357,7 +396,8 @@ void ImageRequestWQ::block_writes(Context *on_blocked) { m_image_ctx.flush(on_blocked); } -void ImageRequestWQ::unblock_writes() { +template +void ImageRequestWQ::unblock_writes() { CephContext *cct = m_image_ctx.cct; bool wake_up = false; @@ -374,72 +414,113 @@ void ImageRequestWQ::unblock_writes() { } if (wake_up) { - signal(); + this->signal(); } } -void ImageRequestWQ::set_require_lock_on_read() { - CephContext *cct = m_image_ctx.cct; - ldout(cct, 20) << dendl; - - RWLock::WLocker locker(m_lock); - m_require_lock_on_read = true; -} - -void ImageRequestWQ::clear_require_lock_on_read() { +template +void ImageRequestWQ::set_require_lock(Direction direction, bool enabled) { CephContext *cct = m_image_ctx.cct; ldout(cct, 20) << dendl; + bool wake_up = false; { RWLock::WLocker locker(m_lock); - if (!m_require_lock_on_read) { - return; + switch (direction) { + case DIRECTION_READ: + wake_up = (enabled != m_require_lock_on_read); + m_require_lock_on_read = enabled; + break; + case DIRECTION_WRITE: + wake_up = (enabled != m_require_lock_on_write); + m_require_lock_on_write = enabled; + break; + case DIRECTION_BOTH: + wake_up = (enabled != m_require_lock_on_read || + enabled != m_require_lock_on_write); + m_require_lock_on_read = enabled; + m_require_lock_on_write = enabled; + break; } + } - m_require_lock_on_read = false; + // wake up the thread pool whenever the state changes so that + // we can re-request the lock if required + if (wake_up) { + this->signal(); } - signal(); } -void *ImageRequestWQ::_void_dequeue() { - ImageRequest<> *peek_item = front(); +template +void *ImageRequestWQ::_void_dequeue() { + CephContext *cct = m_image_ctx.cct; + ImageRequest *peek_item = this->front(); - // no IO ops available or refresh in-progress (IO stalled) - if (peek_item == nullptr || m_refresh_in_progress) { + // no queued IO requests or all IO is blocked/stalled + if (peek_item == nullptr || m_io_blockers.load() > 0) { return nullptr; } + bool lock_required; bool refresh_required = m_image_ctx.state->is_refresh_required(); { RWLock::RLocker locker(m_lock); - if (peek_item->is_write_op()) { - if (m_write_blockers > 0) { + bool write_op = peek_item->is_write_op(); + lock_required = is_lock_required(write_op); + if (write_op) { + if (!lock_required && m_write_blockers > 0) { + // missing lock is not the write blocker return nullptr; } - // refresh will requeue the op -- don't count it as in-progress - if (!refresh_required) { - m_in_progress_writes++; + if (!lock_required && !refresh_required) { + // completed ops will requeue the IO -- don't count it as in-progress + m_in_flight_writes++; } - } else if (m_require_lock_on_read) { - return nullptr; } } - ImageRequest<> *item = reinterpret_cast *>( - ThreadPool::PointerWQ >::_void_dequeue()); + ImageRequest *item = reinterpret_cast *>( + ThreadPool::PointerWQ >::_void_dequeue()); assert(peek_item == item); + if (lock_required) { + this->get_pool_lock().Unlock(); + m_image_ctx.owner_lock.get_read(); + if (m_image_ctx.exclusive_lock != nullptr) { + ldout(cct, 5) << "exclusive lock required: delaying IO " << item << dendl; + if (!m_image_ctx.get_exclusive_lock_policy()->may_auto_request_lock()) { + lderr(cct) << "op requires exclusive lock" << dendl; + fail_in_flight_io(-EROFS, item); + + // wake up the IO since we won't be returning a request to process + this->signal(); + } else { + // stall IO until the acquire completes + ++m_io_blockers; + m_image_ctx.exclusive_lock->acquire_lock(new C_AcquireLock(this, item)); + } + } else { + // raced with the exclusive lock being disabled + lock_required = false; + } + m_image_ctx.owner_lock.put_read(); + this->get_pool_lock().Lock(); + + if (lock_required) { + return nullptr; + } + } + if (refresh_required) { - ldout(m_image_ctx.cct, 15) << "image refresh required: delaying IO " << item - << dendl; + ldout(cct, 5) << "image refresh required: delaying IO " << item << dendl; // stall IO until the refresh completes - m_refresh_in_progress = true; + ++m_io_blockers; - get_pool_lock().Unlock(); + this->get_pool_lock().Unlock(); m_image_ctx.state->refresh(new C_RefreshFinish(this, item)); - get_pool_lock().Lock(); + this->get_pool_lock().Lock(); return nullptr; } @@ -447,23 +528,25 @@ void *ImageRequestWQ::_void_dequeue() { return item; } -void ImageRequestWQ::process(ImageRequest<> *req) { +template +void ImageRequestWQ::process(ImageRequest *req) { CephContext *cct = m_image_ctx.cct; ldout(cct, 20) << "ictx=" << &m_image_ctx << ", " << "req=" << req << dendl; req->send(); - finish_queued_op(req); + finish_queued_io(req); if (req->is_write_op()) { - finish_in_progress_write(); + finish_in_flight_write(); } delete req; - finish_in_flight_op(); + finish_in_flight_io(); } -void ImageRequestWQ::finish_queued_op(ImageRequest<> *req) { +template +void ImageRequestWQ::finish_queued_io(ImageRequest *req) { RWLock::RLocker locker(m_lock); if (req->is_write_op()) { assert(m_queued_writes > 0); @@ -474,12 +557,13 @@ void ImageRequestWQ::finish_queued_op(ImageRequest<> *req) { } } -void ImageRequestWQ::finish_in_progress_write() { +template +void ImageRequestWQ::finish_in_flight_write() { bool writes_blocked = false; { RWLock::RLocker locker(m_lock); - assert(m_in_progress_writes > 0); - if (--m_in_progress_writes == 0 && + assert(m_in_flight_writes > 0); + if (--m_in_flight_writes == 0 && !m_write_blocker_contexts.empty()) { writes_blocked = true; } @@ -490,26 +574,29 @@ void ImageRequestWQ::finish_in_progress_write() { } } -int ImageRequestWQ::start_in_flight_op(AioCompletion *c) { +template +int ImageRequestWQ::start_in_flight_io(AioCompletion *c) { RWLock::RLocker locker(m_lock); if (m_shutdown) { CephContext *cct = m_image_ctx.cct; lderr(cct) << "IO received on closed image" << dendl; + c->get(); c->fail(-ESHUTDOWN); return false; } - m_in_flight_ops++; + m_in_flight_ios++; return true; } -void ImageRequestWQ::finish_in_flight_op() { +template +void ImageRequestWQ::finish_in_flight_io() { Context *on_shutdown; { RWLock::RLocker locker(m_lock); - if (--m_in_flight_ops > 0 || !m_shutdown) { + if (--m_in_flight_ios > 0 || !m_shutdown) { return; } on_shutdown = m_on_shutdown; @@ -522,75 +609,77 @@ void ImageRequestWQ::finish_in_flight_op() { m_image_ctx.flush(on_shutdown); } -bool ImageRequestWQ::is_lock_required() const { - assert(m_image_ctx.owner_lock.is_locked()); - if (m_image_ctx.exclusive_lock == NULL) { - return false; - } +template +void ImageRequestWQ::fail_in_flight_io(int r, ImageRequest *req) { + this->process_finish(); + req->fail(r); + finish_queued_io(req); + delete req; + finish_in_flight_io(); +} - return (!m_image_ctx.exclusive_lock->is_lock_owner()); +template +bool ImageRequestWQ::is_lock_required(bool write_op) const { + assert(m_lock.is_locked()); + return ((write_op && m_require_lock_on_write) || + (!write_op && m_require_lock_on_read)); } -void ImageRequestWQ::queue(ImageRequest<> *req) { +template +void ImageRequestWQ::queue(ImageRequest *req) { + assert(m_image_ctx.owner_lock.is_locked()); + CephContext *cct = m_image_ctx.cct; ldout(cct, 20) << "ictx=" << &m_image_ctx << ", " << "req=" << req << dendl; - assert(m_image_ctx.owner_lock.is_locked()); - bool write_op = req->is_write_op(); - bool lock_required = (m_image_ctx.exclusive_lock != nullptr && - ((write_op && is_lock_required()) || - (!write_op && m_require_lock_on_read))); - - if (lock_required && !m_image_ctx.get_exclusive_lock_policy()->may_auto_request_lock()) { - lderr(cct) << "op requires exclusive lock" << dendl; - req->fail(-EROFS); - delete req; - finish_in_flight_op(); - return; - } - - if (write_op) { + if (req->is_write_op()) { m_queued_writes++; } else { m_queued_reads++; } - ThreadPool::PointerWQ >::queue(req); + ThreadPool::PointerWQ >::queue(req); +} - if (lock_required) { - m_image_ctx.exclusive_lock->acquire_lock(nullptr); +template +void ImageRequestWQ::handle_acquire_lock(int r, ImageRequest *req) { + CephContext *cct = m_image_ctx.cct; + ldout(cct, 5) << "r=" << r << ", " << "req=" << req << dendl; + + if (r < 0) { + fail_in_flight_io(r, req); + } else { + // since IO was stalled for acquire -- original IO order is preserved + // if we requeue this op for work queue processing + this->requeue(req); } + + assert(m_io_blockers.load() > 0); + --m_io_blockers; + this->signal(); } -void ImageRequestWQ::handle_refreshed(int r, ImageRequest<> *req) { +template +void ImageRequestWQ::handle_refreshed(int r, ImageRequest *req) { CephContext *cct = m_image_ctx.cct; - ldout(cct, 15) << "resuming IO after image refresh: r=" << r << ", " - << "req=" << req << dendl; + ldout(cct, 5) << "resuming IO after image refresh: r=" << r << ", " + << "req=" << req << dendl; if (r < 0) { - process_finish(); - req->fail(r); - finish_queued_op(req); - delete req; - finish_in_flight_op(); + fail_in_flight_io(r, req); } else { // since IO was stalled for refresh -- original IO order is preserved // if we requeue this op for work queue processing - requeue(req); + this->requeue(req); } - m_refresh_in_progress = false; - signal(); - - // refresh might have enabled exclusive lock -- IO stalled until - // we acquire the lock - RWLock::RLocker owner_locker(m_image_ctx.owner_lock); - if (is_lock_required() && is_lock_request_needed()) { - m_image_ctx.exclusive_lock->acquire_lock(nullptr); - } + assert(m_io_blockers.load() > 0); + --m_io_blockers; + this->signal(); } -void ImageRequestWQ::handle_blocked_writes(int r) { +template +void ImageRequestWQ::handle_blocked_writes(int r) { Contexts contexts; { RWLock::WLocker locker(m_lock); @@ -602,5 +691,7 @@ void ImageRequestWQ::handle_blocked_writes(int r) { } } +template class librbd::io::ImageRequestWQ; + } // namespace io } // namespace librbd diff --git a/ceph/src/librbd/io/ImageRequestWQ.h b/ceph/src/librbd/io/ImageRequestWQ.h index 0ed843daf..64f1790f7 100644 --- a/ceph/src/librbd/io/ImageRequestWQ.h +++ b/ceph/src/librbd/io/ImageRequestWQ.h @@ -7,6 +7,7 @@ #include "include/Context.h" #include "common/RWLock.h" #include "common/WorkQueue.h" +#include "librbd/io/Types.h" #include #include @@ -21,9 +22,11 @@ class AioCompletion; template class ImageRequest; class ReadResult; -class ImageRequestWQ : protected ThreadPool::PointerWQ > { +template +class ImageRequestWQ + : public ThreadPool::PointerWQ > { public: - ImageRequestWQ(ImageCtx *image_ctx, const string &name, time_t ti, + ImageRequestWQ(ImageCtxT *image_ctx, const string &name, time_t ti, ThreadPool *tp); ssize_t read(uint64_t off, uint64_t len, ReadResult &&read_result, @@ -42,15 +45,12 @@ public: void aio_writesame(AioCompletion *c, uint64_t off, uint64_t len, bufferlist &&bl, int op_flags, bool native_async=true); - using ThreadPool::PointerWQ >::drain; + using ThreadPool::PointerWQ >::drain; - using ThreadPool::PointerWQ >::empty; + using ThreadPool::PointerWQ >::empty; void shut_down(Context *on_shutdown); - bool is_lock_required() const; - bool is_lock_request_needed() const; - inline bool writes_blocked() const { RWLock::RLocker locker(m_lock); return (m_write_blockers > 0); @@ -60,73 +60,62 @@ public: void block_writes(Context *on_blocked); void unblock_writes(); - void set_require_lock_on_read(); - void clear_require_lock_on_read(); + void set_require_lock(Direction direction, bool enabled); protected: void *_void_dequeue() override; - void process(ImageRequest *req) override; + void process(ImageRequest *req) override; private: typedef std::list Contexts; - struct C_RefreshFinish : public Context { - ImageRequestWQ *aio_work_queue; - ImageRequest *aio_image_request; - - C_RefreshFinish(ImageRequestWQ *aio_work_queue, - ImageRequest *aio_image_request) - : aio_work_queue(aio_work_queue), aio_image_request(aio_image_request) { - } - void finish(int r) override { - aio_work_queue->handle_refreshed(r, aio_image_request); - } - }; - - struct C_BlockedWrites : public Context { - ImageRequestWQ *aio_work_queue; - C_BlockedWrites(ImageRequestWQ *_aio_work_queue) - : aio_work_queue(_aio_work_queue) { - } - - void finish(int r) override { - aio_work_queue->handle_blocked_writes(r); - } - }; - - ImageCtx &m_image_ctx; + struct C_AcquireLock; + struct C_BlockedWrites; + struct C_RefreshFinish; + + ImageCtxT &m_image_ctx; mutable RWLock m_lock; Contexts m_write_blocker_contexts; - uint32_t m_write_blockers; + uint32_t m_write_blockers = 0; bool m_require_lock_on_read = false; - std::atomic m_in_progress_writes { 0 }; + bool m_require_lock_on_write = false; std::atomic m_queued_reads { 0 }; std::atomic m_queued_writes { 0 }; - std::atomic m_in_flight_ops { 0 }; + std::atomic m_in_flight_ios { 0 }; + std::atomic m_in_flight_writes { 0 }; + std::atomic m_io_blockers { 0 }; - bool m_refresh_in_progress; + bool m_shutdown = false; + Context *m_on_shutdown = nullptr; - bool m_shutdown; - Context *m_on_shutdown; + bool is_lock_required(bool write_op) const; + inline bool require_lock_on_read() const { + RWLock::RLocker locker(m_lock); + return m_require_lock_on_read; + } inline bool writes_empty() const { RWLock::RLocker locker(m_lock); return (m_queued_writes == 0); } - void finish_queued_op(ImageRequest *req); - void finish_in_progress_write(); + void finish_queued_io(ImageRequest *req); + void finish_in_flight_write(); - int start_in_flight_op(AioCompletion *c); - void finish_in_flight_op(); + int start_in_flight_io(AioCompletion *c); + void finish_in_flight_io(); + void fail_in_flight_io(int r, ImageRequest *req); - void queue(ImageRequest *req); + void queue(ImageRequest *req); - void handle_refreshed(int r, ImageRequest *req); + void handle_acquire_lock(int r, ImageRequest *req); + void handle_refreshed(int r, ImageRequest *req); void handle_blocked_writes(int r); }; } // namespace io } // namespace librbd +extern template class librbd::io::ImageRequestWQ; + #endif // CEPH_LIBRBD_IO_IMAGE_REQUEST_WQ_H diff --git a/ceph/src/librbd/io/Types.h b/ceph/src/librbd/io/Types.h index 874e1dd3e..006b22298 100644 --- a/ceph/src/librbd/io/Types.h +++ b/ceph/src/librbd/io/Types.h @@ -23,6 +23,12 @@ typedef enum { AIO_TYPE_WRITESAME, } aio_type_t; +enum Direction { + DIRECTION_READ, + DIRECTION_WRITE, + DIRECTION_BOTH +}; + typedef std::vector > Extents; typedef std::map ExtentMap; diff --git a/ceph/src/librbd/operation/DisableFeaturesRequest.cc b/ceph/src/librbd/operation/DisableFeaturesRequest.cc index 41eddbd7c..34cc9579f 100644 --- a/ceph/src/librbd/operation/DisableFeaturesRequest.cc +++ b/ceph/src/librbd/operation/DisableFeaturesRequest.cc @@ -354,14 +354,14 @@ void DisableFeaturesRequest::send_close_journal() { { RWLock::WLocker locker(image_ctx.owner_lock); if (image_ctx.journal != nullptr) { - ldout(cct, 20) << this << " " << __func__ << dendl; + std::swap(m_journal, image_ctx.journal); Context *ctx = create_context_callback< DisableFeaturesRequest, &DisableFeaturesRequest::handle_close_journal>(this); - image_ctx.journal->close(ctx); + m_journal->close(ctx); return; } } @@ -378,9 +378,12 @@ Context *DisableFeaturesRequest::handle_close_journal(int *result) { if (*result < 0) { lderr(cct) << "failed to close image journal: " << cpp_strerror(*result) << dendl; - return handle_finish(*result); } + assert(m_journal != nullptr); + delete m_journal; + m_journal = nullptr; + send_remove_journal(); return nullptr; } diff --git a/ceph/src/librbd/operation/DisableFeaturesRequest.h b/ceph/src/librbd/operation/DisableFeaturesRequest.h index 623eb1f87..b064bc45f 100644 --- a/ceph/src/librbd/operation/DisableFeaturesRequest.h +++ b/ceph/src/librbd/operation/DisableFeaturesRequest.h @@ -4,6 +4,7 @@ #ifndef CEPH_LIBRBD_OPERATION_DISABLE_FEATURES_REQUEST_H #define CEPH_LIBRBD_OPERATION_DISABLE_FEATURES_REQUEST_H +#include "librbd/ImageCtx.h" #include "librbd/operation/Request.h" #include "cls/rbd/cls_rbd_client.h" @@ -113,6 +114,7 @@ private: uint64_t m_disable_flags = 0; uint64_t m_features_mask = 0; + decltype(ImageCtxT::journal) m_journal = nullptr; cls::rbd::MirrorMode m_mirror_mode = cls::rbd::MIRROR_MODE_DISABLED; bufferlist m_out_bl; diff --git a/ceph/src/mds/CDir.cc b/ceph/src/mds/CDir.cc index 6561d2fb2..c190cca17 100644 --- a/ceph/src/mds/CDir.cc +++ b/ceph/src/mds/CDir.cc @@ -2583,8 +2583,11 @@ void CDir::set_dir_auth(mds_authority_t a) inode->adjust_nested_auth_pins(-1, NULL); // unpin parent of frozen dir/tree? - if (inode->is_auth() && (is_frozen_tree_root() || is_frozen_dir())) - inode->auth_unpin(this); + if (inode->is_auth()) { + assert(!is_frozen_tree_root()); + if (is_frozen_dir()) + inode->auth_unpin(this); + } } if (was_subtree && !is_subtree_root()) { dout(10) << " old subtree root, adjusting auth_pins" << dendl; @@ -2594,8 +2597,11 @@ void CDir::set_dir_auth(mds_authority_t a) inode->adjust_nested_auth_pins(1, NULL); // pin parent of frozen dir/tree? - if (inode->is_auth() && (is_frozen_tree_root() || is_frozen_dir())) - inode->auth_pin(this); + if (inode->is_auth()) { + assert(!is_frozen_tree_root()); + if (is_frozen_dir()) + inode->auth_pin(this); + } } // newly single auth? @@ -2774,13 +2780,30 @@ void CDir::_freeze_tree() state_clear(STATE_FREEZINGTREE); // actually, this may get set again by next context? --num_freezing_trees; } + + if (is_auth()) { + mds_authority_t auth; + bool was_subtree = is_subtree_root(); + if (was_subtree) { + auth = get_dir_auth(); + } else { + // temporarily prevent parent subtree from becoming frozen. + inode->auth_pin(this); + // create new subtree + auth = authority(); + } + + assert(auth.first >= 0); + assert(auth.second == CDIR_AUTH_UNKNOWN); + auth.second = auth.first; + inode->mdcache->adjust_subtree_auth(this, auth); + if (!was_subtree) + inode->auth_unpin(this); + } + state_set(STATE_FROZENTREE); ++num_frozen_trees; get(PIN_FROZEN); - - // auth_pin inode for duration of freeze, if we are not a subtree root. - if (is_auth() && !is_subtree_root()) - inode->auth_pin(this); } void CDir::unfreeze_tree() @@ -2794,9 +2817,16 @@ void CDir::unfreeze_tree() put(PIN_FROZEN); - // unpin (may => FREEZEABLE) FIXME: is this order good? - if (is_auth() && !is_subtree_root()) - inode->auth_unpin(this); + if (is_auth()) { + // must be subtree + assert(is_subtree_root()); + // for debug purpose, caller should ensure 'dir_auth.second == dir_auth.first' + mds_authority_t auth = get_dir_auth(); + assert(auth.first >= 0); + assert(auth.second == auth.first); + auth.second = CDIR_AUTH_UNKNOWN; + inode->mdcache->adjust_subtree_auth(this, auth); + } // waiters? finish_waiting(WAIT_UNFREEZE); diff --git a/ceph/src/mds/CInode.cc b/ceph/src/mds/CInode.cc index 567668a12..4e6af3e97 100644 --- a/ceph/src/mds/CInode.cc +++ b/ceph/src/mds/CInode.cc @@ -339,11 +339,16 @@ void CInode::mark_dirty_rstat() dout(10) << "mark_dirty_rstat" << dendl; state_set(STATE_DIRTYRSTAT); get(PIN_DIRTYRSTAT); - CDentry *dn = get_projected_parent_dn(); - CDir *pdir = dn->dir; - pdir->dirty_rstat_inodes.push_back(&dirty_rstat_item); - - mdcache->mds->locker->mark_updated_scatterlock(&pdir->inode->nestlock); + CDentry *pdn = get_projected_parent_dn(); + if (pdn->is_auth()) { + CDir *pdir = pdn->dir; + pdir->dirty_rstat_inodes.push_back(&dirty_rstat_item); + mdcache->mds->locker->mark_updated_scatterlock(&pdir->inode->nestlock); + } else { + // under cross-MDS rename. + // DIRTYRSTAT flag will get cleared when rename finishes + assert(state_test(STATE_AMBIGUOUSAUTH)); + } } } void CInode::clear_dirty_rstat() diff --git a/ceph/src/mds/FSMap.cc b/ceph/src/mds/FSMap.cc index eb08d02b7..cdce14b60 100644 --- a/ceph/src/mds/FSMap.cc +++ b/ceph/src/mds/FSMap.cc @@ -18,6 +18,8 @@ #include using std::stringstream; +#include "mon/health_check.h" + void Filesystem::dump(Formatter *f) const { @@ -327,6 +329,30 @@ bool FSMap::check_health(void) return changed; } +void FSMap::get_health_checks(health_check_map_t *checks) const +{ + mds_rank_t standby_count_wanted = 0; + for (const auto &i : filesystems) { + const auto &fs = i.second; + health_check_map_t fschecks; + fs->mds_map.get_health_checks(&fschecks); + checks->merge(fschecks); + standby_count_wanted = std::max( + standby_count_wanted, + fs->mds_map.get_standby_count_wanted((mds_rank_t)standby_daemons.size())); + } + + // MDS_INSUFFICIENT_STANDBY + if (standby_count_wanted) { + std::ostringstream oss, dss; + oss << "insufficient standby daemons available"; + auto& d = checks->add("MDS_INSUFFICIENT_STANDBY", HEALTH_WARN, oss.str()); + dss << "have " << standby_daemons.size() << "; want " << standby_count_wanted + << " more"; + d.detail.push_back(dss.str()); + } +} + void FSMap::encode(bufferlist& bl, uint64_t features) const { if (features & CEPH_FEATURE_SERVER_JEWEL) { diff --git a/ceph/src/mds/FSMap.h b/ceph/src/mds/FSMap.h index 3d389c488..ea102a712 100644 --- a/ceph/src/mds/FSMap.h +++ b/ceph/src/mds/FSMap.h @@ -35,6 +35,7 @@ #include "mds/mdstypes.h" class CephContext; +class health_check_map_t; #define MDS_FEATURE_INCOMPAT_BASE CompatSet::Feature(1, "base v0.20") #define MDS_FEATURE_INCOMPAT_CLIENTRANGES CompatSet::Feature(2, "client writeable ranges") @@ -476,6 +477,8 @@ public: void get_health(list >& summary, list > *detail) const; + void get_health_checks(health_check_map_t *checks) const; + bool check_health(void); /** diff --git a/ceph/src/mds/Locker.cc b/ceph/src/mds/Locker.cc index 6cb9a7351..cf795ed22 100644 --- a/ceph/src/mds/Locker.cc +++ b/ceph/src/mds/Locker.cc @@ -365,6 +365,10 @@ bool Locker::acquire_locks(MDRequestRef& mdr, } dout(10) << " can't auth_pin (freezing?), waiting to authpin " << *object << dendl; object->add_waiter(MDSCacheObject::WAIT_UNFREEZE, new C_MDS_RetryRequest(mdcache, mdr)); + + if (!mdr->remote_auth_pins.empty()) + notify_freeze_waiter(object); + return false; } } @@ -615,6 +619,28 @@ bool Locker::acquire_locks(MDRequestRef& mdr, return result; } +void Locker::notify_freeze_waiter(MDSCacheObject *o) +{ + CDir *dir = NULL; + if (CInode *in = dynamic_cast(o)) { + if (!in->is_root()) + dir = in->get_parent_dir(); + } else if (CDentry *dn = dynamic_cast(o)) { + dir = dn->get_dir(); + } else { + dir = dynamic_cast(o); + assert(dir); + } + if (dir) { + if (dir->is_freezing_dir()) + mdcache->fragment_freeze_inc_num_waiters(dir); + if (dir->is_freezing_tree()) { + while (!dir->is_freezing_tree_root()) + dir = dir->get_parent_dir(); + mdcache->migrator->export_freeze_inc_num_waiters(dir); + } + } +} void Locker::set_xlocks_done(MutationImpl *mut, bool skip_dentry) { diff --git a/ceph/src/mds/Locker.h b/ceph/src/mds/Locker.h index 32b7d6301..8cff4ec3e 100644 --- a/ceph/src/mds/Locker.h +++ b/ceph/src/mds/Locker.h @@ -80,6 +80,7 @@ public: CInode *auth_pin_freeze=NULL, bool auth_pin_nonblock=false); + void notify_freeze_waiter(MDSCacheObject *o); void cancel_locking(MutationImpl *mut, set *pneed_issue); void drop_locks(MutationImpl *mut, set *pneed_issue=0); void set_xlocks_done(MutationImpl *mut, bool skip_dentry=false); diff --git a/ceph/src/mds/MDBalancer.cc b/ceph/src/mds/MDBalancer.cc index 26f14e519..186d5f40e 100644 --- a/ceph/src/mds/MDBalancer.cc +++ b/ceph/src/mds/MDBalancer.cc @@ -641,8 +641,6 @@ void MDBalancer::prep_rebalance(int beat) return; } - last_epoch_over = beat_epoch; - // am i over long enough? if (last_epoch_under && beat_epoch - last_epoch_under < 2) { dout(5) << " i am overloaded, but only for " << (beat_epoch - last_epoch_under) << " epochs" << dendl; @@ -1228,3 +1226,9 @@ void MDBalancer::add_import(CDir *dir, utime_t now) } } +void MDBalancer::handle_mds_failure(mds_rank_t who) +{ + if (0 == who) { + last_epoch_under = 0; + } +} diff --git a/ceph/src/mds/MDBalancer.h b/ceph/src/mds/MDBalancer.h index 1f8d0dd1e..d23185b22 100644 --- a/ceph/src/mds/MDBalancer.h +++ b/ceph/src/mds/MDBalancer.h @@ -42,7 +42,7 @@ public: messenger(msgr), mon_client(monc), beat_epoch(0), - last_epoch_under(0), last_epoch_over(0), my_load(0.0), target_load(0.0) + last_epoch_under(0), my_load(0.0), target_load(0.0) { } mds_load_t get_load(utime_t); @@ -73,6 +73,8 @@ public: */ void maybe_fragment(CDir *dir, bool hot); + void handle_mds_failure(mds_rank_t who); + private: typedef struct { std::map targets; @@ -123,7 +125,6 @@ private: int beat_epoch; int last_epoch_under; - int last_epoch_over; string bal_code; string bal_version; diff --git a/ceph/src/mds/MDCache.cc b/ceph/src/mds/MDCache.cc index 6c9f47a72..abdf5b2a7 100644 --- a/ceph/src/mds/MDCache.cc +++ b/ceph/src/mds/MDCache.cc @@ -624,7 +624,7 @@ void MDCache::open_root() assert(!root->is_auth()); CDir *rootdir = root->get_dirfrag(frag_t()); if (!rootdir) { - discover_dir_frag(root, frag_t(), new C_MDS_RetryOpenRoot(this)); + open_remote_dirfrag(root, frag_t(), new C_MDS_RetryOpenRoot(this)); return; } } @@ -798,14 +798,11 @@ void MDCache::list_subtrees(list& ls) * merge with parent and/or child subtrees, if is it appropriate. * merge can ONLY happen if both parent and child have unambiguous auth. */ -void MDCache::adjust_subtree_auth(CDir *dir, mds_authority_t auth, bool do_eval) +void MDCache::adjust_subtree_auth(CDir *dir, mds_authority_t auth) { dout(7) << "adjust_subtree_auth " << dir->get_dir_auth() << " -> " << auth << " on " << *dir << dendl; - if (mds->is_any_replay() || mds->is_resolve()) - do_eval = false; - show_subtrees(); CDir *root; @@ -865,9 +862,6 @@ void MDCache::adjust_subtree_auth(CDir *dir, mds_authority_t auth, bool do_eval) p = p->inode->get_parent_dir(); } } - - if (do_eval) - eval_subtree_root(dir->get_inode()); } show_subtrees(); @@ -880,14 +874,18 @@ void MDCache::try_subtree_merge(CDir *dir) assert(subtrees.count(dir)); set oldbounds = subtrees[dir]; + set to_eval; // try merge at my root - try_subtree_merge_at(dir); + try_subtree_merge_at(dir, &to_eval); // try merge at my old bounds - for (set::iterator p = oldbounds.begin(); - p != oldbounds.end(); - ++p) - try_subtree_merge_at(*p); + for (auto bound : oldbounds) + try_subtree_merge_at(bound, &to_eval); + + if (!(mds->is_any_replay() || mds->is_resolve())) { + for(auto in : to_eval) + eval_subtree_root(in); + } } class C_MDC_SubtreeMergeWB : public MDCacheLogContext { @@ -900,14 +898,11 @@ public: } }; -void MDCache::try_subtree_merge_at(CDir *dir, bool do_eval) +void MDCache::try_subtree_merge_at(CDir *dir, set *to_eval) { dout(10) << "try_subtree_merge_at " << *dir << dendl; assert(subtrees.count(dir)); - if (mds->is_any_replay() || mds->is_resolve()) - do_eval = false; - // merge with parent? CDir *parent = dir; if (!dir->inode->is_base()) @@ -944,8 +939,8 @@ void MDCache::try_subtree_merge_at(CDir *dir, bool do_eval) } } - if (do_eval) - eval_subtree_root(dir->get_inode()); + if (to_eval && dir->get_inode()->is_auth()) + to_eval->insert(dir->get_inode()); } show_subtrees(15); @@ -967,8 +962,8 @@ void MDCache::eval_subtree_root(CInode *diri) { // evaluate subtree inode filelock? // (we should scatter the filelock on subtree bounds) - if (diri->is_auth()) - mds->locker->try_eval(diri, CEPH_LOCK_IFILE | CEPH_LOCK_INEST); + assert(diri->is_auth()); + mds->locker->try_eval(diri, CEPH_LOCK_IFILE | CEPH_LOCK_INEST); } @@ -1031,6 +1026,8 @@ void MDCache::adjust_bounded_subtree_auth(CDir *dir, set& bounds, mds_aut root = dir; } + set to_eval; + // verify/adjust bounds. // - these may be new, or // - beneath existing ambiguous bounds (which will be collapsed), @@ -1060,7 +1057,7 @@ void MDCache::adjust_bounded_subtree_auth(CDir *dir, set& bounds, mds_aut t = get_subtree_root(t->get_parent_dir()); dout(10) << " swallowing intervening subtree at " << *t << dendl; adjust_subtree_auth(t, auth); - try_subtree_merge_at(t); + try_subtree_merge_at(t, &to_eval); t = get_subtree_root(bound->get_parent_dir()); if (t == dir) break; } @@ -1078,7 +1075,7 @@ void MDCache::adjust_bounded_subtree_auth(CDir *dir, set& bounds, mds_aut CDir *stray = *p; dout(10) << " swallowing extra subtree at " << *stray << dendl; adjust_subtree_auth(stray, auth); - try_subtree_merge_at(stray); + try_subtree_merge_at(stray, &to_eval); } } // swallowing subtree may add new subtree bounds @@ -1090,6 +1087,11 @@ void MDCache::adjust_bounded_subtree_auth(CDir *dir, set& bounds, mds_aut verify_subtree_bounds(dir, bounds); show_subtrees(); + + if (!(mds->is_any_replay() || mds->is_resolve())) { + for(auto in : to_eval) + eval_subtree_root(in); + } } @@ -1306,8 +1308,7 @@ void MDCache::project_subtree_rename(CInode *diri, CDir *olddir, CDir *newdir) projected_subtree_renames[diri].push_back(pair(olddir, newdir)); } -void MDCache::adjust_subtree_after_rename(CInode *diri, CDir *olddir, - bool pop, bool imported) +void MDCache::adjust_subtree_after_rename(CInode *diri, CDir *olddir, bool pop) { dout(10) << "adjust_subtree_after_rename " << *diri << " from " << *olddir << dendl; @@ -1352,7 +1353,8 @@ void MDCache::adjust_subtree_after_rename(CInode *diri, CDir *olddir, subtrees[oldparent].erase(dir); assert(subtrees.count(newparent)); subtrees[newparent].insert(dir); - try_subtree_merge_at(dir, !imported); + // caller is responsible for 'eval diri' + try_subtree_merge_at(dir, NULL); } else { // mid-subtree. @@ -1377,8 +1379,9 @@ void MDCache::adjust_subtree_after_rename(CInode *diri, CDir *olddir, // did auth change? if (oldparent->authority() != newparent->authority()) { - adjust_subtree_auth(dir, oldparent->authority(), !imported); // caller is responsible for *diri. - try_subtree_merge_at(dir, !imported); + adjust_subtree_auth(dir, oldparent->authority()); + // caller is responsible for 'eval diri' + try_subtree_merge_at(dir, NULL); } } } @@ -2892,6 +2895,9 @@ void MDCache::handle_mds_failure(mds_rank_t who) // tell the migrator too. migrator->handle_mds_failure_or_stop(who); + // tell the balancer too. + mds->balancer->handle_mds_failure(who); + // clean up any requests slave to/from this node list finish; for (ceph::unordered_map::iterator p = active_requests.begin(); @@ -5929,6 +5935,7 @@ void MDCache::rejoin_send_acks() in = dir->get_inode(); if (in->is_replica(p->first)) break; + in->add_replica(p->first); if (in->is_base()) break; } @@ -8173,22 +8180,11 @@ CInode *MDCache::cache_traverse(const filepath& fp) void MDCache::open_remote_dirfrag(CInode *diri, frag_t approxfg, MDSInternalContextBase *fin) { dout(10) << "open_remote_dir on " << *diri << dendl; - assert(diri->is_dir()); assert(!diri->is_auth()); assert(diri->get_dirfrag(approxfg) == 0); - mds_rank_t auth = diri->authority().first; - - if (!mds->is_cluster_degraded() || - mds->mdsmap->get_state(auth) >= MDSMap::STATE_REJOIN) { - discover_dir_frag(diri, approxfg, fin); - } else { - // mds is down or recovering. forge a replica! - forge_replica_dir(diri, approxfg, auth); - if (fin) - mds->queue_waiter(fin); - } + discover_dir_frag(diri, approxfg, fin); } @@ -10180,21 +10176,6 @@ CDir *MDCache::add_replica_dir(bufferlist::iterator& p, CInode *diri, mds_rank_t return dir; } -CDir *MDCache::forge_replica_dir(CInode *diri, frag_t fg, mds_rank_t from) -{ - assert(mds->mdsmap->get_state(from) < MDSMap::STATE_REJOIN); - - // forge a replica. - CDir *dir = diri->add_dirfrag( new CDir(diri, fg, this, false) ); - - // i'm assuming this is a subtree root. - adjust_subtree_auth(dir, from); - - dout(7) << "forge_replica_dir added " << *dir << " while mds." << from << " is down" << dendl; - - return dir; -} - CDentry *MDCache::add_replica_dentry(bufferlist::iterator& p, CDir *dir, list& finished) { string name; @@ -10324,15 +10305,16 @@ int MDCache::send_dir_updates(CDir *dir, bool bcast) /* This function DOES put the passed message before returning */ void MDCache::handle_dir_update(MDirUpdate *m) { - CDir *dir = get_dirfrag(m->get_dirfrag()); + dirfrag_t df = m->get_dirfrag(); + CDir *dir = get_dirfrag(df); if (!dir) { - dout(5) << "dir_update on " << m->get_dirfrag() << ", don't have it" << dendl; + dout(5) << "dir_update on " << df << ", don't have it" << dendl; // discover it? if (m->should_discover()) { // only try once! // this is key to avoid a fragtree update race, among other things. - m->tried_discover(); + m->inc_tried_discover(); vector trace; CInode *in; filepath path = m->get_path(); @@ -10341,21 +10323,25 @@ void MDCache::handle_dir_update(MDirUpdate *m) int r = path_traverse(null_ref, m, NULL, path, &trace, &in, MDS_TRAVERSE_DISCOVER); if (r > 0) return; - assert(r == 0); - open_remote_dirfrag(in, m->get_dirfrag().frag, - new C_MDS_RetryMessage(mds, m)); - return; + if (r == 0 && + in->ino() == df.ino && + in->get_approx_dirfrag(df.frag) == NULL) { + open_remote_dirfrag(in, df.frag, new C_MDS_RetryMessage(mds, m)); + return; + } } m->put(); return; } - // update - dout(5) << "dir_update on " << *dir << dendl; - dir->dir_rep = m->get_dir_rep(); - dir->dir_rep_by = m->get_dir_rep_by(); - + if (!m->has_tried_discover()) { + // Update if it already exists. Othwerwise it got updated by discover reply. + dout(5) << "dir_update on " << *dir << dendl; + dir->dir_rep = m->get_dir_rep(); + dir->dir_rep_by = m->get_dir_rep_by(); + } + // done m->put(); } @@ -12101,9 +12087,12 @@ void MDCache::repair_dirfrag_stats_work(MDRequestRef& mdr) } if (!mdr->is_auth_pinned(dir) && !dir->can_auth_pin()) { + dir->add_waiter(CDir::WAIT_UNFREEZE, new C_MDS_RetryRequest(this, mdr)); + mds->locker->drop_locks(mdr.get()); mdr->drop_local_auth_pins(); - dir->add_waiter(CDir::WAIT_UNFREEZE, new C_MDS_RetryRequest(this, mdr)); + if (!mdr->remote_auth_pins.empty()) + mds->locker->notify_freeze_waiter(dir); return; } @@ -12383,8 +12372,10 @@ void MDCache::activate_stray_manager() * away. */ void MDCache::maybe_eval_stray(CInode *in, bool delay) { - if (in->inode.nlink > 0 || in->is_base() || is_readonly() || mds->is_standby_replay()) + if (in->inode.nlink > 0 || in->is_base() || is_readonly() || + mds->get_state() <= MDSMap::STATE_REJOIN) return; + CDentry *dn = in->get_projected_parent_dn(); if (dn->state_test(CDentry::STATE_PURGING)) { diff --git a/ceph/src/mds/MDCache.h b/ceph/src/mds/MDCache.h index 768f4cc92..3b0801958 100644 --- a/ceph/src/mds/MDCache.h +++ b/ceph/src/mds/MDCache.h @@ -269,9 +269,9 @@ protected: public: bool is_subtrees() { return !subtrees.empty(); } void list_subtrees(list& ls); - void adjust_subtree_auth(CDir *root, mds_authority_t auth, bool do_eval=true); - void adjust_subtree_auth(CDir *root, mds_rank_t a, mds_rank_t b=CDIR_AUTH_UNKNOWN, bool do_eval=true) { - adjust_subtree_auth(root, mds_authority_t(a,b), do_eval); + void adjust_subtree_auth(CDir *root, mds_authority_t auth); + void adjust_subtree_auth(CDir *root, mds_rank_t a, mds_rank_t b=CDIR_AUTH_UNKNOWN) { + adjust_subtree_auth(root, mds_authority_t(a,b)); } void adjust_bounded_subtree_auth(CDir *dir, set& bounds, mds_authority_t auth); void adjust_bounded_subtree_auth(CDir *dir, set& bounds, mds_rank_t a) { @@ -283,7 +283,7 @@ public: } void map_dirfrag_set(list& dfs, set& result); void try_subtree_merge(CDir *root); - void try_subtree_merge_at(CDir *root, bool do_eval=true); + void try_subtree_merge_at(CDir *root, set *to_eval); void subtree_merge_writebehind_finish(CInode *in, MutationRef& mut); void eval_subtree_root(CInode *diri); CDir *get_subtree_root(CDir *dir); @@ -302,8 +302,7 @@ public: void verify_subtree_bounds(CDir *root, const list& bounds); void project_subtree_rename(CInode *diri, CDir *olddir, CDir *newdir); - void adjust_subtree_after_rename(CInode *diri, CDir *olddir, - bool pop, bool imported = false); + void adjust_subtree_after_rename(CInode *diri, CDir *olddir, bool pop); void get_auth_subtrees(set& s); void get_fullauth_subtrees(set& s); @@ -1014,7 +1013,6 @@ public: } CDir* add_replica_dir(bufferlist::iterator& p, CInode *diri, mds_rank_t from, list& finished); - CDir* forge_replica_dir(CInode *diri, frag_t fg, mds_rank_t from); CDentry *add_replica_dentry(bufferlist::iterator& p, CDir *dir, list& finished); CInode *add_replica_inode(bufferlist::iterator& p, CDentry *dn, list& finished); diff --git a/ceph/src/mds/MDSMap.cc b/ceph/src/mds/MDSMap.cc index b397eb089..bd5446975 100644 --- a/ceph/src/mds/MDSMap.cc +++ b/ceph/src/mds/MDSMap.cc @@ -18,6 +18,8 @@ #include using std::stringstream; +#include "mon/health_check.h" + // features CompatSet get_mdsmap_compat_set_all() { @@ -404,6 +406,78 @@ void MDSMap::get_health(list >& summary, } } +void MDSMap::get_health_checks(health_check_map_t *checks) const +{ + // FS_WITH_FAILED_MDS + // MDS_FAILED + if (!failed.empty()) { + health_check_t& fscheck = checks->add( + "FS_WITH_FAILED_MDS", HEALTH_WARN, + "%num% filesystem%plurals% %isorare% have a failed mds daemon"); + ostringstream ss; + ss << "fs " << fs_name << " has " << failed.size() << " failed mds" + << (failed.size() > 1 ? "s" : ""); + fscheck.detail.push_back(ss.str()); + + health_check_t& check = checks->add("MDS_FAILED", HEALTH_ERR, + "%num% mds daemon%plurals% down"); + for (auto p : failed) { + std::ostringstream oss; + oss << "fs " << fs_name << " mds." << p << " has failed"; + check.detail.push_back(oss.str()); + } + } + + // MDS_DAMAGED + if (!damaged.empty()) { + health_check_t& check = checks->add("MDS_DAMAGED", HEALTH_ERR, + "%num% mds daemon%plurals% damaged"); + for (auto p : damaged) { + std::ostringstream oss; + oss << "fs " << fs_name << " mds." << p << " is damaged"; + check.detail.push_back(oss.str()); + } + } + + // FS_DEGRADED + // MDS_DEGRADED + if (is_degraded()) { + health_check_t& fscheck = checks->add( + "FS_DEGRADED", HEALTH_WARN, + "%num% filesystem%plurals% %isorare% degraded"); + ostringstream ss; + ss << "fs " << fs_name << " is degraded"; + fscheck.detail.push_back(ss.str()); + + list detail; + for (mds_rank_t i = mds_rank_t(0); i< get_max_mds(); i++) { + if (!is_up(i)) + continue; + mds_gid_t gid = up.find(i)->second; + map::const_iterator info = mds_info.find(gid); + stringstream ss; + ss << "fs " << fs_name << " mds." << info->second.name << " at " + << info->second.addr << " rank " << i; + if (is_resolve(i)) + ss << " is resolving"; + if (is_replay(i)) + ss << " is replaying journal"; + if (is_rejoin(i)) + ss << " is rejoining"; + if (is_reconnect(i)) + ss << " is reconnecting to clients"; + if (ss.str().length()) + detail.push_back(ss.str()); + } + if (!detail.empty()) { + health_check_t& check = checks->add( + "MDS_DEGRADED", HEALTH_WARN, + "%num% mds daemon%plurals% %isorare% degraded"); + check.detail.insert(check.detail.end(), detail.begin(), detail.end()); + } + } +} + void MDSMap::mds_info_t::encode_versioned(bufferlist& bl, uint64_t features) const { ENCODE_START(7, 4, bl); diff --git a/ceph/src/mds/MDSMap.h b/ceph/src/mds/MDSMap.h index e99be2be6..e6423c9be 100644 --- a/ceph/src/mds/MDSMap.h +++ b/ceph/src/mds/MDSMap.h @@ -21,6 +21,7 @@ #include "include/types.h" #include "common/Clock.h" #include "msg/Message.h" +#include "include/health.h" #include #include @@ -58,6 +59,7 @@ */ class CephContext; +class health_check_map_t; extern CompatSet get_mdsmap_compat_set_all(); extern CompatSet get_mdsmap_compat_set_default(); @@ -461,6 +463,8 @@ public: void get_health(list >& summary, list > *detail) const; + void get_health_checks(health_check_map_t *checks) const; + typedef enum { AVAILABLE = 0, diff --git a/ceph/src/mds/Migrator.cc b/ceph/src/mds/Migrator.cc index aafd89c28..779a87dc2 100644 --- a/ceph/src/mds/Migrator.cc +++ b/ceph/src/mds/Migrator.cc @@ -288,6 +288,8 @@ void Migrator::export_try_cancel(CDir *dir, bool notify_peer) dout(10) << "export state=freezing : canceling freeze" << dendl; it->second.state = EXPORT_CANCELLED; dir->unfreeze_tree(); // cancel the freeze + if (dir->is_subtree_root()) + cache->try_subtree_merge(dir); if (notify_peer && (!mds->is_cluster_degraded() || mds->mdsmap->is_clientreplay_or_active_or_stopping(it->second.peer))) // tell them. @@ -325,7 +327,6 @@ void Migrator::export_try_cancel(CDir *dir, bool notify_peer) } } dir->unfreeze_tree(); - cache->adjust_subtree_auth(dir, mds->get_nodeid()); cache->try_subtree_merge(dir); if (notify_peer && (!mds->is_cluster_degraded() || @@ -518,7 +519,6 @@ void Migrator::handle_mds_failure_or_stop(mds_rank_t who) // adjust auth back to the exporter cache->adjust_subtree_auth(dir, q->second.peer); - cache->try_subtree_merge(dir); // notify bystanders ; wait in aborting state import_state[df].state = IMPORT_ABORTING; @@ -564,9 +564,8 @@ void Migrator::handle_mds_failure_or_stop(mds_rank_t who) dout(10) << "faking export_notify_ack from mds." << who << " on aborting import " << *dir << " from mds." << q->second.peer << dendl; - if (q->second.bystanders.empty()) { + if (q->second.bystanders.empty()) import_reverse_unfreeze(dir); - } } } } @@ -888,6 +887,10 @@ void Migrator::dispatch_export_dir(MDRequestRef& mdr, int count) export_try_cancel(dir); return; } + + mds->locker->drop_locks(mdr.get()); + mdr->drop_local_auth_pins(); + mds->wait_for_mdsmap(mds->mdsmap->get_epoch(), new C_M_ExportDirWait(this, mdr, count+1)); return; } @@ -1046,14 +1049,15 @@ void Migrator::export_frozen(CDir *dir, uint64_t tid) !diri->nestlock.can_wrlock(-1)) { dout(7) << "export_dir couldn't acquire all needed locks, failing. " << *dir << dendl; - // .. unwind .. dir->unfreeze_tree(); - dir->state_clear(CDir::STATE_EXPORTING); + cache->try_subtree_merge(dir); mds->send_message_mds(new MExportDirCancel(dir->dirfrag(), it->second.tid), it->second.peer); - export_state.erase(it); + + dir->state_clear(CDir::STATE_EXPORTING); + cache->maybe_send_pending_resolves(); return; } @@ -1066,9 +1070,9 @@ void Migrator::export_frozen(CDir *dir, uint64_t tid) cache->show_subtrees(); + // CDir::_freeze_tree() should have forced it into subtree. + assert(dir->get_dir_auth() == mds_authority_t(mds->get_nodeid(), mds->get_nodeid())); // note the bounds. - // force it into a subtree by listing auth as . - cache->adjust_subtree_auth(dir, mds->get_nodeid(), mds->get_nodeid()); set bounds; cache->get_subtree_bounds(dir, bounds); @@ -1783,18 +1787,17 @@ void Migrator::export_reverse(CDir *dir) bd->state_clear(CDir::STATE_EXPORTBOUND); } - // adjust auth, with possible subtree merge. - cache->adjust_subtree_auth(dir, mds->get_nodeid()); - cache->try_subtree_merge(dir); - // notify bystanders export_notify_abort(dir, bounds); + // unfreeze tree, with possible subtree merge. + cache->adjust_subtree_auth(dir, mds->get_nodeid(), mds->get_nodeid()); + // process delayed expires cache->process_delayed_expire(dir); - - // unfreeze + dir->unfreeze_tree(); + cache->try_subtree_merge(dir); // revoke/resume stale caps for (auto in : to_eval) { @@ -1951,10 +1954,13 @@ void Migrator::export_finish(CDir *dir) // finish export (adjust local cache state) int num_dentries = 0; - C_ContextsBase *fin = new C_ContextsBase(g_ceph_context); + list finished; finish_export_dir(dir, ceph_clock_now(), it->second.peer, - it->second.peer_imported, fin->contexts, &num_dentries); - + it->second.peer_imported, finished, &num_dentries); + + assert(!dir->is_auth()); + cache->adjust_subtree_auth(dir, it->second.peer); + // unpin bounds set bounds; cache->get_subtree_bounds(dir, bounds); @@ -1969,9 +1975,14 @@ void Migrator::export_finish(CDir *dir) if (dir->state_test(CDir::STATE_AUXSUBTREE)) dir->state_clear(CDir::STATE_AUXSUBTREE); - // adjust auth, with possible subtree merge. + // discard delayed expires + cache->discard_delayed_expire(dir); + + dout(7) << "export_finish unfreezing" << dendl; + + // unfreeze tree, with possible subtree merge. // (we do this _after_ removing EXPORTBOUND pins, to allow merges) - cache->adjust_subtree_auth(dir, it->second.peer); + dir->unfreeze_tree(); cache->try_subtree_merge(dir); // no more auth subtree? clear scatter dirty @@ -1979,17 +1990,11 @@ void Migrator::export_finish(CDir *dir) !dir->get_inode()->has_subtree_root_dirfrag(mds->get_nodeid())) { dir->get_inode()->clear_scatter_dirty(); // wake up scatter_nudge waiters - dir->get_inode()->take_waiting(CInode::WAIT_ANY_MASK, fin->contexts); + dir->get_inode()->take_waiting(CInode::WAIT_ANY_MASK, finished); } - dir->add_waiter(CDir::WAIT_UNFREEZE, fin); - - // unfreeze - dout(7) << "export_finish unfreezing" << dendl; - dir->unfreeze_tree(); - - // discard delayed expires - cache->discard_delayed_expire(dir); + if (!finished.empty()) + mds->queue_waiters(finished); MutationRef mut = it->second.mut; // remove from exporting list, clean up state @@ -2139,7 +2144,6 @@ void Migrator::handle_export_cancel(MExportDirCancel *m) import_remove_pins(dir, bounds); // adjust auth back to the exportor cache->adjust_subtree_auth(dir, it->second.peer); - cache->try_subtree_merge(dir); import_reverse_unfreeze(dir); } else { assert(0 == "got export_cancel in weird state"); @@ -2628,8 +2632,6 @@ void Migrator::import_reverse(CDir *dir) // log our failure mds->mdlog->start_submit_entry(new EImportFinish(dir, false)); // log failure - cache->try_subtree_merge(dir); - cache->trim(-1, num_dentries); // try trimming dentries // notify bystanders; wait in aborting state @@ -2686,10 +2688,12 @@ void Migrator::import_notify_abort(CDir *dir, set& bounds) void Migrator::import_reverse_unfreeze(CDir *dir) { - assert(dir); dout(7) << "import_reverse_unfreeze " << *dir << dendl; - dir->unfreeze_tree(); + assert(!dir->is_auth()); cache->discard_delayed_expire(dir); + dir->unfreeze_tree(); + if (dir->is_subtree_root()) + cache->try_subtree_merge(dir); import_reverse_final(dir); } @@ -2789,6 +2793,11 @@ void Migrator::import_finish(CDir *dir, bool notify, bool last) assert(it != import_state.end()); assert(it->second.state == IMPORT_ACKING || it->second.state == IMPORT_FINISHING); + if (it->second.state == IMPORT_ACKING) { + assert(dir->is_auth()); + cache->adjust_subtree_auth(dir, mds->get_nodeid(), mds->get_nodeid()); + } + // log finish assert(g_conf->mds_kill_import_at != 9); @@ -2844,18 +2853,15 @@ void Migrator::import_finish(CDir *dir, bool notify, bool last) MutationRef mut = it->second.mut; import_state.erase(it); - // adjust auth, with possible subtree merge. - cache->adjust_subtree_auth(dir, mds->get_nodeid()); - mds->mdlog->start_submit_entry(new EImportFinish(dir, true)); - cache->try_subtree_merge(dir); - // process delayed expires cache->process_delayed_expire(dir); - // ok now unfreeze (and thus kick waiters) + // unfreeze tree, with possible subtree merge. dir->unfreeze_tree(); + cache->try_subtree_merge(dir); + cache->show_subtrees(); //audit(); // this fails, bc we munge up the subtree map during handle_import_map (resolve phase) diff --git a/ceph/src/mds/Server.cc b/ceph/src/mds/Server.cc index 2b4034006..55677f815 100644 --- a/ceph/src/mds/Server.cc +++ b/ceph/src/mds/Server.cc @@ -2256,24 +2256,7 @@ void Server::handle_slave_auth_pin(MDRequestRef& mdr) (*p)->add_waiter(CDir::WAIT_UNFREEZE, new C_MDS_RetryRequest(mdcache, mdr)); mdr->drop_local_auth_pins(); - CDir *dir = NULL; - if (CInode *in = dynamic_cast(*p)) { - if (!in->is_root()) - dir = in->get_parent_dir(); - } else if (CDentry *dn = dynamic_cast(*p)) { - dir = dn->get_dir(); - } else { - ceph_abort(); - } - if (dir) { - if (dir->is_freezing_dir()) - mdcache->fragment_freeze_inc_num_waiters(dir); - if (dir->is_freezing_tree()) { - while (!dir->is_freezing_tree_root()) - dir = dir->get_parent_dir(); - mdcache->migrator->export_freeze_inc_num_waiters(dir); - } - } + mds->locker->notify_freeze_waiter(*p); return; } } @@ -2825,6 +2808,8 @@ CInode* Server::rdlock_path_pin_ref(MDRequestRef& mdr, int n, */ mds->locker->drop_locks(mdr.get(), NULL); mdr->drop_local_auth_pins(); + if (!mdr->remote_auth_pins.empty()) + mds->locker->notify_freeze_waiter(ref); return 0; } @@ -2868,13 +2853,6 @@ CDentry* Server::rdlock_path_xlock_dentry(MDRequestRef& mdr, int n, if (!dir) return 0; dout(10) << "rdlock_path_xlock_dentry dir " << *dir << dendl; - // make sure we can auth_pin (or have already authpinned) dir - if (dir->is_frozen()) { - dout(7) << "waiting for !frozen/authpinnable on " << *dir << dendl; - dir->add_waiter(CInode::WAIT_UNFREEZE, new C_MDS_RetryRequest(mdcache, mdr)); - return 0; - } - CInode *diri = dir->get_inode(); if (!mdr->reqid.name.is_mds()) { if (diri->is_system() && !diri->is_root()) { @@ -2970,7 +2948,7 @@ CDir* Server::try_open_auth_dirfrag(CInode *diri, frag_t fg, MDRequestRef& mdr) if (!dir && diri->is_frozen()) { dout(10) << "try_open_auth_dirfrag: dir inode is frozen, waiting " << *diri << dendl; assert(diri->get_parent_dir()); - diri->get_parent_dir()->add_waiter(CDir::WAIT_UNFREEZE, new C_MDS_RetryRequest(mdcache, mdr)); + diri->add_waiter(CInode::WAIT_UNFREEZE, new C_MDS_RetryRequest(mdcache, mdr)); return 0; } @@ -7170,9 +7148,11 @@ void Server::_rename_prepare(MDRequestRef& mdr, if (destdn->is_auth() && !destdnl->is_null()) { mdcache->predirty_journal_parents(mdr, metablob, oldin, destdn->get_dir(), (destdnl->is_primary() ? PREDIRTY_PRIMARY:0)|predirty_dir, -1); - if (destdnl->is_primary()) + if (destdnl->is_primary()) { + assert(straydn); mdcache->predirty_journal_parents(mdr, metablob, oldin, straydn->get_dir(), PREDIRTY_PRIMARY|PREDIRTY_DIR, 1); + } } // move srcdn @@ -7191,6 +7171,7 @@ void Server::_rename_prepare(MDRequestRef& mdr, // target inode if (!linkmerge) { if (destdnl->is_primary()) { + assert(straydn); if (destdn->is_auth()) { // project snaprealm, too if (oldin->snaprealm || dest_realm->get_newest_seq() + 1 > oldin->get_oldest_snap()) @@ -7284,8 +7265,10 @@ void Server::_rename_prepare(MDRequestRef& mdr, if (srcdnl->is_primary() && destdn->is_auth()) srci->first = destdn->first; - if (oldin && oldin->is_dir()) + if (oldin && oldin->is_dir()) { + assert(straydn); mdcache->project_subtree_rename(oldin, destdn->get_dir(), straydn->get_dir()); + } if (srci->is_dir()) mdcache->project_subtree_rename(srci, srcdn->get_dir(), destdn->get_dir()); @@ -7301,8 +7284,6 @@ void Server::_rename_apply(MDRequestRef& mdr, CDentry *srcdn, CDentry *destdn, C CDentry::linkage_t *destdnl = destdn->get_linkage(); CInode *oldin = destdnl->get_inode(); - - bool imported_inode = false; // primary+remote link merge? bool linkmerge = (srcdnl->get_inode() == destdnl->get_inode() && @@ -7402,7 +7383,6 @@ void Server::_rename_apply(MDRequestRef& mdr, CDentry *srcdn, CDentry *destdn, C // hack: fix auth bit in->state_set(CInode::STATE_AUTH); - imported_inode = true; mdr->clear_ambiguous_auth(); } @@ -7427,7 +7407,7 @@ void Server::_rename_apply(MDRequestRef& mdr, CDentry *srcdn, CDentry *destdn, C // update subtree map? if (destdnl->is_primary() && in->is_dir()) - mdcache->adjust_subtree_after_rename(in, srcdn->get_dir(), true, imported_inode); + mdcache->adjust_subtree_after_rename(in, srcdn->get_dir(), true); if (straydn && oldin->is_dir()) mdcache->adjust_subtree_after_rename(oldin, destdn->get_dir(), true); diff --git a/ceph/src/mds/StrayManager.cc b/ceph/src/mds/StrayManager.cc index 25c247744..b2102ddc2 100644 --- a/ceph/src/mds/StrayManager.cc +++ b/ceph/src/mds/StrayManager.cc @@ -420,6 +420,7 @@ bool StrayManager::_eval_stray(CDentry *dn, bool delay) dout(10) << " inode is " << *dnl->get_inode() << dendl; CInode *in = dnl->get_inode(); assert(in); + assert(!in->state_test(CInode::STATE_REJOINUNDEF)); // The only dentries elegible for purging are those // in the stray directories diff --git a/ceph/src/mds/journal.cc b/ceph/src/mds/journal.cc index 5d8088234..b63fbd980 100644 --- a/ceph/src/mds/journal.cc +++ b/ceph/src/mds/journal.cc @@ -1488,7 +1488,7 @@ void EMetaBlob::replay(MDSRank *mds, LogSegment *logseg, MDSlaveUpdate *slaveup) dir = renamed_diri->get_or_open_dirfrag(mds->mdcache, *p); dout(10) << " creating new rename import bound " << *dir << dendl; dir->state_clear(CDir::STATE_AUTH); - mds->mdcache->adjust_subtree_auth(dir, CDIR_AUTH_UNDEF, false); + mds->mdcache->adjust_subtree_auth(dir, CDIR_AUTH_UNDEF); } } diff --git a/ceph/src/messages/MDirUpdate.h b/ceph/src/messages/MDirUpdate.h index e282b04d3..5752d34c6 100644 --- a/ceph/src/messages/MDirUpdate.h +++ b/ceph/src/messages/MDirUpdate.h @@ -25,33 +25,32 @@ class MDirUpdate : public Message { int32_t discover; compact_set dir_rep_by; filepath path; + int tried_discover; public: mds_rank_t get_source_mds() const { return from_mds; } dirfrag_t get_dirfrag() const { return dirfrag; } int get_dir_rep() const { return dir_rep; } const compact_set& get_dir_rep_by() const { return dir_rep_by; } - bool should_discover() const { return discover > 0; } + bool should_discover() const { return discover > tried_discover; } const filepath& get_path() const { return path; } - void tried_discover() { - if (discover) discover--; - } + bool has_tried_discover() const { return tried_discover > 0; } + void inc_tried_discover() { ++tried_discover; } - MDirUpdate() : Message(MSG_MDS_DIRUPDATE) {} + MDirUpdate() : Message(MSG_MDS_DIRUPDATE), tried_discover(0) {} MDirUpdate(mds_rank_t f, dirfrag_t dirfrag, int dir_rep, compact_set& dir_rep_by, filepath& path, bool discover = false) : - Message(MSG_MDS_DIRUPDATE) { + Message(MSG_MDS_DIRUPDATE), tried_discover(0) { this->from_mds = f; this->dirfrag = dirfrag; this->dir_rep = dir_rep; this->dir_rep_by = dir_rep_by; - if (discover) this->discover = 5; - else this->discover = 0; + this->discover = discover ? 5 : 0; this->path = path; } private: diff --git a/ceph/src/messages/MMDSBeacon.h b/ceph/src/messages/MMDSBeacon.h index 31febe50a..a83502e85 100644 --- a/ceph/src/messages/MMDSBeacon.h +++ b/ceph/src/messages/MMDSBeacon.h @@ -43,6 +43,56 @@ enum mds_metric_t { MDS_HEALTH_CACHE_OVERSIZED }; +static inline const char *mds_metric_name(mds_metric_t m) +{ + switch (m) { + case MDS_HEALTH_TRIM: return "MDS_TRIM"; + case MDS_HEALTH_CLIENT_RECALL: return "MDS_CLIENT_RECALL"; + case MDS_HEALTH_CLIENT_LATE_RELEASE: return "MDS_CLIENT_LATE_RELEASE"; + case MDS_HEALTH_CLIENT_RECALL_MANY: return "MDS_CLIENT_RECALL_MANY"; + case MDS_HEALTH_CLIENT_LATE_RELEASE_MANY: return "MDS_CLIENT_LATE_RELEASE_MANY"; + case MDS_HEALTH_CLIENT_OLDEST_TID: return "MDS_CLIENT_OLDEST_TID"; + case MDS_HEALTH_CLIENT_OLDEST_TID_MANY: return "MDS_CLIENT_OLDEST_TID_MANY"; + case MDS_HEALTH_DAMAGE: return "MDS_DAMAGE"; + case MDS_HEALTH_READ_ONLY: return "MDS_READ_ONLY"; + case MDS_HEALTH_SLOW_REQUEST: return "MDS_SLOW_REQUEST"; + case MDS_HEALTH_CACHE_OVERSIZED: return "MDS_CACHE_OVERSIZED"; + default: + return "???"; + } +} + +static inline const char *mds_metric_summary(mds_metric_t m) +{ + switch (m) { + case MDS_HEALTH_TRIM: + return "%num% MDSs behind on trimming"; + case MDS_HEALTH_CLIENT_RECALL: + return "%num% clients failing to respond to cache pressure"; + case MDS_HEALTH_CLIENT_LATE_RELEASE: + return "%num% clients failing to respond to capability release"; + case MDS_HEALTH_CLIENT_RECALL_MANY: + return "%num% MDSs have many clients failing to respond to cache pressure"; + case MDS_HEALTH_CLIENT_LATE_RELEASE_MANY: + return "%num% MDSs have many clients failing to respond to capability " + "release"; + case MDS_HEALTH_CLIENT_OLDEST_TID: + return "%num% clients failing to advance oldest client/flush tid"; + case MDS_HEALTH_CLIENT_OLDEST_TID_MANY: + return "%num% MDSs have clients failing to advance oldest client/flush tid"; + case MDS_HEALTH_DAMAGE: + return "%num% MDSs report damaged metadata"; + case MDS_HEALTH_READ_ONLY: + return "%num% MDSs are read only"; + case MDS_HEALTH_SLOW_REQUEST: + return "%num% MDSs report slow requests"; + case MDS_HEALTH_CACHE_OVERSIZED: + return "%num% MDSs report oversized cache"; + default: + return "???"; + } +} + /** * This structure is designed to allow some flexibility in how we emit health * complaints, such that: diff --git a/ceph/src/messages/MMgrBeacon.h b/ceph/src/messages/MMgrBeacon.h index 2962d9c9a..ab55a9642 100644 --- a/ceph/src/messages/MMgrBeacon.h +++ b/ceph/src/messages/MMgrBeacon.h @@ -22,7 +22,7 @@ class MMgrBeacon : public PaxosServiceMessage { - static const int HEAD_VERSION = 2; + static const int HEAD_VERSION = 3; static const int COMPAT_VERSION = 1; protected: @@ -31,6 +31,7 @@ protected: bool available; std::string name; uuid_d fsid; + std::set available_modules; public: MMgrBeacon() @@ -40,10 +41,11 @@ public: } MMgrBeacon(const uuid_d& fsid_, uint64_t gid_, const std::string &name_, - entity_addr_t server_addr_, bool available_) + entity_addr_t server_addr_, bool available_, + const std::set& module_list) : PaxosServiceMessage(MSG_MGR_BEACON, 0, HEAD_VERSION, COMPAT_VERSION), gid(gid_), server_addr(server_addr_), available(available_), name(name_), - fsid(fsid_) + fsid(fsid_), available_modules(module_list) { } @@ -52,6 +54,7 @@ public: bool get_available() const { return available; } const std::string& get_name() const { return name; } const uuid_d& get_fsid() const { return fsid; } + std::set& get_available_modules() { return available_modules; } private: ~MMgrBeacon() override {} @@ -62,7 +65,8 @@ public: void print(ostream& out) const override { out << get_type_name() << " mgr." << name << "(" << fsid << "," - << gid << ", " << server_addr << ", " << available << ")"; + << gid << ", " << server_addr << ", " << available + << ")"; } void encode_payload(uint64_t features) override { @@ -72,6 +76,7 @@ public: ::encode(available, payload); ::encode(name, payload); ::encode(fsid, payload); + ::encode(available_modules, payload); } void decode_payload() override { bufferlist::iterator p = payload.begin(); @@ -83,6 +88,9 @@ public: if (header.version >= 2) { ::decode(fsid, p); } + if (header.version >= 3) { + ::decode(available_modules, p); + } } }; diff --git a/ceph/src/messages/MMgrOpen.h b/ceph/src/messages/MMgrOpen.h index 13c67586b..5db75e3f1 100644 --- a/ceph/src/messages/MMgrOpen.h +++ b/ceph/src/messages/MMgrOpen.h @@ -19,26 +19,55 @@ class MMgrOpen : public Message { - static const int HEAD_VERSION = 1; + static const int HEAD_VERSION = 2; static const int COMPAT_VERSION = 1; public: std::string daemon_name; + std::string service_name; // optional; otherwise infer from entity type + + bool service_daemon = false; + std::map daemon_metadata; + std::map daemon_status; void decode_payload() override { bufferlist::iterator p = payload.begin(); ::decode(daemon_name, p); + if (header.version >= 2) { + ::decode(service_name, p); + ::decode(service_daemon, p); + if (service_daemon) { + ::decode(daemon_metadata, p); + ::decode(daemon_status, p); + } + } } void encode_payload(uint64_t features) override { ::encode(daemon_name, payload); + ::encode(service_name, payload); + ::encode(service_daemon, payload); + if (service_daemon) { + ::encode(daemon_metadata, payload); + ::encode(daemon_status, payload); + } } const char *get_type_name() const override { return "mgropen"; } void print(ostream& out) const override { - out << get_type_name() << "(" << daemon_name << ")"; + out << get_type_name() << "("; + if (service_name.length()) { + out << service_name; + } else { + out << ceph_entity_type_name(get_source().type()); + } + out << "." << daemon_name; + if (service_daemon) { + out << " daemon"; + } + out << ")"; } MMgrOpen() diff --git a/ceph/src/messages/MMgrReport.h b/ceph/src/messages/MMgrReport.h index 52090b256..9b033ec23 100644 --- a/ceph/src/messages/MMgrReport.h +++ b/ceph/src/messages/MMgrReport.h @@ -15,6 +15,8 @@ #ifndef CEPH_MMGRREPORT_H_ #define CEPH_MMGRREPORT_H_ +#include + #include "msg/Message.h" #include "common/perf_counters.h" @@ -55,7 +57,7 @@ WRITE_CLASS_ENCODER(PerfCounterType) class MMgrReport : public Message { - static const int HEAD_VERSION = 2; + static const int HEAD_VERSION = 4; static const int COMPAT_VERSION = 1; public: @@ -76,6 +78,10 @@ public: bufferlist packed; std::string daemon_name; + std::string service_name; // optional; otherwise infer from entity type + + // for service registration + boost::optional> daemon_status; void decode_payload() override { @@ -85,6 +91,10 @@ public: ::decode(packed, p); if (header.version >= 2) ::decode(undeclare_types, p); + if (header.version >= 3) { + ::decode(service_name, p); + ::decode(daemon_status, p); + } } void encode_payload(uint64_t features) override { @@ -92,12 +102,26 @@ public: ::encode(declare_types, payload); ::encode(packed, payload); ::encode(undeclare_types, payload); + ::encode(service_name, payload); + ::encode(daemon_status, payload); } const char *get_type_name() const override { return "mgrreport"; } void print(ostream& out) const override { - out << get_type_name() << "(+" << declare_types.size() << "-" << undeclare_types.size() - << " packed " << packed.length() << ")"; + out << get_type_name() << "("; + if (service_name.length()) { + out << service_name; + } else { + out << ceph_entity_type_name(get_source().type()); + } + out << "." << daemon_name + << " +" << declare_types.size() + << "-" << undeclare_types.size() + << " packed " << packed.length(); + if (daemon_status) { + out << " status=" << daemon_status->size(); + } + out << ")"; } MMgrReport() diff --git a/ceph/src/messages/MMonElection.h b/ceph/src/messages/MMonElection.h index 79503875e..c9b87c451 100644 --- a/ceph/src/messages/MMonElection.h +++ b/ceph/src/messages/MMonElection.h @@ -22,7 +22,7 @@ class MMonElection : public Message { - static const int HEAD_VERSION = 6; + static const int HEAD_VERSION = 7; static const int COMPAT_VERSION = 5; public: @@ -48,25 +48,19 @@ public: uint64_t quorum_features; mon_feature_t mon_features; bufferlist sharing_bl; - /* the following were both used in the next branch for a while - * on user cluster, so we've left them in for compatibility. */ - version_t defunct_one; - version_t defunct_two; + map metadata; MMonElection() : Message(MSG_MON_ELECTION, HEAD_VERSION, COMPAT_VERSION), op(0), epoch(0), quorum_features(0), - mon_features(0), - defunct_one(0), - defunct_two(0) + mon_features(0) { } MMonElection(int o, epoch_t e, MonMap *m) : Message(MSG_MON_ELECTION, HEAD_VERSION, COMPAT_VERSION), fsid(m->fsid), op(o), epoch(e), quorum_features(0), - mon_features(0), - defunct_one(0), defunct_two(0) + mon_features(0) { // encode using full feature set; we will reencode for dest later, // if necessary @@ -96,10 +90,11 @@ public: ::encode(monmap_bl, payload); ::encode(quorum, payload); ::encode(quorum_features, payload); - ::encode(defunct_one, payload); - ::encode(defunct_two, payload); + ::encode((version_t)0, payload); // defunct + ::encode((version_t)0, payload); // defunct ::encode(sharing_bl, payload); ::encode(mon_features, payload); + ::encode(metadata, payload); } void decode_payload() override { bufferlist::iterator p = payload.begin(); @@ -109,11 +104,16 @@ public: ::decode(monmap_bl, p); ::decode(quorum, p); ::decode(quorum_features, p); - ::decode(defunct_one, p); - ::decode(defunct_two, p); + { + version_t v; // defunct fields from old encoding + ::decode(v, p); + ::decode(v, p); + } ::decode(sharing_bl, p); if (header.version >= 6) ::decode(mon_features, p); + if (header.version >= 7) + ::decode(metadata, p); } }; diff --git a/ceph/src/messages/MMonHealthChecks.h b/ceph/src/messages/MMonHealthChecks.h new file mode 100644 index 000000000..6b6684763 --- /dev/null +++ b/ceph/src/messages/MMonHealthChecks.h @@ -0,0 +1,47 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_MMON_HEALTH_CHECKS_H +#define CEPH_MMON_HEALTH_CHECKS_H + +#include "messages/PaxosServiceMessage.h" +#include "mon/health_check.h" + +struct MMonHealthChecks : public PaxosServiceMessage +{ + static const int HEAD_VERSION = 1; + static const int COMPAT_VERSION = 1; + + health_check_map_t health_checks; + + MMonHealthChecks() + : PaxosServiceMessage(MSG_MON_HEALTH_CHECKS, HEAD_VERSION, COMPAT_VERSION) { + } + MMonHealthChecks(health_check_map_t& m) + : PaxosServiceMessage(MSG_MON_HEALTH_CHECKS, HEAD_VERSION, COMPAT_VERSION), + health_checks(m) { + } + +private: + ~MMonHealthChecks() override { } + +public: + const char *get_type_name() const override { return "mon_health_checks"; } + void print(ostream &o) const override { + o << "mon_health_checks(" << health_checks.checks.size() << " checks)"; + } + + void decode_payload() override { + bufferlist::iterator p = payload.begin(); + paxos_decode(p); + ::decode(health_checks, p); + } + + void encode_payload(uint64_t features) override { + paxos_encode(); + ::encode(health_checks, payload); + } + +}; + +#endif diff --git a/ceph/src/messages/MMonMgrReport.h b/ceph/src/messages/MMonMgrReport.h index bf91519eb..eef0966f1 100644 --- a/ceph/src/messages/MMonMgrReport.h +++ b/ceph/src/messages/MMonMgrReport.h @@ -17,17 +17,8 @@ #include "messages/PaxosServiceMessage.h" #include "include/types.h" - -// health_status_t -static inline void encode(health_status_t hs, bufferlist& bl) { - uint8_t v = hs; - ::encode(v, bl); -} -static inline void decode(health_status_t& hs, bufferlist::iterator& p) { - uint8_t v; - ::decode(v, p); - hs = health_status_t(v); -} +#include "include/health.h" +#include "mon/health_check.h" class MMonMgrReport : public PaxosServiceMessage { @@ -36,7 +27,8 @@ class MMonMgrReport : public PaxosServiceMessage { public: // PGMapDigest is in data payload - list> health_summary, health_detail; + health_check_map_t health_checks; + bufferlist service_map_bl; // encoded ServiceMap MMonMgrReport() : PaxosServiceMessage(MSG_MON_MGR_REPORT, 0, HEAD_VERSION, COMPAT_VERSION) @@ -48,19 +40,19 @@ public: const char *get_type_name() const override { return "monmgrreport"; } void print(ostream& out) const override { - out << get_type_name(); + out << get_type_name() << "(" << health_checks.checks.size() << " checks)"; } void encode_payload(uint64_t features) override { paxos_encode(); - ::encode(health_summary, payload); - ::encode(health_detail, payload); + ::encode(health_checks, payload); + ::encode(service_map_bl, payload); } void decode_payload() override { bufferlist::iterator p = payload.begin(); paxos_decode(p); - ::decode(health_summary, p); - ::decode(health_detail, p); + ::decode(health_checks, p); + ::decode(service_map_bl, p); } }; diff --git a/ceph/src/messages/MOSDOp.h b/ceph/src/messages/MOSDOp.h index b6b87f131..69d12a7a9 100755 --- a/ceph/src/messages/MOSDOp.h +++ b/ceph/src/messages/MOSDOp.h @@ -559,7 +559,7 @@ struct ceph_osd_request_head { } void clear_buffers() override { - ops.clear(); + OSDOp::clear_data(ops); } const char *get_type_name() const override { return "osd_op"; } diff --git a/ceph/src/messages/MOSDOpReply.h b/ceph/src/messages/MOSDOpReply.h index ef701fda5..30358fdd6 100644 --- a/ceph/src/messages/MOSDOpReply.h +++ b/ceph/src/messages/MOSDOpReply.h @@ -236,6 +236,7 @@ public: ::decode(do_redirect, p); if (do_redirect) ::decode(redirect, p); + decode_trace(p); } else if (header.version < 2) { ceph_osd_reply_head head; ::decode(head, p); diff --git a/ceph/src/messages/MOSDPing.h b/ceph/src/messages/MOSDPing.h index f9b775a0d..0801e8a04 100644 --- a/ceph/src/messages/MOSDPing.h +++ b/ceph/src/messages/MOSDPing.h @@ -34,8 +34,8 @@ class MOSDPing : public Message { - static const int HEAD_VERSION = 3; - static const int COMPAT_VERSION = 2; + static const int HEAD_VERSION = 4; + static const int COMPAT_VERSION = 4; public: enum { @@ -59,16 +59,14 @@ class MOSDPing : public Message { } uuid_d fsid; - epoch_t map_epoch, peer_as_of_epoch; + epoch_t map_epoch; __u8 op; - osd_peer_stat_t peer_stat; utime_t stamp; uint32_t min_message_size; MOSDPing(const uuid_d& f, epoch_t e, __u8 o, utime_t s, uint32_t min_message) : Message(MSG_OSD_PING, HEAD_VERSION, COMPAT_VERSION), - fsid(f), map_epoch(e), peer_as_of_epoch(0), op(o), stamp(s), - min_message_size(min_message) + fsid(f), map_epoch(e), op(o), stamp(s), min_message_size(min_message) { } MOSDPing() : Message(MSG_OSD_PING, HEAD_VERSION, COMPAT_VERSION), min_message_size(0) @@ -81,9 +79,15 @@ public: bufferlist::iterator p = payload.begin(); ::decode(fsid, p); ::decode(map_epoch, p); - ::decode(peer_as_of_epoch, p); - ::decode(op, p); - ::decode(peer_stat, p); + if (header.version < 4) { + osd_peer_stat_t peer_stat; + epoch_t peer_as_of_epoch; + ::decode(peer_as_of_epoch, p); + ::decode(op, p); + ::decode(peer_stat, p); + } else { + ::decode(op, p); + } ::decode(stamp, p); if (header.version >= 3) { int payload_mid_length = p.get_off(); @@ -96,11 +100,20 @@ public: void encode_payload(uint64_t features) override { ::encode(fsid, payload); ::encode(map_epoch, payload); - ::encode(peer_as_of_epoch, payload); - ::encode(op, payload); - ::encode(peer_stat, payload); + + // with luminous, we drop peer_as_of_epoch and peer_stat + if (!HAVE_FEATURE(features, SERVER_LUMINOUS)) { + epoch_t dummy_epoch = {}; + osd_peer_stat_t dummy_stat = {}; + header.version = 3; + header.compat_version = 2; + ::encode(dummy_epoch, payload); + ::encode(op, payload); + ::encode(dummy_stat, payload); + } else { + ::encode(op, payload); + } ::encode(stamp, payload); - size_t s = 0; if (min_message_size > payload.length()) s = min_message_size - payload.length(); @@ -112,11 +125,11 @@ public: // that at runtime we are only adding a bufferptr reference to it. static char zeros[16384] = {}; while (s > sizeof(zeros)) { - payload.append(buffer::create_static(sizeof(zeros), zeros)); - s -= sizeof(zeros); + payload.append(buffer::create_static(sizeof(zeros), zeros)); + s -= sizeof(zeros); } if (s) { - payload.append(buffer::create_static(s, zeros)); + payload.append(buffer::create_static(s, zeros)); } } } @@ -125,7 +138,6 @@ public: void print(ostream& out) const override { out << "osd_ping(" << get_op_name(op) << " e" << map_epoch - //<< " as_of " << peer_as_of_epoch << " stamp " << stamp << ")"; } diff --git a/ceph/src/messages/MServiceMap.h b/ceph/src/messages/MServiceMap.h new file mode 100644 index 000000000..b7dd91310 --- /dev/null +++ b/ceph/src/messages/MServiceMap.h @@ -0,0 +1,34 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#pragma once + +#include "msg/Message.h" +#include "mgr/ServiceMap.h" + +class MServiceMap : public Message { +public: + ServiceMap service_map; + + MServiceMap() : Message(MSG_SERVICE_MAP) { } + explicit MServiceMap(const ServiceMap& sm) + : Message(MSG_SERVICE_MAP), + service_map(sm) { + } +private: + ~MServiceMap() override {} + +public: + const char *get_type_name() const override { return "service_map"; } + void print(ostream& out) const override { + out << "service_map(e" << service_map.epoch << " " + << service_map.services.size() << " svc)"; + } + void encode_payload(uint64_t features) override { + ::encode(service_map, payload, features); + } + void decode_payload() override { + bufferlist::iterator p = payload.begin(); + ::decode(service_map, p); + } +}; diff --git a/ceph/src/mgr/ClusterState.cc b/ceph/src/mgr/ClusterState.cc index 8bc88c530..7e01a811e 100644 --- a/ceph/src/mgr/ClusterState.cc +++ b/ceph/src/mgr/ClusterState.cc @@ -22,8 +22,15 @@ #undef dout_prefix #define dout_prefix *_dout << "mgr " << __func__ << " " -ClusterState::ClusterState(MonClient *monc_, Objecter *objecter_) - : monc(monc_), objecter(objecter_), lock("ClusterState"), pgservice(pg_map) +ClusterState::ClusterState( + MonClient *monc_, + Objecter *objecter_, + const MgrMap& mgrmap) + : monc(monc_), + objecter(objecter_), + lock("ClusterState"), + mgr_map(mgrmap), + pgservice(pg_map) {} void ClusterState::set_objecter(Objecter *objecter_) @@ -40,6 +47,18 @@ void ClusterState::set_fsmap(FSMap const &new_fsmap) fsmap = new_fsmap; } +void ClusterState::set_mgr_map(MgrMap const &new_mgrmap) +{ + Mutex::Locker l(lock); + mgr_map = new_mgrmap; +} + +void ClusterState::set_service_map(ServiceMap const &new_service_map) +{ + Mutex::Locker l(lock); + servicemap = new_service_map; +} + void ClusterState::load_digest(MMgrDigest *m) { health_json = std::move(m->health_json); @@ -79,10 +98,12 @@ void ClusterState::ingest_pgstats(MPGStats *stats) } // In case we already heard about more recent stats from this PG // from another OSD - if (pg_map.pg_stat[pgid].get_version_pair() > pg_stats.get_version_pair()) { + const auto q = pg_map.pg_stat.find(pgid); + if (q != pg_map.pg_stat.end() && + q->second.get_version_pair() > pg_stats.get_version_pair()) { dout(15) << " had " << pgid << " from " - << pg_map.pg_stat[pgid].reported_epoch << ":" - << pg_map.pg_stat[pgid].reported_seq << dendl; + << q->second.reported_epoch << ":" + << q->second.reported_seq << dendl; continue; } diff --git a/ceph/src/mgr/ClusterState.h b/ceph/src/mgr/ClusterState.h index ae08c75da..9513c763b 100644 --- a/ceph/src/mgr/ClusterState.h +++ b/ceph/src/mgr/ClusterState.h @@ -15,11 +15,13 @@ #define CLUSTER_STATE_H_ #include "mds/FSMap.h" +#include "mon/MgrMap.h" #include "common/Mutex.h" #include "osdc/Objecter.h" #include "mon/MonClient.h" #include "mon/PGMap.h" +#include "mgr/ServiceMap.h" class MMgrDigest; class MMonMgrReport; @@ -36,8 +38,11 @@ protected: MonClient *monc; Objecter *objecter; FSMap fsmap; + ServiceMap servicemap; mutable Mutex lock; + MgrMap mgr_map; + set existing_pools; ///< pools that exist, as of PGMap epoch PGMap pg_map; PGMap::Incremental pending_inc; @@ -57,10 +62,12 @@ public: const bufferlist &get_health() const {return health_json;} const bufferlist &get_mon_status() const {return mon_status_json;} - ClusterState(MonClient *monc_, Objecter *objecter_); + ClusterState(MonClient *monc_, Objecter *objecter_, const MgrMap& mgrmap); void set_objecter(Objecter *objecter_); void set_fsmap(FSMap const &new_fsmap); + void set_mgr_map(MgrMap const &new_mgrmap); + void set_service_map(ServiceMap const &new_service_map); void notify_osdmap(const OSDMap &osd_map); @@ -69,6 +76,13 @@ public: return fsmap.get_epoch() > 0; } + template + void with_servicemap(Callback&& cb, Args&&...args) const + { + Mutex::Locker l(lock); + std::forward(cb)(servicemap, std::forward(args)...); + } + template void with_fsmap(Callback&& cb, Args&&...args) const { @@ -76,6 +90,13 @@ public: std::forward(cb)(fsmap, std::forward(args)...); } + template + void with_mgrmap(Callback&& cb, Args&&...args) const + { + Mutex::Locker l(lock); + std::forward(cb)(mgr_map, std::forward(args)...); + } + template auto with_pgmap(Callback&& cb, Args&&...args) const -> decltype(cb(pg_map, std::forward(args)...)) diff --git a/ceph/src/mgr/DaemonServer.cc b/ceph/src/mgr/DaemonServer.cc index e8d8c8a21..6454c8da3 100644 --- a/ceph/src/mgr/DaemonServer.cc +++ b/ceph/src/mgr/DaemonServer.cc @@ -24,6 +24,7 @@ #include "messages/MCommandReply.h" #include "messages/MPGStats.h" #include "messages/MOSDScrub.h" +#include "common/errno.h" #define dout_context g_ceph_context #define dout_subsys ceph_subsys_mgr @@ -112,6 +113,8 @@ int DaemonServer::init(uint64_t gid, entity_addr_t client_addr) msgr->start(); msgr->add_dispatcher_tail(this); + started_at = ceph_clock_now(); + return 0; } @@ -176,7 +179,7 @@ bool DaemonServer::ms_verify_authorizer(Connection *con, if (peer_type == CEPH_ENTITY_TYPE_OSD) { Mutex::Locker l(lock); s->osd_id = atoi(s->entity_name.get_id().c_str()); - dout(10) << __func__ << " registering osd." << s->osd_id << " session " + dout(10) << "registering osd." << s->osd_id << " session " << s << " con " << con << dendl; osd_cons[s->osd_id].insert(con); } @@ -214,7 +217,7 @@ bool DaemonServer::ms_handle_reset(Connection *con) } session->put(); // SessionRef takes a ref Mutex::Locker l(lock); - dout(10) << __func__ << " unregistering osd." << session->osd_id + dout(10) << "unregistering osd." << session->osd_id << " session " << session << " con " << con << dendl; osd_cons[session->osd_id].erase(con); } @@ -234,6 +237,7 @@ bool DaemonServer::ms_dispatch(Message *m) switch (m->get_type()) { case MSG_PGSTATS: cluster_state.ingest_pgstats(static_cast(m)); + maybe_ready(m->get_source().num()); m->put(); return true; case MSG_MGR_REPORT: @@ -248,31 +252,59 @@ bool DaemonServer::ms_dispatch(Message *m) }; } +void DaemonServer::maybe_ready(int32_t osd_id) +{ + if (!pgmap_ready && reported_osds.find(osd_id) == reported_osds.end()) { + dout(4) << "initial report from osd " << osd_id << dendl; + reported_osds.insert(osd_id); + std::set up_osds; + + cluster_state.with_osdmap([&](const OSDMap& osdmap) { + osdmap.get_up_osds(up_osds); + }); + + std::set unreported_osds; + std::set_difference(up_osds.begin(), up_osds.end(), + reported_osds.begin(), reported_osds.end(), + std::inserter(unreported_osds, unreported_osds.begin())); + + if (unreported_osds.size() == 0) { + dout(4) << "all osds have reported, sending PG state to mon" << dendl; + pgmap_ready = true; + reported_osds.clear(); + // Avoid waiting for next tick + send_report(); + } else { + dout(4) << "still waiting for " << unreported_osds.size() << " osds" + " to report in before PGMap is ready" << dendl; + } + } +} + void DaemonServer::shutdown() { - dout(10) << __func__ << dendl; + dout(10) << "begin" << dendl; msgr->shutdown(); msgr->wait(); - dout(10) << __func__ << " done" << dendl; + dout(10) << "done" << dendl; } bool DaemonServer::handle_open(MMgrOpen *m) { - uint32_t type = m->get_connection()->get_peer_type(); - DaemonKey key(type, m->daemon_name); + DaemonKey key; + if (!m->service_name.empty()) { + key.first = m->service_name; + } else { + key.first = ceph_entity_type_name(m->get_connection()->get_peer_type()); + } + key.second = m->daemon_name; - dout(4) << "from " << m->get_connection() << " name " - << ceph_entity_type_name(type) << "." << m->daemon_name << dendl; + dout(4) << "from " << m->get_connection() << " " << key << dendl; auto configure = new MMgrConfigure(); - if (m->get_connection()->get_peer_type() == entity_name_t::TYPE_CLIENT) { - // We don't want clients to send us stats - configure->stats_period = 0; - } else { - configure->stats_period = g_conf->mgr_stats_period; - } + configure->stats_period = g_conf->mgr_stats_period; m->get_connection()->send_message(configure); if (daemon_state.exists(key)) { @@ -280,42 +312,92 @@ bool DaemonServer::handle_open(MMgrOpen *m) daemon_state.get(key)->perf_counters.clear(); } + if (m->service_daemon) { + DaemonStatePtr daemon; + if (daemon_state.exists(key)) { + daemon = daemon_state.get(key); + } else { + dout(4) << "constructing new DaemonState for " << key << dendl; + daemon = std::make_shared(daemon_state.types); + daemon->key = key; + if (m->daemon_metadata.count("hostname")) { + daemon->hostname = m->daemon_metadata["hostname"]; + } + daemon_state.insert(daemon); + } + daemon->service_daemon = true; + daemon->metadata = m->daemon_metadata; + daemon->service_status = m->daemon_status; + + utime_t now = ceph_clock_now(); + auto d = pending_service_map.get_daemon(m->service_name, + m->daemon_name); + if (d->gid != (uint64_t)m->get_source().num()) { + dout(10) << "registering " << key << " in pending_service_map" << dendl; + d->gid = m->get_source().num(); + d->addr = m->get_source_addr(); + d->start_epoch = pending_service_map.epoch; + d->start_stamp = now; + d->metadata = m->daemon_metadata; + pending_service_map_dirty = pending_service_map.epoch; + } + } + m->put(); return true; } bool DaemonServer::handle_report(MMgrReport *m) { - uint32_t type = m->get_connection()->get_peer_type(); - DaemonKey key(type, m->daemon_name); + DaemonKey key; + if (!m->service_name.empty()) { + key.first = m->service_name; + } else { + key.first = ceph_entity_type_name(m->get_connection()->get_peer_type()); + } + key.second = m->daemon_name; - dout(4) << "from " << m->get_connection() << " name " - << ceph_entity_type_name(type) << "." << m->daemon_name << dendl; + dout(4) << "from " << m->get_connection() << " " << key << dendl; - if (m->get_connection()->get_peer_type() == entity_name_t::TYPE_CLIENT) { - // Clients should not be sending us stats - dout(4) << "rejecting report from client " << m->daemon_name << dendl; + if (m->get_connection()->get_peer_type() == entity_name_t::TYPE_CLIENT && + m->service_name.empty()) { + // Clients should not be sending us stats unless they are declaring + // themselves to be a daemon for some service. + dout(4) << "rejecting report from non-daemon client " << m->daemon_name + << dendl; m->put(); return true; } DaemonStatePtr daemon; if (daemon_state.exists(key)) { - dout(20) << "updating existing DaemonState for " << m->daemon_name << dendl; + dout(20) << "updating existing DaemonState for " << key << dendl; daemon = daemon_state.get(key); } else { - dout(4) << "constructing new DaemonState for " << m->daemon_name << dendl; + dout(4) << "constructing new DaemonState for " << key << dendl; daemon = std::make_shared(daemon_state.types); // FIXME: crap, we don't know the hostname at this stage. daemon->key = key; daemon_state.insert(daemon); - // FIXME: we should request metadata at this stage + // FIXME: we should avoid this case by rejecting MMgrReport from + // daemons without sessions, and ensuring that session open + // always contains metadata. } - assert(daemon != nullptr); auto &daemon_counters = daemon->perf_counters; daemon_counters.update(m); - + + if (daemon->service_daemon) { + utime_t now = ceph_clock_now(); + if (m->daemon_status) { + daemon->service_status = *m->daemon_status; + daemon->service_status_stamp = now; + } + daemon->last_service_beacon = now; + } else if (m->daemon_status) { + derr << "got status from non-daemon " << key << dendl; + } + m->put(); return true; } @@ -451,7 +533,7 @@ bool DaemonServer::handle_command(MCommand *m) con->mark_disposable(); } - dout(1) << "do_command r=" << r << " " << rs << dendl; + dout(1) << "handle_command " << cpp_strerror(r) << " " << rs << dendl; if (con) { MCommandReply *reply = new MCommandReply(r, rs); reply->set_tid(m->get_tid()); @@ -575,6 +657,51 @@ bool DaemonServer::handle_command(MCommand *m) << "entity='" << session->entity_name << "' " << "cmd=" << m->cmd << ": dispatch"; + // ---------------- + // service map commands + if (prefix == "service dump") { + if (!f) + f.reset(Formatter::create("json-pretty")); + cluster_state.with_servicemap([&](const ServiceMap &service_map) { + f->dump_object("service_map", service_map); + }); + f->flush(cmdctx->odata); + cmdctx->reply(0, ss); + return true; + } + if (prefix == "service status") { + if (!f) + f.reset(Formatter::create("json-pretty")); + // only include state from services that are in the persisted service map + f->open_object_section("service_status"); + ServiceMap s; + cluster_state.with_servicemap([&](const ServiceMap& service_map) { + s = service_map; + }); + for (auto& p : s.services) { + f->open_object_section(p.first.c_str()); + for (auto& q : p.second.daemons) { + f->open_object_section(q.first.c_str()); + DaemonKey key(p.first, q.first); + assert(daemon_state.exists(key)); + auto daemon = daemon_state.get(key); + f->dump_stream("status_stamp") << daemon->service_status_stamp; + f->dump_stream("last_beacon") << daemon->last_service_beacon; + f->open_object_section("status"); + for (auto& r : daemon->service_status) { + f->dump_string(r.first.c_str(), r.second); + } + f->close_section(); + f->close_section(); + } + f->close_section(); + } + f->close_section(); + f->flush(cmdctx->odata); + cmdctx->reply(0, ss); + return true; + } + // ----------- // PG commands @@ -634,7 +761,7 @@ bool DaemonServer::handle_command(MCommand *m) get_str_vec(prefix, pvec); set osds; - if (whostr == "*") { + if (whostr == "*" || whostr == "all" || whostr == "any") { cluster_state.with_osdmap([&](const OSDMap& osdmap) { for (int i = 0; i < osdmap.get_max_osd(); i++) if (osdmap.is_up(i)) { @@ -841,21 +968,90 @@ bool DaemonServer::handle_command(MCommand *m) } } +void DaemonServer::_prune_pending_service_map() +{ + utime_t cutoff = ceph_clock_now(); + cutoff -= g_conf->mgr_service_beacon_grace; + auto p = pending_service_map.services.begin(); + while (p != pending_service_map.services.end()) { + auto q = p->second.daemons.begin(); + while (q != p->second.daemons.end()) { + DaemonKey key(p->first, q->first); + if (!daemon_state.exists(key)) { + derr << "missing key " << key << dendl; + ++q; + continue; + } + auto daemon = daemon_state.get(key); + if (daemon->last_service_beacon == utime_t()) { + // we must have just restarted; assume they are alive now. + daemon->last_service_beacon = ceph_clock_now(); + ++q; + continue; + } + if (daemon->last_service_beacon < cutoff) { + dout(10) << "pruning stale " << p->first << "." << q->first + << " last_beacon " << daemon->last_service_beacon << dendl; + q = p->second.daemons.erase(q); + pending_service_map_dirty = pending_service_map.epoch; + } else { + ++q; + } + } + if (p->second.daemons.empty()) { + p = pending_service_map.services.erase(p); + pending_service_map_dirty = pending_service_map.epoch; + } else { + ++p; + } + } +} + void DaemonServer::send_report() { + if (!pgmap_ready) { + if (ceph_clock_now() - started_at > g_conf->mgr_stats_period * 4.0) { + pgmap_ready = true; + reported_osds.clear(); + dout(1) << "Giving up on OSDs that haven't reported yet, sending " + << "potentially incomplete PG state to mon" << dendl; + } else { + dout(1) << "Not sending PG status to monitor yet, waiting for OSDs" + << dendl; + return; + } + } + auto m = new MMonMgrReport(); cluster_state.with_pgmap([&](const PGMap& pg_map) { cluster_state.update_delta_stats(); - // FIXME: reporting health detail here might be a bad idea? + if (pending_service_map.epoch) { + _prune_pending_service_map(); + if (pending_service_map_dirty >= pending_service_map.epoch) { + pending_service_map.modified = ceph_clock_now(); + ::encode(pending_service_map, m->service_map_bl, CEPH_FEATURES_ALL); + dout(10) << "sending service_map e" << pending_service_map.epoch + << dendl; + pending_service_map.epoch++; + } + } + cluster_state.with_osdmap([&](const OSDMap& osdmap) { // FIXME: no easy way to get mon features here. this will do for // now, though, as long as we don't make a backward-incompat change. pg_map.encode_digest(osdmap, m->get_data(), CEPH_FEATURES_ALL); dout(10) << pg_map << dendl; - pg_map.get_health(g_ceph_context, osdmap, - m->health_summary, - &m->health_detail); + + pg_map.get_health_checks(g_ceph_context, osdmap, + &m->health_checks); + dout(10) << m->health_checks.checks.size() << " health checks" + << dendl; + dout(20) << "health checks:\n"; + JSONFormatter jf(true); + jf.dump_object("health_checks", m->health_checks); + jf.flush(*_dout); + *_dout << dendl; }); }); // TODO? We currently do not notify the PyModules @@ -863,3 +1059,42 @@ void DaemonServer::send_report() // so, or the state is updated. monc->send_mon_message(m); } + +void DaemonServer::got_service_map() +{ + Mutex::Locker l(lock); + + cluster_state.with_servicemap([&](const ServiceMap& service_map) { + if (pending_service_map.epoch == 0) { + // we just started up + dout(10) << "got initial map e" << service_map.epoch << dendl; + pending_service_map = service_map; + } else { + // we we already active and therefore must have persisted it, + // which means ours is the same or newer. + dout(10) << "got updated map e" << service_map.epoch << dendl; + } + pending_service_map.epoch = service_map.epoch + 1; + }); + + // cull missing daemons, populate new ones + for (auto& p : pending_service_map.services) { + std::set names; + for (auto& q : p.second.daemons) { + names.insert(q.first); + DaemonKey key(p.first, q.first); + if (!daemon_state.exists(key)) { + auto daemon = std::make_shared(daemon_state.types); + daemon->key = key; + daemon->metadata = q.second.metadata; + if (q.second.metadata.count("hostname")) { + daemon->hostname = q.second.metadata["hostname"]; + } + daemon->service_daemon = true; + daemon_state.insert(daemon); + dout(10) << "added missing " << key << dendl; + } + } + daemon_state.cull(p.first, names); + } +} diff --git a/ceph/src/mgr/DaemonServer.h b/ceph/src/mgr/DaemonServer.h index a1ed292e1..4877cfe85 100644 --- a/ceph/src/mgr/DaemonServer.h +++ b/ceph/src/mgr/DaemonServer.h @@ -27,6 +27,7 @@ #include "auth/AuthAuthorizeHandler.h" +#include "ServiceMap.h" #include "MgrSession.h" #include "DaemonState.h" @@ -66,6 +67,9 @@ protected: /// connections for osds ceph::unordered_map> osd_cons; + ServiceMap pending_service_map; // uncommitted + epoch_t pending_service_map_dirty = 0; + Mutex lock; static void _generate_command_map(map& cmdmap, @@ -83,6 +87,13 @@ private: bool _reply(MCommand* m, int ret, const std::string& s, const bufferlist& payload); + void _prune_pending_service_map(); + + utime_t started_at; + bool pgmap_ready = false; + std::set reported_osds; + void maybe_ready(int32_t osd_id); + public: int init(uint64_t gid, entity_addr_t client_addr); void shutdown(); @@ -116,6 +127,7 @@ public: bool handle_report(MMgrReport *m); bool handle_command(MCommand *m); void send_report(); + void got_service_map(); }; #endif diff --git a/ceph/src/mgr/DaemonState.cc b/ceph/src/mgr/DaemonState.cc index 290fde651..2c7f52f30 100644 --- a/ceph/src/mgr/DaemonState.cc +++ b/ceph/src/mgr/DaemonState.cc @@ -46,14 +46,15 @@ void DaemonStateIndex::_erase(const DaemonKey& dmk) all.erase(to_erase); } -DaemonStateCollection DaemonStateIndex::get_by_type(uint8_t type) const +DaemonStateCollection DaemonStateIndex::get_by_service( + const std::string& svc) const { Mutex::Locker l(lock); DaemonStateCollection result; for (const auto &i : all) { - if (i.first.first == type) { + if (i.first.first == svc) { result[i.first] = i.second; } } @@ -86,17 +87,17 @@ DaemonStatePtr DaemonStateIndex::get(const DaemonKey &key) return all.at(key); } -void DaemonStateIndex::cull(entity_type_t daemon_type, +void DaemonStateIndex::cull(const std::string& svc_name, const std::set& names_exist) { std::vector victims; Mutex::Locker l(lock); - auto begin = all.lower_bound({daemon_type, ""}); + auto begin = all.lower_bound({svc_name, ""}); auto end = all.end(); for (auto &i = begin; i != end; ++i) { const auto& daemon_key = i->first; - if (daemon_key.first != daemon_type) + if (daemon_key.first != svc_name) break; if (names_exist.count(daemon_key.second) == 0) { victims.push_back(daemon_key.second); @@ -105,7 +106,7 @@ void DaemonStateIndex::cull(entity_type_t daemon_type, for (auto &i : victims) { dout(4) << "Removing data for " << i << dendl; - _erase({daemon_type, i}); + _erase({svc_name, i}); } } diff --git a/ceph/src/mgr/DaemonState.h b/ceph/src/mgr/DaemonState.h index 91160d7f0..e75b96842 100644 --- a/ceph/src/mgr/DaemonState.h +++ b/ceph/src/mgr/DaemonState.h @@ -29,7 +29,7 @@ // Unique reference to a daemon within a cluster -typedef std::pair DaemonKey; +typedef std::pair DaemonKey; // An instance of a performance counter type, within // a particular daemon. @@ -102,6 +102,12 @@ class DaemonState // The metadata (hostname, version, etc) sent from the daemon std::map metadata; + // Ephemeral state + bool service_daemon = false; + utime_t service_status_stamp; + std::map service_status; + utime_t last_service_beacon; + // The perf counters received in MMgrReport messages DaemonPerfCounters perf_counters; @@ -146,7 +152,7 @@ class DaemonStateIndex bool exists(const DaemonKey &key) const; DaemonStatePtr get(const DaemonKey &key); DaemonStateCollection get_by_server(const std::string &hostname) const; - DaemonStateCollection get_by_type(uint8_t type) const; + DaemonStateCollection get_by_service(const std::string &svc_name) const; const DaemonStateCollection &get_all() const {return all;} const std::map &get_all_servers() const @@ -164,7 +170,8 @@ class DaemonStateIndex * a cluster map and want to ensure that anything absent in the map * is also absent in this class. */ - void cull(entity_type_t daemon_type, const std::set& names_exist); + void cull(const std::string& svc_name, + const std::set& names_exist); }; #endif diff --git a/ceph/src/mgr/Mgr.cc b/ceph/src/mgr/Mgr.cc index 15fae8502..68126e943 100644 --- a/ceph/src/mgr/Mgr.cc +++ b/ceph/src/mgr/Mgr.cc @@ -30,6 +30,7 @@ #include "messages/MCommand.h" #include "messages/MCommandReply.h" #include "messages/MLog.h" +#include "messages/MServiceMap.h" #include "Mgr.h" @@ -39,7 +40,8 @@ #define dout_prefix *_dout << "mgr " << __func__ << " " -Mgr::Mgr(MonClient *monc_, Messenger *clientm_, Objecter *objecter_, +Mgr::Mgr(MonClient *monc_, const MgrMap& mgrmap, + Messenger *clientm_, Objecter *objecter_, Client* client_, LogChannelRef clog_, LogChannelRef audit_clog_) : monc(monc_), objecter(objecter_), @@ -48,9 +50,10 @@ Mgr::Mgr(MonClient *monc_, Messenger *clientm_, Objecter *objecter_, lock("Mgr::lock"), timer(g_ceph_context, lock), finisher(g_ceph_context, "Mgr", "mgr-fin"), - py_modules(daemon_state, cluster_state, *monc, *objecter, *client, + digest_received(false), + py_modules(daemon_state, cluster_state, *monc, clog_, *objecter, *client, finisher), - cluster_state(monc, nullptr), + cluster_state(monc, nullptr, mgrmap), server(monc, finisher, daemon_state, cluster_state, py_modules, clog_, audit_clog_), initialized(false), @@ -92,14 +95,13 @@ public: { daemon_state.clear_updating(key); if (r == 0) { - if (key.first == CEPH_ENTITY_TYPE_MDS) { + if (key.first == "mds") { json_spirit::mValue json_result; bool read_ok = json_spirit::read( outbl.to_str(), json_result); if (!read_ok) { dout(1) << "mon returned invalid JSON for " - << ceph_entity_type_name(key.first) - << "." << key.second << dendl; + << key.first << "." << key.second << dendl; return; } @@ -133,20 +135,20 @@ public: daemon_state.insert(state); } - } else if (key.first == CEPH_ENTITY_TYPE_OSD) { + } else if (key.first == "osd") { } else { ceph_abort(); } } else { dout(1) << "mon failed to return metadata for " - << ceph_entity_type_name(key.first) - << "." << key.second << ": " << cpp_strerror(r) << dendl; + << key.first << "." << key.second << ": " + << cpp_strerror(r) << dendl; } } }; -void Mgr::background_init() +void Mgr::background_init(Context *completion) { Mutex::Locker l(lock); assert(!initializing); @@ -155,8 +157,9 @@ void Mgr::background_init() finisher.start(); - finisher.queue(new FunctionContext([this](int r){ + finisher.queue(new FunctionContext([this, completion](int r){ init(); + completion->complete(0); })); } @@ -184,6 +187,7 @@ void Mgr::init() monc->sub_want("log-info", 0, 0); monc->sub_want("mgrdigest", 0, 0); monc->sub_want("fsmap", 0, 0); + monc->sub_want("servicemap", 0, 0); dout(4) << "waiting for OSDMap..." << dendl; // Subscribe to OSDMap update to pass on to ClusterState @@ -217,11 +221,14 @@ void Mgr::init() // all sets will come via mgr) load_config(); - // Wait for MgrDigest...? - // TODO + // Wait for MgrDigest... + dout(4) << "waiting for MgrDigest..." << dendl; + while (!digest_received) { + digest_cond.Wait(lock); + } // assume finisher already initialized in background_init - + dout(4) << "starting PyModules..." << dendl; py_modules.init(); py_modules.start(); @@ -259,7 +266,7 @@ void Mgr::load_all_metadata() } DaemonStatePtr dm = std::make_shared(daemon_state.types); - dm->key = DaemonKey(CEPH_ENTITY_TYPE_MDS, + dm->key = DaemonKey("mds", daemon_meta.at("name").get_str()); dm->hostname = daemon_meta.at("hostname").get_str(); @@ -281,7 +288,7 @@ void Mgr::load_all_metadata() } DaemonStatePtr dm = std::make_shared(daemon_state.types); - dm->key = DaemonKey(CEPH_ENTITY_TYPE_MON, + dm->key = DaemonKey("mon", daemon_meta.at("name").get_str()); dm->hostname = daemon_meta.at("hostname").get_str(); @@ -304,7 +311,7 @@ void Mgr::load_all_metadata() dout(4) << osd_metadata.at("hostname").get_str() << dendl; DaemonStatePtr dm = std::make_shared(daemon_state.types); - dm->key = DaemonKey(CEPH_ENTITY_TYPE_OSD, + dm->key = DaemonKey("osd", stringify(osd_metadata.at("id").get_int())); dm->hostname = osd_metadata.at("hostname").get_str(); @@ -400,7 +407,7 @@ void Mgr::handle_osd_map() // Consider whether to update the daemon metadata (new/restarted daemon) bool update_meta = false; - const auto k = DaemonKey(CEPH_ENTITY_TYPE_OSD, stringify(osd_id)); + const auto k = DaemonKey("osd", stringify(osd_id)); if (daemon_state.is_updating(k)) { continue; } @@ -445,7 +452,7 @@ void Mgr::handle_osd_map() }); // TODO: same culling for MonMap - daemon_state.cull(CEPH_ENTITY_TYPE_OSD, names_exist); + daemon_state.cull("osd", names_exist); } void Mgr::handle_log(MLog *m) @@ -457,6 +464,13 @@ void Mgr::handle_log(MLog *m) m->put(); } +void Mgr::handle_service_map(MServiceMap *m) +{ + dout(10) << "e" << m->service_map.epoch << dendl; + cluster_state.set_service_map(m->service_map); + server.got_service_map(); +} + bool Mgr::ms_dispatch(Message *m) { dout(4) << *m << dendl; @@ -485,6 +499,11 @@ bool Mgr::ms_dispatch(Message *m) objecter->maybe_request_map(); m->put(); break; + case MSG_SERVICE_MAP: + handle_service_map((MServiceMap*)m); + py_modules.notify_all("service_map", ""); + m->put(); + break; case MSG_LOG: handle_log(static_cast(m)); break; @@ -524,7 +543,7 @@ void Mgr::handle_fs_map(MFSMap* m) // Remember which MDS exists so that we can cull any that don't names_exist.insert(info.name); - const auto k = DaemonKey(CEPH_ENTITY_TYPE_MDS, info.name); + const auto k = DaemonKey("mds", info.name); if (daemon_state.is_updating(k)) { continue; } @@ -564,9 +583,28 @@ void Mgr::handle_fs_map(MFSMap* m) {}, &c->outbl, &c->outs, c); } } - daemon_state.cull(CEPH_ENTITY_TYPE_MDS, names_exist); + daemon_state.cull("mds", names_exist); } +bool Mgr::got_mgr_map(const MgrMap& m) +{ + Mutex::Locker l(lock); + dout(10) << m << dendl; + + set old_modules; + cluster_state.with_mgrmap([&](const MgrMap& m) { + old_modules = m.modules; + }); + if (m.modules != old_modules) { + derr << "mgrmap module list changed to (" << m.modules << "), respawn" + << dendl; + return true; + } + + cluster_state.set_mgr_map(m); + + return false; +} void Mgr::handle_mgr_digest(MMgrDigest* m) { @@ -582,10 +620,15 @@ void Mgr::handle_mgr_digest(MMgrDigest* m) dout(10) << "done." << dendl; m->put(); + + if (!digest_received) { + digest_received = true; + digest_cond.Signal(); + } } void Mgr::tick() { - dout(0) << dendl; + dout(10) << dendl; server.send_report(); } diff --git a/ceph/src/mgr/Mgr.h b/ceph/src/mgr/Mgr.h index 0aa5b5c5b..ccf22da9e 100644 --- a/ceph/src/mgr/Mgr.h +++ b/ceph/src/mgr/Mgr.h @@ -29,6 +29,7 @@ #include "auth/Auth.h" #include "common/Finisher.h" #include "common/Timer.h" +#include "mon/MgrMap.h" #include "DaemonServer.h" #include "PyModules.h" @@ -39,10 +40,10 @@ class MCommand; class MMgrDigest; class MLog; +class MServiceMap; class Objecter; class Client; - class MgrPyModule; class Mgr { @@ -56,7 +57,10 @@ protected: SafeTimer timer; Finisher finisher; + // Track receipt of initial data during startup Cond fs_map_cond; + bool digest_received; + Cond digest_cond; PyModules py_modules; DaemonStateIndex daemon_state; @@ -72,7 +76,8 @@ protected: bool initializing; public: - Mgr(MonClient *monc_, Messenger *clientm_, Objecter *objecter_, + Mgr(MonClient *monc_, const MgrMap& mgrmap, + Messenger *clientm_, Objecter *objecter_, Client *client_, LogChannelRef clog_, LogChannelRef audit_clog_); ~Mgr(); @@ -83,12 +88,15 @@ public: void handle_fs_map(MFSMap* m); void handle_osd_map(); void handle_log(MLog *m); + void handle_service_map(MServiceMap *m); + + bool got_mgr_map(const MgrMap& m); bool ms_dispatch(Message *m); void tick(); - void background_init(); + void background_init(Context *completion); void shutdown(); }; diff --git a/ceph/src/mgr/MgrClient.cc b/ceph/src/mgr/MgrClient.cc index c7774959d..624fc0f4f 100644 --- a/ceph/src/mgr/MgrClient.cc +++ b/ceph/src/mgr/MgrClient.cc @@ -140,12 +140,15 @@ void MgrClient::reconnect() session.reset(new MgrSessionState()); session->con = msgr->get_connection(inst); + if (service_daemon) { + daemon_dirty_status = true; + } + // Don't send an open if we're just a client (i.e. doing // command-sending, not stats etc) - if (g_conf && !g_conf->name.is_client()) { - auto open = new MMgrOpen(); - open->daemon_name = g_conf->name.get_id(); - session->con->send_message(open); + if ((g_conf && !g_conf->name.is_client()) || + service_daemon) { + _send_open(); } // resend any pending commands @@ -157,6 +160,24 @@ void MgrClient::reconnect() } } +void MgrClient::_send_open() +{ + if (session && session->con) { + auto open = new MMgrOpen(); + if (!service_name.empty()) { + open->service_name = service_name; + open->daemon_name = daemon_name; + } else { + open->daemon_name = g_conf->name.get_id(); + } + if (service_daemon) { + open->service_daemon = service_daemon; + open->daemon_metadata = daemon_metadata; + } + session->con->send_message(open); + } +} + bool MgrClient::handle_mgr_map(MMgrMap *m) { assert(lock.is_locked_by_me()); @@ -250,7 +271,17 @@ void MgrClient::send_report() ldout(cct, 20) << "encoded " << report->packed.length() << " bytes" << dendl; - report->daemon_name = g_conf->name.get_id(); + if (daemon_name.size()) { + report->daemon_name = daemon_name; + } else { + report->daemon_name = g_conf->name.get_id(); + } + report->service_name = service_name; + + if (daemon_dirty_status) { + report->daemon_status = daemon_status; + daemon_dirty_status = false; + } session->con->send_message(report); @@ -354,3 +385,44 @@ bool MgrClient::handle_command_reply(MCommandReply *m) return true; } +int MgrClient::service_daemon_register( + const std::string& service, + const std::string& name, + const std::map& metadata) +{ + Mutex::Locker l(lock); + if (name == "osd" || + name == "mds" || + name == "client" || + name == "mon" || + name == "mgr") { + // normal ceph entity types are not allowed! + return -EINVAL; + } + if (service_daemon) { + return -EEXIST; + } + ldout(cct,1) << service << "." << name << " metadata " << metadata << dendl; + service_daemon = true; + service_name = service; + daemon_name = name; + daemon_metadata = metadata; + daemon_dirty_status = true; + + // late register? + if (g_conf->name.is_client() && session && session->con) { + _send_open(); + } + + return 0; +} + +int MgrClient::service_daemon_update_status( + const std::map& status) +{ + Mutex::Locker l(lock); + ldout(cct,10) << status << dendl; + daemon_status = status; + daemon_dirty_status = true; + return 0; +} diff --git a/ceph/src/mgr/MgrClient.h b/ceph/src/mgr/MgrClient.h index 87df28650..09fe831b3 100644 --- a/ceph/src/mgr/MgrClient.h +++ b/ceph/src/mgr/MgrClient.h @@ -72,7 +72,15 @@ protected: // our reports (hook for use by OSD) std::function pgstats_cb; + // for service registration and beacon + bool service_daemon = false; + bool daemon_dirty_status = false; + std::string service_name, daemon_name; + std::map daemon_metadata; + std::map daemon_status; + void reconnect(); + void _send_open(); public: MgrClient(CephContext *cct_, Messenger *msgr_); @@ -103,6 +111,13 @@ public: int start_command(const vector& cmd, const bufferlist& inbl, bufferlist *outbl, string *outs, Context *onfinish); + + int service_daemon_register( + const std::string& service, + const std::string& name, + const std::map& metadata); + int service_daemon_update_status( + const std::map& status); }; #endif diff --git a/ceph/src/mgr/MgrCommands.h b/ceph/src/mgr/MgrCommands.h index 7df74d730..62d3df508 100644 --- a/ceph/src/mgr/MgrCommands.h +++ b/ceph/src/mgr/MgrCommands.h @@ -100,10 +100,18 @@ COMMAND("osd test-reweight-by-pg " \ COMMAND("osd scrub " \ "name=who,type=CephString", \ - "initiate scrub on osd ", "osd", "rw", "cli,rest") + "initiate scrub on osd , or use to scrub all", \ + "osd", "rw", "cli,rest") COMMAND("osd deep-scrub " \ "name=who,type=CephString", \ - "initiate deep scrub on osd ", "osd", "rw", "cli,rest") + "initiate deep scrub on osd , or use to deep scrub all", \ + "osd", "rw", "cli,rest") COMMAND("osd repair " \ "name=who,type=CephString", \ - "initiate repair on osd ", "osd", "rw", "cli,rest") + "initiate repair on osd , or use to repair all", \ + "osd", "rw", "cli,rest") + +COMMAND("service dump", + "dump service map", "service", "r", "cli,rest") +COMMAND("service status", + "dump service state", "service", "r", "cli,rest") diff --git a/ceph/src/mgr/MgrStandby.cc b/ceph/src/mgr/MgrStandby.cc index d46dc194a..5e82de97f 100644 --- a/ceph/src/mgr/MgrStandby.cc +++ b/ceph/src/mgr/MgrStandby.cc @@ -148,22 +148,26 @@ void MgrStandby::send_beacon() { assert(lock.is_locked_by_me()); dout(1) << state_str() << dendl; - dout(10) << "sending beacon as gid " << monc.get_global_id() << dendl; + set modules; + PyModules::list_modules(&modules); bool available = active_mgr != nullptr && active_mgr->is_initialized(); auto addr = available ? active_mgr->get_server_addr() : entity_addr_t(); + dout(10) << "sending beacon as gid " << monc.get_global_id() + << " modules " << modules << dendl; + MMgrBeacon *m = new MMgrBeacon(monc.get_fsid(), monc.get_global_id(), g_conf->name.get_id(), addr, - available); - + available, + modules); monc.send_mon_message(m); } void MgrStandby::tick() { - dout(0) << __func__ << dendl; + dout(10) << __func__ << dendl; send_beacon(); if (active_mgr) { @@ -282,12 +286,22 @@ void MgrStandby::handle_mgr_map(MMgrMap* mmap) if (active_in_map) { if (!active_mgr) { dout(1) << "Activating!" << dendl; - active_mgr.reset(new Mgr(&monc, client_messenger.get(), &objecter, + active_mgr.reset(new Mgr(&monc, map, client_messenger.get(), &objecter, &client, clog, audit_clog)); - active_mgr->background_init(); - dout(1) << "I am now active" << dendl; + active_mgr->background_init(new FunctionContext( + [this](int r){ + // Advertise our active-ness ASAP instead of waiting for + // next tick. + Mutex::Locker l(lock); + send_beacon(); + })); + dout(1) << "I am now activating" << dendl; } else { dout(10) << "I was already active" << dendl; + bool need_respawn = active_mgr->got_mgr_map(map); + if (need_respawn) { + respawn(); + } } } else { if (active_mgr != nullptr) { diff --git a/ceph/src/mgr/MgrStandby.h b/ceph/src/mgr/MgrStandby.h index 79cdaa0c0..2e2bc6b5f 100644 --- a/ceph/src/mgr/MgrStandby.h +++ b/ceph/src/mgr/MgrStandby.h @@ -24,11 +24,6 @@ #include "mon/MonClient.h" #include "osdc/Objecter.h" -#include "DaemonServer.h" -#include "PyModules.h" - -#include "DaemonState.h" -#include "ClusterState.h" class MMgrMap; class Mgr; diff --git a/ceph/src/mgr/PyModules.cc b/ceph/src/mgr/PyModules.cc index 988e16ba6..8412e6cbf 100644 --- a/ceph/src/mgr/PyModules.cc +++ b/ceph/src/mgr/PyModules.cc @@ -15,7 +15,6 @@ #include "PyState.h" #include "Gil.h" -#include #include "common/errno.h" #include "include/stringify.h" @@ -40,9 +39,9 @@ std::string PyModules::config_prefix; // because ServeThread is still an "incomplete" type there PyModules::PyModules(DaemonStateIndex &ds, ClusterState &cs, - MonClient &mc, Objecter &objecter_, Client &client_, - Finisher &f) - : daemon_state(ds), cluster_state(cs), monc(mc), + MonClient &mc, LogChannelRef clog_, Objecter &objecter_, + Client &client_, Finisher &f) + : daemon_state(ds), cluster_state(cs), monc(mc), clog(clog_), objecter(objecter_), client(client_), finisher(f), lock("PyModules") {} @@ -59,7 +58,7 @@ void PyModules::dump_server(const std::string &hostname, for (const auto &i : dmc) { const auto &key = i.first; - const std::string str_type = ceph_entity_type_name(key.first); + const std::string &str_type = key.first; const std::string &svc_name = key.second; // TODO: pick the highest version, and make sure that @@ -117,10 +116,12 @@ PyObject *PyModules::list_servers_python() return f.get(); } -PyObject *PyModules::get_metadata_python(std::string const &handle, - entity_type_t svc_type, const std::string &svc_id) +PyObject *PyModules::get_metadata_python( + std::string const &handle, + const std::string &svc_name, + const std::string &svc_id) { - auto metadata = daemon_state.get(DaemonKey(svc_type, svc_id)); + auto metadata = daemon_state.get(DaemonKey(svc_name, svc_id)); PyFormatter f; f.dump_string("hostname", metadata->hostname); for (const auto &i : metadata->metadata) { @@ -130,6 +131,18 @@ PyObject *PyModules::get_metadata_python(std::string const &handle, return f.get(); } +PyObject *PyModules::get_daemon_status_python( + std::string const &handle, + const std::string &svc_name, + const std::string &svc_id) +{ + auto metadata = daemon_state.get(DaemonKey(svc_name, svc_id)); + PyFormatter f; + for (const auto &i : metadata->service_status) { + f.dump_string(i.first.c_str(), i.second); + } + return f.get(); +} PyObject *PyModules::get_python(const std::string &what) { @@ -174,9 +187,17 @@ PyObject *PyModules::get_python(const std::string &what) } ); return f.get(); + } else if (what == "service_map") { + PyFormatter f; + cluster_state.with_servicemap( + [&f](const ServiceMap &service_map) { + service_map.dump(&f); + } + ); + return f.get(); } else if (what == "osd_metadata") { PyFormatter f; - auto dmc = daemon_state.get_by_type(CEPH_ENTITY_TYPE_OSD); + auto dmc = daemon_state.get_by_service("osd"); for (const auto &i : dmc) { f.open_object_section(i.first.second.c_str()); f.dump_string("hostname", i.second->hostname); @@ -260,6 +281,12 @@ PyObject *PyModules::get_python(const std::string &what) } f.dump_string("json", json.to_str()); return f.get(); + } else if (what == "mgr_map") { + PyFormatter f; + cluster_state.with_mgrmap([&f](const MgrMap &mgr_map) { + mgr_map.dump(&f); + }); + return f.get(); } else { derr << "Python module requested unknown data '" << what << "'" << dendl; Py_RETURN_NONE; @@ -360,9 +387,14 @@ int PyModules::init() // thread state becomes NULL) pMainThreadState = PyEval_SaveThread(); + std::list failed_modules; + // Load python code - boost::tokenizer<> tok(g_conf->mgr_modules); - for(const auto& module_name : tok) { + set ls; + cluster_state.with_mgrmap([&](const MgrMap& m) { + ls = m.modules; + }); + for (const auto& module_name : ls) { dout(1) << "Loading python module '" << module_name << "'" << dendl; auto mod = std::unique_ptr(new MgrPyModule(module_name, sys_path, pMainThreadState)); int r = mod->load(); @@ -371,6 +403,7 @@ int PyModules::init() // or the right thread state (this is deliberate). derr << "Error loading module '" << module_name << "': " << cpp_strerror(r) << dendl; + failed_modules.push_back(module_name); // Don't drop out here, load the other modules } else { // Success! @@ -378,6 +411,11 @@ int PyModules::init() } } + if (!failed_modules.empty()) { + clog->error() << "Failed to load ceph-mgr modules: " << joinify( + failed_modules.begin(), failed_modules.end(), std::string(", ")); + } + return 0; } @@ -607,7 +645,7 @@ void PyModules::log(const std::string &handle, PyObject* PyModules::get_counter_python( const std::string &handle, - entity_type_t svc_type, + const std::string &svc_name, const std::string &svc_id, const std::string &path) { @@ -618,7 +656,7 @@ PyObject* PyModules::get_counter_python( PyFormatter f; f.open_array_section(path.c_str()); - auto metadata = daemon_state.get(DaemonKey(svc_type, svc_id)); + auto metadata = daemon_state.get(DaemonKey(svc_name, svc_id)); // FIXME: this is unsafe, I need to either be inside DaemonStateIndex's // lock or put a lock on individual DaemonStates @@ -635,8 +673,7 @@ PyObject* PyModules::get_counter_python( } } else { dout(4) << "Missing counter: '" << path << "' (" - << ceph_entity_type_name(svc_type) << "." - << svc_id << ")" << dendl; + << svc_name << "." << svc_id << ")" << dendl; dout(20) << "Paths are:" << dendl; for (const auto &i : metadata->perf_counters.instances) { dout(20) << i.first << dendl; @@ -644,8 +681,7 @@ PyObject* PyModules::get_counter_python( } } else { dout(4) << "No daemon state for " - << ceph_entity_type_name(svc_type) << "." - << svc_id << ")" << dendl; + << svc_name << "." << svc_id << ")" << dendl; } f.close_section(); return f.get(); @@ -664,3 +700,32 @@ PyObject *PyModules::get_context() return capsule; } +static void _list_modules( + const std::string path, + std::set *modules) +{ + DIR *dir = opendir(path.c_str()); + if (!dir) { + return; + } + struct dirent *entry = NULL; + while ((entry = readdir(dir)) != NULL) { + string n(entry->d_name); + string fn = path + "/" + n; + struct stat st; + int r = ::stat(fn.c_str(), &st); + if (r == 0 && S_ISDIR(st.st_mode)) { + string initfn = fn + "/module.py"; + r = ::stat(initfn.c_str(), &st); + if (r == 0) { + modules->insert(n); + } + } + } + closedir(dir); +} + +void PyModules::list_modules(std::set *modules) +{ + _list_modules(g_conf->mgr_module_path, modules); +} diff --git a/ceph/src/mgr/PyModules.h b/ceph/src/mgr/PyModules.h index 6a71b6493..467555b51 100644 --- a/ceph/src/mgr/PyModules.h +++ b/ceph/src/mgr/PyModules.h @@ -22,6 +22,8 @@ #include "osdc/Objecter.h" #include "client/Client.h" +#include "common/LogClient.h" +#include "mon/MgrMap.h" #include "DaemonState.h" #include "ClusterState.h" @@ -35,6 +37,7 @@ class PyModules DaemonStateIndex &daemon_state; ClusterState &cluster_state; MonClient &monc; + LogChannelRef clog; Objecter &objecter; Client &client; Finisher &finisher; @@ -49,7 +52,7 @@ public: static std::string config_prefix; PyModules(DaemonStateIndex &ds, ClusterState &cs, MonClient &mc, - Objecter &objecter_, Client &client_, + LogChannelRef clog_, Objecter &objecter_, Client &client_, Finisher &f); ~PyModules(); @@ -62,11 +65,17 @@ public: PyObject *get_python(const std::string &what); PyObject *get_server_python(const std::string &hostname); PyObject *list_servers_python(); - PyObject *get_metadata_python(std::string const &handle, - entity_type_t svc_type, const std::string &svc_id); - PyObject *get_counter_python(std::string const &handle, - entity_type_t svc_type, const std::string &svc_id, - const std::string &path); + PyObject *get_metadata_python( + std::string const &handle, + const std::string &svc_name, const std::string &svc_id); + PyObject *get_daemon_status_python( + std::string const &handle, + const std::string &svc_name, const std::string &svc_id); + PyObject *get_counter_python( + std::string const &handle, + const std::string &svc_name, + const std::string &svc_id, + const std::string &path); PyObject *get_context(); std::map config_cache; @@ -99,6 +108,8 @@ public: void log(const std::string &handle, int level, const std::string &record); + + static void list_modules(std::set *modules); }; #endif diff --git a/ceph/src/mgr/PyState.cc b/ceph/src/mgr/PyState.cc index ce71dcd3f..3bc8a23a8 100644 --- a/ceph/src/mgr/PyState.cc +++ b/ceph/src/mgr/PyState.cc @@ -152,9 +152,27 @@ ceph_send_command(PyObject *self, PyObject *args) return nullptr; } } else if (std::string(type) == "pg") { - // TODO: expose objecter::pg_command + pg_t pgid; + if (!pgid.parse(name)) { + delete c; + string msg("invalid pgid: "); + msg.append("\"").append(name).append("\""); + PyErr_SetString(PyExc_ValueError, msg.c_str()); + return nullptr; + } + + ceph_tid_t tid; + global_handle->get_objecter().pg_command( + pgid, + {cmd_json}, + {}, + &tid, + &c->outbl, + &c->outs, + c); return nullptr; } else { + delete c; string msg("unknown service type: "); msg.append(type); PyErr_SetString(PyExc_ValueError, msg.c_str()); @@ -249,37 +267,29 @@ ceph_config_set(PyObject *self, PyObject *args) Py_RETURN_NONE; } -static entity_type_t svc_type_from_str(const std::string &type_str) -{ - if (type_str == std::string("mds")) { - return CEPH_ENTITY_TYPE_MDS; - } else if (type_str == std::string("osd")) { - return CEPH_ENTITY_TYPE_OSD; - } else if (type_str == std::string("mon")) { - return CEPH_ENTITY_TYPE_MON; - } else { - return CEPH_ENTITY_TYPE_ANY; - } -} - static PyObject* get_metadata(PyObject *self, PyObject *args) { char *handle = nullptr; - char *type_str = NULL; + char *svc_name = NULL; char *svc_id = NULL; - if (!PyArg_ParseTuple(args, "sss:get_metadata", &handle, &type_str, &svc_id)) { + if (!PyArg_ParseTuple(args, "sss:get_metadata", &handle, &svc_name, &svc_id)) { return nullptr; } + return global_handle->get_metadata_python(handle, svc_name, svc_id); +} - entity_type_t svc_type = svc_type_from_str(type_str); - if (svc_type == CEPH_ENTITY_TYPE_ANY) { - // FIXME: form a proper exception +static PyObject* +get_daemon_status(PyObject *self, PyObject *args) +{ + char *handle = nullptr; + char *svc_name = NULL; + char *svc_id = NULL; + if (!PyArg_ParseTuple(args, "sss:get_daemon_status", &handle, &svc_name, + &svc_id)) { return nullptr; } - - - return global_handle->get_metadata_python(handle, svc_type, svc_id); + return global_handle->get_daemon_status_python(handle, svc_name, svc_id); } static PyObject* @@ -313,22 +323,15 @@ static PyObject* get_counter(PyObject *self, PyObject *args) { char *handle = nullptr; - char *type_str = nullptr; + char *svc_name = nullptr; char *svc_id = nullptr; char *counter_path = nullptr; - if (!PyArg_ParseTuple(args, "ssss:get_counter", &handle, &type_str, + if (!PyArg_ParseTuple(args, "ssss:get_counter", &handle, &svc_name, &svc_id, &counter_path)) { return nullptr; } - - entity_type_t svc_type = svc_type_from_str(type_str); - if (svc_type == CEPH_ENTITY_TYPE_ANY) { - // FIXME: form a proper exception - return nullptr; - } - return global_handle->get_counter_python( - handle, svc_type, svc_id, counter_path); + handle, svc_name, svc_id, counter_path); } PyMethodDef CephStateMethods[] = { @@ -338,6 +341,8 @@ PyMethodDef CephStateMethods[] = { "Get a server object"}, {"get_metadata", get_metadata, METH_VARARGS, "Get a service's metadata"}, + {"get_daemon_status", get_daemon_status, METH_VARARGS, + "Get a service's status"}, {"send_command", ceph_send_command, METH_VARARGS, "Send a mon command"}, {"get_mgr_id", ceph_get_mgr_id, METH_NOARGS, diff --git a/ceph/src/mgr/ServiceMap.cc b/ceph/src/mgr/ServiceMap.cc new file mode 100644 index 000000000..9074e2f87 --- /dev/null +++ b/ceph/src/mgr/ServiceMap.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 "mgr/ServiceMap.h" + +#include "common/Formatter.h" + +// Daemon + +void ServiceMap::Daemon::encode(bufferlist& bl, uint64_t features) const +{ + ENCODE_START(1, 1, bl); + ::encode(gid, bl); + ::encode(addr, bl, features); + ::encode(start_epoch, bl); + ::encode(start_stamp, bl); + ::encode(metadata, bl); + ENCODE_FINISH(bl); +} + +void ServiceMap::Daemon::decode(bufferlist::iterator& p) +{ + DECODE_START(1, p); + ::decode(gid, p); + ::decode(addr, p); + ::decode(start_epoch, p); + ::decode(start_stamp, p); + ::decode(metadata, p); + DECODE_FINISH(p); +} + +void ServiceMap::Daemon::dump(Formatter *f) const +{ + f->dump_unsigned("start_epoch", start_epoch); + f->dump_stream("start_stamp") << start_stamp; + f->dump_unsigned("gid", gid); + f->dump_stream("addr") << addr; + f->open_object_section("metadata"); + for (auto& p : metadata) { + f->dump_string(p.first.c_str(), p.second); + } + f->close_section(); +} + +void ServiceMap::Daemon::generate_test_instances(std::list& ls) +{ + ls.push_back(new Daemon); + ls.push_back(new Daemon); + ls.back()->gid = 222; + ls.back()->metadata["this"] = "that"; +} + +// Service + +void ServiceMap::Service::encode(bufferlist& bl, uint64_t features) const +{ + ENCODE_START(1, 1, bl); + ::encode(daemons, bl, features); + ::encode(summary, bl); + ENCODE_FINISH(bl); +} + +void ServiceMap::Service::decode(bufferlist::iterator& p) +{ + DECODE_START(1, p); + ::decode(daemons, p); + ::decode(summary, p); + DECODE_FINISH(p); +} + +void ServiceMap::Service::dump(Formatter *f) const +{ + f->open_object_section("daemons"); + f->dump_string("summary", summary); + for (auto& p : daemons) { + f->dump_object(p.first.c_str(), p.second); + } + f->close_section(); +} + +void ServiceMap::Service::generate_test_instances(std::list& ls) +{ + ls.push_back(new Service); + ls.push_back(new Service); + ls.back()->daemons["one"].gid = 1; + ls.back()->daemons["two"].gid = 2; +} + +// ServiceMap + +void ServiceMap::encode(bufferlist& bl, uint64_t features) const +{ + ENCODE_START(1, 1, bl); + ::encode(epoch, bl); + ::encode(modified, bl); + ::encode(services, bl, features); + ENCODE_FINISH(bl); +} + +void ServiceMap::decode(bufferlist::iterator& p) +{ + DECODE_START(1, p); + ::decode(epoch, p); + ::decode(modified, p); + ::decode(services, p); + DECODE_FINISH(p); +} + +void ServiceMap::dump(Formatter *f) const +{ + f->dump_unsigned("epoch", epoch); + f->dump_stream("modified") << modified; + f->open_object_section("services"); + for (auto& p : services) { + f->dump_object(p.first.c_str(), p.second); + } + f->close_section(); +} + +void ServiceMap::generate_test_instances(std::list& ls) +{ + ls.push_back(new ServiceMap); + ls.push_back(new ServiceMap); + ls.back()->epoch = 123; + ls.back()->services["rgw"].daemons["one"].gid = 123; + ls.back()->services["rgw"].daemons["two"].gid = 344; + ls.back()->services["iscsi"].daemons["foo"].gid = 3222; +} diff --git a/ceph/src/mgr/ServiceMap.h b/ceph/src/mgr/ServiceMap.h new file mode 100644 index 000000000..5137f9f84 --- /dev/null +++ b/ceph/src/mgr/ServiceMap.h @@ -0,0 +1,89 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#pragma once + +#include +#include +#include +#include + +#include "include/utime.h" +#include "include/buffer.h" +#include "msg/msg_types.h" + +namespace ceph { + class Formatter; +} + +struct ServiceMap { + struct Daemon { + uint64_t gid = 0; + entity_addr_t addr; + epoch_t start_epoch = 0; ///< epoch first registered + utime_t start_stamp; ///< timestamp daemon started/registered + std::map metadata; ///< static metadata + + void encode(bufferlist& bl, uint64_t features) const; + void decode(bufferlist::iterator& p); + void dump(Formatter *f) const; + static void generate_test_instances(std::list& ls); + }; + + struct Service { + map daemons; + std::string summary; ///< summary status string for 'ceph -s' + + void encode(bufferlist& bl, uint64_t features) const; + void decode(bufferlist::iterator& p); + void dump(Formatter *f) const; + static void generate_test_instances(std::list& ls); + + std::string get_summary() const { + if (summary.size()) { + return summary; + } + if (daemons.empty()) { + return "no daemons active"; + } + std::ostringstream ss; + ss << daemons.size() << (daemons.size() > 1 ? "daemonss" : "daemon") + << " active"; + return ss.str(); + } + }; + + epoch_t epoch = 0; + utime_t modified; + map services; + + void encode(bufferlist& bl, uint64_t features) const; + void decode(bufferlist::iterator& p); + void dump(Formatter *f) const; + static void generate_test_instances(std::list& ls); + + Daemon* get_daemon(const std::string& service, + const std::string& daemon) { + return &services[service].daemons[daemon]; + } + + bool rm_daemon(const std::string& service, + const std::string& daemon) { + auto p = services.find(service); + if (p == services.end()) { + return false; + } + auto q = p->second.daemons.find(daemon); + if (q == p->second.daemons.end()) { + return false; + } + p->second.daemons.erase(q); + if (p->second.daemons.empty()) { + services.erase(p); + } + return true; + } +}; +WRITE_CLASS_ENCODER_FEATURES(ServiceMap) +WRITE_CLASS_ENCODER_FEATURES(ServiceMap::Service) +WRITE_CLASS_ENCODER_FEATURES(ServiceMap::Daemon) diff --git a/ceph/src/mon/CMakeLists.txt b/ceph/src/mon/CMakeLists.txt index 9e40ef588..556157132 100644 --- a/ceph/src/mon/CMakeLists.txt +++ b/ceph/src/mon/CMakeLists.txt @@ -16,6 +16,7 @@ set(lib_mon_srcs AuthMonitor.cc Elector.cc HealthMonitor.cc + OldHealthMonitor.cc DataHealthService.cc PGMonitor.cc PGMap.cc diff --git a/ceph/src/mon/ConfigKeyService.h b/ceph/src/mon/ConfigKeyService.h index 997796873..7dfb140c7 100644 --- a/ceph/src/mon/ConfigKeyService.h +++ b/ceph/src/mon/ConfigKeyService.h @@ -57,8 +57,7 @@ public: * @{ */ void init() override { } - void get_health(Formatter *f, - list >& summary, + void get_health(list >& summary, list > *detail) override { } bool service_dispatch(MonOpRequestRef op) override; diff --git a/ceph/src/mon/DataHealthService.cc b/ceph/src/mon/DataHealthService.cc index 6305263a8..4a5b42ab3 100644 --- a/ceph/src/mon/DataHealthService.cc +++ b/ceph/src/mon/DataHealthService.cc @@ -65,16 +65,10 @@ void DataHealthService::start_epoch() } void DataHealthService::get_health( - Formatter *f, list >& summary, list > *detail) { dout(10) << __func__ << dendl; - if (f) { - f->open_object_section("data_health"); - f->open_array_section("mons"); - } - for (map::iterator it = stats.begin(); it != stats.end(); ++it) { string mon_name = mon->monmap->get_name(it->first.addr); @@ -110,22 +104,6 @@ void DataHealthService::get_health( if (detail) detail->push_back(make_pair(health_status, ss.str())); } - - if (f) { - f->open_object_section("mon"); - f->dump_string("name", mon_name.c_str()); - // leave this unenclosed by an object section to avoid breaking backward-compatibility - stats.dump(f); - f->dump_stream("health") << health_status; - if (health_status != HEALTH_OK) - f->dump_string("health_detail", health_detail); - f->close_section(); - } - } - - if (f) { - f->close_section(); // mons - f->close_section(); // data_health } } diff --git a/ceph/src/mon/DataHealthService.h b/ceph/src/mon/DataHealthService.h index 8834b600b..91caf4e32 100644 --- a/ceph/src/mon/DataHealthService.h +++ b/ceph/src/mon/DataHealthService.h @@ -65,9 +65,9 @@ public: start_tick(); } - void get_health(Formatter *f, - list >& summary, - list > *detail) override; + void get_health( + list >& summary, + list > *detail) override; int get_type() override { return HealthService::SERVICE_HEALTH_DATA; diff --git a/ceph/src/mon/Elector.cc b/ceph/src/mon/Elector.cc index 303510530..a2244a3c6 100644 --- a/ceph/src/mon/Elector.cc +++ b/ceph/src/mon/Elector.cc @@ -87,6 +87,7 @@ void Elector::start() electing_me = true; acked_me[mon->rank].cluster_features = CEPH_FEATURES_ALL; acked_me[mon->rank].mon_features = ceph::features::mon::get_supported(); + mon->collect_metadata(&acked_me[mon->rank].metadata); leader_acked = -1; // bcast to everyone else @@ -117,6 +118,7 @@ void Elector::defer(int who) MMonElection *m = new MMonElection(MMonElection::OP_ACK, epoch, mon->monmap); m->mon_features = ceph::features::mon::get_supported(); m->sharing_bl = mon->get_supported_commands_bl(); + mon->collect_metadata(&m->metadata); mon->messenger->send_message(m, mon->monmap->get_inst(who)); // set a timer @@ -184,12 +186,14 @@ void Elector::victory() uint64_t cluster_features = CEPH_FEATURES_ALL; mon_feature_t mon_features = ceph::features::mon::get_supported(); set quorum; - for (map::iterator p = acked_me.begin(); + map metadata; + for (map::iterator p = acked_me.begin(); p != acked_me.end(); ++p) { quorum.insert(p->first); cluster_features &= p->second.cluster_features; mon_features &= p->second.mon_features; + metadata[p->first] = p->second.metadata; } cancel_timer(); @@ -216,10 +220,10 @@ void Elector::victory() m->sharing_bl = *cmds_bl; mon->messenger->send_message(m, mon->monmap->get_inst(*p)); } - + // tell monitor mon->win_election(epoch, quorum, - cluster_features, mon_features, + cluster_features, mon_features, metadata, cmds, cmdsize); } @@ -331,8 +335,9 @@ void Elector::handle_ack(MonOpRequestRef op) // thanks acked_me[from].cluster_features = m->get_connection()->get_features(); acked_me[from].mon_features = m->mon_features; + acked_me[from].metadata = m->metadata; dout(5) << " so far i have {"; - for (map::const_iterator p = acked_me.begin(); + for (map::const_iterator p = acked_me.begin(); p != acked_me.end(); ++p) { if (p != acked_me.begin()) diff --git a/ceph/src/mon/Elector.h b/ceph/src/mon/Elector.h index 2e407d290..b9e6310b5 100644 --- a/ceph/src/mon/Elector.h +++ b/ceph/src/mon/Elector.h @@ -47,9 +47,10 @@ class Elector { * mon-specific features. Instead of keeping maps to hold them both, or * a pair, which would be weird, a struct to keep them seems appropriate. */ - struct elector_features_t { + struct elector_info_t { uint64_t cluster_features; mon_feature_t mon_features; + map metadata; }; /** @@ -130,7 +131,7 @@ class Elector { * If we are acked by everyone in the MonMap, we will declare * victory. Also note each peer's feature set. */ - map acked_me; + map acked_me; /** * @} */ diff --git a/ceph/src/mon/FSCommands.cc b/ceph/src/mon/FSCommands.cc index abdea4333..4f9806bb7 100644 --- a/ceph/src/mon/FSCommands.cc +++ b/ceph/src/mon/FSCommands.cc @@ -370,12 +370,6 @@ public: }); ss << "disallowed increasing the cluster size past 1"; } else { - string confirm; - if (!cmd_getval(g_ceph_context, cmdmap, "confirm", confirm) || - confirm != "--yes-i-really-mean-it") { - ss << EXPERIMENTAL_WARNING; - return -EPERM; - } fsmap.modify_filesystem( fs->fscid, [](std::shared_ptr fs) diff --git a/ceph/src/mon/HealthMonitor.cc b/ceph/src/mon/HealthMonitor.cc index 0887bdc1b..32f62667e 100644 --- a/ceph/src/mon/HealthMonitor.cc +++ b/ceph/src/mon/HealthMonitor.cc @@ -12,13 +12,13 @@ * */ -#include #include #include +#include +#include -// #include -// Because intusive_ptr clobbers our assert... #include "include/assert.h" +#include "include/stringify.h" #include "mon/Monitor.h" #include "mon/HealthService.h" @@ -26,8 +26,9 @@ #include "mon/DataHealthService.h" #include "messages/MMonHealth.h" +#include "messages/MMonHealthChecks.h" + #include "common/Formatter.h" -// #include "common/config.h" #define dout_subsys ceph_subsys_mon #undef dout_prefix @@ -35,84 +36,345 @@ static ostream& _prefix(std::ostream *_dout, const Monitor *mon, const HealthMonitor *hmon) { return *_dout << "mon." << mon->name << "@" << mon->rank - << "(" << mon->get_state_name() << ")." << hmon->get_name() - << "(" << hmon->get_epoch() << ") "; + << "(" << mon->get_state_name() << ").health "; +} + +HealthMonitor::HealthMonitor(Monitor *m, Paxos *p, const string& service_name) + : PaxosService(m, p, service_name) { } void HealthMonitor::init() { dout(10) << __func__ << dendl; - assert(services.empty()); - services[HealthService::SERVICE_HEALTH_DATA] = new DataHealthService(mon); +} + +void HealthMonitor::create_initial() +{ + dout(10) << __func__ << dendl; +} + +void HealthMonitor::update_from_paxos(bool *need_bootstrap) +{ + version = get_last_committed(); + dout(10) << __func__ << dendl; + load_health(); + + bufferlist qbl; + mon->store->get(service_name, "quorum", qbl); + if (qbl.length()) { + auto p = qbl.begin(); + ::decode(quorum_checks, p); + } else { + quorum_checks.clear(); + } + + bufferlist lbl; + mon->store->get(service_name, "leader", lbl); + if (lbl.length()) { + auto p = lbl.begin(); + ::decode(leader_checks, p); + } else { + leader_checks.clear(); + } - for (map::iterator it = services.begin(); - it != services.end(); - ++it) { - it->second->init(); + dout(20) << "dump:"; + JSONFormatter jf(true); + jf.open_object_section("health"); + jf.open_object_section("quorum_health"); + for (auto& p : quorum_checks) { + string s = string("mon.") + stringify(p.first); + jf.dump_object(s.c_str(), p.second); } + jf.close_section(); + jf.dump_object("leader_health", leader_checks); + jf.close_section(); + jf.flush(*_dout); + *_dout << dendl; } -bool HealthMonitor::service_dispatch(MonOpRequestRef op) +void HealthMonitor::create_pending() { - assert(op->get_req()->get_type() == MSG_MON_HEALTH); - MMonHealth *hm = static_cast(op->get_req()); - int service_type = hm->get_service_type(); - if (services.count(service_type) == 0) { - dout(1) << __func__ << " service type " << service_type - << " not registered -- drop message!" << dendl; - return false; - } - return services[service_type]->service_dispatch(op); + dout(10) << " " << version << dendl; } -void HealthMonitor::start_epoch() { - epoch_t epoch = get_epoch(); - for (map::iterator it = services.begin(); - it != services.end(); ++it) { - it->second->start(epoch); +void HealthMonitor::encode_pending(MonitorDBStore::TransactionRef t) +{ + ++version; + dout(10) << " " << version << dendl; + put_last_committed(t, version); + + bufferlist qbl; + ::encode(quorum_checks, qbl); + t->put(service_name, "quorum", qbl); + bufferlist lbl; + ::encode(leader_checks, lbl); + t->put(service_name, "leader", lbl); + + health_check_map_t pending_health; + + // combine per-mon details carefully... + map> names; // code -> + for (auto p : quorum_checks) { + for (auto q : p.second.checks) { + names[q.first].insert(mon->monmap->get_name(p.first)); + } + pending_health.merge(p.second); } + for (auto p : pending_health.checks) { + p.second.summary = boost::regex_replace( + p.second.summary, + boost::regex("%num%"), stringify(names[p.first].size())); + p.second.summary = boost::regex_replace( + p.second.summary, + boost::regex("%names%"), stringify(names[p.first])); + p.second.summary = boost::regex_replace( + p.second.summary, + boost::regex("%plurals%"), + names[p.first].size() > 1 ? "s" : ""); + p.second.summary = boost::regex_replace( + p.second.summary, + boost::regex("%isorare%"), + names[p.first].size() > 1 ? "are" : "is"); + } + + pending_health.merge(leader_checks); + encode_health(pending_health, t); } -void HealthMonitor::finish_epoch() { - generic_dout(20) << "HealthMonitor::finish_epoch()" << dendl; - for (map::iterator it = services.begin(); - it != services.end(); ++it) { - assert(it->second != NULL); - it->second->finish(); +version_t HealthMonitor::get_trim_to() +{ + // we don't actually need *any* old states, but keep a few. + if (version > 5) { + return version - 5; } + return 0; } -void HealthMonitor::service_shutdown() +bool HealthMonitor::preprocess_query(MonOpRequestRef op) { - dout(0) << "HealthMonitor::service_shutdown " - << services.size() << " services" << dendl; - for (map::iterator it = services.begin(); - it != services.end(); - ++it) { - it->second->shutdown(); - delete it->second; - } - services.clear(); + switch (op->get_req()->get_type()) { + case MSG_MON_HEALTH: + { + MMonHealth *hm = static_cast(op->get_req()); + int service_type = hm->get_service_type(); + if (services.count(service_type) == 0) { + dout(1) << __func__ << " service type " << service_type + << " not registered -- drop message!" << dendl; + return false; + } + return services[service_type]->service_dispatch(op); + } + + case MSG_MON_HEALTH_CHECKS: + return preprocess_health_checks(op); + } + return false; } -void HealthMonitor::get_health(Formatter *f, - list >& summary, - list > *detail) +bool HealthMonitor::prepare_update(MonOpRequestRef op) { - if (f) { - f->open_object_section("health"); - f->open_array_section("health_services"); + return false; +} + +bool HealthMonitor::preprocess_health_checks(MonOpRequestRef op) +{ + MMonHealthChecks *m = static_cast(op->get_req()); + quorum_checks[m->get_source().num()] = m->health_checks; + return true; +} + +void HealthMonitor::tick() +{ + if (!is_active()) { + return; + } + dout(10) << __func__ << dendl; + bool changed = false; + if (check_member_health()) { + changed = true; + } + if (mon->is_leader()) { + if (check_leader_health()) { + changed = true; + } } + if (changed) { + propose_pending(); + } +} + +bool HealthMonitor::check_member_health() +{ + dout(20) << __func__ << dendl; + bool changed = false; - for (map::iterator it = services.begin(); - it != services.end(); - ++it) { - it->second->get_health(f, summary, detail); + // snapshot of usage + DataStats stats; + get_fs_stats(stats.fs_stats, g_conf->mon_data.c_str()); + map extra; + uint64_t store_size = mon->store->get_estimated_size(extra); + assert(store_size > 0); + stats.store_stats.bytes_total = store_size; + stats.store_stats.bytes_sst = extra["sst"]; + stats.store_stats.bytes_log = extra["log"]; + stats.store_stats.bytes_misc = extra["misc"]; + stats.last_update = ceph_clock_now(); + dout(10) << __func__ << " avail " << stats.fs_stats.avail_percent << "%" + << " total " << prettybyte_t(stats.fs_stats.byte_total) + << ", used " << prettybyte_t(stats.fs_stats.byte_used) + << ", avail " << prettybyte_t(stats.fs_stats.byte_avail) << dendl; + + // MON_DISK_{LOW,CRIT,BIG} + health_check_map_t next; + if (stats.fs_stats.avail_percent <= g_conf->mon_data_avail_crit) { + stringstream ss, ss2; + ss << "mon%plurals% %names% %isorare% very low on available space"; + auto& d = next.add("MON_DISK_CRIT", HEALTH_ERR, ss.str()); + ss2 << "mon." << mon->name << " has " << stats.fs_stats.avail_percent + << "% avail"; + d.detail.push_back(ss2.str()); + } else if (stats.fs_stats.avail_percent <= g_conf->mon_data_avail_warn) { + stringstream ss, ss2; + ss << "mon%plurals% %names% %isorare% low on available space"; + auto& d = next.add("MON_DISK_LOW", HEALTH_ERR, ss.str()); + ss2 << "mon." << mon->name << " has " << stats.fs_stats.avail_percent + << "% avail"; + d.detail.push_back(ss2.str()); + } + if (stats.store_stats.bytes_total >= g_conf->mon_data_size_warn) { + stringstream ss, ss2; + ss << "mon%plurals% %names% %isorare% using a lot of disk space"; + auto& d = next.add("MON_DISK_BIG", HEALTH_WARN, ss.str()); + ss2 << "mon." << mon->name << " is " + << prettybyte_t(stats.store_stats.bytes_total) + << " >= mon_data_size_warn (" + << prettybyte_t(g_conf->mon_data_size_warn) << ")"; + d.detail.push_back(ss2.str()); } - if (f) { - f->close_section(); // health_services - f->close_section(); // health + auto p = quorum_checks.find(mon->rank); + if (p == quorum_checks.end() || + p->second != next) { + if (mon->is_leader()) { + // prepare to propose + quorum_checks[mon->rank] = next; + changed = true; + } else { + // tell the leader + mon->messenger->send_message(new MMonHealthChecks(next), + mon->monmap->get_inst(mon->get_leader())); + } } + + // OSD_NO_DOWN_OUT_INTERVAL + { + // Warn if 'mon_osd_down_out_interval' is set to zero. + // Having this option set to zero on the leader acts much like the + // 'noout' flag. It's hard to figure out what's going wrong with clusters + // without the 'noout' flag set but acting like that just the same, so + // we report a HEALTH_WARN in case this option is set to zero. + // This is an ugly hack to get the warning out, but until we find a way + // to spread global options throughout the mon cluster and have all mons + // using a base set of the same options, we need to work around this sort + // of things. + // There's also the obvious drawback that if this is set on a single + // monitor on a 3-monitor cluster, this warning will only be shown every + // third monitor connection. + if (g_conf->mon_warn_on_osd_down_out_interval_zero && + g_conf->mon_osd_down_out_interval == 0) { + ostringstream ss, ds; + ss << "mon%plurals% %names %hasorhave% mon_osd_down_out_interval set to 0"; + auto& d = next.add("OSD_NO_DOWN_OUT_INTERVAL", HEALTH_WARN, ss.str()); + ds << "mon." << mon->name << " has mon_osd_down_out_interval set to 0"; + d.detail.push_back(ds.str()); + } + } + + return changed; } +bool HealthMonitor::check_leader_health() +{ + dout(20) << __func__ << dendl; + bool changed = false; + + // prune quorum_health + { + auto& qset = mon->get_quorum(); + auto p = quorum_checks.begin(); + while (p != quorum_checks.end()) { + if (qset.count(p->first) == 0) { + p = quorum_checks.erase(p); + changed = true; + } else { + ++p; + } + } + } + + health_check_map_t next; + + // MON_DOWN + { + int max = mon->monmap->size(); + int actual = mon->get_quorum().size(); + if (actual < max) { + ostringstream ss; + ss << (max-actual) << "/" << max << " mons down, quorum " + << mon->get_quorum_names(); + auto& d = next.add("MON_DOWN", HEALTH_WARN, ss.str()); + set q = mon->get_quorum(); + for (int i=0; imonmap->get_name(i) << " (rank " << i + << ") addr " << mon->monmap->get_addr(i) + << " is down (out of quorum)"; + d.detail.push_back(ss.str()); + } + } + } + } + + // MON_CLOCK_SKEW + if (!mon->timecheck_skews.empty()) { + list warns; + list details; + for (map::iterator i = mon->timecheck_skews.begin(); + i != mon->timecheck_skews.end(); ++i) { + entity_inst_t inst = i->first; + double skew = i->second; + double latency = mon->timecheck_latencies[inst]; + string name = mon->monmap->get_name(inst.addr); + ostringstream tcss; + health_status_t tcstatus = mon->timecheck_status(tcss, skew, latency); + if (tcstatus != HEALTH_OK) { + warns.push_back(name); + ostringstream tmp_ss; + tmp_ss << "mon." << name + << " addr " << inst.addr << " " << tcss.str() + << " (latency " << latency << "s)"; + details.push_back(tmp_ss.str()); + } + } + if (!warns.empty()) { + ostringstream ss; + ss << "clock skew detected on"; + while (!warns.empty()) { + ss << " mon." << warns.front(); + warns.pop_front(); + if (!warns.empty()) + ss << ","; + } + auto& d = next.add("MON_CLOCK_SKEW", HEALTH_WARN, + "monitor clock skew detected"); + d.detail.swap(details); + } + } + + if (next != leader_checks) { + changed = true; + leader_checks = next; + } + return changed; +} diff --git a/ceph/src/mon/HealthMonitor.h b/ceph/src/mon/HealthMonitor.h index 9d05c64e9..5387ce034 100644 --- a/ceph/src/mon/HealthMonitor.h +++ b/ceph/src/mon/HealthMonitor.h @@ -14,50 +14,54 @@ #ifndef CEPH_HEALTH_MONITOR_H #define CEPH_HEALTH_MONITOR_H -#include "mon/QuorumService.h" +#include "mon/PaxosService.h" //forward declaration namespace ceph { class Formatter; } class HealthService; -class HealthMonitor : public QuorumService +class HealthMonitor : public PaxosService { map services; - -protected: - void service_shutdown() override; + version_t version = 0; + map quorum_checks; // for each quorum member + health_check_map_t leader_checks; // leader only public: - HealthMonitor(Monitor *m) : QuorumService(m) { } + HealthMonitor(Monitor *m, Paxos *p, const string& service_name); ~HealthMonitor() override { assert(services.empty()); } - /** * @defgroup HealthMonitor_Inherited_h Inherited abstract methods * @{ */ void init() override; - void get_health(Formatter *f, - list >& summary, - list > *detail) override; - bool service_dispatch(MonOpRequestRef op) override; - void start_epoch() override; + void get_health( + list >& summary, + list > *detail, + CephContext *cct) const override {} - void finish_epoch() override; + bool preprocess_query(MonOpRequestRef op) override; + bool prepare_update(MonOpRequestRef op) override; - void cleanup() override { } - void service_tick() override { } + bool preprocess_health_checks(MonOpRequestRef op); + bool prepare_health_checks(MonOpRequestRef op); - int get_type() override { - return QuorumService::SERVICE_HEALTH; - } + bool check_leader_health(); + bool check_member_health(); - string get_name() const override { - return "health"; - } + void create_initial() override; + void update_from_paxos(bool *need_bootstrap) override; + void create_pending() override; + void encode_pending(MonitorDBStore::TransactionRef t) override; + version_t get_trim_to() override; + + void encode_full(MonitorDBStore::TransactionRef t) override { } + + void tick() override; /** * @} // HealthMonitor_Inherited_h diff --git a/ceph/src/mon/LogMonitor.cc b/ceph/src/mon/LogMonitor.cc index cc5fd6bcb..20fc13327 100644 --- a/ceph/src/mon/LogMonitor.cc +++ b/ceph/src/mon/LogMonitor.cc @@ -403,13 +403,44 @@ bool LogMonitor::preprocess_command(MonOpRequestRef op) if (f) { f->open_array_section("tail"); } + + std::string level_str; + clog_type level; + if (cmd_getval(g_ceph_context, cmdmap, "level", level_str)) { + level = LogEntry::str_to_level(level_str); + if (level == CLOG_UNKNOWN) { + ss << "Invalid severity '" << level_str << "'"; + mon->reply_command(op, -EINVAL, ss.str(), get_last_committed()); + return true; + } + } else { + level = CLOG_INFO; + } + + std::string channel; + if (!cmd_getval(g_ceph_context, cmdmap, "channel", channel)) { + channel = CLOG_CHANNEL_DEFAULT; + } + + // We'll apply this twice, once while counting out lines + // and once while outputting them. + auto match = [level, channel](const LogEntry &entry) { + return entry.prio >= level && (entry.channel == channel || channel == "*"); + }; + auto p = summary.tail.end(); while (num > 0 && p != summary.tail.begin()) { - num--; + if (match(*p)) { + num--; + } --p; } ostringstream ss; for ( ; p != summary.tail.end(); ++p) { + if (!match(*p)) { + continue; + } + if (f) { f->dump_object("entry", *p); } else { @@ -468,6 +499,7 @@ bool LogMonitor::prepare_command(MonOpRequestRef op) le.stamp = m->get_recv_stamp(); le.seq = 0; le.prio = CLOG_INFO; + le.channel = CLOG_CHANNEL_DEFAULT; le.msg = str_join(logtext, " "); pending_summary.add(le); pending_summary.prune(g_conf->mon_log_max_summary); @@ -485,17 +517,11 @@ bool LogMonitor::prepare_command(MonOpRequestRef op) int LogMonitor::sub_name_to_id(const string& n) { - if (n == "log-debug") - return CLOG_DEBUG; - if (n == "log-info") - return CLOG_INFO; - if (n == "log-sec") - return CLOG_SEC; - if (n == "log-warn") - return CLOG_WARN; - if (n == "log-error") - return CLOG_ERROR; - return CLOG_UNKNOWN; + if (n.substr(0, 4) == "log-" && n.size() > 4) { + return LogEntry::str_to_level(n.substr(4)); + } else { + return CLOG_UNKNOWN; + } } void LogMonitor::check_subs() diff --git a/ceph/src/mon/MDSMonitor.cc b/ceph/src/mon/MDSMonitor.cc index 608e1aeed..d5a350efb 100644 --- a/ceph/src/mon/MDSMonitor.cc +++ b/ceph/src/mon/MDSMonitor.cc @@ -14,6 +14,7 @@ #include #include +#include #include "MDSMonitor.h" #include "FSCommands.h" @@ -99,6 +100,8 @@ void MDSMonitor::update_from_paxos(bool *need_bootstrap) << ", my e " << fsmap.epoch << dendl; assert(version > fsmap.epoch); + load_health(); + // read and decode bufferlist fsmap_bl; fsmap_bl.clear(); @@ -174,6 +177,65 @@ void MDSMonitor::encode_pending(MonitorDBStore::TransactionRef t) } pending_daemon_health_rm.clear(); remove_from_metadata(t); + + // health + health_check_map_t new_checks; + const auto info_map = pending_fsmap.get_mds_info(); + for (const auto &i : info_map) { + const auto &gid = i.first; + const auto &info = i.second; + if (pending_daemon_health_rm.count(gid)) { + continue; + } + MDSHealth health; + auto p = pending_daemon_health.find(gid); + if (p != pending_daemon_health.end()) { + health = p->second; + } else { + bufferlist bl; + mon->store->get(MDS_HEALTH_PREFIX, stringify(gid), bl); + if (!bl.length()) { + derr << "Missing health data for MDS " << gid << dendl; + continue; + } + bufferlist::iterator bl_i = bl.begin(); + health.decode(bl_i); + } + for (const auto &metric : health.metrics) { + int const rank = info.rank; + health_check_t *check = &new_checks.get_or_add( + mds_metric_name(metric.type), + metric.sev, + mds_metric_summary(metric.type)); + ostringstream ss; + ss << "mds" << info.name << "(mds." << rank << "): " << metric.message; + for (auto p = metric.metadata.begin(); + p != metric.metadata.end(); + ++p) { + if (p != metric.metadata.begin()) { + ss << ", "; + } + ss << p->first << ": " << p->second; + } + check->detail.push_back(ss.str()); + } + } + pending_fsmap.get_health_checks(&new_checks); + for (auto& p : new_checks.checks) { + p.second.summary = boost::regex_replace( + p.second.summary, + boost::regex("%num%"), + stringify(p.second.detail.size())); + p.second.summary = boost::regex_replace( + p.second.summary, + boost::regex("%plurals%"), + p.second.detail.size() > 1 ? "s" : ""); + p.second.summary = boost::regex_replace( + p.second.summary, + boost::regex("%isorare%"), + p.second.detail.size() > 1 ? "are" : "is"); + } + encode_health(new_checks, t); } version_t MDSMonitor::get_trim_to() @@ -741,8 +803,9 @@ void MDSMonitor::on_active() tick(); update_logger(); - if (mon->is_leader()) - mon->clog->info() << "fsmap " << fsmap; + if (mon->is_leader()) { + mon->clog->debug() << "fsmap " << fsmap; + } } void MDSMonitor::get_health(list >& summary, diff --git a/ceph/src/mon/MgrMap.h b/ceph/src/mon/MgrMap.h index 5a7d33397..3841840cf 100644 --- a/ceph/src/mon/MgrMap.h +++ b/ceph/src/mon/MgrMap.h @@ -25,9 +25,11 @@ class StandbyInfo public: uint64_t gid; std::string name; + std::set available_modules; - StandbyInfo(uint64_t gid_, const std::string &name_) - : gid(gid_), name(name_) + StandbyInfo(uint64_t gid_, const std::string &name_, + std::set& am) + : gid(gid_), name(name_), available_modules(am) {} StandbyInfo() @@ -36,17 +38,21 @@ public: void encode(bufferlist& bl) const { - ENCODE_START(1, 1, bl); + ENCODE_START(2, 1, bl); ::encode(gid, bl); ::encode(name, bl); + ::encode(available_modules, bl); ENCODE_FINISH(bl); } void decode(bufferlist::iterator& p) { - DECODE_START(1, p); + DECODE_START(2, p); ::decode(gid, p); ::decode(name, p); + if (struct_v >= 2) { + ::decode(available_modules, p); + } DECODE_FINISH(p); } }; @@ -68,33 +74,54 @@ public: std::map standbys; + std::set modules; + std::set available_modules; + epoch_t get_epoch() const { return epoch; } entity_addr_t get_active_addr() const { return active_addr; } uint64_t get_active_gid() const { return active_gid; } bool get_available() const { return available; } const std::string &get_active_name() const { return active_name; } + bool all_support_module(const std::string& module) { + if (!available_modules.count(module)) { + return false; + } + for (auto& p : standbys) { + if (!p.second.available_modules.count(module)) { + return false; + } + } + return true; + } + void encode(bufferlist& bl, uint64_t features) const { - ENCODE_START(1, 1, bl); + ENCODE_START(2, 1, bl); ::encode(epoch, bl); ::encode(active_addr, bl, features); ::encode(active_gid, bl); ::encode(available, bl); ::encode(active_name, bl); ::encode(standbys, bl); + ::encode(modules, bl); + ::encode(available_modules, bl); ENCODE_FINISH(bl); } void decode(bufferlist::iterator& p) { - DECODE_START(1, p); + DECODE_START(2, p); ::decode(epoch, p); ::decode(active_addr, p); ::decode(active_gid, p); ::decode(available, p); ::decode(active_name, p); ::decode(standbys, p); + if (struct_v >= 2) { + ::decode(modules, p); + ::decode(available_modules, p); + } DECODE_FINISH(p); } @@ -109,7 +136,22 @@ public: f->open_object_section("standby"); f->dump_int("gid", i.second.gid); f->dump_string("name", i.second.name); + f->open_array_section("available_modules"); + for (auto& j : i.second.available_modules) { + f->dump_string("module", j); + } f->close_section(); + f->close_section(); + } + f->close_section(); + f->open_array_section("modules"); + for (auto& i : modules) { + f->dump_string("module", i); + } + f->close_section(); + f->open_array_section("available_modules"); + for (auto& j : available_modules) { + f->dump_string("module", j); } f->close_section(); } diff --git a/ceph/src/mon/MgrMonitor.cc b/ceph/src/mon/MgrMonitor.cc index 863672afe..f06c256b2 100644 --- a/ceph/src/mon/MgrMonitor.cc +++ b/ceph/src/mon/MgrMonitor.cc @@ -11,6 +11,8 @@ * Foundation. See file COPYING. */ +#include + #include "messages/MMgrBeacon.h" #include "messages/MMgrMap.h" #include "messages/MMgrDigest.h" @@ -35,6 +37,11 @@ static ostream& _prefix(std::ostream *_dout, Monitor *mon, void MgrMonitor::create_initial() { + boost::tokenizer<> tok(g_conf->mgr_initial_modules); + for (auto& m : tok) { + pending_map.modules.insert(m); + } + dout(10) << __func__ << " initial modules " << pending_map.modules << dendl; } void MgrMonitor::update_from_paxos(bool *need_bootstrap) @@ -53,6 +60,10 @@ void MgrMonitor::update_from_paxos(bool *need_bootstrap) dout(4) << "active server: " << map.active_addr << "(" << map.active_gid << ")" << dendl; + ever_had_active_mgr = get_value("ever_had_active_mgr"); + + load_health(); + if (map.available) { first_seen_inactive = utime_t(); } else { @@ -72,6 +83,27 @@ void MgrMonitor::create_pending() pending_map.epoch++; } +health_status_t MgrMonitor::should_warn_about_mgr_down() +{ + utime_t now = ceph_clock_now(); + // we warn if + // - we've ever had an active mgr, or + // - we have osds AND we've exceeded the grace period + // which means a new mon cluster and be HEALTH_OK indefinitely as long as + // no OSDs are ever created. + if (ever_had_active_mgr || + (mon->osdmon()->osdmap.get_num_osds() > 0 && + now > mon->monmap->created + g_conf->mon_mgr_mkfs_grace)) { + health_status_t level = HEALTH_WARN; + if (first_seen_inactive != utime_t() && + now - first_seen_inactive > g_conf->mon_mgr_inactive_grace) { + level = HEALTH_ERR; + } + return level; + } + return HEALTH_OK; +} + void MgrMonitor::encode_pending(MonitorDBStore::TransactionRef t) { dout(10) << __func__ << " " << pending_map << dendl; @@ -79,6 +111,20 @@ void MgrMonitor::encode_pending(MonitorDBStore::TransactionRef t) pending_map.encode(bl, mon->get_quorum_con_features()); put_version(t, pending_map.epoch, bl); put_last_committed(t, pending_map.epoch); + + health_check_map_t next; + if (pending_map.active_gid == 0) { + auto level = should_warn_about_mgr_down(); + if (level != HEALTH_OK) { + next.add("MGR_DOWN", level, "no active mgr"); + } else { + dout(10) << __func__ << " no health warning (never active and new cluster)" + << dendl; + } + } else { + put_value(t, "ever_had_active_mgr", 1); + } + encode_health(next, t); } bool MgrMonitor::check_caps(MonOpRequestRef op, const uuid_d& fsid) @@ -174,6 +220,8 @@ bool MgrMonitor::prepare_beacon(MonOpRequestRef op) && m->get_gid() != pending_map.active_gid) { dout(4) << "Active daemon restart (mgr." << m->get_name() << ")" << dendl; + mon->clog->info() << "Active manager daemon " << m->get_name() + << " restarted"; drop_active(); } @@ -182,6 +230,8 @@ bool MgrMonitor::prepare_beacon(MonOpRequestRef op) const StandbyInfo &s = i.second; if (s.name == m->get_name() && s.gid != m->get_gid()) { dout(4) << "Standby daemon restart (mgr." << m->get_name() << ")" << dendl; + mon->clog->debug() << "Standby manager daemon " << m->get_name() + << " restarted"; drop_standby(i.first); break; } @@ -203,9 +253,17 @@ bool MgrMonitor::prepare_beacon(MonOpRequestRef op) if (pending_map.get_available() != m->get_available()) { dout(4) << "available " << m->get_gid() << dendl; + mon->clog->info() << "Manager daemon " << pending_map.active_name + << " is now available"; pending_map.available = m->get_available(); updated = true; } + if (pending_map.available_modules != m->get_available_modules()) { + dout(4) << "available_modules " << m->get_available_modules() + << " (was " << pending_map.available_modules << ")" << dendl; + pending_map.available_modules = m->get_available_modules(); + updated = true; + } } else if (pending_map.active_gid == 0) { // There is no currently active daemon, select this one. if (pending_map.standbys.count(m->get_gid())) { @@ -217,14 +275,29 @@ bool MgrMonitor::prepare_beacon(MonOpRequestRef op) << pending_map.active_name << ")" << dendl; pending_map.active_gid = m->get_gid(); pending_map.active_name = m->get_name(); + pending_map.available_modules = m->get_available_modules(); + + mon->clog->info() << "Activating manager daemon " + << pending_map.active_name; updated = true; } else { if (pending_map.standbys.count(m->get_gid()) > 0) { dout(10) << "from existing standby " << m->get_gid() << dendl; + if (pending_map.standbys[m->get_gid()].available_modules != + m->get_available_modules()) { + dout(10) << "existing standby " << m->get_gid() << " available_modules " + << m->get_available_modules() << " (was " + << pending_map.standbys[m->get_gid()].available_modules << ")" + << dendl; + pending_map.standbys[m->get_gid()].available_modules = + m->get_available_modules(); + updated = true; + } } else { dout(10) << "new standby " << m->get_gid() << dendl; - pending_map.standbys[m->get_gid()] = {m->get_gid(), m->get_name()}; + mon->clog->debug() << "Standby manager daemon " << m->get_name() + << " started"; updated = true; } } @@ -253,7 +326,8 @@ void MgrMonitor::check_sub(Subscription *sub) { if (sub->type == "mgrmap") { if (sub->next <= map.get_epoch()) { - dout(20) << "Sending map to subscriber " << sub->session->con << dendl; + dout(20) << "Sending map to subscriber " << sub->session->con + << " " << sub->session->con->get_peer_addr() << dendl; sub->session->con->send_message(new MMgrMap(map)); if (sub->onetime) { mon->session_map.remove_sub(sub); @@ -280,17 +354,19 @@ void MgrMonitor::send_digests() if (!is_active()) { return; } + dout(10) << __func__ << dendl; const std::string type = "mgrdigest"; if (mon->session_map.subs.count(type) == 0) return; for (auto sub : *(mon->session_map.subs[type])) { + dout(10) << __func__ << " sending digest to subscriber " << sub->session->con + << " " << sub->session->con->get_peer_addr() << dendl; MMgrDigest *mdigest = new MMgrDigest; JSONFormatter f; - std::list health_strs; - mon->get_health(health_strs, nullptr, &f); + mon->get_health_status(true, &f, nullptr, nullptr, nullptr); f.flush(mdigest->health_json); f.reset(); @@ -318,8 +394,9 @@ void MgrMonitor::cancel_timer() void MgrMonitor::on_active() { - if (mon->is_leader()) - mon->clog->info() << "mgrmap e" << map.epoch << ": " << map; + if (mon->is_leader()) { + mon->clog->debug() << "mgrmap e" << map.epoch << ": " << map; + } } void MgrMonitor::get_health( @@ -338,7 +415,7 @@ void MgrMonitor::get_health( return; } - if (!map.available) { + if (map.active_gid == 0) { auto level = HEALTH_WARN; // do not escalate to ERR if they are still upgrading to jewel. if (mon->osdmon()->osdmap.require_osd_release >= CEPH_RELEASE_LUMINOUS) { @@ -393,27 +470,48 @@ void MgrMonitor::tick() if (pending_map.active_gid != 0 && last_beacon.at(pending_map.active_gid) < cutoff) { - + const std::string old_active_name = pending_map.active_name; drop_active(); propose = true; dout(4) << "Dropping active" << pending_map.active_gid << dendl; if (promote_standby()) { dout(4) << "Promoted standby " << pending_map.active_gid << dendl; + mon->clog->info() << "Manager daemon " << old_active_name + << " is unresponsive, replacing it with standby" + << " daemon " << pending_map.active_name; } else { dout(4) << "Active is laggy but have no standbys to replace it" << dendl; + mon->clog->warn() << "Manager daemon " << old_active_name + << " is unresponsive. No standby daemons available."; } } else if (pending_map.active_gid == 0) { if (promote_standby()) { dout(4) << "Promoted standby " << pending_map.active_gid << dendl; + mon->clog->info() << "Activating manager daemon " + << pending_map.active_name; propose = true; } } + if (!pending_map.available && + should_warn_about_mgr_down() != HEALTH_OK) { + dout(10) << " exceeded mon_mgr_mkfs_grace " << g_conf->mon_mgr_mkfs_grace + << " seconds" << dendl; + propose = true; + } + if (propose) { propose_pending(); } } +void MgrMonitor::on_restart() +{ + // Clear out the leader-specific state. + last_beacon.clear(); +} + + bool MgrMonitor::promote_standby() { assert(pending_map.active_gid == 0); @@ -442,6 +540,10 @@ void MgrMonitor::drop_active() pending_map.active_gid = 0; pending_map.available = false; pending_map.active_addr = entity_addr_t(); + + // So that when new active mgr subscribes to mgrdigest, it will + // get an immediate response instead of waiting for next timer + cancel_timer(); } void MgrMonitor::drop_standby(uint64_t gid) @@ -500,6 +602,13 @@ bool MgrMonitor::preprocess_command(MonOpRequestRef op) f->dump_object("mgrmap", m); } f->flush(rdata); + } else if (prefix == "mgr module ls") { + f->open_array_section("modules"); + for (auto& p : map.modules) { + f->dump_string("module", p); + } + f->close_section(); + f->flush(rdata); } else { return false; } @@ -531,6 +640,10 @@ bool MgrMonitor::prepare_command(MonOpRequestRef op) return true; } + string format; + cmd_getval(g_ceph_context, cmdmap, "format", format, string("plain")); + boost::scoped_ptr f(Formatter::create(format)); + string prefix; cmd_getval(g_ceph_context, cmdmap, "prefix", prefix); @@ -578,10 +691,37 @@ bool MgrMonitor::prepare_command(MonOpRequestRef op) if (changed && pending_map.active_gid == 0) { promote_standby(); } + } else if (prefix == "mgr module enable") { + string module; + cmd_getval(g_ceph_context, cmdmap, "module", module); + if (module.empty()) { + r = -EINVAL; + goto out; + } + string force; + cmd_getval(g_ceph_context, cmdmap, "force", force); + if (!pending_map.all_support_module(module) && + force != "--force") { + ss << "all mgr daemons do not support module '" << module << "', pass " + << "--force to force enablement"; + r = -ENOENT; + goto out; + } + pending_map.modules.insert(module); + } else if (prefix == "mgr module disable") { + string module; + cmd_getval(g_ceph_context, cmdmap, "module", module); + if (module.empty()) { + r = -EINVAL; + goto out; + } + pending_map.modules.erase(module); } else { + ss << "Command '" << prefix << "' not implemented!"; r = -ENOSYS; } +out: dout(4) << __func__ << " done, r=" << r << dendl; /* Compose response */ string rs; diff --git a/ceph/src/mon/MgrMonitor.h b/ceph/src/mon/MgrMonitor.h index ea1a0a91a..0dc1af571 100644 --- a/ceph/src/mon/MgrMonitor.h +++ b/ceph/src/mon/MgrMonitor.h @@ -22,6 +22,7 @@ class MgrMonitor: public PaxosService { MgrMap map; MgrMap pending_map; + bool ever_had_active_mgr = false; utime_t first_seen_inactive; @@ -42,6 +43,8 @@ class MgrMonitor: public PaxosService bool check_caps(MonOpRequestRef op, const uuid_d& fsid); + health_status_t should_warn_about_mgr_down(); + public: MgrMonitor(Monitor *mn, Paxos *p, const string& service_name) : PaxosService(mn, p, service_name) @@ -76,6 +79,8 @@ public: void send_digests(); void on_active() override; + void on_restart() override; + void get_health(list >& summary, list > *detail, CephContext *cct) const override; diff --git a/ceph/src/mon/MgrStatMonitor.cc b/ceph/src/mon/MgrStatMonitor.cc index df92265d3..6a0606a4b 100644 --- a/ceph/src/mon/MgrStatMonitor.cc +++ b/ceph/src/mon/MgrStatMonitor.cc @@ -10,6 +10,7 @@ #include "messages/MMonMgrReport.h" #include "messages/MStatfs.h" #include "messages/MStatfsReply.h" +#include "messages/MServiceMap.h" class MgrPGStatService : public MonPGStatService { PGMapDigest& digest; @@ -70,31 +71,88 @@ MonPGStatService *MgrStatMonitor::get_pg_stat_service() void MgrStatMonitor::create_initial() { - dout(10) << dendl; + dout(10) << __func__ << dendl; version = 0; + service_map.epoch = 1; + ::encode(service_map, pending_service_map_bl, CEPH_FEATURES_ALL); } void MgrStatMonitor::update_from_paxos(bool *need_bootstrap) { version = get_last_committed(); dout(10) << " " << version << dendl; + load_health(); bufferlist bl; get_version(version, bl); if (version) { assert(bl.length()); - auto p = bl.begin(); - ::decode(digest, p); - ::decode(health_summary, p); - ::decode(health_detail, p); + try { + auto p = bl.begin(); + ::decode(digest, p); + ::decode(service_map, p); + dout(10) << __func__ << " v" << version + << " service_map e" << service_map.epoch << dendl; + } + catch (buffer::error& e) { + derr << "failed to decode mgrstat state; luminous dev version?" << dendl; + } + } + check_subs(); + update_logger(); +} + +void MgrStatMonitor::update_logger() +{ + dout(20) << __func__ << dendl; + if (mon->osdmon()->osdmap.require_osd_release < CEPH_RELEASE_LUMINOUS) { + dout(20) << "yielding cluster perfcounter updates to pgmon" << dendl; + return; + } + + mon->cluster_logger->set(l_cluster_osd_bytes, digest.osd_sum.kb * 1024ull); + mon->cluster_logger->set(l_cluster_osd_bytes_used, + digest.osd_sum.kb_used * 1024ull); + mon->cluster_logger->set(l_cluster_osd_bytes_avail, + digest.osd_sum.kb_avail * 1024ull); + + mon->cluster_logger->set(l_cluster_num_pool, digest.pg_pool_sum.size()); + uint64_t num_pg = 0; + for (auto i : digest.num_pg_by_pool) { + num_pg += i.second; } + mon->cluster_logger->set(l_cluster_num_pg, num_pg); + + unsigned active = 0, active_clean = 0, peering = 0; + for (auto p = digest.num_pg_by_state.begin(); + p != digest.num_pg_by_state.end(); + ++p) { + if (p->first & PG_STATE_ACTIVE) { + active += p->second; + if (p->first & PG_STATE_CLEAN) + active_clean += p->second; + } + if (p->first & PG_STATE_PEERING) + peering += p->second; + } + mon->cluster_logger->set(l_cluster_num_pg_active_clean, active_clean); + mon->cluster_logger->set(l_cluster_num_pg_active, active); + mon->cluster_logger->set(l_cluster_num_pg_peering, peering); + + mon->cluster_logger->set(l_cluster_num_object, digest.pg_sum.stats.sum.num_objects); + mon->cluster_logger->set(l_cluster_num_object_degraded, digest.pg_sum.stats.sum.num_objects_degraded); + mon->cluster_logger->set(l_cluster_num_object_misplaced, digest.pg_sum.stats.sum.num_objects_misplaced); + mon->cluster_logger->set(l_cluster_num_object_unfound, digest.pg_sum.stats.sum.num_objects_unfound); + mon->cluster_logger->set(l_cluster_num_bytes, digest.pg_sum.stats.sum.num_bytes); + } void MgrStatMonitor::create_pending() { dout(10) << " " << version << dendl; pending_digest = digest; - pending_health_summary = health_summary; - pending_health_detail = health_detail; + pending_health_checks = get_health_checks(); + pending_service_map_bl.clear(); + ::encode(service_map, pending_service_map_bl, mon->get_quorum_con_features()); } void MgrStatMonitor::encode_pending(MonitorDBStore::TransactionRef t) @@ -108,10 +166,12 @@ void MgrStatMonitor::encode_pending(MonitorDBStore::TransactionRef t) dout(10) << " " << version << dendl; bufferlist bl; ::encode(pending_digest, bl, mon->get_quorum_con_features()); - ::encode(pending_health_summary, bl); - ::encode(pending_health_detail, bl); + assert(pending_service_map_bl.length()); + bl.append(pending_service_map_bl); put_version(t, version, bl); put_last_committed(t, version); + + encode_health(pending_health_checks, t); } version_t MgrStatMonitor::get_trim_to() @@ -125,16 +185,13 @@ version_t MgrStatMonitor::get_trim_to() void MgrStatMonitor::on_active() { + update_logger(); } void MgrStatMonitor::get_health(list >& summary, list > *detail, CephContext *cct) const { - summary.insert(summary.end(), health_summary.begin(), health_summary.end()); - if (detail) { - detail->insert(detail->end(), health_detail.begin(), health_detail.end()); - } } void MgrStatMonitor::tick() @@ -187,9 +244,12 @@ bool MgrStatMonitor::prepare_report(MonOpRequestRef op) bufferlist bl = m->get_data(); auto p = bl.begin(); ::decode(pending_digest, p); - dout(10) << __func__ << " " << pending_digest << dendl; - pending_health_summary.swap(m->health_summary); - pending_health_detail.swap(m->health_detail); + pending_health_checks.swap(m->health_checks); + if (m->service_map_bl.length()) { + pending_service_map_bl.swap(m->service_map_bl); + } + dout(10) << __func__ << " " << pending_digest << ", " + << pending_health_checks.checks.size() << " health checks" << dendl; return true; } @@ -260,3 +320,40 @@ bool MgrStatMonitor::preprocess_statfs(MonOpRequestRef op) mon->send_reply(op, reply); return true; } + +void MgrStatMonitor::check_sub(Subscription *sub) +{ + const auto epoch = mon->monmap->get_epoch(); + dout(10) << __func__ + << " next " << sub->next + << " have " << epoch << dendl; + if (sub->next <= service_map.epoch) { + auto m = new MServiceMap(service_map); + sub->session->con->send_message(m); + if (sub->onetime) { + mon->with_session_map([this, sub](MonSessionMap& session_map) { + session_map.remove_sub(sub); + }); + } else { + sub->next = epoch + 1; + } + } +} + +void MgrStatMonitor::check_subs() +{ + dout(10) << __func__ << dendl; + if (!service_map.epoch) { + return; + } + auto subs = mon->session_map.subs.find("servicemap"); + if (subs == mon->session_map.subs.end()) { + return; + } + auto p = subs->second->begin(); + while (!p.end()) { + auto sub = *p; + ++p; + check_sub(sub); + } +} diff --git a/ceph/src/mon/MgrStatMonitor.h b/ceph/src/mon/MgrStatMonitor.h index 7ecbc9d37..c1846a544 100644 --- a/ceph/src/mon/MgrStatMonitor.h +++ b/ceph/src/mon/MgrStatMonitor.h @@ -6,6 +6,7 @@ #include "include/Context.h" #include "PaxosService.h" #include "mon/PGMap.h" +#include "mgr/ServiceMap.h" class MonPGStatService; class MgrPGStatService; @@ -14,13 +15,12 @@ class MgrStatMonitor : public PaxosService { // live version version_t version = 0; PGMapDigest digest; - list> health_summary; - list> health_detail; + ServiceMap service_map; // pending commit PGMapDigest pending_digest; - list> pending_health_summary; - list> pending_health_detail; + health_check_map_t pending_health_checks; + bufferlist pending_service_map_bl; std::unique_ptr pgservice; @@ -62,10 +62,14 @@ public: return digest.get_last_osd_stat_seq(osd); } + void update_logger(); void print_summary(Formatter *f, std::ostream *ss) const; MonPGStatService *get_pg_stat_service(); + const ServiceMap& get_service_map() { + return service_map; + } friend class C_Updated; }; diff --git a/ceph/src/mon/MonClient.cc b/ceph/src/mon/MonClient.cc index 6f9ab9e4a..bc5626dad 100644 --- a/ceph/src/mon/MonClient.cc +++ b/ceph/src/mon/MonClient.cc @@ -639,18 +639,24 @@ MonConnection& MonClient::_add_conn(unsigned rank, uint64_t global_id) void MonClient::_add_conns(uint64_t global_id) { - const unsigned num_mons = monmap.size(); - vector ranks(num_mons); - for (unsigned i = 0; i < num_mons; i++) { - ranks[i] = i; + uint16_t min_priority = std::numeric_limits::max(); + for (const auto& m : monmap.mon_info) { + if (m.second.priority < min_priority) { + min_priority = m.second.priority; + } + } + vector ranks; + for (const auto& m : monmap.mon_info) { + if (m.second.priority == min_priority) { + ranks.push_back(monmap.get_rank(m.first)); + } } std::random_device rd; std::mt19937 rng(rd()); std::shuffle(ranks.begin(), ranks.end(), rng); - unsigned n = cct->_conf->mon_client_hunt_parallel; - if (n == 0 || n > monmap.size()) { - n = num_mons; + if (n == 0 || n > ranks.size()) { + n = ranks.size(); } for (unsigned i = 0; i < n; i++) { _add_conn(ranks[i], global_id); diff --git a/ceph/src/mon/MonCommands.h b/ceph/src/mon/MonCommands.h index 00a1642e0..bd255fe5b 100644 --- a/ceph/src/mon/MonCommands.h +++ b/ceph/src/mon/MonCommands.h @@ -125,11 +125,13 @@ // note: this should be replaced shortly! COMMAND("pg force_create_pg name=pgid,type=CephPgid", \ "force creation of pg ", "pg", "rw", "cli,rest") -COMMAND("pg set_full_ratio name=ratio,type=CephFloat,range=0.0|1.0", \ - "set ratio at which pgs are considered full", "pg", "rw", "cli,rest") -COMMAND("pg set_nearfull_ratio name=ratio,type=CephFloat,range=0.0|1.0", \ - "set ratio at which pgs are considered nearly full", \ - "pg", "rw", "cli,rest") +COMMAND_WITH_FLAG("pg set_full_ratio name=ratio,type=CephFloat,range=0.0|1.0", \ + "set ratio at which pgs are considered full", \ + "pg", "rw", "cli,rest", FLAG(DEPRECATED)) +COMMAND_WITH_FLAG("pg set_nearfull_ratio " \ + "name=ratio,type=CephFloat,range=0.0|1.0", \ + "set ratio at which pgs are considered nearly full", \ + "pg", "rw", "cli,rest", FLAG(DEPRECATED)) COMMAND("pg map name=pgid,type=CephPgid", "show mapping of pg to osds", \ "pg", "r", "cli,rest") @@ -197,7 +199,10 @@ COMMAND_WITH_FLAG("scrub", "scrub the monitor stores", \ COMMAND("fsid", "show cluster FSID/UUID", "mon", "r", "cli,rest") COMMAND("log name=logtext,type=CephString,n=N", \ "log supplied text to the monitor log", "mon", "rw", "cli,rest") -COMMAND("log last name=num,type=CephInt,range=1,req=false", \ +COMMAND("log last " + "name=num,type=CephInt,range=1,req=false " + "name=level,type=CephChoices,strings=debug|info|sec|warn|error,req=false " + "name=channel,type=CephChoices,strings=*|cluster|audit,req=false", \ "print last few lines of the cluster log", \ "mon", "rw", "cli,rest") COMMAND_WITH_FLAG("injectargs " \ @@ -207,6 +212,7 @@ COMMAND_WITH_FLAG("injectargs " \ COMMAND("status", "show cluster status", "mon", "r", "cli,rest") COMMAND("health name=detail,type=CephChoices,strings=detail,req=false", \ "show cluster health", "mon", "r", "cli,rest") +COMMAND("time-sync-status", "show time sync status", "mon", "r", "cli,rest") COMMAND("df name=detail,type=CephChoices,strings=detail,req=false", \ "show cluster free space stats", "mon", "r", "cli,rest") COMMAND("report name=tags,type=CephString,n=N,req=false", \ @@ -301,7 +307,8 @@ COMMAND("mds compat show", "show mds compatibility settings", \ "mds", "r", "cli,rest") COMMAND_WITH_FLAG("mds stop name=who,type=CephString", "stop mds", \ "mds", "rw", "cli,rest", FLAG(DEPRECATED)) -COMMAND("mds deactivate name=who,type=CephString", "stop mds", \ +COMMAND("mds deactivate name=who,type=CephString", + "clean up specified MDS rank (use with `set max_mds` to shrink cluster)", \ "mds", "rw", "cli,rest") COMMAND_WITH_FLAG("mds set_max_mds " \ "name=maxmds,type=CephInt,range=0", \ @@ -320,7 +327,8 @@ COMMAND("mds set_state " \ "name=state,type=CephInt,range=0|20", \ "set mds state of to ", "mds", "rw", "cli,rest") COMMAND("mds fail name=who,type=CephString", \ - "force mds to status failed", "mds", "rw", "cli,rest") + "Mark MDS failed: trigger a failover if a standby is available", + "mds", "rw", "cli,rest") COMMAND("mds repaired name=rank,type=CephString", \ "mark a damaged MDS rank as no longer damaged", "mds", "rw", "cli,rest") COMMAND("mds rm " \ @@ -423,7 +431,7 @@ COMMAND("mon remove " \ COMMAND("mon rm " \ "name=name,type=CephString", \ "remove monitor named ", "mon", "rw", "cli,rest") -COMMAND("mon feature list " \ +COMMAND("mon feature ls " \ "name=with_value,type=CephChoices,strings=--with-value,req=false", \ "list available mon map features to be set/unset", \ "mon", "r", "cli,rest") @@ -522,9 +530,10 @@ COMMAND("osd crush add " \ "add or update crushmap position and weight for with and location ", \ "osd", "rw", "cli,rest") COMMAND("osd crush set-device-class " \ - "name=id,type=CephOsdName " \ - "name=class,type=CephString ", \ - "set the of the device ", \ + "name=class,type=CephString " \ + "name=ids,type=CephString,n=N", \ + "set the of the osd(s) [...]," \ + "or use to set all.", \ "osd", "rw", "cli,rest") COMMAND("osd crush create-or-move " \ "name=id,type=CephOsdName " \ @@ -597,6 +606,13 @@ COMMAND("osd crush rule create-simple " \ "name=mode,type=CephChoices,strings=firstn|indep,req=false", "create crush rule to start from , replicate across buckets of type , using a choose mode of (default firstn; indep best for erasure pools)", \ "osd", "rw", "cli,rest") +COMMAND("osd crush rule create-replicated " \ + "name=name,type=CephString,goodchars=[A-Za-z0-9-_.] " \ + "name=root,type=CephString,goodchars=[A-Za-z0-9-_.] " \ + "name=type,type=CephString,goodchars=[A-Za-z0-9-_.] " \ + "name=class,type=CephString,goodchars=[A-Za-z0-9-_.],req=false", + "create crush rule for replicated pool to start from , replicate across buckets of type , using a choose mode of (default firstn; indep best for erasure pools)", \ + "osd", "rw", "cli,rest") COMMAND("osd crush rule create-erasure " \ "name=name,type=CephString,goodchars=[A-Za-z0-9-_.] " \ "name=profile,type=CephString,req=false,goodchars=[A-Za-z0-9-_.=]", \ @@ -616,9 +632,18 @@ COMMAND("osd crush class rm " \ "name=class,type=CephString,goodchars=[A-Za-z0-9-_]", \ "remove crush device class ", \ "osd", "rw", "cli,rest") +COMMAND("osd crush class rename " \ + "name=srcname,type=CephString,goodchars=[A-Za-z0-9-_] " \ + "name=dstname,type=CephString,goodchars=[A-Za-z0-9-_]", \ + "rename crush device class to ", \ + "osd", "rw", "cli,rest") COMMAND("osd crush class ls", \ "list all crush device classes", \ "osd", "r", "cli,rest") +COMMAND("osd crush class ls-osd " \ + "name=class,type=CephString,goodchars=[A-Za-z0-9-_]", \ + "list all osds belonging to the specific ", \ + "osd", "r", "cli,rest") COMMAND("osd setmaxosd " \ "name=newmax,type=CephInt,range=0", \ "set new maximum osd value", "osd", "rw", "cli,rest") @@ -749,13 +774,12 @@ COMMAND("osd pg-temp " \ COMMAND("osd pg-upmap " \ "name=pgid,type=CephPgid " \ "name=id,type=CephOsdName,n=N", \ - "set pg_upmap mapping :[ [...]] primary (developers only)", \ + "set pg_upmap mapping :[ [...]] (developers only)", \ "osd", "rw", "cli,rest") COMMAND("osd rm-pg-upmap " \ "name=pgid,type=CephPgid", \ "clear pg_upmap mapping for (developers only)", \ "osd", "rw", "cli,rest") - COMMAND("osd pg-upmap-items " \ "name=pgid,type=CephPgid " \ "name=id,type=CephOsdName,n=N", \ @@ -834,7 +858,7 @@ COMMAND("osd pool create " \ COMMAND("osd pool delete " \ "name=pool,type=CephPoolname " \ "name=pool2,type=CephPoolname,req=false " \ - "name=sure,type=CephChoices,strings=--yes-i-really-really-mean-it,req=false", \ + "name=sure,type=CephString,req=false", \ "delete pool", \ "osd", "rw", "cli,rest") COMMAND("osd pool rm " \ @@ -849,11 +873,11 @@ COMMAND("osd pool rename " \ "rename to ", "osd", "rw", "cli,rest") COMMAND("osd pool get " \ "name=pool,type=CephPoolname " \ - "name=var,type=CephChoices,strings=size|min_size|crash_replay_interval|pg_num|pgp_num|crush_rule|hashpspool|nodelete|nopgchange|nosizechange|write_fadvise_dontneed|noscrub|nodeep-scrub|hit_set_type|hit_set_period|hit_set_count|hit_set_fpp|auid|target_max_objects|target_max_bytes|cache_target_dirty_ratio|cache_target_dirty_high_ratio|cache_target_full_ratio|cache_min_flush_age|cache_min_evict_age|erasure_code_profile|min_read_recency_for_promote|all|min_write_recency_for_promote|fast_read|hit_set_grade_decay_rate|hit_set_search_last_n|scrub_min_interval|scrub_max_interval|deep_scrub_interval|recovery_priority|recovery_op_priority|scrub_priority|compression_mode|compression_algorithm|compression_required_ratio|compression_max_blob_size|compression_min_blob_size|csum_type|csum_min_block|csum_max_block", \ + "name=var,type=CephChoices,strings=size|min_size|crash_replay_interval|pg_num|pgp_num|crush_rule|hashpspool|nodelete|nopgchange|nosizechange|write_fadvise_dontneed|noscrub|nodeep-scrub|hit_set_type|hit_set_period|hit_set_count|hit_set_fpp|use_gmt_hitset|auid|target_max_objects|target_max_bytes|cache_target_dirty_ratio|cache_target_dirty_high_ratio|cache_target_full_ratio|cache_min_flush_age|cache_min_evict_age|erasure_code_profile|min_read_recency_for_promote|all|min_write_recency_for_promote|fast_read|hit_set_grade_decay_rate|hit_set_search_last_n|scrub_min_interval|scrub_max_interval|deep_scrub_interval|recovery_priority|recovery_op_priority|scrub_priority|compression_mode|compression_algorithm|compression_required_ratio|compression_max_blob_size|compression_min_blob_size|csum_type|csum_min_block|csum_max_block", \ "get pool parameter ", "osd", "r", "cli,rest") COMMAND("osd pool set " \ "name=pool,type=CephPoolname " \ - "name=var,type=CephChoices,strings=size|min_size|crash_replay_interval|pg_num|pgp_num|crush_rule|hashpspool|nodelete|nopgchange|nosizechange|write_fadvise_dontneed|noscrub|nodeep-scrub|hit_set_type|hit_set_period|hit_set_count|hit_set_fpp|use_gmt_hitset|debug_fake_ec_pool|target_max_bytes|target_max_objects|cache_target_dirty_ratio|cache_target_dirty_high_ratio|cache_target_full_ratio|cache_min_flush_age|cache_min_evict_age|auid|min_read_recency_for_promote|min_write_recency_for_promote|fast_read|hit_set_grade_decay_rate|hit_set_search_last_n|scrub_min_interval|scrub_max_interval|deep_scrub_interval|recovery_priority|recovery_op_priority|scrub_priority|compression_mode|compression_algorithm|compression_required_ratio|compression_max_blob_size|compression_min_blob_size|csum_type|csum_min_block|csum_max_block|allow_ec_overwrites " \ + "name=var,type=CephChoices,strings=size|min_size|crash_replay_interval|pg_num|pgp_num|crush_rule|hashpspool|nodelete|nopgchange|nosizechange|write_fadvise_dontneed|noscrub|nodeep-scrub|hit_set_type|hit_set_period|hit_set_count|hit_set_fpp|use_gmt_hitset|target_max_bytes|target_max_objects|cache_target_dirty_ratio|cache_target_dirty_high_ratio|cache_target_full_ratio|cache_min_flush_age|cache_min_evict_age|auid|min_read_recency_for_promote|min_write_recency_for_promote|fast_read|hit_set_grade_decay_rate|hit_set_search_last_n|scrub_min_interval|scrub_max_interval|deep_scrub_interval|recovery_priority|recovery_op_priority|scrub_priority|compression_mode|compression_algorithm|compression_required_ratio|compression_max_blob_size|compression_min_blob_size|csum_type|csum_min_block|csum_max_block|allow_ec_overwrites " \ "name=val,type=CephString " \ "name=force,type=CephChoices,strings=--yes-i-really-mean-it,req=false", \ "set pool parameter to ", "osd", "rw", "cli,rest") @@ -943,6 +967,15 @@ COMMAND("config-key dump", "dump keys and values", "config-key", "r", "cli,rest" COMMAND("mgr dump " \ "name=epoch,type=CephInt,range=0,req=false", \ "dump the latest MgrMap", \ - "mgr", "rw", "cli,rest") + "mgr", "r", "cli,rest") COMMAND("mgr fail name=who,type=CephString", \ "treat the named manager daemon as failed", "mgr", "rw", "cli,rest") +COMMAND("mgr module ls", + "list active mgr modules", "mgr", "r", "cli,rest") +COMMAND("mgr module enable " \ + "name=module,type=CephString " \ + "name=force,type=CephChoices,strings=--force,req=false", + "enable mgr module", "mgr", "rw", "cli,rest") +COMMAND("mgr module disable " \ + "name=module,type=CephString", + "disable mgr module", "mgr", "rw", "cli,rest") diff --git a/ceph/src/mon/MonMap.cc b/ceph/src/mon/MonMap.cc index 836c6901c..218df9aa8 100644 --- a/ceph/src/mon/MonMap.cc +++ b/ceph/src/mon/MonMap.cc @@ -20,9 +20,10 @@ using ceph::Formatter; void mon_info_t::encode(bufferlist& bl, uint64_t features) const { - ENCODE_START(1, 1, bl); + ENCODE_START(2, 1, bl); ::encode(name, bl); ::encode(public_addr, bl, features); + ::encode(priority, bl); ENCODE_FINISH(bl); } @@ -31,13 +32,17 @@ void mon_info_t::decode(bufferlist::iterator& p) DECODE_START(1, p); ::decode(name, p); ::decode(public_addr, p); + if (struct_v >= 2) { + ::decode(priority, p); + } DECODE_FINISH(p); } void mon_info_t::print(ostream& out) const { out << "mon." << name - << " public " << public_addr; + << " public " << public_addr + << " priority " << priority; } void MonMap::sanitize_mons(map& o) @@ -247,7 +252,7 @@ void MonMap::generate_test_instances(list& o) entity_addr_t local_pub_addr; local_pub_addr.parse(local_pub_addr_s, &end_p); - m->add("filled_pub_addr", local_pub_addr); + m->add(mon_info_t("filled_pub_addr", local_pub_addr, 1)); m->add("empty_addr_zero", entity_addr_t()); } @@ -510,13 +515,23 @@ int MonMap::build_initial(CephContext *cct, ostream& errout) if (addr.get_port() == 0) addr.set_port(CEPH_MON_PORT); + uint16_t priority = 0; + if (!conf->get_val_from_conf_file(sections, "mon priority", val, false)) { + try { + priority = std::stoul(val); + } catch (std::logic_error&) { + errout << "unable to parse priority for mon." << *m + << ": priority='" << val << "'" << std::endl; + continue; + } + } // the make sure this mon isn't already in the map if (contains(addr)) remove(get_name(addr)); if (contains(*m)) remove(*m); - add(m->c_str(), addr); + add(mon_info_t{*m, addr, priority}); } if (size() == 0) { @@ -530,16 +545,18 @@ int MonMap::build_initial(CephContext *cct, ostream& errout) srv_name = srv_name.substr(0, idx); } - map addrs; + map records; if (DNSResolver::get_instance()->resolve_srv_hosts(cct, srv_name, - DNSResolver::SRV_Protocol::TCP, domain, &addrs) != 0) { + DNSResolver::SRV_Protocol::TCP, domain, &records) != 0) { errout << "unable to get monitor info from DNS SRV with service name: " << "ceph-mon" << std::endl; } else { - for (const auto& addr : addrs) { - add(addr.first, addr.second); + for (const auto& record : records) { + add(mon_info_t{record.first, + record.second.addr, + record.second.priority}); } } } diff --git a/ceph/src/mon/MonMap.h b/ceph/src/mon/MonMap.h index 52b4e232f..63cc22090 100644 --- a/ceph/src/mon/MonMap.h +++ b/ceph/src/mon/MonMap.h @@ -39,8 +39,15 @@ struct mon_info_t { * and other monitors. */ entity_addr_t public_addr; + /** + * the priority of the mon, the lower value the more preferred + */ + uint16_t priority{0}; - mon_info_t(string &n, entity_addr_t& p_addr) + mon_info_t(const string& n, const entity_addr_t& p_addr, uint16_t p) + : name(n), public_addr(p_addr), priority(p) + {} + mon_info_t(const string &n, const entity_addr_t& p_addr) : name(n), public_addr(p_addr) { } @@ -136,6 +143,18 @@ public: } } + /** + * Add new monitor to the monmap + * + * @param m monitor info of the new monitor + */ + void add(mon_info_t &&m) { + assert(mon_info.count(m.name) == 0); + assert(addr_mons.count(m.public_addr) == 0); + mon_info[m.name] = std::move(m); + calc_ranks(); + } + /** * Add new monitor to the monmap * @@ -143,14 +162,9 @@ public: * @param addr Monitor's public address */ void add(const string &name, const entity_addr_t &addr) { - assert(mon_info.count(name) == 0); - assert(addr_mons.count(addr) == 0); - mon_info_t &m = mon_info[name]; - m.name = name; - m.public_addr = addr; - calc_ranks(); + add(mon_info_t(name, addr)); } - + /** * Remove monitor from the monmap * diff --git a/ceph/src/mon/Monitor.cc b/ceph/src/mon/Monitor.cc index 9a7304fca..9421b4cbf 100644 --- a/ceph/src/mon/Monitor.cc +++ b/ceph/src/mon/Monitor.cc @@ -77,6 +77,7 @@ #include "MgrMonitor.h" #include "MgrStatMonitor.h" #include "mon/QuorumService.h" +#include "mon/OldHealthMonitor.h" #include "mon/HealthMonitor.h" #include "mon/ConfigKeyService.h" #include "common/config.h" @@ -204,8 +205,9 @@ Monitor::Monitor(CephContext* cct_, string nm, MonitorDBStore *s, paxos_service[PAXOS_AUTH] = new AuthMonitor(this, paxos, "auth"); paxos_service[PAXOS_MGR] = new MgrMonitor(this, paxos, "mgr"); paxos_service[PAXOS_MGRSTAT] = new MgrStatMonitor(this, paxos, "mgrstat"); + paxos_service[PAXOS_HEALTH] = new HealthMonitor(this, paxos, "health"); - health_monitor = new HealthMonitor(this); + health_monitor = new OldHealthMonitor(this); config_key_service = new ConfigKeyService(this, paxos); mon_caps = new MonCap(); @@ -227,27 +229,6 @@ Monitor::Monitor(CephContext* cct_, string nm, MonitorDBStore *s, pgservice = mgrstatmon()->get_pg_stat_service(); } -PaxosService *Monitor::get_paxos_service_by_name(const string& name) -{ - if (name == "mdsmap") - return paxos_service[PAXOS_MDSMAP]; - if (name == "monmap") - return paxos_service[PAXOS_MONMAP]; - if (name == "osdmap") - return paxos_service[PAXOS_OSDMAP]; - if (name == "pgmap") - return paxos_service[PAXOS_PGMAP]; - if (name == "logm") - return paxos_service[PAXOS_LOG]; - if (name == "auth") - return paxos_service[PAXOS_AUTH]; - if (name == "mgr") - return paxos_service[PAXOS_MGR]; - - assert(0 == "given name does not match known paxos service"); - return NULL; -} - Monitor::~Monitor() { for (vector::iterator p = paxos_service.begin(); p != paxos_service.end(); ++p) @@ -296,7 +277,8 @@ void Monitor::do_admin_command(string command, cmdmap_t& cmdmap, string format, bool read_only = (command == "mon_status" || command == "mon metadata" || command == "quorum_status" || - command == "ops"); + command == "ops" || + command == "sessions"); (read_only ? audit_clog->debug() : audit_clog->info()) << "from='admin socket' entity='admin socket' " @@ -334,6 +316,17 @@ void Monitor::do_admin_command(string command, cmdmap_t& cmdmap, string format, if (f) { f->flush(ss); } + } else if (command == "sessions") { + + if (f) { + f->open_array_section("sessions"); + for (auto p : session_map.sessions) { + f->dump_stream("session") << *p; + } + f->close_section(); + f->flush(ss); + } + } else { assert(0 == "bad AdminSocket command binding"); } @@ -768,6 +761,11 @@ int Monitor::preinit() admin_hook, "show the ops currently in flight"); assert(r == 0); + r = admin_socket->register_command("sessions", + "sessions", + admin_hook, + "list existing sessions"); + assert(r == 0); lock.Lock(); @@ -846,6 +844,7 @@ void Monitor::refresh_from_paxos(bool *need_bootstrap) for (int i = 0; i < PAXOS_NUM; ++i) { paxos_service[i]->post_refresh(); } + load_metadata(); } void Monitor::register_cluster_logger() @@ -897,6 +896,7 @@ void Monitor::shutdown() admin_socket->unregister_command("quorum enter"); admin_socket->unregister_command("quorum exit"); admin_socket->unregister_command("ops"); + admin_socket->unregister_command("sessions"); delete admin_hook; admin_hook = NULL; } @@ -1421,8 +1421,10 @@ void Monitor::handle_sync_get_chunk(MonOpRequestRef op) while (sp.last_committed < paxos->get_version() && left > 0) { bufferlist bl; sp.last_committed++; - store->get(paxos->get_name(), sp.last_committed, bl); - // TODO: what if store->get returns error or empty bl? + + int err = store->get(paxos->get_name(), sp.last_committed, bl); + assert(err == 0); + tx->put(paxos->get_name(), sp.last_committed, bl); left -= bl.length(); dout(20) << __func__ << " including paxos state " << sp.last_committed @@ -1867,12 +1869,16 @@ void Monitor::win_standalone_election() set q; q.insert(rank); - const MonCommand *my_cmds; - int cmdsize; + map metadata; + collect_metadata(&metadata[0]); + + const MonCommand *my_cmds = nullptr; + int cmdsize = 0; get_locally_supported_monitor_commands(&my_cmds, &cmdsize); win_election(elector.get_epoch(), q, CEPH_FEATURES_ALL, ceph::features::mon::get_supported(), + metadata, my_cmds, cmdsize); } @@ -1901,6 +1907,7 @@ void Monitor::_finish_svc_election() void Monitor::win_election(epoch_t epoch, set& active, uint64_t features, const mon_feature_t& mon_features, + const map& metadata, const MonCommand *cmdset, int cmdsize) { dout(10) << __func__ << " epoch " << epoch << " quorum " << active @@ -1914,6 +1921,7 @@ void Monitor::win_election(epoch_t epoch, set& active, uint64_t features, quorum = active; quorum_con_features = features; quorum_mon_features = mon_features; + pending_metadata = metadata; outside_quorum.clear(); clog->info() << "mon." << name << "@" << rank @@ -1933,6 +1941,27 @@ void Monitor::win_election(epoch_t epoch, set& active, uint64_t features, logger->inc(l_mon_election_win); + // inject new metadata in first transaction. + { + // include previous metadata for missing mons (that aren't part of + // the current quorum). + map m = metadata; + for (unsigned rank = 0; rank < monmap->size(); ++rank) { + if (m.count(rank) == 0 && + mon_metadata.count(rank)) { + m[rank] = mon_metadata[rank]; + } + } + + // FIXME: This is a bit sloppy because we aren't guaranteed to submit + // a new transaction immediately after the election finishes. We should + // do that anyway for other reasons, though. + MonitorDBStore::TransactionRef t = paxos->get_pending_transaction(); + bufferlist bl; + ::encode(m, bl); + t->put(MONITOR_STORE_PREFIX, "last_metadata", bl); + } + finish_election(); if (monmap->size() > 1 && monmap->get_epoch() > 0) { @@ -1941,11 +1970,6 @@ void Monitor::win_election(epoch_t epoch, set& active, uint64_t features, do_health_to_clog_interval(); scrub_event_start(); } - - Metadata my_meta; - collect_sys_info(&my_meta, g_ceph_context); - my_meta["addr"] = stringify(messenger->get_myaddr()); - update_mon_metadata(rank, std::move(my_meta)); } void Monitor::lose_election(epoch_t epoch, set &q, int l, @@ -1972,14 +1996,22 @@ void Monitor::lose_election(epoch_t epoch, set &q, int l, finish_election(); - if (quorum_con_features & CEPH_FEATURE_MON_METADATA) { + if ((quorum_con_features & CEPH_FEATURE_MON_METADATA) && + !HAVE_FEATURE(quorum_con_features, SERVER_LUMINOUS)) { + // for pre-luminous mons only Metadata sys_info; - collect_sys_info(&sys_info, g_ceph_context); + collect_metadata(&sys_info); messenger->send_message(new MMonMetadata(sys_info), monmap->get_inst(get_leader())); } } +void Monitor::collect_metadata(Metadata *m) +{ + collect_sys_info(m, g_ceph_context); + (*m)["addr"] = stringify(messenger->get_myaddr()); +} + void Monitor::finish_election() { apply_quorum_to_compatset_features(); @@ -2392,27 +2424,180 @@ void Monitor::do_health_to_clog(bool force) dout(10) << __func__ << (force ? " (force)" : "") << dendl; - list status; - health_status_t overall = get_health(status, NULL, NULL); + if (osdmon()->osdmap.require_osd_release >= CEPH_RELEASE_LUMINOUS) { + string summary; + health_status_t level = get_health_status(false, nullptr, &summary); + if (!force && + summary == health_status_cache.summary && + level == health_status_cache.overall) + return; + if (level == HEALTH_OK) + clog->info() << "overall " << summary; + else if (level == HEALTH_WARN) + clog->warn() << "overall " << summary; + else if (level == HEALTH_ERR) + clog->error() << "overall " << summary; + else + ceph_abort(); + health_status_cache.summary = summary; + health_status_cache.overall = level; + } else { + // for jewel only + list status; + health_status_t overall = get_health(status, NULL, NULL); + dout(25) << __func__ + << (force ? " (force)" : "") + << dendl; - dout(25) << __func__ - << (force ? " (force)" : "") - << dendl; + string summary = joinify(status.begin(), status.end(), string("; ")); + + if (!force && + overall == health_status_cache.overall && + !health_status_cache.summary.empty() && + health_status_cache.summary == summary) { + // we got a dup! + return; + } + + clog->info() << summary; + + health_status_cache.overall = overall; + health_status_cache.summary = summary; + } +} + +health_status_t Monitor::get_health_status( + bool want_detail, + Formatter *f, + std::string *plain, + const char *sep1, + const char *sep2) +{ + health_status_t r = HEALTH_OK; + bool compat = g_conf->mon_health_preluminous_compat; + if (f) { + f->open_object_section("health"); + f->open_object_section("checks"); + } + + string summary; + string *psummary = f ? nullptr : &summary; + for (auto& svc : paxos_service) { + r = std::min(r, svc->get_health_checks().dump_summary( + f, psummary, sep2, want_detail)); + } + + if (f) { + f->close_section(); + f->dump_stream("status") << r; + } else { + // one-liner: HEALTH_FOO[ thing1[; thing2 ...]] + *plain = stringify(r); + if (summary.size()) { + *plain += sep1; + *plain += summary; + } + *plain += "\n"; + } - string summary = joinify(status.begin(), status.end(), string("; ")); + if (f && compat) { + f->open_array_section("summary"); + for (auto& svc : paxos_service) { + svc->get_health_checks().dump_summary_compat(f); + } + f->close_section(); + f->dump_stream("overall_status") << r; + } + + if (want_detail) { + if (f && compat) { + f->open_array_section("detail"); + } + + for (auto& svc : paxos_service) { + svc->get_health_checks().dump_detail(f, plain, compat); + } + + if (f && compat) { + f->close_section(); + } + } + if (f) { + f->close_section(); + } + return r; +} - if (!force && - overall == health_status_cache.overall && - !health_status_cache.summary.empty() && - health_status_cache.summary == summary) { - // we got a dup! +void Monitor::log_health( + const health_check_map_t& updated, + const health_check_map_t& previous, + MonitorDBStore::TransactionRef t) +{ + if (!g_conf->mon_health_to_clog) { return; } + // FIXME: log atomically as part of @t instead of using clog. + dout(10) << __func__ << " updated " << updated.checks.size() + << " previous " << previous.checks.size() + << dendl; + for (auto& p : updated.checks) { + auto q = previous.checks.find(p.first); + if (q == previous.checks.end()) { + // new + ostringstream ss; + ss << "Health check failed: " << p.second.summary << " (" + << p.first << ")"; + if (p.second.severity == HEALTH_WARN) + clog->warn() << ss.str(); + else + clog->error() << ss.str(); + } else { + if (p.second.summary != q->second.summary || + p.second.severity != q->second.severity) { + // summary or severity changed (ignore detail changes at this level) + ostringstream ss; + ss << "Health check update: " << p.second.summary << " (" << p.first << ")"; + if (p.second.severity == HEALTH_WARN) + clog->warn() << ss.str(); + else + clog->error() << ss.str(); + } + } + } + for (auto& p : previous.checks) { + if (!updated.checks.count(p.first)) { + // cleared + ostringstream ss; + if (p.first == "DEGRADED_OBJECTS") { + clog->info() << "All degraded objects recovered"; + } else if (p.first == "OSD_FLAGS") { + clog->info() << "OSD flags cleared"; + } else { + clog->info() << "Health check cleared: " << p.first << " (was: " + << p.second.summary << ")"; + } + } + } - clog->info() << summary; + if (previous.checks.size() && updated.checks.size() == 0) { + // We might be going into a fully healthy state, check + // other subsystems + bool any_checks = false; + for (auto& svc : paxos_service) { + if (&(svc->get_health_checks()) == &(previous)) { + // Ignore the ones we're clearing right now + continue; + } - health_status_cache.overall = overall; - health_status_cache.summary = summary; + if (svc->get_health_checks().checks.size() > 0) { + any_checks = true; + break; + } + } + if (!any_checks) { + clog->info() << "Cluster is now healthy"; + } + } } health_status_t Monitor::get_health(list& status, @@ -2432,52 +2617,29 @@ health_status_t Monitor::get_health(list& status, s->get_health(summary, detailbl ? &detail : NULL, cct); } - health_monitor->get_health(f, summary, (detailbl ? &detail : NULL)); - - if (f) { - f->open_object_section("timechecks"); - f->dump_unsigned("epoch", get_epoch()); - f->dump_int("round", timecheck_round); - f->dump_stream("round_status") - << ((timecheck_round%2) ? "on-going" : "finished"); - } + health_monitor->get_health(summary, (detailbl ? &detail : NULL)); health_status_t overall = HEALTH_OK; if (!timecheck_skews.empty()) { list warns; - if (f) - f->open_array_section("mons"); for (map::iterator i = timecheck_skews.begin(); i != timecheck_skews.end(); ++i) { entity_inst_t inst = i->first; double skew = i->second; double latency = timecheck_latencies[inst]; string name = monmap->get_name(inst.addr); - ostringstream tcss; health_status_t tcstatus = timecheck_status(tcss, skew, latency); if (tcstatus != HEALTH_OK) { if (overall > tcstatus) overall = tcstatus; warns.push_back(name); - ostringstream tmp_ss; tmp_ss << "mon." << name << " addr " << inst.addr << " " << tcss.str() << " (latency " << latency << "s)"; detail.push_back(make_pair(tcstatus, tmp_ss.str())); } - - if (f) { - f->open_object_section("mon"); - f->dump_string("name", name.c_str()); - f->dump_float("skew", skew); - f->dump_float("latency", latency); - f->dump_stream("health") << tcstatus; - if (tcstatus != HEALTH_OK) - f->dump_stream("details") << tcss.str(); - f->close_section(); - } } if (!warns.empty()) { ostringstream ss; @@ -2491,11 +2653,7 @@ health_status_t Monitor::get_health(list& status, status.push_back(ss.str()); summary.push_back(make_pair(HEALTH_WARN, "Monitor clock skew detected ")); } - if (f) - f->close_section(); } - if (f) - f->close_section(); if (f) f->open_array_section("summary"); @@ -2547,12 +2705,9 @@ void Monitor::get_cluster_status(stringstream &ss, Formatter *f) if (f) f->open_object_section("status"); - // reply with the status for all the components - list health; - get_health(health, NULL, f); - if (f) { f->dump_stream("fsid") << monmap->get_fsid(); + get_health_status(false, f, nullptr); f->dump_unsigned("election_epoch", get_epoch()); { f->open_array_section("quorum"); @@ -2568,7 +2723,7 @@ void Monitor::get_cluster_status(stringstream &ss, Formatter *f) monmap->dump(f); f->close_section(); f->open_object_section("osdmap"); - osdmon()->osdmap.print_summary(f, cout); + osdmon()->osdmap.print_summary(f, cout, string(12, ' ')); f->close_section(); f->open_object_section("pgmap"); pgservice->print_summary(f, NULL); @@ -2576,43 +2731,67 @@ void Monitor::get_cluster_status(stringstream &ss, Formatter *f) f->open_object_section("fsmap"); mdsmon()->get_fsmap().print_summary(f, NULL); f->close_section(); - f->open_object_section("mgrmap"); mgrmon()->get_map().print_summary(f, nullptr); f->close_section(); + + f->dump_object("servicemap", mgrstatmon()->get_service_map()); f->close_section(); } else { - ss << " cluster:\n"; ss << " id: " << monmap->get_fsid() << "\n"; - ss << " health: " << joinify(health.begin(), health.end(), - string("\n ")) << "\n"; + + string health; + if (osdmon()->osdmap.require_osd_release >= CEPH_RELEASE_LUMINOUS) { + get_health_status(false, nullptr, &health, + "\n ", "\n "); + } else { + list ls; + get_health(ls, NULL, f); + health = joinify(ls.begin(), ls.end(), + string("\n ")); + } + ss << " health: " << health << "\n"; + ss << "\n \n services:\n"; - const auto quorum_names = get_quorum_names(); - const auto mon_count = monmap->mon_info.size(); - ss << " mon: " << mon_count << " daemons, quorum " - << quorum_names; - if (quorum_names.size() != mon_count) { - std::list out_of_q; - for (size_t i = 0; i < monmap->ranks.size(); ++i) { - if (quorum.count(i) == 0) { - out_of_q.push_back(monmap->ranks[i]); - } + { + size_t maxlen = 3; + auto& service_map = mgrstatmon()->get_service_map(); + for (auto& p : service_map.services) { + maxlen = std::max(maxlen, p.first.size()); + } + string spacing(maxlen - 3, ' '); + const auto quorum_names = get_quorum_names(); + const auto mon_count = monmap->mon_info.size(); + ss << " mon: " << spacing << mon_count << " daemons, quorum " + << quorum_names; + if (quorum_names.size() != mon_count) { + std::list out_of_q; + for (size_t i = 0; i < monmap->ranks.size(); ++i) { + if (quorum.count(i) == 0) { + out_of_q.push_back(monmap->ranks[i]); + } + } + ss << ", out of quorum: " << joinify(out_of_q.begin(), + out_of_q.end(), std::string(", ")); } - ss << ", out of quorum: " << joinify(out_of_q.begin(), - out_of_q.end(), std::string(", ")); - } - ss << "\n"; - if (mgrmon()->in_use()) { - ss << " mgr: "; - mgrmon()->get_map().print_summary(nullptr, &ss); ss << "\n"; + if (mgrmon()->in_use()) { + ss << " mgr: " << spacing; + mgrmon()->get_map().print_summary(nullptr, &ss); + ss << "\n"; + } + if (mdsmon()->get_fsmap().filesystem_count() > 0) { + ss << " mds: " << spacing << mdsmon()->get_fsmap() << "\n"; + } + ss << " osd: " << spacing; + osdmon()->osdmap.print_summary(NULL, ss, string(maxlen + 6, ' ')); + ss << "\n"; + for (auto& p : service_map.services) { + ss << " " << p.first << ": " << string(maxlen - p.first.size(), ' ') + << p.second.get_summary() << "\n"; + } } - if (mdsmon()->get_fsmap().filesystem_count() > 0) { - ss << " mds: " << mdsmon()->get_fsmap() << "\n"; - } - ss << " osd: "; - osdmon()->osdmap.print_summary(NULL, ss); ss << "\n \n data:\n"; pgservice->print_summary(NULL, &ss); @@ -3026,7 +3205,7 @@ void Monitor::handle_command(MonOpRequestRef op) end -= start; dout(1) << "finished manual compaction in " << end << " seconds" << dendl; ostringstream oss; - oss << "compacted leveldb in " << end; + oss << "compacted " << g_conf->get_val("mon_keyvaluedb") << " in " << end << " seconds"; rs = oss.str(); r = 0; } @@ -3044,6 +3223,40 @@ void Monitor::handle_command(MonOpRequestRef op) rs = "must supply options to be parsed in a single string"; r = -EINVAL; } + } else if (prefix == "time-sync-status") { + if (!f) + f.reset(Formatter::create("json-pretty")); + f->open_object_section("time_sync"); + if (!timecheck_skews.empty()) { + f->open_object_section("time_skew_status"); + for (auto& i : timecheck_skews) { + entity_inst_t inst = i.first; + double skew = i.second; + double latency = timecheck_latencies[inst]; + string name = monmap->get_name(inst.addr); + ostringstream tcss; + health_status_t tcstatus = timecheck_status(tcss, skew, latency); + f->open_object_section(name.c_str()); + f->dump_float("skew", skew); + f->dump_float("latency", latency); + f->dump_stream("health") << tcstatus; + if (tcstatus != HEALTH_OK) { + f->dump_stream("details") << tcss.str(); + } + f->close_section(); + } + f->close_section(); + } + f->open_object_section("timechecks"); + f->dump_unsigned("epoch", get_epoch()); + f->dump_int("round", timecheck_round); + f->dump_stream("round_status") << ((timecheck_round%2) ? + "on-going" : "finished"); + f->close_section(); + f->close_section(); + f->flush(rdata); + r = 0; + rs = ""; } else if (prefix == "status" || prefix == "health" || prefix == "df") { @@ -3060,25 +3273,35 @@ void Monitor::handle_command(MonOpRequestRef op) } rdata.append(ds); } else if (prefix == "health") { - list health_str; - get_health(health_str, detail == "detail" ? &rdata : NULL, f.get()); - if (f) { - f->flush(ds); - ds << '\n'; + if (osdmon()->osdmap.require_osd_release >= CEPH_RELEASE_LUMINOUS) { + string plain; + get_health_status(detail == "detail", f.get(), f ? nullptr : &plain); + if (f) { + f->flush(rdata); + } else { + rdata.append(plain); + } } else { - assert(!health_str.empty()); - ds << health_str.front(); - health_str.pop_front(); - if (!health_str.empty()) { - ds << ' '; - ds << joinify(health_str.begin(), health_str.end(), string("; ")); + list health_str; + get_health(health_str, detail == "detail" ? &rdata : NULL, f.get()); + if (f) { + f->flush(ds); + ds << '\n'; + } else { + assert(!health_str.empty()); + ds << health_str.front(); + health_str.pop_front(); + if (!health_str.empty()) { + ds << ' '; + ds << joinify(health_str.begin(), health_str.end(), string("; ")); + } } + bufferlist comb; + comb.append(ds); + if (detail == "detail") + comb.append(rdata); + rdata = comb; } - bufferlist comb; - comb.append(ds); - if (detail == "detail") - comb.append(rdata); - rdata = comb; } else if (prefix == "df") { bool verbose = (detail == "detail"); if (f) @@ -3648,7 +3871,8 @@ void Monitor::resend_routed_requests() void Monitor::remove_session(MonSession *s) { - dout(10) << "remove_session " << s << " " << s->inst << dendl; + dout(10) << "remove_session " << s << " " << s->inst + << " features 0x" << std::hex << s->con_features << std::dec << dendl; assert(s->con); assert(!s->closed); for (set::iterator p = s->routed_request_tids.begin(); @@ -3741,6 +3965,30 @@ void Monitor::_ms_dispatch(Message *m) if (s && s->closed) { return; } + + if (src_is_mon && s) { + ConnectionRef con = m->get_connection(); + if (con->get_messenger() && con->get_features() != s->con_features) { + // only update features if this is a non-anonymous connection + dout(10) << __func__ << " feature change for " << m->get_source_inst() + << " (was " << s->con_features + << ", now " << con->get_features() << ")" << dendl; + // connection features changed - recreate session. + if (s->con && s->con != con) { + dout(10) << __func__ << " connection for " << m->get_source_inst() + << " changed from session; mark down and replace" << dendl; + s->con->mark_down(); + } + if (s->item.is_on_list()) { + // forwarded messages' sessions are not in the sessions map and + // exist only while the op is being handled. + remove_session(s); + } + s->put(); + s = nullptr; + } + } + if (!s) { // if the sender is not a monitor, make sure their first message for a // session is an MAuth. If it is not, assume it's a stray message, @@ -3762,7 +4010,9 @@ void Monitor::_ms_dispatch(Message *m) } assert(s); con->set_priv(s->get()); - dout(10) << __func__ << " new session " << s << " " << *s << dendl; + dout(10) << __func__ << " new session " << s << " " << *s + << " features 0x" << std::hex + << s->con_features << std::dec << dendl; op->set_session(s); logger->set(l_mon_num_sessions, session_map.get_size()); @@ -4040,6 +4290,11 @@ void Monitor::dispatch_op(MonOpRequestRef op) health_monitor->dispatch(op); break; + case MSG_MON_HEALTH_CHECKS: + op->set_type_service(); + paxos_service[PAXOS_HEALTH]->dispatch(op); + break; + default: dealt_with = false; break; @@ -4583,6 +4838,8 @@ void Monitor::handle_subscribe(MonOpRequestRef op) logmon()->check_sub(s->sub_map[p->first]); } else if (p->first == "mgrmap" || p->first == "mgrdigest") { mgrmon()->check_sub(s->sub_map[p->first]); + } else if (p->first == "servicemap") { + mgrstatmon()->check_sub(s->sub_map[p->first]); } } @@ -4705,48 +4962,37 @@ void Monitor::handle_mon_metadata(MonOpRequestRef op) void Monitor::update_mon_metadata(int from, Metadata&& m) { - pending_metadata.insert(make_pair(from, std::move(m))); - - bufferlist bl; - int err = store->get(MONITOR_STORE_PREFIX, "last_metadata", bl); - map last_metadata; - if (!err) { - bufferlist::iterator iter = bl.begin(); - ::decode(last_metadata, iter); - pending_metadata.insert(last_metadata.begin(), last_metadata.end()); - } + // NOTE: this is now for legacy (kraken or jewel) mons only. + pending_metadata[from] = std::move(m); MonitorDBStore::TransactionRef t = paxos->get_pending_transaction(); - bl.clear(); + bufferlist bl; ::encode(pending_metadata, bl); t->put(MONITOR_STORE_PREFIX, "last_metadata", bl); paxos->trigger_propose(); } -int Monitor::load_metadata(map& metadata) +int Monitor::load_metadata() { bufferlist bl; int r = store->get(MONITOR_STORE_PREFIX, "last_metadata", bl); if (r) return r; bufferlist::iterator it = bl.begin(); - ::decode(metadata, it); + ::decode(mon_metadata, it); + + pending_metadata = mon_metadata; return 0; } int Monitor::get_mon_metadata(int mon, Formatter *f, ostream& err) { assert(f); - map last_metadata; - if (int r = load_metadata(last_metadata)) { - err << "Unable to load metadata: " << cpp_strerror(r); - return r; - } - if (!last_metadata.count(mon)) { + if (!mon_metadata.count(mon)) { err << "mon." << mon << " not found"; return -EINVAL; } - const Metadata& m = last_metadata[mon]; + const Metadata& m = mon_metadata[mon]; for (Metadata::const_iterator p = m.begin(); p != m.end(); ++p) { f->dump_string(p->first.c_str(), p->second); } @@ -4755,10 +5001,8 @@ int Monitor::get_mon_metadata(int mon, Formatter *f, ostream& err) void Monitor::count_metadata(const string& field, Formatter *f) { - map meta; - load_metadata(meta); map by_val; - for (auto& p : meta) { + for (auto& p : mon_metadata) { auto q = p.second.find(field); if (q == p.second.end()) { by_val["unknown"]++; @@ -4775,15 +5019,9 @@ void Monitor::count_metadata(const string& field, Formatter *f) int Monitor::print_nodes(Formatter *f, ostream& err) { - map metadata; - if (int r = load_metadata(metadata)) { - err << "Unable to load metadata.\n"; - return r; - } - map > mons; // hostname => mon - for (map::iterator it = metadata.begin(); - it != metadata.end(); ++it) { + for (map::iterator it = mon_metadata.begin(); + it != mon_metadata.end(); ++it) { const Metadata& m = it->second; Metadata::const_iterator hostname = m.find("hostname"); if (hostname == m.end()) { @@ -4950,14 +5188,16 @@ bool Monitor::_scrub(ScrubResult *r, } bufferlist bl; - //TODO: what when store->get returns error or empty bl? - store->get(k.first, k.second, bl); + int err = store->get(k.first, k.second, bl); + assert(err == 0); + uint32_t key_crc = bl.crc32c(0); dout(30) << __func__ << " " << k << " bl " << bl.length() << " bytes" << " crc " << key_crc << dendl; r->prefix_keys[k.first]++; - if (r->prefix_crc.count(k.first) == 0) + if (r->prefix_crc.count(k.first) == 0) { r->prefix_crc[k.first] = 0; + } r->prefix_crc[k.first] = bl.crc32c(r->prefix_crc[k.first]); if (cct->_conf->mon_scrub_inject_crc_mismatch > 0.0 && diff --git a/ceph/src/mon/Monitor.h b/ceph/src/mon/Monitor.h index a7a00642a..fa7f9e9ac 100644 --- a/ceph/src/mon/Monitor.h +++ b/ceph/src/mon/Monitor.h @@ -27,10 +27,12 @@ #include #include "include/types.h" +#include "include/health.h" #include "msg/Messenger.h" #include "common/Timer.h" +#include "health_check.h" #include "MonMap.h" #include "Elector.h" #include "Paxos.h" @@ -496,6 +498,7 @@ private: version_t timecheck_round; unsigned int timecheck_acks; utime_t timecheck_round_start; + friend class HealthMonitor; /* 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 @@ -556,6 +559,9 @@ private: public: epoch_t get_epoch(); int get_leader() const { return leader; } + string get_leader_name() { + return quorum.empty() ? string() : monmap->get_name(*quorum.begin()); + } const set& get_quorum() const { return quorum; } list get_quorum_names() { list q; @@ -594,6 +600,7 @@ public: void win_election(epoch_t epoch, set& q, uint64_t features, const mon_feature_t& mon_features, + const map& metadata, const MonCommand *cmdset, int cmdsize); void lose_election(epoch_t epoch, set& q, int l, uint64_t features, @@ -612,8 +619,6 @@ public: */ vector paxos_service; - PaxosService *get_paxos_service_by_name(const string& name); - class PGMonitor *pgmon() { return (class PGMonitor *)paxos_service[PAXOS_PGMAP]; } @@ -646,6 +651,10 @@ public: return (class MgrStatMonitor*) paxos_service[PAXOS_MGRSTAT]; } + class MgrStatMonitor *healthmon() { + return (class MgrStatMonitor*) paxos_service[PAXOS_MGRSTAT]; + } + friend class Paxos; friend class OSDMonitor; friend class MDSMonitor; @@ -693,6 +702,7 @@ public: int print_nodes(Formatter *f, ostream& err); // Accumulate metadata across calls to update_mon_metadata + map mon_metadata; map pending_metadata; /** @@ -734,6 +744,18 @@ public: */ health_status_t get_health(list& status, bufferlist *detailbl, Formatter *f); + + health_status_t get_health_status( + bool want_detail, + Formatter *f, + std::string *plain, + const char *sep1 = " ", + const char *sep2 = "; "); + void log_health( + const health_check_map_t& updated, + const health_check_map_t& previous, + MonitorDBStore::TransactionRef t); + void get_cluster_status(stringstream &ss, Formatter *f); void reply_command(MonOpRequestRef op, int rc, const string &rs, version_t version); @@ -873,8 +895,9 @@ public: int write_default_keyring(bufferlist& bl); void extract_save_mon_key(KeyRing& keyring); + void collect_metadata(Metadata *m); void update_mon_metadata(int from, Metadata&& m); - int load_metadata(map& m); + int load_metadata(); void count_metadata(const string& field, Formatter *f); // features diff --git a/ceph/src/mon/MonmapMonitor.cc b/ceph/src/mon/MonmapMonitor.cc index b5ac990df..7a0fb684d 100644 --- a/ceph/src/mon/MonmapMonitor.cc +++ b/ceph/src/mon/MonmapMonitor.cc @@ -37,7 +37,7 @@ static ostream& _prefix(std::ostream *_dout, Monitor *mon) { void MonmapMonitor::create_initial() { - dout(10) << "create_initial using current monmap" << dendl; + dout(10) << __func__ << " using current monmap" << dendl; pending_map = *mon->monmap; pending_map.epoch = 1; @@ -70,7 +70,7 @@ void MonmapMonitor::update_from_paxos(bool *need_bootstrap) assert(ret == 0); assert(monmap_bl.length()); - dout(10) << "update_from_paxos got " << version << dendl; + dout(10) << __func__ << " got " << version << dendl; mon->monmap->decode(monmap_bl); if (mon->store->exists("mkfs", "monmap")) { @@ -87,12 +87,12 @@ void MonmapMonitor::create_pending() pending_map = *mon->monmap; pending_map.epoch++; pending_map.last_changed = ceph_clock_now(); - dout(10) << "create_pending monmap epoch " << pending_map.epoch << dendl; + dout(10) << __func__ << " monmap epoch " << pending_map.epoch << dendl; } void MonmapMonitor::encode_pending(MonitorDBStore::TransactionRef t) { - dout(10) << "encode_pending epoch " << pending_map.epoch << dendl; + dout(10) << __func__ << " epoch " << pending_map.epoch << dendl; assert(mon->monmap->epoch + 1 == pending_map.epoch || pending_map.epoch == 1); // special case mkfs! @@ -251,8 +251,9 @@ bool MonmapMonitor::preprocess_command(MonOpRequestRef op) if (prefix == "mon stat") { mon->monmap->print_summary(ss); - ss << ", election epoch " << mon->get_epoch() << ", quorum " << mon->get_quorum() - << " " << mon->get_quorum_names(); + ss << ", election epoch " << mon->get_epoch() << ", leader " + << mon->get_leader() << " " << mon->get_leader_name() + << ", quorum " << mon->get_quorum() << " " << mon->get_quorum_names(); rdata.append(ss); ss.str(""); r = 0; @@ -309,7 +310,7 @@ bool MonmapMonitor::preprocess_command(MonOpRequestRef op) if (p != mon->monmap) delete p; - } else if (prefix == "mon feature list") { + } else if (prefix == "mon feature ls") { bool list_with_value = false; string with_value; @@ -397,7 +398,7 @@ reply: bool MonmapMonitor::prepare_update(MonOpRequestRef op) { PaxosServiceMessage *m = static_cast(op->get_req()); - dout(7) << "prepare_update " << *m << " from " << m->get_orig_source_inst() << dendl; + dout(7) << __func__ << " " << *m << " from " << m->get_orig_source_inst() << dendl; switch (m->get_type()) { case MSG_MON_COMMAND: @@ -688,7 +689,7 @@ reply: bool MonmapMonitor::preprocess_join(MonOpRequestRef op) { MMonJoin *join = static_cast(op->get_req()); - dout(10) << "preprocess_join " << join->name << " at " << join->addr << dendl; + dout(10) << __func__ << " " << join->name << " at " << join->addr << dendl; MonSession *session = join->get_session(); if (!session || diff --git a/ceph/src/mon/OSDMonitor.cc b/ceph/src/mon/OSDMonitor.cc index ddfeb2a29..4f05449bc 100644 --- a/ceph/src/mon/OSDMonitor.cc +++ b/ceph/src/mon/OSDMonitor.cc @@ -17,6 +17,8 @@ */ #include +#include +#include #include #include "mon/OSDMonitor.h" @@ -72,6 +74,7 @@ #include "common/cmdparse.h" #include "include/str_list.h" #include "include/str_map.h" +#include "include/scope_guard.h" #include "json_spirit/json_spirit_reader.h" @@ -213,8 +216,7 @@ void OSDMonitor::create_initial() newmap.decode(bl); newmap.set_fsid(mon->monmap->fsid); } else { - newmap.build_simple(g_ceph_context, 0, mon->monmap->fsid, 0, - g_conf->osd_pg_bits, g_conf->osd_pgp_bits); + newmap.build_simple(g_ceph_context, 0, mon->monmap->fsid, 0); } newmap.set_epoch(1); newmap.created = newmap.modified = ceph_clock_now(); @@ -275,6 +277,8 @@ void OSDMonitor::update_from_paxos(bool *need_bootstrap) mapping_job.reset(); } + load_health(); + /* * We will possibly have a stashed latest that *we* wrote, and we will * always be sure to have the oldest full map in the first..last range @@ -495,12 +499,17 @@ void OSDMonitor::start_mapping() << dendl; mapping_job->abort(); } - auto fin = new C_UpdateCreatingPGs(this, osdmap.get_epoch()); - mapping_job = mapping.start_update(osdmap, mapper, - g_conf->mon_osd_mapping_pgs_per_chunk); - dout(10) << __func__ << " started mapping job " << mapping_job.get() - << " at " << fin->start << dendl; - mapping_job->set_finish_event(fin); + if (!osdmap.get_pools().empty()) { + auto fin = new C_UpdateCreatingPGs(this, osdmap.get_epoch()); + mapping_job = mapping.start_update(osdmap, mapper, + g_conf->mon_osd_mapping_pgs_per_chunk); + dout(10) << __func__ << " started mapping job " << mapping_job.get() + << " at " << fin->start << dendl; + mapping_job->set_finish_event(fin); + } else { + dout(10) << __func__ << " no pools, no mapping job" << dendl; + mapping_job = nullptr; + } } void OSDMonitor::update_msgr_features() @@ -527,7 +536,7 @@ void OSDMonitor::on_active() update_logger(); if (mon->is_leader()) { - mon->clog->info() << "osdmap " << osdmap; + mon->clog->debug() << "osdmap " << osdmap; } else { list ls; take_all_failures(ls); @@ -795,7 +804,9 @@ void OSDMonitor::maybe_prime_pg_temp() next.deepish_copy_from(osdmap); next.apply_incremental(pending_inc); - if (all) { + if (next.get_pools().empty()) { + dout(10) << __func__ << " no pools, no pg_temp priming" << dendl; + } else if (all) { PrimeTempJob job(next, this); mapper.queue(&job, g_conf->mon_osd_mapping_pgs_per_chunk); if (job.wait_for(g_conf->mon_osd_prime_pg_temp_max_time)) { @@ -964,6 +975,31 @@ void OSDMonitor::encode_pending(MonitorDBStore::TransactionRef t) << "required " << ceph_release_name(mv); pending_inc.new_require_min_compat_client = mv; } + + if (osdmap.require_osd_release < CEPH_RELEASE_LUMINOUS) { + // convert ec profile ruleset-* -> crush-* + for (auto& p : tmp.erasure_code_profiles) { + bool changed = false; + map newprofile; + for (auto& q : p.second) { + if (q.first.find("ruleset-") == 0) { + string key = "crush-"; + key += q.first.substr(8); + newprofile[key] = q.second; + changed = true; + dout(20) << " updating ec profile " << p.first + << " key " << q.first << " -> " << key << dendl; + } else { + newprofile[q.first] = q.second; + } + } + if (changed) { + dout(10) << " updated ec profile " << p.first << ": " + << newprofile << dendl; + pending_inc.new_erasure_code_profiles[p.first] = newprofile; + } + } + } } } @@ -1069,6 +1105,11 @@ void OSDMonitor::encode_pending(MonitorDBStore::TransactionRef t) ::encode(pending_creatings, creatings_bl); t->put(OSD_PG_CREATING_PREFIX, "creating", creatings_bl); } + + // health + health_check_map_t next; + tmp.check_health(&next); + encode_health(next, t); } void OSDMonitor::trim_creating_pgs(creating_pgs_t* creating_pgs, @@ -1811,7 +1852,7 @@ bool OSDMonitor::check_failure(utime_t now, int target_osd, failure_info_t& fi) return false; } -void OSDMonitor::force_failure(utime_t now, int target_osd, int by) +void OSDMonitor::force_failure(int target_osd, int by) { // already pending failure? if (pending_inc.new_state.count(target_osd) && @@ -1852,7 +1893,7 @@ bool OSDMonitor::prepare_failure(MonOpRequestRef op) if (m->is_immediate()) { mon->clog->debug() << m->get_target() << " reported immediately failed by " << m->get_orig_source_inst(); - force_failure(now, target_osd, reporter); + force_failure(target_osd, reporter); return true; } mon->clog->debug() << m->get_target() << " reported failed by " @@ -3214,7 +3255,8 @@ void OSDMonitor::tick() do_propose = true; - mon->clog->info() << "osd." << o << " out (down for " << down << ")"; + mon->clog->info() << "Marking osd." << o << " out (has been down for " + << int(down.sec()) << " seconds)"; } else continue; } @@ -3333,7 +3375,7 @@ void OSDMonitor::get_health(list >& summary, osds.insert(i); } continue; - } + } if (osdmap.is_out(i)) continue; ++num_in_osds; @@ -3744,7 +3786,17 @@ void OSDMonitor::get_health(list >& summary, } } - get_pools_health(summary, detail); + for (auto it : osdmap.get_pools()) { + const pg_pool_t &pool = it.second; + if (pool.has_flag(pg_pool_t::FLAG_FULL)) { + const string& pool_name = osdmap.get_pool_name(it.first); + stringstream ss; + ss << "pool '" << pool_name << "' is full"; + summary.push_back(make_pair(HEALTH_WARN, ss.str())); + if (detail) + detail->push_back(make_pair(HEALTH_WARN, ss.str())); + } + } } } @@ -3835,7 +3887,7 @@ bool OSDMonitor::preprocess_command(MonOpRequestRef op) boost::scoped_ptr f(Formatter::create(format)); if (prefix == "osd stat") { - osdmap.print_summary(f.get(), ds); + osdmap.print_summary(f.get(), ds, ""); if (f) f->flush(rdata); else @@ -3877,6 +3929,12 @@ bool OSDMonitor::preprocess_command(MonOpRequestRef op) p->decode(osdmap_bl); } + auto sg = make_scope_guard([&] { + if (p != &osdmap) { + delete p; + } + }); + if (prefix == "osd dump") { stringstream ds; if (f) { @@ -3990,8 +4048,6 @@ bool OSDMonitor::preprocess_command(MonOpRequestRef op) rdata.append(ds); } - if (p != &osdmap) - delete p; } else if (prefix == "osd df") { string method; cmd_getval(g_ceph_context, cmdmap, "output_method", method); @@ -4201,15 +4257,15 @@ bool OSDMonitor::preprocess_command(MonOpRequestRef op) } goto reply; - } else if ((prefix == "osd scrub" || - prefix == "osd deep-scrub" || - prefix == "osd repair")) { + } else if (prefix == "osd scrub" || + prefix == "osd deep-scrub" || + prefix == "osd repair") { string whostr; cmd_getval(g_ceph_context, cmdmap, "who", whostr); vector pvec; get_str_vec(prefix, pvec); - if (whostr == "*") { + if (whostr == "*" || whostr == "all" || whostr == "any") { ss << "osds "; int c = 0; for (int i = 0; i < osdmap.get_max_osd(); i++) @@ -4889,6 +4945,17 @@ bool OSDMonitor::preprocess_command(MonOpRequestRef op) f->dump_string("class", i.second); f->close_section(); f->flush(rdata); + } else if (prefix == "osd crush class ls-osd") { + string name; + cmd_getval(g_ceph_context, cmdmap, "class", name); + boost::scoped_ptr f(Formatter::create(format, "json-pretty", "json-pretty")); + set osds; + osdmap.crush->get_devices_by_class(name, &osds); + f->open_array_section("osds"); + for (auto& osd : osds) + f->dump_int("osd", osd); + f->close_section(); + f->flush(rdata); } else if (prefix == "osd erasure-code-profile ls") { const auto &profiles = osdmap.get_erasure_code_profiles(); if (f) @@ -5002,90 +5069,6 @@ bool OSDMonitor::update_pools_status() return ret; } -void OSDMonitor::get_pools_health( - list >& summary, - list > *detail) const -{ - auto& pools = osdmap.get_pools(); - for (auto it = pools.begin(); it != pools.end(); ++it) { - const pool_stat_t *pstat = mon->pgservice->get_pool_stat(it->first); - if (!pstat) - continue; - const object_stat_sum_t& sum = pstat->stats.sum; - const pg_pool_t &pool = it->second; - const string& pool_name = osdmap.get_pool_name(it->first); - - if (pool.has_flag(pg_pool_t::FLAG_FULL)) { - // uncomment these asserts if/when we update the FULL flag on pg_stat update - //assert((pool.quota_max_objects > 0) || (pool.quota_max_bytes > 0)); - - stringstream ss; - ss << "pool '" << pool_name << "' is full"; - summary.push_back(make_pair(HEALTH_WARN, ss.str())); - if (detail) - detail->push_back(make_pair(HEALTH_WARN, ss.str())); - } - - float warn_threshold = (float)g_conf->mon_pool_quota_warn_threshold/100; - float crit_threshold = (float)g_conf->mon_pool_quota_crit_threshold/100; - - if (pool.quota_max_objects > 0) { - stringstream ss; - health_status_t status = HEALTH_OK; - if ((uint64_t)sum.num_objects >= pool.quota_max_objects) { - // uncomment these asserts if/when we update the FULL flag on pg_stat update - //assert(pool.has_flag(pg_pool_t::FLAG_FULL)); - } else if (crit_threshold > 0 && - sum.num_objects >= pool.quota_max_objects*crit_threshold) { - ss << "pool '" << pool_name - << "' has " << sum.num_objects << " objects" - << " (max " << pool.quota_max_objects << ")"; - status = HEALTH_ERR; - } else if (warn_threshold > 0 && - sum.num_objects >= pool.quota_max_objects*warn_threshold) { - ss << "pool '" << pool_name - << "' has " << sum.num_objects << " objects" - << " (max " << pool.quota_max_objects << ")"; - status = HEALTH_WARN; - } - if (status != HEALTH_OK) { - pair s(status, ss.str()); - summary.push_back(s); - if (detail) - detail->push_back(s); - } - } - - if (pool.quota_max_bytes > 0) { - health_status_t status = HEALTH_OK; - stringstream ss; - if ((uint64_t)sum.num_bytes >= pool.quota_max_bytes) { - // uncomment these asserts if/when we update the FULL flag on pg_stat update - //assert(pool.has_flag(pg_pool_t::FLAG_FULL)); - } else if (crit_threshold > 0 && - sum.num_bytes >= pool.quota_max_bytes*crit_threshold) { - ss << "pool '" << pool_name - << "' has " << si_t(sum.num_bytes) << " bytes" - << " (max " << si_t(pool.quota_max_bytes) << ")"; - status = HEALTH_ERR; - } else if (warn_threshold > 0 && - sum.num_bytes >= pool.quota_max_bytes*warn_threshold) { - ss << "pool '" << pool_name - << "' has " << si_t(sum.num_bytes) << " bytes" - << " (max " << si_t(pool.quota_max_bytes) << ")"; - status = HEALTH_WARN; - } - if (status != HEALTH_OK) { - pair s(status, ss.str()); - summary.push_back(s); - if (detail) - detail->push_back(s); - } - } - } -} - - int OSDMonitor::prepare_new_pool(MonOpRequestRef op) { op->mark_osdmon_event(__func__); @@ -5237,7 +5220,7 @@ int OSDMonitor::crush_rule_create_erasure(const string &name, return err; } - err = erasure_code->create_ruleset(name, newcrush, ss); + err = erasure_code->create_rule(name, newcrush, ss); erasure_code.reset(); if (err < 0) return err; @@ -5472,10 +5455,10 @@ int OSDMonitor::prepare_pool_stripe_width(const unsigned pool_type, } int OSDMonitor::prepare_pool_crush_rule(const unsigned pool_type, - const string &erasure_code_profile, - const string &rule_name, - int *crush_rule, - ostream *ss) + const string &erasure_code_profile, + const string &rule_name, + int *crush_rule, + ostream *ss) { if (*crush_rule < 0) { @@ -5483,7 +5466,7 @@ int OSDMonitor::prepare_pool_crush_rule(const unsigned pool_type, case pg_pool_t::TYPE_REPLICATED: { if (rule_name == "") { - //Use default rule + // Use default rule *crush_rule = osdmap.crush->get_osd_pool_default_crush_replicated_ruleset(g_ceph_context); if (*crush_rule < 0) { // Errors may happen e.g. if no valid rule is available @@ -5534,8 +5517,8 @@ int OSDMonitor::prepare_pool_crush_rule(const unsigned pool_type, } int OSDMonitor::get_crush_rule(const string &rule_name, - int *crush_rule, - ostream *ss) + int *crush_rule, + ostream *ss) { int ret; ret = osdmap.crush->get_rule_id(rule_name); @@ -5553,7 +5536,7 @@ int OSDMonitor::get_crush_rule(const string &rule_name, << " try again" << dendl; return -EAGAIN; } else { - //Cannot find it , return error + // Cannot find it , return error *ss << "specified rule " << rule_name << " doesn't exist"; return ret; } @@ -5614,24 +5597,20 @@ int OSDMonitor::prepare_new_pool(string& name, uint64_t auid, dout(10) << " prepare_pool_crush_rule returns " << r << dendl; return r; } - CrushWrapper newcrush; - _get_pending_crush(newcrush); - ostringstream err; - CrushTester tester(newcrush, err); - // use the internal crush tester if crushtool config is empty - if (g_conf->crushtool.empty()) { - r = tester.test(); - } else { - r = tester.test_with_crushtool(g_conf->crushtool.c_str(), - osdmap.get_max_osd(), - g_conf->mon_lease, - crush_rule); - } - if (r) { - dout(10) << " tester.test_with_crushtool returns " << r - << ": " << err.str() << dendl; - *ss << "crushtool check failed with " << r << ": " << err.str(); - return r; + if (g_conf->mon_osd_crush_smoke_test) { + CrushWrapper newcrush; + _get_pending_crush(newcrush); + ostringstream err; + CrushTester tester(newcrush, err); + tester.set_max_x(50); + tester.set_rule(crush_rule); + r = tester.test_with_fork(g_conf->mon_lease); + if (r < 0) { + dout(10) << " tester.test_with_fork returns " << r + << ": " << err.str() << dendl; + *ss << "crush test failed with " << r << ": " << err.str(); + return r; + } } unsigned size, min_size; r = prepare_pool_size(pool_type, erasure_code_profile, &size, &min_size, ss); @@ -6021,6 +6000,12 @@ int OSDMonitor::prepare_command_pool_set(map &cmdmap, ss << "ec overwrites can only be enabled for an erasure coded pool"; return -EINVAL; } + stringstream err; + if (!g_conf->mon_debug_no_require_bluestore_for_ec_overwrites && + !is_pool_currently_all_bluestore(pool, p, &err)) { + ss << "pool must only be stored on bluestore for scrubbing to work: " << err.str(); + return -EINVAL; + } if (val == "true" || (interr.empty() && n == 1)) { p.flags |= pg_pool_t::FLAG_EC_OVERWRITES; } else if (val == "false" || (interr.empty() && n == 0)) { @@ -6030,12 +6015,6 @@ int OSDMonitor::prepare_command_pool_set(map &cmdmap, ss << "expecting value 'true', 'false', '0', or '1'"; return -EINVAL; } - stringstream err; - if (!g_conf->mon_debug_no_require_bluestore_for_ec_overwrites && - !is_pool_currently_all_bluestore(pool, p, &err)) { - ss << "pool must only be stored on bluestore for scrubbing to work: " << err.str(); - return -EINVAL; - } } else if (var == "target_max_objects") { if (interr.length()) { ss << "error parsing int '" << val << "': " << interr; @@ -6136,32 +6115,37 @@ int OSDMonitor::prepare_command_pool_set(map &cmdmap, return -EINVAL; } } else if (pool_opts_t::is_opt_name(var)) { + bool unset = val == "unset"; if (var == "compression_mode") { - auto cmode = Compressor::get_comp_mode_type(val); - if (!cmode) { - ss << "unrecognized compression mode '" << val << "'"; - return EINVAL; + if (!unset) { + auto cmode = Compressor::get_comp_mode_type(val); + if (!cmode) { + ss << "unrecognized compression mode '" << val << "'"; + return -EINVAL; + } } } else if (var == "compression_algorithm") { - auto alg = Compressor::get_comp_alg_type(val); - if (!alg) { - ss << "unrecognized compression_algorithm '" << val << "'"; - return EINVAL; + if (!unset) { + auto alg = Compressor::get_comp_alg_type(val); + if (!alg) { + ss << "unrecognized compression_algorithm '" << val << "'"; + return -EINVAL; + } } } else if (var == "compression_required_ratio") { if (floaterr.length()) { ss << "error parsing float value '" << val << "': " << floaterr; return -EINVAL; } - if (f < 0 || f>1) { + if (f < 0 || f > 1) { ss << "compression_required_ratio is out of range (0-1): '" << val << "'"; - return EINVAL; + return -EINVAL; } } else if (var == "csum_type") { - auto t = val != "unset" ? Checksummer::get_csum_string_type(val) : 0; + auto t = unset ? 0 : Checksummer::get_csum_string_type(val); if (t < 0 ) { ss << "unrecognized csum_type '" << val << "'"; - return EINVAL; + return -EINVAL; } //preserve csum_type numeric value n = t; @@ -6179,7 +6163,7 @@ int OSDMonitor::prepare_command_pool_set(map &cmdmap, pool_opts_t::opt_desc_t desc = pool_opts_t::get_opt_desc(var); switch (desc.type) { case pool_opts_t::STR: - if (val.empty()) { + if (unset) { p.opts.unset(desc.key); } else { p.opts.set(desc.key, static_cast(val)); @@ -6214,7 +6198,11 @@ int OSDMonitor::prepare_command_pool_set(map &cmdmap, ss << "unrecognized variable '" << var << "'"; return -EINVAL; } - ss << "set pool " << pool << " " << var << " to " << val; + if (val != "unset") { + ss << "set pool " << pool << " " << var << " to " << val; + } else { + ss << "unset pool " << pool << " " << var; + } p.last_change = pending_inc.epoch; pending_inc.new_pools[pool] = p; return 0; @@ -6792,7 +6780,6 @@ int OSDMonitor::prepare_command_osd_destroy( if (err < 0) { if (err == -ENOENT) { idempotent_auth = true; - err = 0; } else { return err; } @@ -7020,34 +7007,33 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op, } } - // sanity check: test some inputs to make sure this map isn't totally broken - dout(10) << " testing map" << dendl; - stringstream ess; - CrushTester tester(crush, ess); - // XXX: Use mon_lease as a timeout value for crushtool. - // If the crushtool consistently takes longer than 'mon_lease' seconds, - // then we would consistently trigger an election before the command - // finishes, having a flapping monitor unable to hold quorum. - int r = tester.test_with_crushtool(g_conf->crushtool.c_str(), - osdmap.get_max_osd(), - g_conf->mon_lease); - if (r < 0) { - derr << "error on crush map: " << ess.str() << dendl; - ss << "Failed crushmap test: " << ess.str(); - err = r; - goto reply; + if (g_conf->mon_osd_crush_smoke_test) { + // sanity check: test some inputs to make sure this map isn't + // totally broken + dout(10) << " testing map" << dendl; + stringstream ess; + CrushTester tester(crush, ess); + tester.set_max_x(50); + int r = tester.test_with_fork(g_conf->mon_lease); + if (r < 0) { + dout(10) << " tester.test_with_fork returns " << r + << ": " << ess.str() << dendl; + ss << "crush smoke test failed with " << r << ": " << ess.str(); + err = r; + goto reply; + } + dout(10) << " crush test result " << ess.str() << dendl; } - dout(10) << " result " << ess.str() << dendl; - pending_inc.crush = data; ss << osdmap.get_crush_version() + 1; goto update; } else if (prefix == "osd crush set-device-class") { - if (!osdmap.exists(osdid)) { - err = -ENOENT; - ss << name << " does not exist. create it before updating the crush map"; + if (osdmap.require_osd_release < CEPH_RELEASE_LUMINOUS) { + ss << "you must complete the upgrade and 'ceph osd require-osd-release " + << "luminous' before using crush device classes"; + err = -EPERM; goto reply; } @@ -7057,38 +7043,77 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op, goto reply; } + bool stop = false; + vector idvec; + cmd_getval(g_ceph_context, cmdmap, "ids", idvec); CrushWrapper newcrush; _get_pending_crush(newcrush); + set updated; + for (unsigned j = 0; j < idvec.size() && !stop; j++) { + set osds; + // wildcard? + if (j == 0 && + (idvec[0] == "any" || idvec[0] == "all" || idvec[0] == "*")) { + osdmap.get_all_osds(osds); + stop = true; + } else { + // try traditional single osd way + long osd = parse_osd_id(idvec[j].c_str(), &ss); + if (osd < 0) { + // ss has reason for failure + ss << ", unable to parse osd id:\"" << idvec[j] << "\". "; + err = -EINVAL; + continue; + } + osds.insert(osd); + } - string action; - if (newcrush.item_exists(osdid)) { - action = "updating"; - } else { - action = "creating"; - newcrush.set_item_name(osdid, name); - } + for (auto &osd : osds) { + if (!osdmap.exists(osd)) { + ss << "osd." << osd << " does not exist. "; + continue; + } - dout(5) << action << " crush item id " << osdid << " name '" - << name << "' device_class " << device_class << dendl; - err = newcrush.update_device_class(g_ceph_context, osdid, device_class, name); + ostringstream oss; + oss << "osd." << osd; + string name = oss.str(); - if (err < 0) - goto reply; + string action; + if (newcrush.item_exists(osd)) { + action = "updating"; + } else { + action = "creating"; + newcrush.set_item_name(osd, name); + } - if (err == 0 && !_have_pending_crush()) { - ss << "set-device-class item id " << osdid << " name '" << name << "' device_class " - << device_class << " : no change"; - goto reply; + dout(5) << action << " crush item id " << osd << " name '" << name + << "' device_class '" << device_class << "'" + << dendl; + err = newcrush.update_device_class(osd, device_class, name, &ss); + if (err < 0) { + goto reply; + } + if (err == 0 && !_have_pending_crush()) { + if (!stop) { + // for single osd only, wildcard makes too much noise + ss << "set-device-class item id " << osd << " name '" << name + << "' device_class '" << device_class << "': no change"; + } + } else { + updated.insert(osd); + } + } } - pending_inc.crush.clear(); - newcrush.encode(pending_inc.crush, mon->get_quorum_con_features()); - ss << "set-device-class item id " << osdid << " name '" << name << "' device_class " - << device_class; - getline(ss, rs); - wait_for_finished_proposal(op, new Monitor::C_Command(mon, op, 0, rs, - get_last_committed() + 1)); - return true; + if (!updated.empty()) { + pending_inc.crush.clear(); + newcrush.encode(pending_inc.crush, mon->get_quorum_con_features()); + ss << "set osd(s) " << updated << " to class '" << device_class << "'"; + 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 crush add-bucket") { // os crush add-bucket @@ -7157,7 +7182,12 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op, err = -EINVAL; // no value! goto reply; } - + if (osdmap.require_osd_release < CEPH_RELEASE_LUMINOUS) { + ss << "you must complete the upgrade and 'ceph osd require-osd-release " + << "luminous' before using crush device classes"; + err = -EPERM; + goto reply; + } if (!_have_pending_crush() && _get_stable_crush().class_exists(device_class)) { ss << "class '" << device_class << "' already exists"; @@ -7186,6 +7216,12 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op, err = -EINVAL; // no value! goto reply; } + if (osdmap.require_osd_release < CEPH_RELEASE_LUMINOUS) { + ss << "you must complete the upgrade and 'ceph osd require-osd-release " + << "luminous' before using crush device classes"; + err = -EPERM; + goto reply; + } CrushWrapper newcrush; _get_pending_crush(newcrush); @@ -7216,6 +7252,59 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op, ss << "removed class " << device_class << " with id " << class_id << " from crush map"; goto update; + + } else if (prefix == "osd crush class rename") { + string srcname, dstname; + if (!cmd_getval(g_ceph_context, cmdmap, "srcname", srcname)) { + err = -EINVAL; + goto reply; + } + if (osdmap.require_osd_release < CEPH_RELEASE_LUMINOUS) { + ss << "you must complete the upgrade and 'ceph osd require-osd-release " + << "luminous' before using crush device classes"; + err = -EPERM; + goto reply; + } + + if (!cmd_getval(g_ceph_context, cmdmap, "dstname", dstname)) { + err = -EINVAL; + goto reply; + } + + CrushWrapper newcrush; + _get_pending_crush(newcrush); + + if (!newcrush.class_exists(srcname)) { + err = -ENOENT; + ss << "class '" << srcname << "' does not exist"; + goto reply; + } + + if (newcrush.class_exists(dstname)) { + err = -EEXIST; + ss << "class '" << dstname << "' already exists"; + goto reply; + } + + int class_id = newcrush.get_class_id(srcname); + + if (newcrush.class_is_in_use(class_id)) { + err = -EBUSY; + ss << "class '" << srcname << "' is in use"; + goto reply; + } + + err = newcrush.rename_class(srcname, dstname); + if (err < 0) { + ss << "fail to rename '" << srcname << "' to '" << dstname << "':" + << cpp_strerror(err); + goto reply; + } + + pending_inc.crush.clear(); + newcrush.encode(pending_inc.crush, mon->get_quorum_con_features()); + ss << "rename class '" << srcname << "' to '" << dstname << "'"; + goto update; } else if (osdid_present && (prefix == "osd crush set" || prefix == "osd crush add")) { @@ -7414,6 +7503,7 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op, int r = newcrush.swap_bucket(g_ceph_context, sid, did); if (r < 0) { ss << "failed to swap bucket contents: " << cpp_strerror(r); + err = r; goto reply; } ss << "swapped bucket of " << source << " to " << dest; @@ -7539,7 +7629,6 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op, } while (false); } else if (prefix == "osd crush reweight-all") { - // osd crush reweight CrushWrapper newcrush; _get_pending_crush(newcrush); @@ -7682,7 +7771,7 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op, } if (tunable == "straw_calc_version") { - if (value < 0 || value > 1) { + if (value != 0 && value != 1) { ss << "value must be 0 or 1; got " << value; err = -EINVAL; goto reply; @@ -7733,7 +7822,7 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op, ss << "rule " << name << " already exists"; err = 0; } else { - int ruleno = newcrush.add_simple_rule(name, root, type, mode, + int ruleno = newcrush.add_simple_rule(name, root, type, "", mode, pg_pool_t::TYPE_REPLICATED, &ss); if (ruleno < 0) { err = ruleno; @@ -7748,6 +7837,55 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op, get_last_committed() + 1)); return true; + } else if (prefix == "osd crush rule create-replicated") { + string name, root, type, device_class; + cmd_getval(g_ceph_context, cmdmap, "name", name); + cmd_getval(g_ceph_context, cmdmap, "root", root); + cmd_getval(g_ceph_context, cmdmap, "type", type); + cmd_getval(g_ceph_context, cmdmap, "class", device_class); + + if (!device_class.empty()) { + if (osdmap.require_osd_release < CEPH_RELEASE_LUMINOUS) { + ss << "you must complete the upgrade and 'ceph osd require-osd-release " + << "luminous' before using crush device classes"; + err = -EPERM; + goto reply; + } + } + + if (osdmap.crush->rule_exists(name)) { + // The name is uniquely associated to a ruleid and the rule it contains + // From the user point of view, the rule is more meaningfull. + ss << "rule " << name << " already exists"; + err = 0; + goto reply; + } + + CrushWrapper newcrush; + _get_pending_crush(newcrush); + + if (newcrush.rule_exists(name)) { + // The name is uniquely associated to a ruleid and the rule it contains + // From the user point of view, the rule is more meaningfull. + ss << "rule " << name << " already exists"; + err = 0; + } else { + int ruleno = newcrush.add_simple_rule( + name, root, type, device_class, + "firstn", pg_pool_t::TYPE_REPLICATED, &ss); + if (ruleno < 0) { + err = ruleno; + goto reply; + } + + pending_inc.crush.clear(); + newcrush.encode(pending_inc.crush, mon->get_quorum_con_features()); + } + 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 erasure-code-profile rm") { string name; cmd_getval(g_ceph_context, cmdmap, "name", name); @@ -8004,15 +8142,15 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op, prefix == "osd set-backfillfull-ratio" || prefix == "osd set-nearfull-ratio") { if (osdmap.require_osd_release < CEPH_RELEASE_LUMINOUS) { - ss << "you must complete the upgrade and set require_osd_release =" - << "luminous before using the new interface"; + ss << "you must complete the upgrade and 'ceph osd require-osd-release " + << "luminous' before using the new interface"; err = -EPERM; goto reply; } double n; if (!cmd_getval(g_ceph_context, cmdmap, "ratio", n)) { ss << "unable to parse 'ratio' value '" - << cmd_vartype_stringify(cmdmap["who"]) << "'"; + << cmd_vartype_stringify(cmdmap["ratio"]) << "'"; err = -EINVAL; goto reply; } @@ -8029,8 +8167,8 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op, return true; } else if (prefix == "osd set-require-min-compat-client") { if (osdmap.require_osd_release < CEPH_RELEASE_LUMINOUS) { - ss << "you must complete the upgrade and set require_osd_release =" - << "luminous before using the new interface"; + ss << "you must complete the upgrade and 'ceph osd require-osd-release " + << "luminous' before using the new interface"; err = -EPERM; goto reply; } @@ -8206,10 +8344,7 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op, return prepare_unset_flag(op, CEPH_OSDMAP_NODEEP_SCRUB); else if (key == "notieragent") return prepare_unset_flag(op, CEPH_OSDMAP_NOTIERAGENT); - else if (key == "sortbitwise") { - ss << "the sortbitwise flag is required and cannot be unset"; - err = -EPERM; - } else { + else { ss << "unrecognized flag '" << key << "'"; err = -EINVAL; } @@ -8318,6 +8453,17 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op, pending_inc.new_xinfo[osd].old_weight = osdmap.osd_weight[osd]; } ss << "marked out osd." << osd << ". "; + std::ostringstream msg; + msg << "Client " << op->get_session()->entity_name + << " marked osd." << osd << " out"; + if (osdmap.is_up(osd)) { + msg << ", while it was still marked up"; + } else { + msg << ", after it was down for " << int(down_pending_out[osd].sec()) + << " seconds"; + } + + mon->clog->info() << msg.str(); any = true; } } else if (prefix == "osd in") { @@ -8706,6 +8852,22 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op, new_pg_temp.push_back(osd); } + int pool_min_size = osdmap.get_pg_pool_min_size(pgid); + if ((int)new_pg_temp.size() < pool_min_size) { + ss << "num of osds (" << new_pg_temp.size() <<") < pool min size (" + << pool_min_size << ")"; + err = -EINVAL; + goto reply; + } + + int pool_size = osdmap.get_pg_pool_size(pgid); + if ((int)new_pg_temp.size() > pool_size) { + ss << "num of osds (" << new_pg_temp.size() <<") > pool size (" + << pool_size << ")"; + err = -EINVAL; + goto reply; + } + pending_inc.new_pg_temp[pgid] = mempool::osdmap::vector( new_pg_temp.begin(), new_pg_temp.end()); ss << "set " << pgid << " pg_temp mapping to " << new_pg_temp; @@ -8759,17 +8921,22 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op, pending_inc.new_primary_temp[pgid] = osd; ss << "set " << pgid << " primary_temp mapping to " << osd; goto update; - } else if (prefix == "osd pg-upmap") { + } else if (prefix == "osd pg-upmap" || + prefix == "osd rm-pg-upmap" || + prefix == "osd pg-upmap-items" || + prefix == "osd rm-pg-upmap-items") { if (osdmap.require_osd_release < CEPH_RELEASE_LUMINOUS) { - ss << "you must complete the upgrade and set require_osd_release =" - << "luminous before using the new interface"; + ss << "you must complete the upgrade and 'ceph osd require-osd-release " + << "luminous' before using the new interface"; err = -EPERM; goto reply; } if (osdmap.require_min_compat_client < CEPH_RELEASE_LUMINOUS) { ss << "min_compat_client " << ceph_release_name(osdmap.require_min_compat_client) - << " < luminous, which is required for pg-upmap"; + << " < luminous, which is required for pg-upmap. " + << "Try 'ceph osd set-require-min-compat-client luminous' " + << "before using the new interface"; err = -EPERM; goto reply; } @@ -8796,193 +8963,188 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op, err = -ENOENT; goto reply; } - if (pending_inc.new_pg_upmap.count(pgid) || - pending_inc.old_pg_upmap.count(pgid)) { - dout(10) << __func__ << " waiting for pending update on " << pgid << dendl; - wait_for_finished_proposal(op, new C_RetryMessage(this, op)); - return true; - } - vector id_vec; - if (!cmd_getval(g_ceph_context, cmdmap, "id", id_vec)) { - ss << "unable to parse 'id' value(s) '" - << cmd_vartype_stringify(cmdmap["id"]) << "'"; - err = -EINVAL; - goto reply; + + enum { + OP_PG_UPMAP, + OP_RM_PG_UPMAP, + OP_PG_UPMAP_ITEMS, + OP_RM_PG_UPMAP_ITEMS, + } option; + + if (prefix == "osd pg-upmap") { + option = OP_PG_UPMAP; + } else if (prefix == "osd rm-pg-upmap") { + option = OP_RM_PG_UPMAP; + } else if (prefix == "osd pg-upmap-items") { + option = OP_PG_UPMAP_ITEMS; + } else { + option = OP_RM_PG_UPMAP_ITEMS; } - vector new_pg_upmap; - for (auto osd : id_vec) { - if (osd != CRUSH_ITEM_NONE && !osdmap.exists(osd)) { - ss << "osd." << osd << " does not exist"; - err = -ENOENT; - goto reply; + + // check pending upmap changes + switch (option) { + case OP_PG_UPMAP: // fall through + case OP_RM_PG_UPMAP: + if (pending_inc.new_pg_upmap.count(pgid) || + pending_inc.old_pg_upmap.count(pgid)) { + dout(10) << __func__ << " waiting for pending update on " + << pgid << dendl; + wait_for_finished_proposal(op, new C_RetryMessage(this, op)); + return true; } - new_pg_upmap.push_back(osd); - } + break; - pending_inc.new_pg_upmap[pgid] = mempool::osdmap::vector( - new_pg_upmap.begin(), new_pg_upmap.end()); - ss << "set " << pgid << " pg_upmap mapping to " << new_pg_upmap; - goto update; - } else if (prefix == "osd rm-pg-upmap") { - if (osdmap.require_osd_release < CEPH_RELEASE_LUMINOUS) { - ss << "you must complete the upgrade and set require_osd_release =" - << "luminous before using the new interface"; - err = -EPERM; - goto reply; - } - if (osdmap.require_min_compat_client < CEPH_RELEASE_LUMINOUS) { - ss << "require_min_compat_client " - << ceph_release_name(osdmap.require_min_compat_client) - << " < luminous, which is required for pg-upmap"; - err = -EPERM; - goto reply; - } - err = check_cluster_features(CEPH_FEATUREMASK_OSDMAP_PG_UPMAP, ss); - if (err == -EAGAIN) - goto wait; - if (err < 0) - goto reply; - string pgidstr; - if (!cmd_getval(g_ceph_context, cmdmap, "pgid", pgidstr)) { - ss << "unable to parse 'pgid' value '" - << cmd_vartype_stringify(cmdmap["pgid"]) << "'"; - err = -EINVAL; - goto reply; - } - pg_t pgid; - if (!pgid.parse(pgidstr.c_str())) { - ss << "invalid pgid '" << pgidstr << "'"; - err = -EINVAL; - goto reply; - } - if (pending_inc.new_pg_upmap.count(pgid) || - pending_inc.old_pg_upmap.count(pgid)) { - dout(10) << __func__ << " waiting for pending update on " << pgid << dendl; - wait_for_finished_proposal(op, new C_RetryMessage(this, op)); - return true; - } + case OP_PG_UPMAP_ITEMS: // fall through + case OP_RM_PG_UPMAP_ITEMS: + if (pending_inc.new_pg_upmap_items.count(pgid) || + pending_inc.old_pg_upmap_items.count(pgid)) { + dout(10) << __func__ << " waiting for pending update on " + << pgid << dendl; + wait_for_finished_proposal(op, new C_RetryMessage(this, op)); + return true; + } + break; - pending_inc.old_pg_upmap.insert(pgid); - ss << "clear " << pgid << " pg_upmap mapping"; - goto update; - } else if (prefix == "osd pg-upmap-items") { - if (osdmap.require_osd_release < CEPH_RELEASE_LUMINOUS) { - ss << "you must complete the upgrade and set require_osd_release =" - << "luminous before using the new interface"; - err = -EPERM; - goto reply; - } - if (osdmap.require_min_compat_client < CEPH_RELEASE_LUMINOUS) { - ss << "require_min_compat_client " - << ceph_release_name(osdmap.require_min_compat_client) - << " < luminous, which is required for pg-upmap"; - err = -EPERM; - goto reply; - } - err = check_cluster_features(CEPH_FEATUREMASK_OSDMAP_PG_UPMAP, ss); - if (err == -EAGAIN) - goto wait; - if (err < 0) - goto reply; - string pgidstr; - if (!cmd_getval(g_ceph_context, cmdmap, "pgid", pgidstr)) { - ss << "unable to parse 'pgid' value '" - << cmd_vartype_stringify(cmdmap["pgid"]) << "'"; - err = -EINVAL; - goto reply; - } - pg_t pgid; - if (!pgid.parse(pgidstr.c_str())) { - ss << "invalid pgid '" << pgidstr << "'"; - err = -EINVAL; - goto reply; - } - if (!osdmap.pg_exists(pgid)) { - ss << "pg " << pgid << " does not exist"; - err = -ENOENT; - goto reply; - } - if (pending_inc.new_pg_upmap_items.count(pgid) || - pending_inc.old_pg_upmap_items.count(pgid)) { - dout(10) << __func__ << " waiting for pending update on " << pgid << dendl; - wait_for_finished_proposal(op, new C_RetryMessage(this, op)); - return true; - } - vector id_vec; - if (!cmd_getval(g_ceph_context, cmdmap, "id", id_vec)) { - ss << "unable to parse 'id' value(s) '" - << cmd_vartype_stringify(cmdmap["id"]) << "'"; - err = -EINVAL; - goto reply; - } - if (id_vec.size() % 2) { - ss << "you must specify pairs of osd ids to be remapped"; - err = -EINVAL; - goto reply; + default: + assert(0 == "invalid option"); } - vector> new_pg_upmap_items; - for (auto p = id_vec.begin(); p != id_vec.end(); ++p) { - int from = *p++; - int to = *p; - if (!osdmap.exists(from)) { - ss << "osd." << from << " does not exist"; - err = -ENOENT; - goto reply; + + switch (option) { + case OP_PG_UPMAP: + { + vector id_vec; + if (!cmd_getval(g_ceph_context, cmdmap, "id", id_vec)) { + ss << "unable to parse 'id' value(s) '" + << cmd_vartype_stringify(cmdmap["id"]) << "'"; + err = -EINVAL; + goto reply; + } + + int pool_min_size = osdmap.get_pg_pool_min_size(pgid); + if ((int)id_vec.size() < pool_min_size) { + ss << "num of osds (" << id_vec.size() <<") < pool min size (" + << pool_min_size << ")"; + err = -EINVAL; + goto reply; + } + + int pool_size = osdmap.get_pg_pool_size(pgid); + if ((int)id_vec.size() > pool_size) { + ss << "num of osds (" << id_vec.size() <<") > pool size (" + << pool_size << ")"; + err = -EINVAL; + goto reply; + } + + vector new_pg_upmap; + for (auto osd : id_vec) { + if (osd != CRUSH_ITEM_NONE && !osdmap.exists(osd)) { + ss << "osd." << osd << " does not exist"; + err = -ENOENT; + goto reply; + } + auto it = std::find(new_pg_upmap.begin(), new_pg_upmap.end(), osd); + if (it != new_pg_upmap.end()) { + ss << "osd." << osd << " already exists, "; + continue; + } + new_pg_upmap.push_back(osd); + } + + if (new_pg_upmap.empty()) { + ss << "no valid upmap items(pairs) is specified"; + err = -EINVAL; + goto reply; + } + + pending_inc.new_pg_upmap[pgid] = mempool::osdmap::vector( + new_pg_upmap.begin(), new_pg_upmap.end()); + ss << "set " << pgid << " pg_upmap mapping to " << new_pg_upmap; } - if (to != CRUSH_ITEM_NONE && !osdmap.exists(to)) { - ss << "osd." << to << " does not exist"; - err = -ENOENT; - goto reply; + break; + + case OP_RM_PG_UPMAP: + { + pending_inc.old_pg_upmap.insert(pgid); + ss << "clear " << pgid << " pg_upmap mapping"; } - new_pg_upmap_items.push_back(make_pair(from, to)); - } + break; - pending_inc.new_pg_upmap_items[pgid] = - mempool::osdmap::vector>( - new_pg_upmap_items.begin(), new_pg_upmap_items.end()); - ss << "set " << pgid << " pg_upmap_items mapping to " << new_pg_upmap_items; - goto update; - } else if (prefix == "osd rm-pg-upmap-items") { - if (osdmap.require_osd_release < CEPH_RELEASE_LUMINOUS) { - ss << "you must complete the upgrade and set require_osd_release =" - << "luminous before using the new interface"; - err = -EPERM; - goto reply; - } - if (osdmap.require_min_compat_client < CEPH_RELEASE_LUMINOUS) { - ss << "require_min_compat_client " - << ceph_release_name(osdmap.require_min_compat_client) - << " < luminous, which is required for pg-upmap"; - err = -EPERM; - goto reply; - } - err = check_cluster_features(CEPH_FEATUREMASK_OSDMAP_PG_UPMAP, ss); - if (err == -EAGAIN) - goto wait; - if (err < 0) - goto reply; - string pgidstr; - if (!cmd_getval(g_ceph_context, cmdmap, "pgid", pgidstr)) { - ss << "unable to parse 'pgid' value '" - << cmd_vartype_stringify(cmdmap["pgid"]) << "'"; - err = -EINVAL; - goto reply; - } - pg_t pgid; - if (!pgid.parse(pgidstr.c_str())) { - ss << "invalid pgid '" << pgidstr << "'"; - err = -EINVAL; - goto reply; - } - if (pending_inc.new_pg_upmap_items.count(pgid) || - pending_inc.old_pg_upmap_items.count(pgid)) { - dout(10) << __func__ << " waiting for pending update on " << pgid << dendl; - wait_for_finished_proposal(op, new C_RetryMessage(this, op)); - return true; + case OP_PG_UPMAP_ITEMS: + { + vector id_vec; + if (!cmd_getval(g_ceph_context, cmdmap, "id", id_vec)) { + ss << "unable to parse 'id' value(s) '" + << cmd_vartype_stringify(cmdmap["id"]) << "'"; + err = -EINVAL; + goto reply; + } + + if (id_vec.size() % 2) { + ss << "you must specify pairs of osd ids to be remapped"; + err = -EINVAL; + goto reply; + } + + int pool_size = osdmap.get_pg_pool_size(pgid); + if ((int)(id_vec.size() / 2) > pool_size) { + ss << "num of osd pairs (" << id_vec.size() / 2 <<") > pool size (" + << pool_size << ")"; + err = -EINVAL; + goto reply; + } + + vector> new_pg_upmap_items; + ostringstream items; + items << "["; + for (auto p = id_vec.begin(); p != id_vec.end(); ++p) { + int from = *p++; + int to = *p; + if (from == to) { + ss << "from osd." << from << " == to osd." << to << ", "; + continue; + } + if (!osdmap.exists(from)) { + ss << "osd." << from << " does not exist"; + err = -ENOENT; + goto reply; + } + if (to != CRUSH_ITEM_NONE && !osdmap.exists(to)) { + ss << "osd." << to << " does not exist"; + err = -ENOENT; + goto reply; + } + new_pg_upmap_items.push_back(make_pair(from, to)); + items << from << "->" << to << ","; + } + string out(items.str()); + out.resize(out.size() - 1); // drop last ',' + out += "]"; + + if (new_pg_upmap_items.empty()) { + ss << "no valid upmap items(pairs) is specified"; + err = -EINVAL; + goto reply; + } + + pending_inc.new_pg_upmap_items[pgid] = + mempool::osdmap::vector>( + new_pg_upmap_items.begin(), new_pg_upmap_items.end()); + ss << "set " << pgid << " pg_upmap_items mapping to " << out; + } + break; + + case OP_RM_PG_UPMAP_ITEMS: + { + pending_inc.old_pg_upmap_items.insert(pgid); + ss << "clear " << pgid << " pg_upmap_items mapping"; + } + break; + + default: + assert(0 == "invalid option"); } - pending_inc.old_pg_upmap_items.insert(pgid); - ss << "clear " << pgid << " pg_upmap_items mapping"; goto update; } else if (prefix == "osd primary-affinity") { int64_t id; @@ -9079,7 +9241,7 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op, wait_for_finished_proposal( op, new Monitor::C_Command(mon, op, 0, rs, rdata, get_last_committed() + 1)); - return true; + return true; } else if (prefix == "osd lost") { int64_t id; if (!cmd_getval(g_ceph_context, cmdmap, "id", id)) { @@ -9206,7 +9368,7 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op, // make sure authmon is writeable. if (!mon->authmon()->is_writeable()) { dout(10) << __func__ << " waiting for auth mon to be writeable for " - << "osd destroy" << dendl; + << "osd new" << dendl; mon->authmon()->wait_for_writeable(op, new C_RetryMessage(this, op)); return false; } @@ -9344,10 +9506,21 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op, utime_t expires = ceph_clock_now(); double d; // default one hour - cmd_getval(g_ceph_context, cmdmap, "expire", d, double(60*60)); + cmd_getval(g_ceph_context, cmdmap, "expire", d, + g_conf->mon_osd_blacklist_default_expire); expires += d; pending_inc.new_blacklist[addr] = expires; + + { + // cancel any pending un-blacklisting request too + auto it = std::find(pending_inc.old_blacklist.begin(), + pending_inc.old_blacklist.end(), addr); + if (it != pending_inc.old_blacklist.end()) { + pending_inc.old_blacklist.erase(it); + } + } + ss << "blacklisting " << addr << " until " << expires << " (" << d << " sec)"; getline(ss, rs); wait_for_finished_proposal(op, new Monitor::C_Command(mon, op, 0, rs, @@ -9463,7 +9636,7 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op, string pool_type_str; cmd_getval(g_ceph_context, cmdmap, "pool_type", pool_type_str); if (pool_type_str.empty()) - pool_type_str = pg_pool_t::get_default_type(); + pool_type_str = g_conf->osd_pool_default_type; string poolstr; cmd_getval(g_ceph_context, cmdmap, "pool", poolstr); @@ -10686,7 +10859,7 @@ bool OSDMonitor::_check_remove_tier( int OSDMonitor::_prepare_remove_pool( int64_t pool, ostream *ss, bool no_fake) { - dout(10) << "_prepare_remove_pool " << pool << dendl; + dout(10) << __func__ << " " << pool << dendl; const pg_pool_t *p = osdmap.get_pg_pool(pool); int r = _check_remove_pool(pool, *p, ss); if (r < 0) @@ -10703,7 +10876,7 @@ int OSDMonitor::_prepare_remove_pool( } if (pending_inc.old_pools.count(pool)) { - dout(10) << "_prepare_remove_pool " << pool << " already pending removal" + dout(10) << __func__ << " " << pool << " already pending removal" << dendl; return 0; } @@ -10720,25 +10893,44 @@ int OSDMonitor::_prepare_remove_pool( // remove pending_inc.old_pools.insert(pool); - // remove any pg_temp mappings for this pool too + // remove any pg_temp mappings for this pool for (auto p = osdmap.pg_temp->begin(); p != osdmap.pg_temp->end(); ++p) { if (p->first.pool() == (uint64_t)pool) { - dout(10) << "_prepare_remove_pool " << pool << " removing obsolete pg_temp " + dout(10) << __func__ << " " << pool << " removing obsolete pg_temp " << p->first << dendl; pending_inc.new_pg_temp[p->first].clear(); } } + // remove any primary_temp mappings for this pool for (auto p = osdmap.primary_temp->begin(); p != osdmap.primary_temp->end(); ++p) { if (p->first.pool() == (uint64_t)pool) { - dout(10) << "_prepare_remove_pool " << pool + dout(10) << __func__ << " " << pool << " removing obsolete primary_temp" << p->first << dendl; pending_inc.new_primary_temp[p->first] = -1; } } + // remove any pg_upmap mappings for this pool + for (auto& p : osdmap.pg_upmap) { + if (p.first.pool() == (uint64_t)pool) { + dout(10) << __func__ << " " << pool + << " removing obsolete pg_upmap " + << p.first << dendl; + pending_inc.old_pg_upmap.insert(p.first); + } + } + // remove any pg_upmap_items mappings for this pool + for (auto& p : osdmap.pg_upmap_items) { + if (p.first.pool() == (uint64_t)pool) { + dout(10) << __func__ << " " << pool + << " removing obsolete pg_upmap_items " << p.first + << dendl; + pending_inc.old_pg_upmap_items.insert(p.first); + } + } return 0; } diff --git a/ceph/src/mon/OSDMonitor.h b/ceph/src/mon/OSDMonitor.h index 3f258815a..9a9441079 100644 --- a/ceph/src/mon/OSDMonitor.h +++ b/ceph/src/mon/OSDMonitor.h @@ -147,7 +147,7 @@ public: bool check_failures(utime_t now); bool check_failure(utime_t now, int target_osd, failure_info_t& fi); - void force_failure(utime_t now, int target_osd, int by); + void force_failure(int target_osd, int by); // the time of last msg(MSG_ALIVE and MSG_PGTEMP) proposed without delay utime_t last_attempted_minwait_time; @@ -359,8 +359,6 @@ private: void update_pool_flags(int64_t pool_id, uint64_t flags); bool update_pools_status(); - void get_pools_health(list >& summary, - list > *detail) const; bool prepare_set_flag(MonOpRequestRef op, int flag); bool prepare_unset_flag(MonOpRequestRef op, int flag); diff --git a/ceph/src/mon/OldHealthMonitor.cc b/ceph/src/mon/OldHealthMonitor.cc new file mode 100644 index 000000000..d7264a7ee --- /dev/null +++ b/ceph/src/mon/OldHealthMonitor.cc @@ -0,0 +1,107 @@ +// -*- 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) 2013 Inktank, 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 +#include +#include + +// #include +// Because intusive_ptr clobbers our assert... +#include "include/assert.h" + +#include "mon/Monitor.h" +#include "mon/HealthService.h" +#include "mon/OldHealthMonitor.h" +#include "mon/DataHealthService.h" + +#include "messages/MMonHealth.h" +#include "common/Formatter.h" +// #include "common/config.h" + +#define dout_subsys ceph_subsys_mon +#undef dout_prefix +#define dout_prefix _prefix(_dout, mon, this) +static ostream& _prefix(std::ostream *_dout, const Monitor *mon, + const OldHealthMonitor *hmon) { + return *_dout << "mon." << mon->name << "@" << mon->rank + << "(" << mon->get_state_name() << ")." << hmon->get_name() + << "(" << hmon->get_epoch() << ") "; +} + +void OldHealthMonitor::init() +{ + dout(10) << __func__ << dendl; + assert(services.empty()); + services[HealthService::SERVICE_HEALTH_DATA] = new DataHealthService(mon); + + for (map::iterator it = services.begin(); + it != services.end(); + ++it) { + it->second->init(); + } +} + +bool OldHealthMonitor::service_dispatch(MonOpRequestRef op) +{ + assert(op->get_req()->get_type() == MSG_MON_HEALTH); + MMonHealth *hm = static_cast(op->get_req()); + int service_type = hm->get_service_type(); + if (services.count(service_type) == 0) { + dout(1) << __func__ << " service type " << service_type + << " not registered -- drop message!" << dendl; + return false; + } + return services[service_type]->service_dispatch(op); +} + +void OldHealthMonitor::start_epoch() { + epoch_t epoch = get_epoch(); + for (map::iterator it = services.begin(); + it != services.end(); ++it) { + it->second->start(epoch); + } +} + +void OldHealthMonitor::finish_epoch() { + generic_dout(20) << "OldHealthMonitor::finish_epoch()" << dendl; + for (map::iterator it = services.begin(); + it != services.end(); ++it) { + assert(it->second != NULL); + it->second->finish(); + } +} + +void OldHealthMonitor::service_shutdown() +{ + dout(0) << "OldHealthMonitor::service_shutdown " + << services.size() << " services" << dendl; + for (map::iterator it = services.begin(); + it != services.end(); + ++it) { + it->second->shutdown(); + delete it->second; + } + services.clear(); +} + +void OldHealthMonitor::get_health( + list >& summary, + list > *detail) +{ + for (map::iterator it = services.begin(); + it != services.end(); + ++it) { + it->second->get_health(summary, detail); + } +} diff --git a/ceph/src/mon/OldHealthMonitor.h b/ceph/src/mon/OldHealthMonitor.h new file mode 100644 index 000000000..f29569361 --- /dev/null +++ b/ceph/src/mon/OldHealthMonitor.h @@ -0,0 +1,66 @@ +// -*- 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) 2013 Inktank, 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 CEPH_MON_OLDHEALTHMONITOR_H +#define CEPH_MON_OLDHEALTHMONITOR_H + +#include "mon/QuorumService.h" + +//forward declaration +namespace ceph { class Formatter; } +class HealthService; + +class OldHealthMonitor : public QuorumService +{ + map services; + +protected: + void service_shutdown() override; + +public: + OldHealthMonitor(Monitor *m) : QuorumService(m) { } + ~OldHealthMonitor() override { + assert(services.empty()); + } + + + /** + * @defgroup OldHealthMonitor_Inherited_h Inherited abstract methods + * @{ + */ + void init() override; + void get_health(list >& summary, + list > *detail) override; + bool service_dispatch(MonOpRequestRef op) override; + + void start_epoch() override; + + void finish_epoch() override; + + void cleanup() override { } + void service_tick() override { } + + int get_type() override { + return QuorumService::SERVICE_HEALTH; + } + + string get_name() const override { + return "health"; + } + + /** + * @} // OldHealthMonitor_Inherited_h + */ +}; + +#endif diff --git a/ceph/src/mon/PGMap.cc b/ceph/src/mon/PGMap.cc index c0277b7a5..913e035f7 100644 --- a/ceph/src/mon/PGMap.cc +++ b/ceph/src/mon/PGMap.cc @@ -1,6 +1,8 @@ // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- // vim: ts=8 sw=2 smarttab +#include + #include "PGMap.h" #define dout_subsys ceph_subsys_mon @@ -683,6 +685,7 @@ void PGMapDigest::dump_pool_stats_full( int mk = m + k; assert(mk != 0); avail = avail * k / mk; + assert(k != 0); raw_used_rate = (float)mk / k; } else { raw_used_rate = 0.0; @@ -2547,7 +2550,671 @@ namespace { ss << pgs_count << " unscrubbed pgs"; summary.push_back(make_pair(HEALTH_WARN, ss.str())); } + } +} + +void PGMap::get_health_checks( + CephContext *cct, + const OSDMap& osdmap, + health_check_map_t *checks) const +{ + utime_t now = ceph_clock_now(); + const unsigned max = cct->_conf->mon_health_max_detail; + const auto& pools = osdmap.get_pools(); + + checks->clear(); + + typedef enum pg_consequence_t { + UNAVAILABLE = 1, // Client IO to the pool may block + DEGRADED = 2, // Fewer than the requested number of replicas are present + DEGRADED_FULL = 3, // Fewer than the request number of replicas may be present + // and insufficiet resources are present to fix this + DAMAGED = 4 // The data may be missing or inconsistent on disk and + // requires repair + } pg_consequence_t; + + // For a given PG state, how should it be reported at the pool level? + class PgStateResponse { + public: + pg_consequence_t consequence; + typedef std::function< utime_t(const pg_stat_t&) > stuck_cb; + stuck_cb stuck_since; + bool invert; + + PgStateResponse(const pg_consequence_t &c, stuck_cb s) + : consequence(c), stuck_since(s), invert(false) + { + } + + PgStateResponse(const pg_consequence_t &c, stuck_cb s, bool i) + : consequence(c), stuck_since(s), invert(i) + { + } + }; + + // Record the PG state counts that contributed to a reported pool state + class PgCauses { + public: + // Map of PG_STATE_* to number of pgs in that state. + std::map states; + + // List of all PG IDs that had a state contributing + // to this health condition. + std::set pgs; + + std::map pg_messages; + }; + + // Map of PG state to how to respond to it + std::map state_to_response = { + // Immediate reports + { PG_STATE_INCONSISTENT, {DAMAGED, {}} }, + { PG_STATE_INCOMPLETE, {DEGRADED, {}} }, + { PG_STATE_REPAIR, {DAMAGED, {}} }, + { PG_STATE_SNAPTRIM_ERROR, {DAMAGED, {}} }, + { PG_STATE_BACKFILL_TOOFULL, {DEGRADED, {}} }, + { PG_STATE_RECOVERY_TOOFULL, {DEGRADED, {}} }, + { PG_STATE_DEGRADED, {DEGRADED, {}} }, + { PG_STATE_DOWN, {UNAVAILABLE, {}} }, + // Delayed (wait until stuck) reports + { PG_STATE_PEERING, {UNAVAILABLE, [](const pg_stat_t &p){return p.last_peered;} } }, + { PG_STATE_UNDERSIZED, {DEGRADED, [](const pg_stat_t &p){return p.last_fullsized;} } }, + { PG_STATE_STALE, {UNAVAILABLE, [](const pg_stat_t &p){return p.last_unstale;} } }, + // Delayed and inverted reports + { PG_STATE_ACTIVE, {UNAVAILABLE, [](const pg_stat_t &p){return p.last_active;}, true} }, + { PG_STATE_CLEAN, {DEGRADED, [](const pg_stat_t &p){return p.last_clean;}, true} } + }; + + // Specialized state printer that takes account of inversion of + // ACTIVE, CLEAN checks. + auto state_name = [](const uint32_t &state) { + // Special cases for the states that are inverted checks + if (state == PG_STATE_CLEAN) { + return std::string("unclean"); + } else if (state == PG_STATE_ACTIVE) { + return std::string("inactive"); + } else { + return pg_state_string(state); + } + }; + + // Map of what is wrong to information about why, implicitly also stores + // the list of what is wrong. + std::map detected; + + // Optimisation: trim down the number of checks to apply based on + // the summary counters + std::map possible_responses; + for (const auto &i : num_pg_by_state) { + for (const auto &j : state_to_response) { + if (!j.second.invert) { + // Check for normal tests by seeing if any pgs have the flag + if (i.first & j.first) { + possible_responses.insert(j); + } + } + } + } + + for (const auto &j : state_to_response) { + if (j.second.invert) { + // Check for inverted tests by seeing if not-all pgs have the flag + const auto &found = num_pg_by_state.find(j.first); + if (found == num_pg_by_state.end() || found->second != num_pg) { + possible_responses.insert(j); + } + } + } + + utime_t cutoff = now - utime_t(cct->_conf->mon_pg_stuck_threshold, 0); + // Loop over all PGs, if there are any possibly-unhealthy states in there + if (!possible_responses.empty()) { + for (const auto& i : pg_stat) { + const auto &pg_id = i.first; + const auto &pg_info = i.second; + + for (const auto &j : state_to_response) { + const auto &pg_response_state = j.first; + const auto &pg_response = j.second; + + // Apply the state test + if (!(bool(pg_info.state & pg_response_state) != pg_response.invert)) { + continue; + } + + // Apply stuckness test if needed + if (pg_response.stuck_since) { + // Delayed response, check for stuckness + utime_t last_whatever = pg_response.stuck_since(pg_info); + if (last_whatever >= cutoff) { + // Not stuck enough, ignore. + continue; + } else { + + } + } + + auto &causes = detected[pg_response.consequence]; + causes.states[pg_response_state]++; + causes.pgs.insert(pg_id); + + // Don't bother composing detail string if we have already recorded + // too many + if (causes.pg_messages.size() > max) { + continue; + } + + std::ostringstream ss; + if (pg_response.stuck_since) { + utime_t since = pg_response.stuck_since(pg_info); + ss << "pg " << pg_id << " is stuck " << state_name(pg_response_state); + if (since == utime_t()) { + ss << " since forever"; + } else { + utime_t dur = now - since; + ss << " for " << dur; + } + ss << ", current state " << pg_state_string(pg_info.state) + << ", last acting " << pg_info.acting; + } else { + ss << "pg " << pg_id << " is " + << pg_state_string(pg_info.state); + ss << ", acting " << pg_info.acting; + if (pg_info.stats.sum.num_objects_unfound) { + ss << ", " << pg_info.stats.sum.num_objects_unfound + << " unfound"; + } + } + + if (pg_info.state & PG_STATE_INCOMPLETE) { + const pg_pool_t *pi = osdmap.get_pg_pool(pg_id.pool()); + if (pi && pi->min_size > 1) { + ss << " (reducing pool " + << osdmap.get_pool_name(pg_id.pool()) + << " min_size from " << (int)pi->min_size + << " may help; search ceph.com/docs for 'incomplete')"; + } + } + + causes.pg_messages[pg_id] = ss.str(); + } + } + } else { + dout(10) << __func__ << " skipping loop over PGs: counters look OK" << dendl; + } + + for (const auto &i : detected) { + std::string health_code; + health_status_t sev; + std::string summary; + switch(i.first) { + case UNAVAILABLE: + health_code = "PG_AVAILABILITY"; + sev = HEALTH_WARN; + summary = "Reduced data availability: "; + break; + case DEGRADED: + health_code = "PG_DEGRADED"; + summary = "Degraded data redundancy: "; + sev = HEALTH_WARN; + break; + case DEGRADED_FULL: + health_code = "PG_DEGRADED_FULL"; + summary = "Degraded data redundancy (low space): "; + sev = HEALTH_ERR; + break; + case DAMAGED: + health_code = "PG_DAMAGED"; + summary = "Possible data damage: "; + sev = HEALTH_ERR; + break; + default: + assert(false); + } + + if (i.first == DEGRADED) { + if (pg_sum.stats.sum.num_objects_degraded && + pg_sum.stats.sum.num_object_copies > 0) { + double pc = (double)pg_sum.stats.sum.num_objects_degraded / + (double)pg_sum.stats.sum.num_object_copies * (double)100.0; + char b[20]; + snprintf(b, sizeof(b), "%.3lf", pc); + ostringstream ss; + ss << pg_sum.stats.sum.num_objects_degraded + << "/" << pg_sum.stats.sum.num_object_copies << " objects degraded (" + << b << "%)"; + + // Throw in a comma for the benefit of the following PG counts + summary += ss.str() + ", "; + } + } + + // Compose summary message saying how many PGs in what states led + // to this health check failing + std::vector pg_msgs; + for (const auto &j : i.second.states) { + std::ostringstream msg; + msg << j.second << (j.second > 1 ? " pgs " : " pg ") << state_name(j.first); + pg_msgs.push_back(msg.str()); + } + summary += joinify(pg_msgs.begin(), pg_msgs.end(), std::string(", ")); + + + + health_check_t *check = &checks->add( + health_code, + sev, + summary); + + // Compose list of PGs contributing to this health check failing + for (const auto &j : i.second.pg_messages) { + check->detail.push_back(j.second); + } + } + + // OSD_SKEWED_USAGE + if (cct->_conf->mon_warn_osd_usage_min_max_delta) { + int max_osd = -1, min_osd = -1; + float max_osd_usage = 0.0, min_osd_usage = 1.0; + for (auto p = osd_stat.begin(); p != osd_stat.end(); ++p) { + // kb should never be 0, but avoid divide by zero in case of corruption + if (p->second.kb <= 0) + continue; + float usage = ((float)p->second.kb_used) / ((float)p->second.kb); + if (usage > max_osd_usage) { + max_osd_usage = usage; + max_osd = p->first; + } + if (usage < min_osd_usage) { + min_osd_usage = usage; + min_osd = p->first; + } + } + float diff = max_osd_usage - min_osd_usage; + if (diff > cct->_conf->mon_warn_osd_usage_min_max_delta) { + auto& d = checks->add("OSD_SKEWED_USAGE", HEALTH_WARN, + "skewed osd utilization"); + ostringstream ss; + ss << "difference between min (osd." << min_osd << " at " + << roundf(min_osd_usage*1000.0)/100.0 + << "%) and max (osd." << max_osd << " at " + << roundf(max_osd_usage*1000.0)/100.0 + << "%) osd usage " << roundf(diff*1000.0)/100.0 << "% > " + << roundf(cct->_conf->mon_warn_osd_usage_min_max_delta*1000.0)/100.0 + << " (mon_warn_osd_usage_min_max_delta)"; + d.detail.push_back(ss.str()); + } + } + + // OSD_SCRUB_ERRORS + if (pg_sum.stats.sum.num_scrub_errors) { + ostringstream ss; + ss << pg_sum.stats.sum.num_scrub_errors << " scrub errors"; + checks->add("OSD_SCRUB_ERRORS", HEALTH_ERR, ss.str()); + } + + // CACHE_POOL_NEAR_FULL + { + list detail; + unsigned num_pools = 0; + for (auto& p : pools) { + if ((!p.second.target_max_objects && !p.second.target_max_bytes) || + !pg_pool_sum.count(p.first)) { + continue; + } + bool nearfull = false; + const string& name = osdmap.get_pool_name(p.first); + const pool_stat_t& st = get_pg_pool_sum_stat(p.first); + uint64_t ratio = p.second.cache_target_full_ratio_micro + + ((1000000 - p.second.cache_target_full_ratio_micro) * + cct->_conf->mon_cache_target_full_warn_ratio); + if (p.second.target_max_objects && + (uint64_t)(st.stats.sum.num_objects - + st.stats.sum.num_objects_hit_set_archive) > + p.second.target_max_objects * (ratio / 1000000.0)) { + ostringstream ss; + ss << "cache pool '" << name << "' with " + << si_t(st.stats.sum.num_objects) + << " objects at/near target max " + << si_t(p.second.target_max_objects) << " objects"; + detail.push_back(ss.str()); + nearfull = true; + } + if (p.second.target_max_bytes && + (uint64_t)(st.stats.sum.num_bytes - + st.stats.sum.num_bytes_hit_set_archive) > + p.second.target_max_bytes * (ratio / 1000000.0)) { + ostringstream ss; + ss << "cache pool '" << name + << "' with " << si_t(st.stats.sum.num_bytes) + << "B at/near target max " + << si_t(p.second.target_max_bytes) << "B"; + detail.push_back(ss.str()); + nearfull = true; + } + if (nearfull) { + ++num_pools; + } + } + if (!detail.empty()) { + ostringstream ss; + ss << num_pools << " cache pools at or near target size"; + auto& d = checks->add("CACHE_POOL_NEAR_FULL", HEALTH_WARN, ss.str()); + d.detail.swap(detail); + } + } + + // TOO_FEW_PGS + int num_in = osdmap.get_num_in_osds(); + int sum_pg_up = MAX(pg_sum.up, static_cast(pg_stat.size())); + if (num_in && + cct->_conf->mon_pg_warn_min_per_osd > 0 && + osdmap.get_pools().size() > 0) { + int per = sum_pg_up / num_in; + if (per < cct->_conf->mon_pg_warn_min_per_osd && per) { + ostringstream ss; + ss << "too few PGs per OSD (" << per + << " < min " << cct->_conf->mon_pg_warn_min_per_osd << ")"; + checks->add("TOO_FEW_PGS", HEALTH_WARN, ss.str()); + } + } + + // TOO_MANY_PGS + if (num_in && cct->_conf->mon_pg_warn_max_per_osd > 0) { + int per = sum_pg_up / num_in; + if (per > cct->_conf->mon_pg_warn_max_per_osd) { + ostringstream ss; + ss << "too many PGs per OSD (" << per + << " > max " << cct->_conf->mon_pg_warn_max_per_osd << ")"; + checks->add("TOO_MANY_PGS", HEALTH_WARN, ss.str()); + } + } + + // SMALLER_PGP_NUM + // MANY_OBJECTS_PER_PG + if (!pg_stat.empty()) { + list pgp_detail, many_detail; + for (auto p = pg_pool_sum.begin(); + p != pg_pool_sum.end(); + ++p) { + const pg_pool_t *pi = osdmap.get_pg_pool(p->first); + if (!pi) + continue; // in case osdmap changes haven't propagated to PGMap yet + const string& name = osdmap.get_pool_name(p->first); + if (pi->get_pg_num() > pi->get_pgp_num() && + !(name.find(".DELETED") != string::npos && + cct->_conf->mon_fake_pool_delete)) { + ostringstream ss; + ss << "pool " << name << " pg_num " + << pi->get_pg_num() << " > pgp_num " << pi->get_pgp_num(); + pgp_detail.push_back(ss.str()); + } + int average_objects_per_pg = pg_sum.stats.sum.num_objects / pg_stat.size(); + if (average_objects_per_pg > 0 && + pg_sum.stats.sum.num_objects >= cct->_conf->mon_pg_warn_min_objects && + p->second.stats.sum.num_objects >= + cct->_conf->mon_pg_warn_min_pool_objects) { + int objects_per_pg = p->second.stats.sum.num_objects / pi->get_pg_num(); + float ratio = (float)objects_per_pg / (float)average_objects_per_pg; + if (cct->_conf->mon_pg_warn_max_object_skew > 0 && + ratio > cct->_conf->mon_pg_warn_max_object_skew) { + ostringstream ss; + ss << "pool " << name << " objects per pg (" + << objects_per_pg << ") is more than " << ratio + << " times cluster average (" + << average_objects_per_pg << ")"; + many_detail.push_back(ss.str()); + } + } + } + if (!pgp_detail.empty()) { + ostringstream ss; + ss << pgp_detail.size() << " pools have pg_num > pgp_num"; + auto& d = checks->add("SMALLER_PGP_NUM", HEALTH_WARN, ss.str()); + d.detail.swap(pgp_detail); + } + if (!many_detail.empty()) { + ostringstream ss; + ss << many_detail.size() << " pools have many more objects per pg than" + << " average"; + auto& d = checks->add("MANY_OBJECTS_PER_PG", HEALTH_WARN, ss.str()); + d.detail.swap(many_detail); + } + } + // POOL_FULL + // POOL_NEAR_FULL + { + float warn_threshold = (float)g_conf->mon_pool_quota_warn_threshold/100; + float crit_threshold = (float)g_conf->mon_pool_quota_crit_threshold/100; + list full_detail, nearfull_detail; + unsigned full_pools = 0, nearfull_pools = 0; + for (auto it : pools) { + auto it2 = pg_pool_sum.find(it.first); + if (it2 == pg_pool_sum.end()) { + continue; + } + const pool_stat_t *pstat = &it2->second; + const object_stat_sum_t& sum = pstat->stats.sum; + const string& pool_name = osdmap.get_pool_name(it.first); + const pg_pool_t &pool = it.second; + bool full = false, nearfull = false; + if (pool.quota_max_objects > 0) { + stringstream ss; + if ((uint64_t)sum.num_objects >= pool.quota_max_objects) { + } else if (crit_threshold > 0 && + sum.num_objects >= pool.quota_max_objects*crit_threshold) { + ss << "pool '" << pool_name + << "' has " << sum.num_objects << " objects" + << " (max " << pool.quota_max_objects << ")"; + full_detail.push_back(ss.str()); + full = true; + } else if (warn_threshold > 0 && + sum.num_objects >= pool.quota_max_objects*warn_threshold) { + ss << "pool '" << pool_name + << "' has " << sum.num_objects << " objects" + << " (max " << pool.quota_max_objects << ")"; + nearfull_detail.push_back(ss.str()); + nearfull = true; + } + } + if (pool.quota_max_bytes > 0) { + stringstream ss; + if ((uint64_t)sum.num_bytes >= pool.quota_max_bytes) { + } else if (crit_threshold > 0 && + sum.num_bytes >= pool.quota_max_bytes*crit_threshold) { + ss << "pool '" << pool_name + << "' has " << si_t(sum.num_bytes) << " bytes" + << " (max " << si_t(pool.quota_max_bytes) << ")"; + full_detail.push_back(ss.str()); + full = true; + } else if (warn_threshold > 0 && + sum.num_bytes >= pool.quota_max_bytes*warn_threshold) { + ss << "pool '" << pool_name + << "' has " << si_t(sum.num_bytes) << " bytes" + << " (max " << si_t(pool.quota_max_bytes) << ")"; + nearfull_detail.push_back(ss.str()); + nearfull = true; + } + } + if (full) { + ++full_pools; + } + if (nearfull) { + ++nearfull_pools; + } + } + if (full_pools) { + ostringstream ss; + ss << full_pools << " pools full"; + auto& d = checks->add("POOL_FULL", HEALTH_ERR, ss.str()); + d.detail.swap(full_detail); + } + if (nearfull_pools) { + ostringstream ss; + ss << nearfull_pools << " pools full"; + auto& d = checks->add("POOL_NEAR_FULL", HEALTH_WARN, ss.str()); + d.detail.swap(nearfull_detail); + } + } + + // OBJECT_MISPLACED + if (pg_sum.stats.sum.num_objects_misplaced && + pg_sum.stats.sum.num_object_copies > 0) { + double pc = (double)pg_sum.stats.sum.num_objects_misplaced / + (double)pg_sum.stats.sum.num_object_copies * (double)100.0; + char b[20]; + snprintf(b, sizeof(b), "%.3lf", pc); + ostringstream ss; + ss << pg_sum.stats.sum.num_objects_misplaced + << "/" << pg_sum.stats.sum.num_object_copies << " objects misplaced (" + << b << "%)"; + checks->add("OBJECT_MISPLACED", HEALTH_WARN, ss.str()); + } + + // OBJECT_UNFOUND + if (pg_sum.stats.sum.num_objects_unfound && + pg_sum.stats.sum.num_objects) { + double pc = (double)pg_sum.stats.sum.num_objects_unfound / + (double)pg_sum.stats.sum.num_objects * (double)100.0; + char b[20]; + snprintf(b, sizeof(b), "%.3lf", pc); + ostringstream ss; + ss << pg_sum.stats.sum.num_objects_unfound + << "/" << pg_sum.stats.sum.num_objects << " unfound (" << b << "%)"; + checks->add("OBJECT_UNFOUND", HEALTH_WARN, ss.str()); + } + + // REQUEST_SLOW + // REQUEST_STUCK + if (cct->_conf->mon_osd_warn_op_age > 0 && + osd_sum.op_queue_age_hist.upper_bound() > + cct->_conf->mon_osd_warn_op_age) { + list warn_detail, error_detail; + unsigned warn = 0, error = 0; + float err_age = + cct->_conf->mon_osd_warn_op_age * cct->_conf->mon_osd_err_op_age_ratio; + const pow2_hist_t& h = osd_sum.op_queue_age_hist; + for (unsigned i = h.h.size() - 1; i > 0; --i) { + float ub = (float)(1 << i) / 1000.0; + if (ub < cct->_conf->mon_osd_warn_op_age) + break; + if (h.h[i]) { + ostringstream ss; + ss << h.h[i] << " ops are blocked > " << ub << " sec"; + if (ub > err_age) { + error += h.h[i]; + error_detail.push_back(ss.str()); + } else { + warn += h.h[i]; + warn_detail.push_back(ss.str()); + } + } + } + + map> warn_osd_by_max; // max -> osds + map> error_osd_by_max; // max -> osds + if (!warn_detail.empty() || !error_detail.empty()) { + for (auto& p : osd_stat) { + const pow2_hist_t& h = p.second.op_queue_age_hist; + for (unsigned i = h.h.size() - 1; i > 0; --i) { + float ub = (float)(1 << i) / 1000.0; + if (ub < cct->_conf->mon_osd_warn_op_age) + break; + if (h.h[i]) { + if (ub > err_age) { + error_osd_by_max[ub].insert(p.first); + } else { + warn_osd_by_max[ub].insert(p.first); + } + break; + } + } + } + } + + if (!warn_detail.empty()) { + ostringstream ss; + ss << warn << " slow requests are blocked > " + << cct->_conf->mon_osd_warn_op_age << " sec"; + auto& d = checks->add("REQUEST_SLOW", HEALTH_WARN, ss.str()); + d.detail.swap(warn_detail); + int left = max; + for (auto& p : warn_osd_by_max) { + ostringstream ss; + if (p.second.size() > 1) { + ss << "osds " << p.second; + } else { + ss << "osd." << *p.second.begin(); + } + ss << " have blocked requests > " << p.first << " sec"; + d.detail.push_back(ss.str()); + if (--left == 0) { + break; + } + } + } + if (!error_detail.empty()) { + ostringstream ss; + ss << warn << " stuck requests are blocked > " + << err_age << " sec"; + auto& d = checks->add("REQUEST_STUCK", HEALTH_ERR, ss.str()); + d.detail.swap(error_detail); + int left = max; + for (auto& p : error_osd_by_max) { + ostringstream ss; + if (p.second.size() > 1) { + ss << "osds " << p.second; + } else { + ss << "osd." << *p.second.begin(); + } + ss << " have stuck requests > " << p.first << " sec"; + d.detail.push_back(ss.str()); + if (--left == 0) { + break; + } + } + } + } + + // PG_NOT_SCRUBBED + // PG_NOT_DEEP_SCRUBBED + { + list detail, deep_detail; + const double age = cct->_conf->mon_warn_not_scrubbed + + cct->_conf->mon_scrub_interval; + utime_t cutoff = now; + cutoff -= age; + const double deep_age = cct->_conf->mon_warn_not_deep_scrubbed + + cct->_conf->osd_deep_scrub_interval; + utime_t deep_cutoff = now; + deep_cutoff -= deep_age; + for (auto& p : pg_stat) { + if (p.second.last_scrub_stamp < cutoff) { + ostringstream ss; + ss << "pg " << p.first << " not scrubbed since " + << p.second.last_scrub_stamp; + detail.push_back(ss.str()); + } + if (p.second.last_deep_scrub_stamp < deep_cutoff) { + ostringstream ss; + ss << "pg " << p.first << " not deep-scrubbed since " + << p.second.last_deep_scrub_stamp; + deep_detail.push_back(ss.str()); + } + } + if (!detail.empty()) { + ostringstream ss; + ss << detail.size() << " pgs not scrubbed for " << age; + auto& d = checks->add("PG_NOT_SCRUBBED", HEALTH_WARN, ss.str()); + d.detail.swap(detail); + } + if (!deep_detail.empty()) { + ostringstream ss; + ss << deep_detail.size() << " pgs not deep-scrubbed for " << age; + auto& d = checks->add("PG_NOT_DEEP_SCRUBBED", HEALTH_WARN, ss.str()); + d.detail.swap(deep_detail); + } } } @@ -2589,6 +3256,8 @@ void PGMap::get_health( note["backfill_toofull"] += p->second; if (p->first & PG_STATE_RECOVERY_TOOFULL) note["recovery_toofull"] += p->second; + if (p->first & PG_STATE_SNAPTRIM_ERROR) + note["snaptrim_error"] += p->second; } mempool::pgmap::unordered_map stuck_pgs; @@ -2789,11 +3458,11 @@ void PGMap::get_health( float diff = max_osd_usage - min_osd_usage; if (diff > cct->_conf->mon_warn_osd_usage_min_max_delta) { ostringstream ss; - ss << "difference between min (" << roundf(min_osd_usage*1000.0)/100.0 - << "%) and max (" << roundf(max_osd_usage*1000.0)/100.0 - << "%) osd usage " << roundf(diff*1000.0)/100.0 << "% > " - << roundf(cct->_conf->mon_warn_osd_usage_min_max_delta*1000.0)/100.0 - << " (mon_warn_osd_usage_min_max_delta)"; + ss << "difference between min (" << roundf(min_osd_usage*1000.0)/10.0 + << "%) and max (" << roundf(max_osd_usage*1000.0)/10.0 + << "%) osd usage " << roundf(diff*1000.0)/10.0 << "% > " + << roundf(cct->_conf->mon_warn_osd_usage_min_max_delta*1000.0)/10.0 + << "% (mon_warn_osd_usage_min_max_delta)"; summary.push_back(make_pair(HEALTH_WARN, ss.str())); if (detail) detail->push_back(make_pair(HEALTH_WARN, ss.str())); @@ -2870,6 +3539,10 @@ void PGMap::get_health( // pg skew int num_in = osdmap.get_num_in_osds(); int sum_pg_up = MAX(pg_sum.up, static_cast(pg_stat.size())); + int sum_objects = pg_sum.stats.sum.num_objects; + if (sum_objects < cct->_conf->mon_pg_warn_min_objects) { + return; + } if (num_in && cct->_conf->mon_pg_warn_min_per_osd > 0) { int per = sum_pg_up / num_in; if (per < cct->_conf->mon_pg_warn_min_per_osd && per) { @@ -2931,6 +3604,70 @@ void PGMap::get_health( } } + for (auto it : pools) { + auto it2 = pg_pool_sum.find(it.first); + if (it2 == pg_pool_sum.end()) { + continue; + } + const pool_stat_t *pstat = &it2->second; + const object_stat_sum_t& sum = pstat->stats.sum; + const string& pool_name = osdmap.get_pool_name(it.first); + const pg_pool_t &pool = it.second; + + float warn_threshold = (float)g_conf->mon_pool_quota_warn_threshold/100; + float crit_threshold = (float)g_conf->mon_pool_quota_crit_threshold/100; + + if (pool.quota_max_objects > 0) { + stringstream ss; + health_status_t status = HEALTH_OK; + if ((uint64_t)sum.num_objects >= pool.quota_max_objects) { + } else if (crit_threshold > 0 && + sum.num_objects >= pool.quota_max_objects*crit_threshold) { + ss << "pool '" << pool_name + << "' has " << sum.num_objects << " objects" + << " (max " << pool.quota_max_objects << ")"; + status = HEALTH_ERR; + } else if (warn_threshold > 0 && + sum.num_objects >= pool.quota_max_objects*warn_threshold) { + ss << "pool '" << pool_name + << "' has " << sum.num_objects << " objects" + << " (max " << pool.quota_max_objects << ")"; + status = HEALTH_WARN; + } + if (status != HEALTH_OK) { + pair s(status, ss.str()); + summary.push_back(s); + if (detail) + detail->push_back(s); + } + } + + if (pool.quota_max_bytes > 0) { + health_status_t status = HEALTH_OK; + stringstream ss; + if ((uint64_t)sum.num_bytes >= pool.quota_max_bytes) { + } else if (crit_threshold > 0 && + sum.num_bytes >= pool.quota_max_bytes*crit_threshold) { + ss << "pool '" << pool_name + << "' has " << si_t(sum.num_bytes) << " bytes" + << " (max " << si_t(pool.quota_max_bytes) << ")"; + status = HEALTH_ERR; + } else if (warn_threshold > 0 && + sum.num_bytes >= pool.quota_max_bytes*warn_threshold) { + ss << "pool '" << pool_name + << "' has " << si_t(sum.num_bytes) << " bytes" + << " (max " << si_t(pool.quota_max_bytes) << ")"; + status = HEALTH_WARN; + } + if (status != HEALTH_OK) { + pair s(status, ss.str()); + summary.push_back(s); + if (detail) + detail->push_back(s); + } + } + } + print_unscrubbed_pgs(pg_stat, summary, detail, cct); } @@ -3410,9 +4147,12 @@ void PGMapUpdater::check_osd_map( my_pg_num = q->second; unsigned pg_num = pi.get_pg_num(); if (my_pg_num != pg_num) { + ldout(cct,10) << __func__ << " pool " << poolid << " pg_num " << pg_num + << " != my pg_num " << my_pg_num << dendl; for (unsigned ps = my_pg_num; ps < pg_num; ++ps) { pg_t pgid(ps, poolid); if (pending_inc->pg_stat_updates.count(pgid) == 0) { + ldout(cct,20) << __func__ << " adding " << pgid << dendl; pg_stat_t &stats = pending_inc->pg_stat_updates[pgid]; stats.last_fresh = osdmap.get_modified(); stats.last_active = osdmap.get_modified(); diff --git a/ceph/src/mon/PGMap.h b/ceph/src/mon/PGMap.h index 6d58e6b25..3e81c7e05 100644 --- a/ceph/src/mon/PGMap.h +++ b/ceph/src/mon/PGMap.h @@ -21,10 +21,12 @@ #ifndef CEPH_PGMAP_H #define CEPH_PGMAP_H +#include "include/health.h" #include "common/debug.h" #include "common/TextTable.h" #include "osd/osd_types.h" #include "include/mempool.h" +#include "mon/health_check.h" #include #include "mon/PGStatService.h" @@ -495,6 +497,11 @@ public: list >& summary, list > *detail) const; + void get_health_checks( + CephContext *cct, + const OSDMap& osdmap, + health_check_map_t *checks) const; + static void generate_test_instances(list& o); }; WRITE_CLASS_ENCODER_FEATURES(PGMap::Incremental) diff --git a/ceph/src/mon/PGMonitor.cc b/ceph/src/mon/PGMonitor.cc index 7fdb5bd63..37324608b 100644 --- a/ceph/src/mon/PGMonitor.cc +++ b/ceph/src/mon/PGMonitor.cc @@ -558,21 +558,26 @@ version_t PGMonitor::get_trim_to() bool PGMonitor::preprocess_query(MonOpRequestRef op) { - if (mon->osdmon()->osdmap.require_osd_release >= CEPH_RELEASE_LUMINOUS) { - return false; - } - op->mark_pgmon_event(__func__); PaxosServiceMessage *m = static_cast(op->get_req()); - dout(10) << "preprocess_query " << *m << " from " << m->get_orig_source_inst() << dendl; + dout(10) << "preprocess_query " << *m + << " from " << m->get_orig_source_inst() << dendl; switch (m->get_type()) { case MSG_PGSTATS: + if (mon->osdmon()->osdmap.require_osd_release >= CEPH_RELEASE_LUMINOUS) { + return true; + } return preprocess_pg_stats(op); case MSG_MON_COMMAND: + if (mon->osdmon()->osdmap.require_osd_release >= CEPH_RELEASE_LUMINOUS) { + bufferlist rdata; + mon->reply_command(op, -EOPNOTSUPP, "this command is obsolete", rdata, + get_last_committed()); + return true; + } return preprocess_command(op); - default: ceph_abort(); return true; diff --git a/ceph/src/mon/Paxos.cc b/ceph/src/mon/Paxos.cc index b1680d25a..0109643b5 100644 --- a/ceph/src/mon/Paxos.cc +++ b/ceph/src/mon/Paxos.cc @@ -1133,10 +1133,10 @@ void Paxos::handle_lease_ack(MonOpRequestRef op) int from = ack->get_source().num(); if (!lease_ack_timeout_event) { - dout(10) << "handle_lease_ack from " << ack->get_source() + dout(10) << "handle_lease_ack from " << ack->get_source() << " -- stray (probably since revoked)" << dendl; - } - else if (acked_lease.count(from) == 0) { + + } else if (acked_lease.count(from) == 0) { acked_lease.insert(from); if (ack->feature_map.length()) { auto p = ack->feature_map.begin(); @@ -1145,20 +1145,20 @@ void Paxos::handle_lease_ack(MonOpRequestRef op) } if (acked_lease == mon->get_quorum()) { // yay! - dout(10) << "handle_lease_ack from " << ack->get_source() + dout(10) << "handle_lease_ack from " << ack->get_source() << " -- got everyone" << dendl; mon->timer.cancel_event(lease_ack_timeout_event); lease_ack_timeout_event = 0; } else { - dout(10) << "handle_lease_ack from " << ack->get_source() + dout(10) << "handle_lease_ack from " << ack->get_source() << " -- still need " << mon->get_quorum().size() - acked_lease.size() << " more" << dendl; } } else { - dout(10) << "handle_lease_ack from " << ack->get_source() + dout(10) << "handle_lease_ack from " << ack->get_source() << " dup (lagging!), ignoring" << dendl; } diff --git a/ceph/src/mon/PaxosService.cc b/ceph/src/mon/PaxosService.cc index 621f94214..91152943b 100644 --- a/ceph/src/mon/PaxosService.cc +++ b/ceph/src/mon/PaxosService.cc @@ -35,7 +35,7 @@ bool PaxosService::dispatch(MonOpRequestRef op) PaxosServiceMessage *m = static_cast(op->get_req()); op->mark_event("psvc:dispatch"); - dout(10) << "dispatch " << m << " " << *m + dout(10) << __func__ << " " << m << " " << *m << " from " << m->get_orig_source_inst() << " con " << m->get_connection() << dendl; @@ -184,7 +184,7 @@ bool PaxosService::should_propose(double& delay) void PaxosService::propose_pending() { - dout(10) << "propose_pending" << dendl; + dout(10) << __func__ << dendl; assert(have_pending); assert(!proposing); assert(mon->is_leader()); @@ -262,7 +262,7 @@ bool PaxosService::should_stash_full() void PaxosService::restart() { - dout(10) << "restart" << dendl; + dout(10) << __func__ << dendl; if (proposal_timer) { dout(10) << " canceling proposal_timer " << proposal_timer << dendl; mon->timer.cancel_event(proposal_timer); @@ -282,7 +282,7 @@ void PaxosService::restart() void PaxosService::election_finished() { - dout(10) << "election_finished" << dendl; + dout(10) << __func__ << dendl; finish_contexts(g_ceph_context, waiting_for_finished_proposal, -EAGAIN); @@ -293,11 +293,11 @@ void PaxosService::election_finished() void PaxosService::_active() { if (is_proposing()) { - dout(10) << "_acting - proposing" << dendl; + dout(10) << __func__ << " - proposing" << dendl; return; } if (!is_active()) { - dout(10) << "_active - not active" << dendl; + dout(10) << __func__ << " - not active" << dendl; /** * Callback used to make sure we call the PaxosService::_active function * whenever a condition is fulfilled. @@ -318,11 +318,11 @@ void PaxosService::_active() wait_for_active_ctx(new C_Active(this)); return; } - dout(10) << "_active" << dendl; + dout(10) << __func__ << dendl; // create pending state? if (mon->is_leader()) { - dout(7) << "_active creating new pending" << dendl; + dout(7) << __func__ << " creating new pending" << dendl; if (!have_pending) { create_pending(); have_pending = true; @@ -431,3 +431,12 @@ void PaxosService::trim(MonitorDBStore::TransactionRef t, } } +void PaxosService::load_health() +{ + bufferlist bl; + mon->store->get("health", service_name, bl); + if (bl.length()) { + auto p = bl.begin(); + ::decode(health_checks, p); + } +} diff --git a/ceph/src/mon/PaxosService.h b/ceph/src/mon/PaxosService.h index ca7591584..da3038ff1 100644 --- a/ceph/src/mon/PaxosService.h +++ b/ceph/src/mon/PaxosService.h @@ -77,15 +77,23 @@ protected: */ bool have_pending; -protected: + /** + * health checks for this service + * + * Child must populate this during encode_pending() by calling encode_health(). + */ + health_check_map_t health_checks; +public: + const health_check_map_t& get_health_checks() { + return health_checks; + } +protected: /** * format of our state in leveldb, 0 for default */ version_t format_version; - - /** * @defgroup PaxosService_h_callbacks Callback classes * @{ @@ -428,6 +436,15 @@ public: list > *detail, CephContext *cct) const { } + void encode_health(const health_check_map_t& next, + MonitorDBStore::TransactionRef t) { + bufferlist bl; + ::encode(next, bl); + t->put("health", service_name, bl); + mon->log_health(next, health_checks, t); + } + void load_health(); + private: /** * @defgroup PaxosService_h_store_keys Set of keys that are usually used on diff --git a/ceph/src/mon/QuorumService.h b/ceph/src/mon/QuorumService.h index b354c40a7..626ce659e 100644 --- a/ceph/src/mon/QuorumService.h +++ b/ceph/src/mon/QuorumService.h @@ -117,8 +117,7 @@ public: virtual void init() { } - virtual void get_health(Formatter *f, - list >& summary, + virtual void get_health(list >& summary, list > *detail) = 0; virtual int get_type() = 0; virtual string get_name() const = 0; diff --git a/ceph/src/mon/Session.h b/ceph/src/mon/Session.h index cb5946449..6dddee071 100644 --- a/ceph/src/mon/Session.h +++ b/ceph/src/mon/Session.h @@ -206,7 +206,7 @@ struct MonSessionMap { } else { sub = new Subscription(s, what); s->sub_map[what] = sub; - + if (!subs.count(what)) subs[what] = new xlist; subs[what]->push_back(&sub->type_item); @@ -227,7 +227,7 @@ inline ostream& operator<<(ostream& out, const MonSession& s) { out << "MonSession(" << s.inst << " is " << (s.closed ? "closed" : "open"); - out << s.caps << ")"; + out << " " << s.caps << ")"; return out; } diff --git a/ceph/src/mon/health_check.h b/ceph/src/mon/health_check.h new file mode 100644 index 000000000..f0c00d176 --- /dev/null +++ b/ceph/src/mon/health_check.h @@ -0,0 +1,200 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#pragma once + +#include +#include + +#include "include/health.h" +#include "common/Formatter.h" + +struct health_check_t { + health_status_t severity; + std::string summary; + std::list detail; + + DENC(health_check_t, v, p) { + DENC_START(1, 1, p); + denc(v.severity, p); + denc(v.summary, p); + denc(v.detail, p); + DENC_FINISH(p); + } + + friend bool operator==(const health_check_t& l, + const health_check_t& r) { + return l.severity == r.severity && + l.summary == r.summary && + l.detail == r.detail; + } + friend bool operator!=(const health_check_t& l, + const health_check_t& r) { + return !(l == r); + } + + void dump(Formatter *f) const { + f->dump_stream("severity") << severity; + f->dump_string("summary", summary); + f->open_array_section("detail"); + for (auto& p : detail) { + f->dump_string("item", p); + } + f->close_section(); + } + + static void generate_test_instances(list& ls) { + ls.push_back(new health_check_t); + ls.push_back(new health_check_t); + ls.back()->severity = HEALTH_ERR; + ls.back()->summary = "summarization"; + ls.back()->detail = {"one", "two", "three"}; + } +}; +WRITE_CLASS_DENC(health_check_t) + + +struct health_check_map_t { + map checks; + + DENC(health_check_map_t, v, p) { + DENC_START(1, 1, p); + denc(v.checks, p); + DENC_FINISH(p); + } + + void dump(Formatter *f) const { + for (auto& p : checks) { + f->dump_object(p.first.c_str(), p.second); + } + } + + static void generate_test_instances(list& ls) { + ls.push_back(new health_check_map_t); + ls.push_back(new health_check_map_t); + { + auto& d = ls.back()->add("FOO", HEALTH_WARN, "foo"); + d.detail.push_back("a"); + d.detail.push_back("b"); + } + { + auto& d = ls.back()->add("BAR", HEALTH_ERR, "bar!"); + d.detail.push_back("c"); + d.detail.push_back("d"); + } + } + + void clear() { + checks.clear(); + } + void swap(health_check_map_t& other) { + checks.swap(other.checks); + } + + health_check_t& add(const std::string& code, + health_status_t severity, + const std::string& summary) { + assert(checks.count(code) == 0); + health_check_t& r = checks[code]; + r.severity = severity; + r.summary = summary; + return r; + } + health_check_t& get_or_add(const std::string& code, + health_status_t severity, + const std::string& summary) { + health_check_t& r = checks[code]; + r.severity = severity; + r.summary = summary; + return r; + } + + void merge(const health_check_map_t& o) { + for (auto& p : o.checks) { + auto q = checks.find(p.first); + if (q == checks.end()) { + // new check + checks[p.first] = p.second; + } else { + // merge details, and hope the summary matches! + q->second.detail.insert( + q->second.detail.end(), + p.second.detail.begin(), + p.second.detail.end()); + } + } + } + + health_status_t dump_summary(Formatter *f, std::string *plain, + const char *sep, bool detail) const { + health_status_t r = HEALTH_OK; + for (auto& p : checks) { + if (r > p.second.severity) { + r = p.second.severity; + } + if (f) { + f->open_object_section(p.first.c_str()); + f->dump_stream("severity") << p.second.severity; + f->dump_string("message", p.second.summary); + if (detail) { + f->open_array_section("detail"); + for (auto& d : p.second.detail) { + f->dump_string("item", d); + } + f->close_section(); + } + f->close_section(); + } else { + if (!plain->empty()) { + *plain += sep; + } + *plain += p.second.summary; + } + } + return r; + } + + void dump_summary_compat(Formatter *f) const { + for (auto& p : checks) { + f->open_object_section("item"); + f->dump_stream("severity") << p.second.severity; + f->dump_string("summary", p.second.summary); + f->close_section(); + } + } + + void dump_detail(Formatter *f, std::string *plain, bool compat) const { + for (auto& p : checks) { + if (f) { + if (compat) { + // this is sloppy, but the best we can do: just dump all of the + // individual checks' details together + for (auto& d : p.second.detail) { + f->dump_string("item", d); + } + } + } else { + if (!compat) { + *plain += p.first + " " + p.second.summary + "\n"; + } + for (auto& d : p.second.detail) { + if (!compat) { + *plain += " "; + } + *plain += d; + *plain += "\n"; + } + } + } + } + + friend bool operator==(const health_check_map_t& l, + const health_check_map_t& r) { + return l.checks == r.checks; + } + friend bool operator!=(const health_check_map_t& l, + const health_check_map_t& r) { + return !(l == r); + } +}; +WRITE_CLASS_DENC(health_check_map_t) diff --git a/ceph/src/mon/mon_types.h b/ceph/src/mon/mon_types.h index 883f4669e..a23238b7d 100644 --- a/ceph/src/mon/mon_types.h +++ b/ceph/src/mon/mon_types.h @@ -31,7 +31,8 @@ #define PAXOS_AUTH 5 #define PAXOS_MGR 6 #define PAXOS_MGRSTAT 7 -#define PAXOS_NUM 8 +#define PAXOS_HEALTH 8 +#define PAXOS_NUM 9 inline const char *get_paxos_name(int p) { switch (p) { @@ -43,6 +44,7 @@ inline const char *get_paxos_name(int p) { case PAXOS_AUTH: return "auth"; case PAXOS_MGR: return "mgr"; case PAXOS_MGRSTAT: return "mgrstat"; + case PAXOS_HEALTH: return "health"; default: ceph_abort(); return 0; } } diff --git a/ceph/src/msg/Message.cc b/ceph/src/msg/Message.cc index 8232ba39c..9d1953d75 100644 --- a/ceph/src/msg/Message.cc +++ b/ceph/src/msg/Message.cc @@ -96,6 +96,7 @@ using namespace std; #include "messages/MMonGetVersion.h" #include "messages/MMonGetVersionReply.h" #include "messages/MMonHealth.h" +#include "messages/MMonHealthChecks.h" #include "messages/MMonMetadata.h" #include "messages/MDataPing.h" #include "messages/MAuth.h" @@ -169,6 +170,7 @@ using namespace std; #include "messages/MMgrOpen.h" #include "messages/MMgrConfigure.h" #include "messages/MMonMgrReport.h" +#include "messages/MServiceMap.h" #include "messages/MLock.h" @@ -751,6 +753,10 @@ Message *decode_message(CephContext *cct, int crcflags, m = new MMonMgrReport(); break; + case MSG_SERVICE_MAP: + m = new MServiceMap(); + break; + case MSG_MGR_MAP: m = new MMgrMap(); break; @@ -778,6 +784,11 @@ Message *decode_message(CephContext *cct, int crcflags, case MSG_MON_HEALTH: m = new MMonHealth(); break; + + case MSG_MON_HEALTH_CHECKS: + m = new MMonHealthChecks(); + break; + #if defined(HAVE_XIO) case MSG_DATA_PING: m = new MDataPing(); diff --git a/ceph/src/msg/Message.h b/ceph/src/msg/Message.h index b7220e2de..d1b63ac1f 100644 --- a/ceph/src/msg/Message.h +++ b/ceph/src/msg/Message.h @@ -183,6 +183,8 @@ // Special #define MSG_NOP 0x607 +#define MSG_MON_HEALTH_CHECKS 0x608 + // *** ceph-mgr <-> OSD/MDS daemons *** #define MSG_MGR_OPEN 0x700 #define MSG_MGR_CONFIGURE 0x701 @@ -198,6 +200,7 @@ #define MSG_MGR_DIGEST 0x705 // *** cephmgr -> ceph-mon #define MSG_MON_MGR_REPORT 0x706 +#define MSG_SERVICE_MAP 0x707 // ====================================================== diff --git a/ceph/src/msg/Messenger.h b/ceph/src/msg/Messenger.h index a186ec3c8..7c1a0d1fa 100644 --- a/ceph/src/msg/Messenger.h +++ b/ceph/src/msg/Messenger.h @@ -255,6 +255,14 @@ public: * @param addr The address to use as a template. */ virtual void set_addr_unknowns(const entity_addr_t &addr) = 0; + /** + * Set the address for this Messenger. This is useful if the Messenger + * binds to a specific address but advertises a different address on the + * the network. + * + * @param addr The address to use. + */ + virtual void set_addr(const entity_addr_t &addr) = 0; /// Get the default send priority. int get_default_send_priority() { return default_send_priority; } /** diff --git a/ceph/src/msg/QueueStrategy.cc b/ceph/src/msg/QueueStrategy.cc index 0ce279b31..e41ab79fd 100644 --- a/ceph/src/msg/QueueStrategy.cc +++ b/ceph/src/msg/QueueStrategy.cc @@ -15,6 +15,7 @@ #include "QueueStrategy.h" #define dout_subsys ceph_subsys_ms #include "common/debug.h" +#include "common/backport14.h" QueueStrategy::QueueStrategy(int _n_threads) : lock("QueueStrategy::lock"), @@ -85,16 +86,13 @@ void QueueStrategy::shutdown() void QueueStrategy::wait() { - QSThread *thrd; lock.Lock(); assert(stop); - while (disp_threads.size()) { - thrd = &(disp_threads.front()); - disp_threads.pop_front(); + for (auto& thread : threads) { lock.Unlock(); // join outside of lock - thrd->join(); + thread->join(); lock.Lock(); } @@ -103,14 +101,15 @@ void QueueStrategy::wait() void QueueStrategy::start() { - QSThread *thrd; assert(!stop); lock.Lock(); + threads.reserve(n_threads); for (int ix = 0; ix < n_threads; ++ix) { string thread_name = "ms_xio_qs_"; thread_name.append(std::to_string(ix)); - thrd = new QSThread(this); + auto thrd = ceph::make_unique(this); thrd->create(thread_name.c_str()); + threads.emplace_back(std::move(thrd)); } lock.Unlock(); } diff --git a/ceph/src/msg/QueueStrategy.h b/ceph/src/msg/QueueStrategy.h index 41f28bb9e..a531cd777 100644 --- a/ceph/src/msg/QueueStrategy.h +++ b/ceph/src/msg/QueueStrategy.h @@ -16,6 +16,8 @@ #ifndef QUEUE_STRATEGY_H #define QUEUE_STRATEGY_H +#include +#include #include #include "DispatchStrategy.h" #include "msg/Messenger.h" @@ -24,7 +26,7 @@ namespace bi = boost::intrusive; class QueueStrategy : public DispatchStrategy { Mutex lock; - int n_threads; + const int n_threads; bool stop; Message::Queue mqueue; @@ -37,7 +39,6 @@ class QueueStrategy : public DispatchStrategy { explicit QSThread(QueueStrategy *dq) : thread_q(), dq(dq), cond() {} void* entry() { dq->entry(this); - delete(this); return NULL; } @@ -47,7 +48,8 @@ class QueueStrategy : public DispatchStrategy { &QSThread::thread_q > > Queue; }; - QSThread::Queue disp_threads; + std::vector> threads; //< all threads + QSThread::Queue disp_threads; //< waiting threads public: explicit QueueStrategy(int n_threads); diff --git a/ceph/src/msg/async/AsyncConnection.cc b/ceph/src/msg/async/AsyncConnection.cc index f7e8fff0f..3c535f765 100644 --- a/ceph/src/msg/async/AsyncConnection.cc +++ b/ceph/src/msg/async/AsyncConnection.cc @@ -431,6 +431,7 @@ void AsyncConnection::process() #if defined(WITH_LTTNG) && defined(WITH_EVENTTRACE) ltt_recv_stamp = ceph_clock_now(); #endif + recv_stamp = ceph_clock_now(); ldout(async_msgr->cct, 20) << __func__ << " begin MSG" << dendl; ceph_msg_header header; ceph_msg_header_old oldheader; @@ -486,7 +487,6 @@ void AsyncConnection::process() front.clear(); middle.clear(); data.clear(); - recv_stamp = ceph_clock_now(); current_header = header; state = STATE_OPEN_MESSAGE_THROTTLE_MESSAGE; break; @@ -977,9 +977,9 @@ ssize_t AsyncConnection::_process_connection() << " not " << peer_addr << " - presumably this is the same node!" << dendl; } else { - ldout(async_msgr->cct, 0) << __func__ << " connect claims to be " - << paddr << " not " << peer_addr << " - wrong node!" << dendl; - goto fail; + ldout(async_msgr->cct, 10) << __func__ << " connect claims to be " + << paddr << " not " << peer_addr + << " (peer is possibly using public_bind_addr?) " << dendl; } } diff --git a/ceph/src/msg/async/AsyncMessenger.cc b/ceph/src/msg/async/AsyncMessenger.cc index 469584405..1913e8f4c 100644 --- a/ceph/src/msg/async/AsyncMessenger.cc +++ b/ceph/src/msg/async/AsyncMessenger.cc @@ -634,6 +634,15 @@ void AsyncMessenger::set_addr_unknowns(const entity_addr_t &addr) } } +void AsyncMessenger::set_addr(const entity_addr_t &addr) +{ + Mutex::Locker l(lock); + entity_addr_t t = addr; + t.set_nonce(nonce); + set_myaddr(t); + _init_local_connection(); +} + void AsyncMessenger::shutdown_connections(bool queue_reset) { ldout(cct,1) << __func__ << " " << dendl; diff --git a/ceph/src/msg/async/AsyncMessenger.h b/ceph/src/msg/async/AsyncMessenger.h index 0b1f2c8e9..7ebc7777c 100644 --- a/ceph/src/msg/async/AsyncMessenger.h +++ b/ceph/src/msg/async/AsyncMessenger.h @@ -96,6 +96,7 @@ public: * @{ */ void set_addr_unknowns(const entity_addr_t &addr) override; + void set_addr(const entity_addr_t &addr) override; int get_dispatch_queue_len() override { return dispatch_queue.get_queue_len(); diff --git a/ceph/src/msg/async/PosixStack.cc b/ceph/src/msg/async/PosixStack.cc index cf52db9a7..d0e6b5af0 100644 --- a/ceph/src/msg/async/PosixStack.cc +++ b/ceph/src/msg/async/PosixStack.cc @@ -322,7 +322,7 @@ int PosixWorker::listen(entity_addr_t &sa, const SocketOptions &opt, return r; } - r = ::listen(listen_sd, 128); + r = ::listen(listen_sd, cct->_conf->ms_tcp_listen_backlog); if (r < 0) { r = -errno; lderr(cct) << __func__ << " unable to listen on " << sa << ": " << cpp_strerror(r) << dendl; diff --git a/ceph/src/msg/async/rdma/Infiniband.cc b/ceph/src/msg/async/rdma/Infiniband.cc index 0597b09eb..37e1a5307 100644 --- a/ceph/src/msg/async/rdma/Infiniband.cc +++ b/ceph/src/msg/async/rdma/Infiniband.cc @@ -470,8 +470,7 @@ Infiniband::ProtectionDomain::ProtectionDomain(CephContext *cct, Device *device) Infiniband::ProtectionDomain::~ProtectionDomain() { - int rc = ibv_dealloc_pd(pd); - assert(rc == 0); + ibv_dealloc_pd(pd); } @@ -482,7 +481,6 @@ Infiniband::MemoryManager::Chunk::Chunk(ibv_mr* m, uint32_t len, char* b) Infiniband::MemoryManager::Chunk::~Chunk() { - assert(ibv_dereg_mr(mr) == 0); } void Infiniband::MemoryManager::Chunk::set_offset(uint32_t o) @@ -568,6 +566,8 @@ Infiniband::MemoryManager::Cluster::Cluster(MemoryManager& m, uint32_t s) Infiniband::MemoryManager::Cluster::~Cluster() { + int r = ibv_dereg_mr(chunk_base->mr); + assert(r == 0); const auto chunk_end = chunk_base + num_chunk; for (auto chunk = chunk_base; chunk != chunk_end; chunk++) { chunk->~Chunk(); @@ -595,10 +595,10 @@ int Infiniband::MemoryManager::Cluster::fill(uint32_t num) chunk_base = static_cast(::malloc(sizeof(Chunk) * num)); memset(chunk_base, 0, sizeof(Chunk) * num); free_chunks.reserve(num); + ibv_mr* m = ibv_reg_mr(manager.pd->pd, base, bytes, IBV_ACCESS_REMOTE_WRITE | IBV_ACCESS_LOCAL_WRITE); + assert(m); Chunk* chunk = chunk_base; for (uint32_t offset = 0; offset < bytes; offset += buffer_size){ - ibv_mr* m = ibv_reg_mr(manager.pd->pd, base+offset, buffer_size, IBV_ACCESS_REMOTE_WRITE | IBV_ACCESS_LOCAL_WRITE); - assert(m); new(chunk) Chunk(m, buffer_size, base+offset); free_chunks.push_back(chunk); chunk++; diff --git a/ceph/src/msg/async/rdma/RDMAConnectedSocketImpl.cc b/ceph/src/msg/async/rdma/RDMAConnectedSocketImpl.cc index 7bd8a80fd..66dc488cc 100644 --- a/ceph/src/msg/async/rdma/RDMAConnectedSocketImpl.cc +++ b/ceph/src/msg/async/rdma/RDMAConnectedSocketImpl.cc @@ -25,7 +25,7 @@ RDMAConnectedSocketImpl::RDMAConnectedSocketImpl(CephContext *cct, Infiniband* i : cct(cct), connected(0), error(0), infiniband(ib), dispatcher(s), worker(w), lock("RDMAConnectedSocketImpl::lock"), is_server(false), con_handler(new C_handle_connection(this)), - active(false) + active(false), pending(false) { qp = infiniband->create_queue_pair( cct, s->get_tx_cq(), s->get_rx_cq(), IBV_QPT_RC); diff --git a/ceph/src/msg/async/rdma/RDMAServerSocketImpl.cc b/ceph/src/msg/async/rdma/RDMAServerSocketImpl.cc index 8f5fd81d3..6e473d12e 100644 --- a/ceph/src/msg/async/rdma/RDMAServerSocketImpl.cc +++ b/ceph/src/msg/async/rdma/RDMAServerSocketImpl.cc @@ -56,7 +56,7 @@ int RDMAServerSocketImpl::listen(entity_addr_t &sa, const SocketOptions &opt) goto err; } - rc = ::listen(server_setup_socket, 128); + rc = ::listen(server_setup_socket, cct->_conf->ms_tcp_listen_backlog); if (rc < 0) { rc = -errno; lderr(cct) << __func__ << " unable to listen on " << sa << ": " << cpp_strerror(errno) << dendl; @@ -69,7 +69,7 @@ int RDMAServerSocketImpl::listen(entity_addr_t &sa, const SocketOptions &opt) err: ::close(server_setup_socket); server_setup_socket = -1; - return -errno; + return rc; } int RDMAServerSocketImpl::accept(ConnectedSocket *sock, const SocketOptions &opt, entity_addr_t *out, Worker *w) diff --git a/ceph/src/msg/async/rdma/RDMAStack.cc b/ceph/src/msg/async/rdma/RDMAStack.cc index 020dd9853..e16052f1d 100644 --- a/ceph/src/msg/async/rdma/RDMAStack.cc +++ b/ceph/src/msg/async/rdma/RDMAStack.cc @@ -417,6 +417,7 @@ RDMAWorker::RDMAWorker(CephContext *c, unsigned i) plb.add_u64_counter(l_msgr_rdma_tx_bytes, "tx_bytes", "The bytes of tx chunks transmitted"); plb.add_u64_counter(l_msgr_rdma_rx_chunks, "rx_chunks", "The number of rx chunks transmitted"); plb.add_u64_counter(l_msgr_rdma_rx_bytes, "rx_bytes", "The bytes of rx chunks transmitted"); + plb.add_u64_counter(l_msgr_rdma_pending_sent_conns, "pending_sent_conns", "The count of pending sent conns"); perf_logger = plb.create_perf_counters(); cct->get_perfcounters_collection()->add(perf_logger); @@ -474,12 +475,15 @@ int RDMAWorker::get_reged_mem(RDMAConnectedSocketImpl *o, std::vector &c size_t got = global_infiniband->get_memory_manager()->get_tx_buffer_size() * r; ldout(cct, 30) << __func__ << " need " << bytes << " bytes, reserve " << got << " registered bytes, inflight " << dispatcher->inflight << dendl; stack->get_dispatcher()->inflight += r; - if (got == bytes) + if (got >= bytes) return r; if (o) { - if (pending_sent_conns.back() != o) + if (!o->is_pending()) { pending_sent_conns.push_back(o); + perf_logger->inc(l_msgr_rdma_pending_sent_conns, 1); + o->set_pending(1); + } dispatcher->make_pending_worker(this); } return r; @@ -489,25 +493,22 @@ int RDMAWorker::get_reged_mem(RDMAConnectedSocketImpl *o, std::vector &c void RDMAWorker::handle_pending_message() { ldout(cct, 20) << __func__ << " pending conns " << pending_sent_conns.size() << dendl; - std::set done; while (!pending_sent_conns.empty()) { RDMAConnectedSocketImpl *o = pending_sent_conns.front(); pending_sent_conns.pop_front(); - if (!done.count(o)) { - done.insert(o); - ssize_t r = o->submit(false); - ldout(cct, 20) << __func__ << " sent pending bl socket=" << o << " r=" << r << dendl; - if (r < 0) { - if (r == -EAGAIN) { - pending_sent_conns.push_front(o); - dispatcher->make_pending_worker(this); - return ; - } - o->fault(); + ssize_t r = o->submit(false); + ldout(cct, 20) << __func__ << " sent pending bl socket=" << o << " r=" << r << dendl; + if (r < 0) { + if (r == -EAGAIN) { + pending_sent_conns.push_back(o); + dispatcher->make_pending_worker(this); + return ; } + o->fault(); } + o->set_pending(0); + perf_logger->dec(l_msgr_rdma_pending_sent_conns, 1); } - dispatcher->notify_pending_workers(); } diff --git a/ceph/src/msg/async/rdma/RDMAStack.h b/ceph/src/msg/async/rdma/RDMAStack.h index 4f93c157f..27373fb64 100644 --- a/ceph/src/msg/async/rdma/RDMAStack.h +++ b/ceph/src/msg/async/rdma/RDMAStack.h @@ -127,10 +127,11 @@ class RDMADispatcher { int register_qp(QueuePair *qp, RDMAConnectedSocketImpl* csi); void make_pending_worker(RDMAWorker* w) { Mutex::Locker l(w_lock); - if (pending_workers.back() != w) { - pending_workers.push_back(w); - ++num_pending_workers; - } + auto it = std::find(pending_workers.begin(), pending_workers.end(), w); + if (it != pending_workers.end()) + return; + pending_workers.push_back(w); + ++num_pending_workers; } RDMAStack* get_stack() { return stack; } RDMAConnectedSocketImpl* get_conn_lockless(uint32_t qp); @@ -158,6 +159,7 @@ enum { l_msgr_rdma_tx_bytes, l_msgr_rdma_rx_chunks, l_msgr_rdma_rx_bytes, + l_msgr_rdma_pending_sent_conns, l_msgr_rdma_last, }; @@ -229,6 +231,7 @@ class RDMAConnectedSocketImpl : public ConnectedSocketImpl { EventCallbackRef con_handler; int tcp_fd = -1; bool active;// qp is active ? + bool pending; void notify(); ssize_t read_buffers(char* buf, size_t len); @@ -258,7 +261,8 @@ class RDMAConnectedSocketImpl : public ConnectedSocketImpl { void cleanup(); void set_accept_fd(int sd); int try_connect(const entity_addr_t&, const SocketOptions &opt); - + bool is_pending() {return pending;} + void set_pending(bool val) {pending = val;} class C_handle_connection : public EventCallback { RDMAConnectedSocketImpl *csi; bool active; diff --git a/ceph/src/msg/simple/Accepter.cc b/ceph/src/msg/simple/Accepter.cc index 16e6dfbfa..5779cc7ab 100644 --- a/ceph/src/msg/simple/Accepter.cc +++ b/ceph/src/msg/simple/Accepter.cc @@ -211,7 +211,7 @@ int Accepter::bind(const entity_addr_t &bind_addr, const set& avoid_ports) ldout(msgr->cct,10) << __func__ << " bound to " << listen_addr << dendl; // listen! - rc = ::listen(listen_sd, 128); + rc = ::listen(listen_sd, msgr->cct->_conf->ms_tcp_listen_backlog); if (rc < 0) { rc = -errno; lderr(msgr->cct) << __func__ << " unable to listen on " << listen_addr diff --git a/ceph/src/msg/simple/Pipe.cc b/ceph/src/msg/simple/Pipe.cc index fc415df8a..355c2528f 100644 --- a/ceph/src/msg/simple/Pipe.cc +++ b/ceph/src/msg/simple/Pipe.cc @@ -1089,9 +1089,9 @@ int Pipe::connect() ldout(msgr->cct,0) << "connect claims to be " << paddr << " not " << peer_addr << " - presumably this is the same node!" << dendl; } else { - ldout(msgr->cct,0) << "connect claims to be " - << paddr << " not " << peer_addr << " - wrong node!" << dendl; - goto fail; + ldout(msgr->cct,10) << "connect claims to be " + << paddr << " not " << peer_addr + << " (peer is possibly using public_bind_addr?) " << dendl; } } diff --git a/ceph/src/msg/simple/SimpleMessenger.cc b/ceph/src/msg/simple/SimpleMessenger.cc index 84b6a253e..78e190d02 100644 --- a/ceph/src/msg/simple/SimpleMessenger.cc +++ b/ceph/src/msg/simple/SimpleMessenger.cc @@ -159,6 +159,14 @@ void SimpleMessenger::set_addr_unknowns(const entity_addr_t &addr) } } +void SimpleMessenger::set_addr(const entity_addr_t &addr) +{ + entity_addr_t t = addr; + t.set_nonce(nonce); + set_myaddr(t); + init_local_connection(); +} + int SimpleMessenger::get_proto_version(int peer_type, bool connect) { int my_type = my_inst.name.type(); diff --git a/ceph/src/msg/simple/SimpleMessenger.h b/ceph/src/msg/simple/SimpleMessenger.h index 4ddc9767c..0a0512382 100644 --- a/ceph/src/msg/simple/SimpleMessenger.h +++ b/ceph/src/msg/simple/SimpleMessenger.h @@ -93,6 +93,7 @@ public: * @{ */ void set_addr_unknowns(const entity_addr_t& addr) override; + void set_addr(const entity_addr_t &addr) override; int get_dispatch_queue_len() override { return dispatch_queue.get_queue_len(); diff --git a/ceph/src/msg/xio/XioMessenger.h b/ceph/src/msg/xio/XioMessenger.h index 9a81fb247..ea20d36bd 100644 --- a/ceph/src/msg/xio/XioMessenger.h +++ b/ceph/src/msg/xio/XioMessenger.h @@ -100,6 +100,8 @@ public: /* Messenger interface */ virtual void set_addr_unknowns(const entity_addr_t &addr) override { } /* XXX applicable? */ + virtual void set_addr(const entity_addr_t &addr) override + { } /* XXX applicable? */ virtual int get_dispatch_queue_len() { return 0; } /* XXX bogus? */ diff --git a/ceph/src/os/CMakeLists.txt b/ceph/src/os/CMakeLists.txt index feda6a23b..5edbb2db9 100644 --- a/ceph/src/os/CMakeLists.txt +++ b/ceph/src/os/CMakeLists.txt @@ -1,9 +1,3 @@ -if(HAVE_LIBXFS) - set(libos_xfs_srcs - filestore/XfsFileStoreBackend.cc - fs/XFS.cc) -endif(HAVE_LIBXFS) - set(libos_srcs ObjectStore.cc Transaction.cc @@ -19,13 +13,11 @@ set(libos_srcs filestore/IndexManager.cc filestore/LFNIndex.cc filestore/WBThrottle.cc - filestore/ZFSFileStoreBackend.cc memstore/MemStore.cc kstore/KStore.cc kstore/kstore_types.cc fs/FS.cc - fs/aio.cc - ${libos_xfs_srcs}) + fs/aio.cc) if(HAVE_LIBAIO) list(APPEND libos_srcs @@ -55,6 +47,21 @@ if(WITH_PMEM) bluestore/PMEMDevice.cc) endif(WITH_PMEM) +if(HAVE_LIBXFS) + list(APPEND libos_srcs + filestore/XfsFileStoreBackend.cc + fs/XFS.cc) +endif() + +if(HAVE_LIBZFS) + add_library(os_zfs_objs OBJECT + filestore/ZFSFileStoreBackend.cc + fs/ZFS.cc) + target_include_directories(os_zfs_objs PRIVATE + ${ZFS_INCLUDE_DIRS}) + list(APPEND libos_srcs $) +endif() + if(WITH_SPDK) list(APPEND libos_srcs bluestore/NVMEDevice.cc) @@ -76,6 +83,10 @@ if(WITH_PMEM) target_link_libraries(os ${PMEM_LIBRARY}) endif() +if(HAVE_LIBZFS) + target_link_libraries(os ${ZFS_LIBRARIES}) +endif() + if(WITH_SPDK) target_link_libraries(os ${SPDK_LIBRARIES} diff --git a/ceph/src/os/ObjectMap.h b/ceph/src/os/ObjectMap.h index 68341628d..67a5780ae 100644 --- a/ceph/src/os/ObjectMap.h +++ b/ceph/src/os/ObjectMap.h @@ -154,6 +154,8 @@ public: virtual int check(std::ostream &out, bool repair = false) { return 0; } + virtual void compact() {} + typedef KeyValueDB::GenericIteratorImpl ObjectMapIteratorImpl; typedef ceph::shared_ptr ObjectMapIterator; virtual ObjectMapIterator get_iterator(const ghobject_t &oid) { diff --git a/ceph/src/os/ObjectStore.h b/ceph/src/os/ObjectStore.h index 71f5e80b1..c88cf09c6 100644 --- a/ceph/src/os/ObjectStore.h +++ b/ceph/src/os/ObjectStore.h @@ -1575,6 +1575,10 @@ public: return true; } + virtual string get_default_device_class() { + return is_rotational() ? "hdd" : "ssd"; + } + virtual bool can_sort_nibblewise() { return false; // assume a backend cannot, unless it says otherwise } @@ -1702,17 +1706,15 @@ public: uint64_t offset, size_t len, bufferlist& bl, - uint32_t op_flags = 0, - bool allow_eio = false) = 0; + uint32_t op_flags = 0) = 0; virtual int read( CollectionHandle &c, const ghobject_t& oid, uint64_t offset, size_t len, bufferlist& bl, - uint32_t op_flags = 0, - bool allow_eio = false) { - return read(c->get_cid(), oid, offset, len, bl, op_flags, allow_eio); + uint32_t op_flags = 0) { + return read(c->get_cid(), oid, offset, len, bl, op_flags); } /** @@ -2022,6 +2024,8 @@ public: // DEBUG virtual void inject_data_error(const ghobject_t &oid) {} virtual void inject_mdata_error(const ghobject_t &oid) {} + + virtual void compact() {} }; WRITE_CLASS_ENCODER(ObjectStore::Transaction) WRITE_CLASS_ENCODER(ObjectStore::Transaction::TransactionData) diff --git a/ceph/src/os/bluestore/BitmapFreelistManager.cc b/ceph/src/os/bluestore/BitmapFreelistManager.cc index a3b3a5ec8..d3fdbb71a 100644 --- a/ceph/src/os/bluestore/BitmapFreelistManager.cc +++ b/ceph/src/os/bluestore/BitmapFreelistManager.cc @@ -183,6 +183,7 @@ void BitmapFreelistManager::enumerate_reset() enumerate_offset = 0; enumerate_bl_pos = 0; enumerate_bl.clear(); + enumerate_p.reset(); } int get_next_clear_bit(bufferlist& bl, int start) diff --git a/ceph/src/os/bluestore/BlueFS.cc b/ceph/src/os/bluestore/BlueFS.cc index f73e27cf6..36f0b3cb0 100644 --- a/ceph/src/os/bluestore/BlueFS.cc +++ b/ceph/src/os/bluestore/BlueFS.cc @@ -1138,6 +1138,11 @@ void BlueFS::_compact_log_sync() assert(r == 0); wait_for_aio(log_writer); + list completed_ios; + _claim_completed_aios(log_writer, &completed_ios); + flush_bdev(); + completed_ios.clear(); + dout(10) << __func__ << " writing super" << dendl; super.log_fnode = log_file->fnode; ++super.version; @@ -1206,6 +1211,8 @@ void BlueFS::_compact_log_async(std::unique_lock& l) // 2. prepare compacted log bluefs_transaction_t t; + //avoid record two times in log_t and _compact_log_dump_metadata. + log_t.clear(); _compact_log_dump_metadata(&t); // conservative estimate for final encoded size @@ -1238,7 +1245,11 @@ void BlueFS::_compact_log_async(std::unique_lock& l) // 4. wait dout(10) << __func__ << " waiting for compacted log to sync" << dendl; wait_for_aio(new_log_writer); + + list completed_ios; + _claim_completed_aios(new_log_writer, &completed_ios); flush_bdev(); + completed_ios.clear(); // 5. retake lock lock.lock(); diff --git a/ceph/src/os/bluestore/BlueStore.cc b/ceph/src/os/bluestore/BlueStore.cc index 38d1e272e..8e68e06bc 100644 --- a/ceph/src/os/bluestore/BlueStore.cc +++ b/ceph/src/os/bluestore/BlueStore.cc @@ -134,36 +134,68 @@ const string PREFIX_SHARED_BLOB = "X"; // u64 offset -> shared_blob_t template static void append_escaped(const string &in, S *out) { - char hexbyte[8]; + char hexbyte[in.length() * 3 + 1]; + char* ptr = &hexbyte[0]; for (string::const_iterator i = in.begin(); i != in.end(); ++i) { if (*i <= '#') { - snprintf(hexbyte, sizeof(hexbyte), "#%02x", (uint8_t)*i); - out->append(hexbyte); + *ptr++ = '#'; + *ptr++ = "0123456789abcdef"[(*i >> 4) & 0x0f]; + *ptr++ = "0123456789abcdef"[*i & 0x0f]; } else if (*i >= '~') { - snprintf(hexbyte, sizeof(hexbyte), "~%02x", (uint8_t)*i); - out->append(hexbyte); + *ptr++ = '~'; + *ptr++ = "0123456789abcdef"[(*i >> 4) & 0x0f]; + *ptr++ = "0123456789abcdef"[*i & 0x0f]; } else { - out->push_back(*i); + *ptr++ = *i; } } - out->push_back('!'); + *ptr++ = '!'; + out->append(hexbyte, ptr - &hexbyte[0]); +} + +inline unsigned h2i(char c) +{ + if ((c >= '0') && (c <= '9')) { + return c - 0x30; + } else if ((c >= 'a') && (c <= 'f')) { + return c - 'a' + 10; + } else if ((c >= 'A') && (c <= 'F')) { + return c - 'A' + 10; + } else { + return 256; // make it always larger than 255 + } } static int decode_escaped(const char *p, string *out) { + char buff[256]; + char* ptr = &buff[0]; + char* max = &buff[252]; const char *orig_p = p; while (*p && *p != '!') { if (*p == '#' || *p == '~') { - unsigned hex; - int r = sscanf(++p, "%2x", &hex); - if (r < 1) - return -EINVAL; - out->push_back((char)hex); - p += 2; + unsigned hex = 0; + p++; + hex = h2i(*p++) << 4; + if (hex > 255) { + return -EINVAL; + } + hex |= h2i(*p++); + if (hex > 255) { + return -EINVAL; + } + *ptr++ = hex; } else { - out->push_back(*p++); + *ptr++ = *p++; + } + if (ptr > max) { + out->append(buff, ptr-buff); + ptr = &buff[0]; } } + if (ptr != buff) { + out->append(buff, ptr-buff); + } return p - orig_p; } @@ -285,7 +317,7 @@ static int get_key_shared_blob(const string& key, uint64_t *sbid) const char *p = key.c_str(); if (key.length() < sizeof(uint64_t)) return -1; - p = _key_decode_u64(p, sbid); + _key_decode_u64(p, sbid); return 0; } @@ -452,7 +484,7 @@ int get_key_extent_shard(const string& key, string *onode_key, uint32_t *offset) int okey_len = key.size() - sizeof(uint32_t) - 1; *onode_key = key.substr(0, okey_len); const char *p = key.data() + okey_len; - p = _key_decode_u32(p, offset); + _key_decode_u32(p, offset); return 0; } @@ -1323,55 +1355,59 @@ int BlueStore::BufferSpace::_discard(Cache* cache, uint32_t offset, uint32_t len void BlueStore::BufferSpace::read( Cache* cache, - uint32_t offset, uint32_t length, + uint32_t offset, + uint32_t length, BlueStore::ready_regions_t& res, interval_set& res_intervals) { - std::lock_guard l(cache->lock); res.clear(); res_intervals.clear(); uint32_t want_bytes = length; uint32_t end = offset + length; - for (auto i = _data_lower_bound(offset); - i != buffer_map.end() && offset < end && i->first < end; - ++i) { - Buffer *b = i->second.get(); - assert(b->end() > offset); - if (b->is_writing() || b->is_clean()) { - if (b->offset < offset) { - uint32_t skip = offset - b->offset; - uint32_t l = MIN(length, b->length - skip); - res[offset].substr_of(b->data, skip, l); - res_intervals.insert(offset, l); - offset += l; - length -= l; - if (!b->is_writing()) { + + { + std::lock_guard l(cache->lock); + for (auto i = _data_lower_bound(offset); + i != buffer_map.end() && offset < end && i->first < end; + ++i) { + Buffer *b = i->second.get(); + assert(b->end() > offset); + if (b->is_writing() || b->is_clean()) { + if (b->offset < offset) { + uint32_t skip = offset - b->offset; + uint32_t l = MIN(length, b->length - skip); + res[offset].substr_of(b->data, skip, l); + res_intervals.insert(offset, l); + offset += l; + length -= l; + if (!b->is_writing()) { + cache->_touch_buffer(b); + } + continue; + } + if (b->offset > offset) { + uint32_t gap = b->offset - offset; + if (length <= gap) { + break; + } + offset += gap; + length -= gap; + } + if (!b->is_writing()) { cache->_touch_buffer(b); - } - continue; - } - if (b->offset > offset) { - uint32_t gap = b->offset - offset; - if (length <= gap) { - break; - } - offset += gap; - length -= gap; - } - if (!b->is_writing()) { - cache->_touch_buffer(b); - } - if (b->length > length) { - res[offset].substr_of(b->data, 0, length); - res_intervals.insert(offset, length); - break; - } else { - res[offset].append(b->data); - res_intervals.insert(offset, b->length); - if (b->length == length) + } + if (b->length > length) { + res[offset].substr_of(b->data, 0, length); + res_intervals.insert(offset, length); break; - offset += b->length; - length -= b->length; + } else { + res[offset].append(b->data); + res_intervals.insert(offset, b->length); + if (b->length == length) + break; + offset += b->length; + length -= b->length; + } } } } @@ -1490,19 +1526,30 @@ BlueStore::OnodeRef BlueStore::OnodeSpace::add(const ghobject_t& oid, OnodeRef o BlueStore::OnodeRef BlueStore::OnodeSpace::lookup(const ghobject_t& oid) { - std::lock_guard l(cache->lock); ldout(cache->cct, 30) << __func__ << dendl; - ceph::unordered_map::iterator p = onode_map.find(oid); - if (p == onode_map.end()) { - ldout(cache->cct, 30) << __func__ << " " << oid << " miss" << dendl; + OnodeRef o; + bool hit = false; + + { + std::lock_guard l(cache->lock); + ceph::unordered_map::iterator p = onode_map.find(oid); + if (p == onode_map.end()) { + ldout(cache->cct, 30) << __func__ << " " << oid << " miss" << dendl; + } else { + ldout(cache->cct, 30) << __func__ << " " << oid << " hit " << p->second + << dendl; + cache->_touch_onode(p->second); + hit = true; + o = p->second; + } + } + + if (hit) { + cache->logger->inc(l_bluestore_onode_hits); + } else { cache->logger->inc(l_bluestore_onode_misses); - return OnodeRef(); } - ldout(cache->cct, 30) << __func__ << " " << oid << " hit " << p->second - << dendl; - cache->_touch_onode(p->second); - cache->logger->inc(l_bluestore_onode_hits); - return p->second; + return o; } void BlueStore::OnodeSpace::clear() @@ -1664,13 +1711,13 @@ ostream& operator<<(ostream& out, const BlueStore::Blob& b) void BlueStore::Blob::discard_unallocated(Collection *coll) { - if (blob.is_shared()) { + if (get_blob().is_shared()) { return; } - if (blob.is_compressed()) { + if (get_blob().is_compressed()) { bool discard = false; bool all_invalid = true; - for (auto e : blob.get_extents()) { + for (auto e : get_blob().get_extents()) { if (!e.is_valid()) { discard = true; } else { @@ -1680,11 +1727,12 @@ void BlueStore::Blob::discard_unallocated(Collection *coll) assert(discard == all_invalid); // in case of compressed blob all // or none pextents are invalid. if (discard) { - shared_blob->bc.discard(shared_blob->get_cache(), 0, blob.get_logical_length()); + shared_blob->bc.discard(shared_blob->get_cache(), 0, + get_blob().get_logical_length()); } } else { size_t pos = 0; - for (auto e : blob.get_extents()) { + for (auto e : get_blob().get_extents()) { if (!e.is_valid()) { ldout(coll->store->cct, 20) << __func__ << " 0x" << std::hex << pos << "~" << e.length @@ -1693,12 +1741,11 @@ void BlueStore::Blob::discard_unallocated(Collection *coll) } pos += e.length; } - if (blob.can_prune_tail()) { - dirty_blob(); - blob.prune_tail(); - used_in_blob.prune_tail(blob.get_ondisk_length()); + if (get_blob().can_prune_tail()) { + dirty_blob().prune_tail(); + used_in_blob.prune_tail(get_blob().get_ondisk_length()); auto cct = coll->store->cct; //used by dout - dout(20) << __func__ << " pruned tail, now " << blob << dendl; + dout(20) << __func__ << " pruned tail, now " << get_blob() << dendl; } } } @@ -1719,10 +1766,10 @@ void BlueStore::Blob::get_ref( if (used_in_blob.is_empty()) { uint32_t min_release_size = - blob.get_release_size(coll->store->min_alloc_size); - uint64_t l = blob.get_logical_length(); - dout(20) << __func__ << " init 0x" << std::hex << l << ", " << min_release_size - << std::dec << dendl; + get_blob().get_release_size(coll->store->min_alloc_size); + uint64_t l = get_blob().get_logical_length(); + dout(20) << __func__ << " init 0x" << std::hex << l << ", " + << min_release_size << std::dec << dendl; used_in_blob.init(l, min_release_size); } used_in_blob.get( @@ -1756,7 +1803,7 @@ bool BlueStore::Blob::put_ref( return b.release_extents(empty, logical, r); } -bool BlueStore::Blob::try_reuse_blob(uint32_t min_alloc_size, +bool BlueStore::Blob::can_reuse_blob(uint32_t min_alloc_size, uint32_t target_blob_size, uint32_t b_offset, uint32_t *length0) { @@ -1784,17 +1831,25 @@ bool BlueStore::Blob::try_reuse_blob(uint32_t min_alloc_size, target_blob_size = MAX(blen, target_blob_size); if (b_offset >= blen) { - //new data totally stands out of the existing blob - new_blen = b_offset + length; + // new data totally stands out of the existing blob + new_blen = end; } else { - //new data overlaps with the existing blob - new_blen = MAX(blen, length + b_offset); - if (!get_blob().is_unallocated( - b_offset, - new_blen > blen ? blen - b_offset : length)) { - return false; + // new data overlaps with the existing blob + new_blen = MAX(blen, end); + + uint32_t overlap = 0; + if (new_blen > blen) { + overlap = blen - b_offset; + } else { + overlap = length; + } + + if (!get_blob().is_unallocated(b_offset, overlap)) { + // abort if any piece of the overlap has already been allocated + return false; } } + if (new_blen > blen) { int64_t overflow = int64_t(new_blen) - target_blob_size; // Unable to decrease the provided length to fit into max_blob_size @@ -1812,10 +1867,11 @@ bool BlueStore::Blob::try_reuse_blob(uint32_t min_alloc_size, length -= overflow; *length0 = length; } + if (new_blen > blen) { dirty_blob().add_tail(new_blen); used_in_blob.add_tail(new_blen, - blob.get_release_size(min_alloc_size)); + get_blob().get_release_size(min_alloc_size)); } } return true; @@ -2905,9 +2961,9 @@ bool BlueStore::WriteContext::has_conflict( for (auto w : writes) { if (b == w.b) { auto loffs2 = P2ALIGN(w.logical_offset, min_alloc_size); - auto loffs2_end = ROUND_UP_TO( w.logical_offset + w.length0, min_alloc_size); + auto loffs2_end = P2ROUNDUP(w.logical_offset + w.length0, min_alloc_size); if ((loffs <= loffs2 && loffs_end > loffs2) || - (loffs >= loffs2 && loffs < loffs2_end)) { + (loffs >= loffs2 && loffs < loffs2_end)) { return true; } } @@ -2959,6 +3015,7 @@ void BlueStore::DeferredBatch::_discard( << " 0x" << std::hex << p->first << "~" << p->second.bl.length() << " -> 0x" << head.length() << std::dec << dendl; auto i = seq_bytes.find(p->second.seq); + assert(i != seq_bytes.end()); if (end > offset + length) { bufferlist tail; tail.substr_of(p->second.bl, offset + length - p->first, @@ -2973,6 +3030,7 @@ void BlueStore::DeferredBatch::_discard( } else { i->second -= end - offset; } + assert(i->second >= 0); p->second.bl.swap(head); } ++p; @@ -2982,6 +3040,7 @@ void BlueStore::DeferredBatch::_discard( break; } auto i = seq_bytes.find(p->second.seq); + assert(i != seq_bytes.end()); auto end = p->first + p->second.bl.length(); if (end > offset + length) { unsigned drop_front = offset + length - p->first; @@ -3001,6 +3060,7 @@ void BlueStore::DeferredBatch::_discard( << std::dec << dendl; i->second -= p->second.bl.length(); } + assert(i->second >= 0); p = iomap.erase(p); } } @@ -3269,7 +3329,7 @@ void *BlueStore::MempoolThread::entry() size_t num_shards = store->cache_shards.size(); float target_ratio = store->cache_meta_ratio + store->cache_data_ratio; // A little sloppy but should be close enough - uint64_t shard_target = target_ratio * (store->cct->_conf->bluestore_cache_size / num_shards); + uint64_t shard_target = target_ratio * (store->cache_size / num_shards); for (auto i : store->cache_shards) { i->trim(shard_target, @@ -3437,17 +3497,6 @@ BlueStore::BlueStore(CephContext *cct, _init_logger(); cct->_conf->add_observer(this); set_cache_shards(1); - - if (cct->_conf->bluestore_shard_finishers) { - m_finisher_num = cct->_conf->osd_op_num_shards; - } - - for (int i = 0; i < m_finisher_num; ++i) { - ostringstream oss; - oss << "finisher-" << i; - Finisher *f = new Finisher(cct, oss.str(), "finisher"); - finishers.push_back(f); - } } BlueStore::~BlueStore() @@ -3552,6 +3601,25 @@ void BlueStore::handle_conf_change(const struct md_config_t *conf, void BlueStore::_set_compression() { + auto m = Compressor::get_comp_mode_type(cct->_conf->bluestore_compression_mode); + if (m) { + comp_mode = *m; + } else { + derr << __func__ << " unrecognized value '" + << cct->_conf->bluestore_compression_mode + << "' for bluestore_compression_mode, reverting to 'none'" + << dendl; + comp_mode = Compressor::COMP_NONE; + } + + compressor = nullptr; + + if (comp_mode == Compressor::COMP_NONE) { + dout(10) << __func__ << " compression mode set to 'none', " + << "ignore other compression setttings" << dendl; + return; + } + if (cct->_conf->bluestore_compression_max_blob_size) { comp_min_blob_size = cct->_conf->bluestore_compression_max_blob_size; } else { @@ -3574,19 +3642,6 @@ void BlueStore::_set_compression() } } - auto m = Compressor::get_comp_mode_type(cct->_conf->bluestore_compression_mode); - if (m) { - comp_mode = *m; - } else { - derr << __func__ << " unrecognized value '" - << cct->_conf->bluestore_compression_mode - << "' for bluestore_compression_mode, reverting to 'none'" - << dendl; - comp_mode = Compressor::COMP_NONE; - } - - compressor = nullptr; - auto& alg_name = cct->_conf->bluestore_compression_algorithm; if (!alg_name.empty()) { compressor = Compressor::create(cct, alg_name); @@ -3647,19 +3702,46 @@ void BlueStore::_set_blob_size() int BlueStore::_set_cache_sizes() { + assert(bdev); + if (cct->_conf->bluestore_cache_size) { + cache_size = cct->_conf->bluestore_cache_size; + } else { + // choose global cache size based on backend type + if (bdev->is_rotational()) { + cache_size = cct->_conf->bluestore_cache_size_hdd; + } else { + cache_size = cct->_conf->bluestore_cache_size_ssd; + } + } cache_meta_ratio = cct->_conf->bluestore_cache_meta_ratio; cache_kv_ratio = cct->_conf->bluestore_cache_kv_ratio; + + double cache_kv_max = cct->_conf->bluestore_cache_kv_max; + double cache_kv_max_ratio = 0; + + // if cache_kv_max is negative, disable it + if (cache_size > 0 && cache_kv_max >= 0) { + cache_kv_max_ratio = (double) cache_kv_max / (double) cache_size; + if (cache_kv_max_ratio < 1.0 && cache_kv_max_ratio < cache_kv_ratio) { + dout(1) << __func__ << " max " << cache_kv_max_ratio + << " < ratio " << cache_kv_ratio + << dendl; + cache_meta_ratio = cache_meta_ratio + cache_kv_ratio - cache_kv_max_ratio; + cache_kv_ratio = cache_kv_max_ratio; + } + } + cache_data_ratio = (double)1.0 - (double)cache_meta_ratio - (double)cache_kv_ratio; - if (cache_meta_ratio <= 0 || cache_meta_ratio > 1.0) { + if (cache_meta_ratio < 0 || cache_meta_ratio > 1.0) { derr << __func__ << "bluestore_cache_meta_ratio (" << cache_meta_ratio - << ") must be in range (0,1.0]" << dendl; + << ") must be in range [0,1.0]" << dendl; return -EINVAL; } - if (cache_kv_ratio <= 0 || cache_kv_ratio > 1.0) { + if (cache_kv_ratio < 0 || cache_kv_ratio > 1.0) { derr << __func__ << "bluestore_cache_kv_ratio (" << cache_kv_ratio - << ") must be in range (0,1.0]" << dendl; + << ") must be in range [0,1.0]" << dendl; return -EINVAL; } if (cache_meta_ratio + cache_kv_ratio > 1.0) { @@ -3673,7 +3755,8 @@ int BlueStore::_set_cache_sizes() // deal with floating point imprecision cache_data_ratio = 0; } - dout(1) << __func__ << " meta " << cache_meta_ratio + dout(1) << __func__ << " cache_size " << cache_size + << " meta " << cache_meta_ratio << " kv " << cache_kv_ratio << " data " << cache_data_ratio << dendl; @@ -3855,14 +3938,8 @@ int BlueStore::get_block_device_fsid(CephContext* cct, const string& path, int BlueStore::_open_path() { - // initial sanity check - int r = _set_cache_sizes(); - if (r < 0) { - return r; - } - assert(path_fd < 0); - path_fd = ::open(path.c_str(), O_DIRECTORY); + path_fd = TEMP_FAILURE_RETRY(::open(path.c_str(), O_DIRECTORY)); if (path_fd < 0) { int r = -errno; derr << __func__ << " unable to open " << path << ": " << cpp_strerror(r) @@ -3890,7 +3967,7 @@ int BlueStore::_write_bdev_label(string path, bluestore_bdev_label_t label) z.zero(); bl.append(std::move(z)); - int fd = ::open(path.c_str(), O_WRONLY); + int fd = TEMP_FAILURE_RETRY(::open(path.c_str(), O_WRONLY)); if (fd < 0) { fd = -errno; derr << __func__ << " failed to open " << path << ": " << cpp_strerror(fd) @@ -3910,7 +3987,7 @@ int BlueStore::_read_bdev_label(CephContext* cct, string path, bluestore_bdev_label_t *label) { dout(10) << __func__ << dendl; - int fd = ::open(path.c_str(), O_RDONLY); + int fd = TEMP_FAILURE_RETRY(::open(path.c_str(), O_RDONLY)); if (fd < 0) { fd = -errno; derr << __func__ << " failed to open " << path << ": " << cpp_strerror(fd) @@ -3981,9 +4058,6 @@ int BlueStore::_check_or_set_bdev_label( void BlueStore::_set_alloc_sizes(void) { - min_alloc_size_order = ctz(min_alloc_size); - assert(min_alloc_size == 1u << min_alloc_size_order); - max_alloc_size = cct->_conf->bluestore_max_alloc_size; if (cct->_conf->bluestore_prefer_deferred_size) { @@ -4037,6 +4111,11 @@ int BlueStore::_open_bdev(bool create) block_mask = ~(block_size - 1); block_size_order = ctz(block_size); assert(block_size == 1u << block_size_order); + // and set cache_size based on device type + r = _set_cache_sizes(); + if (r < 0) { + goto fail_close; + } return 0; fail_close: @@ -4180,6 +4259,7 @@ int BlueStore::_open_alloc() ++num; bytes += length; } + fm->enumerate_reset(); dout(1) << __func__ << " loaded " << pretty_si_t(bytes) << " in " << num << " extents" << dendl; @@ -4584,7 +4664,7 @@ int BlueStore::_open_db(bool create) FreelistManager::setup_merge_operators(db); db->set_merge_operator(PREFIX_STAT, merge_op); - db->set_cache_size(cct->_conf->bluestore_cache_size * cache_kv_ratio); + db->set_cache_size(cache_size * cache_kv_ratio); if (kv_backend == "rocksdb") options = cct->_conf->bluestore_rocksdb_options; @@ -4837,7 +4917,7 @@ int BlueStore::_open_collections(int *errors) return 0; } -void BlueStore::open_statfs() +void BlueStore::_open_statfs() { bufferlist bl; int r = db->get(PREFIX_STAT, "bluestore_statfs", &bl); @@ -4845,8 +4925,7 @@ void BlueStore::open_statfs() if (size_t(bl.length()) >= sizeof(vstatfs.values)) { auto it = bl.begin(); vstatfs.decode(it); - } - else { + } else { dout(10) << __func__ << " store_statfs is corrupt, using empty" << dendl; } } @@ -5077,7 +5156,17 @@ int BlueStore::mkfs() min_alloc_size = cct->_conf->bluestore_min_alloc_size_ssd; } } - _set_alloc_sizes(); + + // make sure min_alloc_size is power of 2 aligned. + if (!ISP2(min_alloc_size)) { + derr << __func__ << " min_alloc_size 0x" + << std::hex << min_alloc_size << std::dec + << " is not power of 2 aligned!" + << dendl; + r = -EINVAL; + goto out_close_fm; + } + { bufferlist bl; ::encode((uint64_t)min_alloc_size, bl); @@ -5089,27 +5178,23 @@ int BlueStore::mkfs() db->submit_transaction_sync(t); } - r = _open_alloc(); - if (r < 0) - goto out_close_fm; r = write_meta("kv_backend", cct->_conf->bluestore_kvbackend); if (r < 0) - goto out_close_alloc; + goto out_close_fm; + r = write_meta("bluefs", stringify((int)cct->_conf->bluestore_bluefs)); if (r < 0) - goto out_close_alloc; + goto out_close_fm; if (fsid != old_fsid) { r = _write_fsid(); if (r < 0) { derr << __func__ << " error writing fsid: " << cpp_strerror(r) << dendl; - goto out_close_alloc; + goto out_close_fm; } } - out_close_alloc: - _close_alloc(); out_close_fm: _close_fm(); out_close_db: @@ -5892,6 +5977,7 @@ int BlueStore::fsck(bool deep) ++errors; } } + fm->enumerate_reset(); size_t count = used_blocks.count(); if (used_blocks.size() != count) { assert(used_blocks.size() > count); @@ -6154,13 +6240,12 @@ int BlueStore::read( uint64_t offset, size_t length, bufferlist& bl, - uint32_t op_flags, - bool allow_eio) + uint32_t op_flags) { CollectionHandle c = _get_collection(cid); if (!c) return -ENOENT; - return read(c, oid, offset, length, bl, op_flags, allow_eio); + return read(c, oid, offset, length, bl, op_flags); } int BlueStore::read( @@ -6169,8 +6254,7 @@ int BlueStore::read( uint64_t offset, size_t length, bufferlist& bl, - uint32_t op_flags, - bool allow_eio) + uint32_t op_flags) { utime_t start = ceph_clock_now(); Collection *c = static_cast(c_.get()); @@ -6200,10 +6284,13 @@ int BlueStore::read( } out: - assert(allow_eio || r != -EIO); if (r == 0 && _debug_data_eio(oid)) { r = -EIO; derr << __func__ << " " << c->cid << " " << oid << " INJECT EIO" << dendl; + } else if (cct->_conf->bluestore_debug_random_read_err && + (rand() % (int)(cct->_conf->bluestore_debug_random_read_err * 100.0)) == 0) { + dout(0) << __func__ << ": inject random EIO" << dendl; + r = -EIO; } dout(10) << __func__ << " " << cid << " " << oid << " 0x" << std::hex << offset << "~" << length << std::dec @@ -7443,6 +7530,8 @@ int BlueStore::_open_super_meta() uint64_t val; ::decode(val, p); min_alloc_size = val; + min_alloc_size_order = ctz(val); + assert(min_alloc_size == 1u << min_alloc_size_order); } catch (buffer::error& e) { derr << __func__ << " unable to read min_alloc_size" << dendl; return -EIO; @@ -7450,7 +7539,7 @@ int BlueStore::_open_super_meta() dout(10) << __func__ << " min_alloc_size 0x" << std::hex << min_alloc_size << std::dec << dendl; } - open_statfs(); + _open_statfs(); _set_alloc_sizes(); _set_throttle_params(); @@ -7504,12 +7593,15 @@ int BlueStore::_upgrade_super() void BlueStore::_assign_nid(TransContext *txc, OnodeRef o) { - if (o->onode.nid) + if (o->onode.nid) { + assert(o->exists); return; + } uint64_t nid = ++nid_last; dout(20) << __func__ << " " << nid << dendl; o->onode.nid = nid; txc->last_nid = nid; + o->exists = true; } uint64_t BlueStore::_assign_blobid(TransContext *txc) @@ -8005,9 +8097,11 @@ void BlueStore::_osr_drain_preceding(TransContext *txc) ++deferred_aggressive; // FIXME: maybe osr-local aggressive flag? { // submit anything pending - std::lock_guard l(deferred_lock); + deferred_lock.lock(); if (osr->deferred_pending) { - _deferred_submit(osr); + _deferred_submit_unlock(osr); + } else { + deferred_lock.unlock(); } } { @@ -8034,8 +8128,7 @@ void BlueStore::_osr_drain_all() ++deferred_aggressive; { // submit anything pending - std::lock_guard l(deferred_lock); - _deferred_try_submit(); + deferred_try_submit(); } { // wake up any previously finished deferred events @@ -8332,16 +8425,16 @@ void BlueStore::_kv_sync_thread() dout(10) << __func__ << " blobid_max now " << blobid_max << dendl; } - utime_t finish = ceph_clock_now(); - utime_t dur_flush = after_flush - start; - utime_t dur_kv = finish - after_flush; - utime_t dur = finish - start; - dout(20) << __func__ << " committed " << kv_committing.size() - << " cleaned " << deferred_stable.size() - << " in " << dur - << " (" << dur_flush << " flush + " << dur_kv << " kv commit)" - << dendl; - if (logger) { + { + utime_t finish = ceph_clock_now(); + utime_t dur_flush = after_flush - start; + utime_t dur_kv = finish - after_flush; + utime_t dur = finish - start; + dout(20) << __func__ << " committed " << kv_committing.size() + << " cleaned " << deferred_stable.size() + << " in " << dur + << " (" << dur_flush << " flush + " << dur_kv << " kv commit)" + << dendl; logger->tinc(l_bluestore_kv_flush_lat, dur_flush); logger->tinc(l_bluestore_kv_commit_lat, dur_kv); logger->tinc(l_bluestore_kv_lat, dur); @@ -8440,10 +8533,9 @@ void BlueStore::_kv_finalize_thread() deferred_stable.clear(); if (!deferred_aggressive) { - std::lock_guard l(deferred_lock); if (deferred_queue_size >= deferred_batch_ops.load() || throttle_deferred_bytes.past_midpoint()) { - _deferred_try_submit(); + deferred_try_submit(); } } @@ -8470,7 +8562,7 @@ bluestore_deferred_op_t *BlueStore::_get_deferred_op( void BlueStore::_deferred_queue(TransContext *txc) { dout(20) << __func__ << " txc " << txc << " osr " << txc->osr << dendl; - std::lock_guard l(deferred_lock); + deferred_lock.lock(); if (!txc->osr->deferred_pending && !txc->osr->deferred_running) { deferred_queue.push_back(*txc->osr); @@ -8492,22 +8584,31 @@ void BlueStore::_deferred_queue(TransContext *txc) } if (deferred_aggressive && !txc->osr->deferred_running) { - _deferred_submit(txc->osr.get()); + _deferred_submit_unlock(txc->osr.get()); + } else { + deferred_lock.unlock(); } } -void BlueStore::_deferred_try_submit() +void BlueStore::deferred_try_submit() { dout(20) << __func__ << " " << deferred_queue.size() << " osrs, " << deferred_queue_size << " txcs" << dendl; + std::lock_guard l(deferred_lock); + vector osrs; + osrs.reserve(deferred_queue.size()); for (auto& osr : deferred_queue) { - if (!osr.deferred_running) { - _deferred_submit(&osr); + osrs.push_back(&osr); + } + for (auto& osr : osrs) { + if (osr->deferred_pending && !osr->deferred_running) { + _deferred_submit_unlock(osr.get()); + deferred_lock.lock(); } } } -void BlueStore::_deferred_submit(OpSequencer *osr) +void BlueStore::_deferred_submit_unlock(OpSequencer *osr) { dout(10) << __func__ << " osr " << osr << " " << osr->deferred_pending->iomap.size() << " ios pending " @@ -8555,6 +8656,10 @@ void BlueStore::_deferred_submit(OpSequencer *osr) bl.claim_append(i->second.bl); ++i; } + + // demote to deferred_submit_lock, then drop that too + std::lock_guard l(deferred_submit_lock); + deferred_lock.unlock(); bdev->aio_submit(&b->ioc); } @@ -8572,7 +8677,10 @@ void BlueStore::_deferred_aio_finish(OpSequencer *osr) auto q = deferred_queue.iterator_to(*osr); deferred_queue.erase(q); } else if (deferred_aggressive) { - _deferred_submit(osr); + dout(20) << __func__ << " queuing async deferred_try_submit" << dendl; + finishers[0]->queue(new FunctionContext([&](int) { + deferred_try_submit(); + })); } } @@ -9093,7 +9201,6 @@ int BlueStore::_touch(TransContext *txc, { dout(15) << __func__ << " " << c->cid << " " << o->oid << dendl; int r = 0; - o->exists = true; _assign_nid(txc, o); txc->write_onode(o); dout(10) << __func__ << " " << c->cid << " " << o->oid << " = " << r << dendl; @@ -9182,12 +9289,12 @@ void BlueStore::_pad_zeros( if (front_pad) { size_t front_copy = MIN(chunk_size - front_pad, length); bufferptr z = buffer::create_page_aligned(chunk_size); - memset(z.c_str(), 0, front_pad); + z.zero(0, front_pad, false); pad_count += front_pad; - memcpy(z.c_str() + front_pad, bl->get_contiguous(0, front_copy), front_copy); + bl->copy(0, front_copy, z.c_str() + front_pad); if (front_copy + front_pad < chunk_size) { back_pad = chunk_size - (length + front_pad); - memset(z.c_str() + front_pad + length, 0, back_pad); + z.zero(front_pad + length, back_pad, false); pad_count += back_pad; } bufferlist old, t; @@ -9196,7 +9303,7 @@ void BlueStore::_pad_zeros( bl->append(z); bl->claim_append(t); *offset -= front_pad; - length += front_pad + back_pad; + length += pad_count; } // back @@ -9207,9 +9314,8 @@ void BlueStore::_pad_zeros( back_pad = chunk_size - back_copy; assert(back_copy <= length); bufferptr tail(chunk_size); - memcpy(tail.c_str(), bl->get_contiguous(length - back_copy, back_copy), - back_copy); - memset(tail.c_str() + back_copy, 0, back_pad); + bl->copy(length - back_copy, back_copy, tail.c_str()); + tail.zero(back_copy, back_pad, false); bufferlist old; old.swap(*bl); bl->substr_of(old, 0, length - back_copy); @@ -9273,7 +9379,7 @@ void BlueStore::_do_write_small( // search suitable extent in both forward and reverse direction in // [offset - target_max_blob_size, offset + target_max_blob_size] range - // then check if blob can be reused via try_reuse_blob func or apply + // then check if blob can be reused via can_reuse_blob func or apply // direct/deferred write (the latter for extents including or higher // than 'offset' only). do { @@ -9317,14 +9423,13 @@ void BlueStore::_do_write_small( b->get_blob().get_ondisk_length() >= b_off + b_len && b->get_blob().is_unused(b_off, b_len) && b->get_blob().is_allocated(b_off, b_len)) { - bufferlist padded; - _apply_padding(head_pad, tail_pad, bl, padded); + _apply_padding(head_pad, tail_pad, bl); dout(20) << __func__ << " write to unused 0x" << std::hex << b_off << "~" << b_len << " pad 0x" << head_pad << " + 0x" << tail_pad << std::dec << " of mutable " << *b << dendl; - _buffer_cache_write(txc, b, b_off, padded, + _buffer_cache_write(txc, b, b_off, bl, wctx->buffered ? 0 : Buffer::FLAG_NOCACHE); if (!g_conf->bluestore_debug_omit_block_device_write) { @@ -9339,17 +9444,17 @@ void BlueStore::_do_write_small( op->extents.emplace_back(bluestore_pextent_t(offset, length)); return 0; }); - op->data = padded; + op->data = bl; } else { b->get_blob().map_bl( - b_off, padded, + b_off, bl, [&](uint64_t offset, bufferlist& t) { bdev->aio_write(offset, t, &txc->ioc, wctx->buffered); }); } } - b->dirty_blob().calc_csum(b_off, padded); + b->dirty_blob().calc_csum(b_off, bl); dout(20) << __func__ << " lex old " << *ep << dendl; Extent *le = o->extent_map.set_lextent(c, offset, b_off + head_pad, length, b, @@ -9379,8 +9484,7 @@ void BlueStore::_do_write_small( b_len % chunk_size == 0 && b->get_blob().is_allocated(b_off, b_len)) { - bufferlist padded; - _apply_padding(head_pad, tail_pad, bl, padded); + _apply_padding(head_pad, tail_pad, bl); dout(20) << __func__ << " reading head 0x" << std::hex << head_read << " and tail 0x" << tail_read << std::dec << dendl; @@ -9394,8 +9498,7 @@ void BlueStore::_do_write_small( head_bl.append_zero(zlen); logger->inc(l_bluestore_write_pad_bytes, zlen); } - head_bl.claim_append(padded); - padded.swap(head_bl); + bl.claim_prepend(head_bl); logger->inc(l_bluestore_write_penalty_read_ops); } if (tail_read) { @@ -9408,14 +9511,14 @@ void BlueStore::_do_write_small( tail_bl.append_zero(zlen); logger->inc(l_bluestore_write_pad_bytes, zlen); } - padded.claim_append(tail_bl); + bl.claim_append(tail_bl); logger->inc(l_bluestore_write_penalty_read_ops); } logger->inc(l_bluestore_write_small_pre_read); bluestore_deferred_op_t *op = _get_deferred_op(txc, o); op->op = bluestore_deferred_op_t::OP_WRITE; - _buffer_cache_write(txc, b, b_off, padded, + _buffer_cache_write(txc, b, b_off, bl, wctx->buffered ? 0 : Buffer::FLAG_NOCACHE); int r = b->get_blob().map( @@ -9426,9 +9529,9 @@ void BlueStore::_do_write_small( }); assert(r == 0); if (b->get_blob().csum_type) { - b->dirty_blob().calc_csum(b_off, padded); + b->dirty_blob().calc_csum(b_off, bl); } - op->data.claim(padded); + op->data.claim(bl); dout(20) << __func__ << " deferred write 0x" << std::hex << b_off << "~" << b_len << std::dec << " of mutable " << *b << " at " << op->extents << dendl; @@ -9440,8 +9543,8 @@ void BlueStore::_do_write_small( logger->inc(l_bluestore_write_small_deferred); return; } - //try to reuse blob - if (b->try_reuse_blob(min_alloc_size, + // try to reuse blob if we can + if (b->can_reuse_blob(min_alloc_size, max_bsize, offset0 - bstart, &alloc_len)) { @@ -9465,8 +9568,8 @@ void BlueStore::_do_write_small( _pad_zeros(&bl, &b_off0, chunk_size); dout(20) << __func__ << " reuse blob " << *b << std::hex - << " (" << b_off0 << "~" << bl.length() << ")" - << " (" << b_off << "~" << length << ")" + << " (0x" << b_off0 << "~" << bl.length() << ")" + << " (0x" << b_off << "~" << length << ")" << std::dec << dendl; o->extent_map.punch_hole(c, offset, length, &wctx->old_extents); @@ -9487,7 +9590,7 @@ void BlueStore::_do_write_small( auto bstart = prev_ep->blob_start(); dout(20) << __func__ << " considering " << *b << " bstart 0x" << std::hex << bstart << std::dec << dendl; - if (b->try_reuse_blob(min_alloc_size, + if (b->can_reuse_blob(min_alloc_size, max_bsize, offset0 - bstart, &alloc_len)) { @@ -9510,8 +9613,8 @@ void BlueStore::_do_write_small( _pad_zeros(&bl, &b_off0, chunk_size); dout(20) << __func__ << " reuse blob " << *b << std::hex - << " (" << b_off0 << "~" << bl.length() << ")" - << " (" << b_off << "~" << length << ")" + << " (0x" << b_off0 << "~" << bl.length() << ")" + << " (0x" << b_off << "~" << length << ")" << std::dec << dendl; o->extent_map.punch_hole(c, offset, length, &wctx->old_extents); @@ -9580,20 +9683,20 @@ void BlueStore::_do_write_big( auto min_off = offset >= max_bsize ? offset - max_bsize : 0; // search suitable extent in both forward and reverse direction in // [offset - target_max_blob_size, offset + target_max_blob_size] range - // then check if blob can be reused via try_reuse_blob func. + // then check if blob can be reused via can_reuse_blob func. bool any_change; do { any_change = false; if (ep != end && ep->logical_offset < offset + max_bsize) { if (offset >= ep->blob_start() && - ep->blob->try_reuse_blob(min_alloc_size, max_bsize, + ep->blob->can_reuse_blob(min_alloc_size, max_bsize, offset - ep->blob_start(), &l)) { b = ep->blob; b_off = offset - ep->blob_start(); prev_ep = end; // to avoid check below dout(20) << __func__ << " reuse blob " << *b << std::hex - << " (" << b_off << "~" << l << ")" << std::dec << dendl; + << " (0x" << b_off << "~" << l << ")" << std::dec << dendl; } else { ++ep; any_change = true; @@ -9601,13 +9704,13 @@ void BlueStore::_do_write_big( } if (prev_ep != end && prev_ep->logical_offset >= min_off) { - if (prev_ep->blob->try_reuse_blob(min_alloc_size, max_bsize, + if (prev_ep->blob->can_reuse_blob(min_alloc_size, max_bsize, offset - prev_ep->blob_start(), &l)) { b = prev_ep->blob; b_off = offset - prev_ep->blob_start(); dout(20) << __func__ << " reuse blob " << *b << std::hex - << " (" << b_off << "~" << l << ")" << std::dec << dendl; + << " (0x" << b_off << "~" << l << ")" << std::dec << dendl; } else if (prev_ep != begin) { --prev_ep; any_change = true; @@ -10025,12 +10128,11 @@ void BlueStore::_choose_write_options( dout(20) << __func__ << " will prefer large blob and csum sizes" << dendl; - auto order = min_alloc_size_order.load(); if (o->onode.expected_write_size) { - wctx->csum_order = std::max(order, + wctx->csum_order = std::max(min_alloc_size_order, (uint8_t)ctz(o->onode.expected_write_size)); } else { - wctx->csum_order = order; + wctx->csum_order = min_alloc_size_order; } if (wctx->compress) { @@ -10216,7 +10318,6 @@ int BlueStore::_write(TransContext *txc, dout(15) << __func__ << " " << c->cid << " " << o->oid << " 0x" << std::hex << offset << "~" << length << std::dec << dendl; - o->exists = true; _assign_nid(txc, o); int r = _do_write(txc, c, o, offset, length, bl, fadvise_flags); txc->write_onode(o); @@ -10235,7 +10336,6 @@ int BlueStore::_zero(TransContext *txc, dout(15) << __func__ << " " << c->cid << " " << o->oid << " 0x" << std::hex << offset << "~" << length << std::dec << dendl; - o->exists = true; _assign_nid(txc, o); int r = _do_zero(txc, c, o, offset, length); dout(10) << __func__ << " " << c->cid << " " << o->oid @@ -10329,7 +10429,8 @@ int BlueStore::_do_remove( OnodeRef o) { set maybe_unshared_blobs; - _do_truncate(txc, c, o, 0, &maybe_unshared_blobs); + bool is_gen = !o->oid.is_no_gen(); + _do_truncate(txc, c, o, 0, is_gen ? &maybe_unshared_blobs : nullptr); if (o->onode.has_omap()) { o->flush(); _do_omap_clear(txc, o->onode.nid); @@ -10351,72 +10452,81 @@ int BlueStore::_do_remove( o->onode = bluestore_onode_t(); _debug_obj_on_delete(o->oid); - if (!o->oid.is_no_gen() && - !maybe_unshared_blobs.empty()) { - // see if we can unshare blobs still referenced by the head - dout(10) << __func__ << " gen and maybe_unshared_blobs " - << maybe_unshared_blobs << dendl; - ghobject_t nogen = o->oid; - nogen.generation = ghobject_t::NO_GEN; - OnodeRef h = c->onode_map.lookup(nogen); - if (h && h->exists) { - dout(20) << __func__ << " checking for unshareable blobs on " << h - << " " << h->oid << dendl; - map expect; - for (auto& e : h->extent_map.extent_map) { - const bluestore_blob_t& b = e.blob->get_blob(); - SharedBlob *sb = e.blob->shared_blob.get(); - if (b.is_shared() && - sb->loaded && - maybe_unshared_blobs.count(sb)) { - b.map(e.blob_offset, e.length, [&](uint64_t off, uint64_t len) { - expect[sb].get(off, len); - return 0; - }); - } - } - vector unshared_blobs; - unshared_blobs.reserve(maybe_unshared_blobs.size()); - for (auto& p : expect) { - dout(20) << " ? " << *p.first << " vs " << p.second << dendl; - if (p.first->persistent->ref_map == p.second) { - SharedBlob *sb = p.first; - dout(20) << __func__ << " unsharing " << *sb << dendl; - unshared_blobs.push_back(sb); - txc->unshare_blob(sb); - uint64_t sbid = c->make_blob_unshared(sb); - string key; - get_shared_blob_key(sbid, &key); - txc->t->rmkey(PREFIX_SHARED_BLOB, key); - } - } + if (!is_gen || maybe_unshared_blobs.empty()) { + return 0; + } - if (!unshared_blobs.empty()) { - uint32_t b_start = OBJECT_MAX_SIZE; - uint32_t b_end = 0; - for (auto& e : h->extent_map.extent_map) { - const bluestore_blob_t& b = e.blob->get_blob(); - SharedBlob *sb = e.blob->shared_blob.get(); - if (b.is_shared() && - std::find(unshared_blobs.begin(), unshared_blobs.end(), - sb) != unshared_blobs.end()) { - dout(20) << __func__ << " unsharing " << e << dendl; - bluestore_blob_t& blob = e.blob->dirty_blob(); - blob.clear_flag(bluestore_blob_t::FLAG_SHARED); - if (e.logical_offset < b_start) { - b_start = e.logical_offset; - } - if (e.logical_end() > b_end) { - b_end = e.logical_end(); - } - } - } + // see if we can unshare blobs still referenced by the head + dout(10) << __func__ << " gen and maybe_unshared_blobs " + << maybe_unshared_blobs << dendl; + ghobject_t nogen = o->oid; + nogen.generation = ghobject_t::NO_GEN; + OnodeRef h = c->onode_map.lookup(nogen); + + if (!h || !h->exists) { + return 0; + } + + dout(20) << __func__ << " checking for unshareable blobs on " << h + << " " << h->oid << dendl; + map expect; + for (auto& e : h->extent_map.extent_map) { + const bluestore_blob_t& b = e.blob->get_blob(); + SharedBlob *sb = e.blob->shared_blob.get(); + if (b.is_shared() && + sb->loaded && + maybe_unshared_blobs.count(sb)) { + b.map(e.blob_offset, e.length, [&](uint64_t off, uint64_t len) { + expect[sb].get(off, len); + return 0; + }); + } + } - h->extent_map.dirty_range(b_start, b_end - b_start); - txc->write_onode(h); + vector unshared_blobs; + unshared_blobs.reserve(maybe_unshared_blobs.size()); + for (auto& p : expect) { + dout(20) << " ? " << *p.first << " vs " << p.second << dendl; + if (p.first->persistent->ref_map == p.second) { + SharedBlob *sb = p.first; + dout(20) << __func__ << " unsharing " << *sb << dendl; + unshared_blobs.push_back(sb); + txc->unshare_blob(sb); + uint64_t sbid = c->make_blob_unshared(sb); + string key; + get_shared_blob_key(sbid, &key); + txc->t->rmkey(PREFIX_SHARED_BLOB, key); + } + } + + if (unshared_blobs.empty()) { + return 0; + } + + uint32_t b_start = OBJECT_MAX_SIZE; + uint32_t b_end = 0; + for (auto& e : h->extent_map.extent_map) { + const bluestore_blob_t& b = e.blob->get_blob(); + SharedBlob *sb = e.blob->shared_blob.get(); + if (b.is_shared() && + std::find(unshared_blobs.begin(), unshared_blobs.end(), + sb) != unshared_blobs.end()) { + dout(20) << __func__ << " unsharing " << e << dendl; + bluestore_blob_t& blob = e.blob->dirty_blob(); + blob.clear_flag(bluestore_blob_t::FLAG_SHARED); + if (e.logical_offset < b_start) { + b_start = e.logical_offset; + } + if (e.logical_end() > b_end) { + b_end = e.logical_end(); } } } + + assert(b_end > b_start); + h->extent_map.dirty_range(b_start, b_end - b_start); + txc->write_onode(h); + return 0; } @@ -10713,7 +10823,6 @@ int BlueStore::_clone(TransContext *txc, return -EINVAL; } - newo->exists = true; _assign_nid(txc, newo); // clone data @@ -10781,7 +10890,9 @@ int BlueStore::_do_clone_range( CollectionRef& c, OnodeRef& oldo, OnodeRef& newo, - uint64_t srcoff, uint64_t length, uint64_t dstoff) + uint64_t srcoff, + uint64_t length, + uint64_t dstoff) { dout(15) << __func__ << " " << c->cid << " " << oldo->oid << " -> " << newo->oid @@ -10798,8 +10909,9 @@ int BlueStore::_do_clone_range( e.blob->last_encoded_id = -1; } int n = 0; - bool dirtied_oldo = false; uint64_t end = srcoff + length; + uint32_t dirty_range_begin = 0; + uint32_t dirty_range_end = 0; for (auto ep = oldo->extent_map.seek_lextent(srcoff); ep != oldo->extent_map.extent_map.end(); ++ep) { @@ -10820,7 +10932,12 @@ int BlueStore::_do_clone_range( // make sure it is shared if (!blob.is_shared()) { c->make_blob_shared(_assign_blobid(txc), e.blob); - dirtied_oldo = true; // fixme: overkill + if (dirty_range_begin == 0) { + dirty_range_begin = e.logical_offset; + } + assert(e.logical_end() > 0); + // -1 to exclude next potential shard + dirty_range_end = e.logical_end() - 1; } else { c->load_shared_blob(e.blob->shared_blob); } @@ -10867,8 +10984,9 @@ int BlueStore::_do_clone_range( dout(20) << __func__ << " dst " << *ne << dendl; ++n; } - if (dirtied_oldo) { - oldo->extent_map.dirty_range(srcoff, length); // overkill + if (dirty_range_end > dirty_range_begin) { + oldo->extent_map.dirty_range(dirty_range_begin, + dirty_range_end - dirty_range_begin); txc->write_onode(oldo); } txc->write_onode(newo); @@ -10898,7 +11016,6 @@ int BlueStore::_clone_range(TransContext *txc, goto out; } - newo->exists = true; _assign_nid(txc, newo); if (length > 0) { @@ -11326,15 +11443,10 @@ void BlueStore::flush_cache() void BlueStore::_apply_padding(uint64_t head_pad, uint64_t tail_pad, - bufferlist& bl, bufferlist& padded) { - padded = bl; if (head_pad) { - bufferlist z; - z.append_zero(head_pad); - z.claim_append(padded); - padded.claim(z); + padded.prepend_zero(head_pad); } if (tail_pad) { padded.append_zero(tail_pad); diff --git a/ceph/src/os/bluestore/BlueStore.h b/ceph/src/os/bluestore/BlueStore.h index 1114e7b4f..f437d5d68 100644 --- a/ceph/src/os/bluestore/BlueStore.h +++ b/ceph/src/os/bluestore/BlueStore.h @@ -263,7 +263,19 @@ public: buffer_map[b->offset].reset(b); if (b->is_writing()) { b->data.reassign_to_mempool(mempool::mempool_bluestore_writing); - writing.push_back(*b); + if (writing.empty() || writing.rbegin()->seq <= b->seq) { + writing.push_back(*b); + } else { + auto it = writing.begin(); + while (it->seq < b->seq) { + ++it; + } + + assert(it->seq >= b->seq); + // note that this will insert b before it + // hence the order is maintained + writing.insert(it, *b); + } } else { b->data.reassign_to_mempool(mempool::mempool_bluestore_cache_data); cache->_add_buffer(b, level, near); @@ -499,7 +511,7 @@ public: get_blob().can_split_at(blob_offset); } - bool try_reuse_blob(uint32_t min_alloc_size, + bool can_reuse_blob(uint32_t min_alloc_size, uint32_t target_blob_size, uint32_t b_offset, uint32_t *length0); @@ -512,10 +524,10 @@ public: #endif } - const bluestore_blob_t& get_blob() const { + inline const bluestore_blob_t& get_blob() const { return blob; } - bluestore_blob_t& dirty_blob() { + inline bluestore_blob_t& dirty_blob() { #ifdef CACHE_BLOB_BL blob_bl.clear(); #endif @@ -1831,7 +1843,7 @@ private: interval_set bluefs_extents; ///< block extents owned by bluefs interval_set bluefs_extents_reclaiming; ///< currently reclaiming - std::mutex deferred_lock; + std::mutex deferred_lock, deferred_submit_lock; std::atomic deferred_seq = {0}; deferred_osr_queue_t deferred_queue; ///< osr's with deferred io pending int deferred_queue_size = 0; ///< num txc's queued across all osrs @@ -1875,24 +1887,26 @@ private: size_t block_size_order = 0; ///< bits to shift to get block size uint64_t min_alloc_size = 0; ///< minimum allocation unit (power of 2) - std::atomic deferred_batch_ops = {0}; ///< deferred batch size - ///< bits for min_alloc_size - std::atomic min_alloc_size_order = {0}; + uint8_t min_alloc_size_order = 0; static_assert(std::numeric_limits::max() > std::numeric_limits::digits, "not enough bits for min_alloc_size"); - ///< size threshold for forced deferred writes - std::atomic prefer_deferred_size = {0}; - ///< maximum allocation unit (power of 2) std::atomic max_alloc_size = {0}; + ///< number threshold for forced deferred writes + std::atomic deferred_batch_ops = {0}; + + ///< size threshold for forced deferred writes + std::atomic prefer_deferred_size = {0}; + ///< approx cost per io, in bytes std::atomic throttle_cost_per_io = {0}; - std::atomic comp_mode = {Compressor::COMP_NONE}; ///< compression mode + std::atomic comp_mode = + {Compressor::COMP_NONE}; ///< compression mode CompressorRef compressor; std::atomic comp_min_blob_size = {0}; std::atomic comp_max_blob_size = {0}; @@ -1903,6 +1917,7 @@ private: uint64_t kv_throttle_costs = 0; // cache trim control + uint64_t cache_size = 0; ///< total cache size float cache_meta_ratio = 0; ///< cache ratio dedicated to metadata float cache_kv_ratio = 0; ///< cache ratio dedicated to kv (e.g., rocksdb) float cache_data_ratio = 0; ///< cache ratio dedicated to object data @@ -1974,7 +1989,7 @@ private: int _open_super_meta(); - void open_statfs(); + void _open_statfs(); int _reconcile_bluefs_freespace(); int _balance_bluefs_freespace(PExtentVector *extents); @@ -2022,12 +2037,8 @@ private: bluestore_deferred_op_t *_get_deferred_op(TransContext *txc, OnodeRef o); void _deferred_queue(TransContext *txc); - void deferred_try_submit() { - std::lock_guard l(deferred_lock); - _deferred_try_submit(); - } - void _deferred_try_submit(); - void _deferred_submit(OpSequencer *osr); + void deferred_try_submit(); + void _deferred_submit_unlock(OpSequencer *osr); void _deferred_aio_finish(OpSequencer *osr); int _deferred_replay(); @@ -2071,7 +2082,6 @@ private: void _apply_padding(uint64_t head_pad, uint64_t tail_pad, - bufferlist& bl, bufferlist& padded); // -- ondisk version --- @@ -2102,6 +2112,17 @@ public: bool is_rotational() override; + string get_default_device_class() override { + string device_class; + map metadata; + collect_metadata(&metadata); + auto it = metadata.find("bluestore_bdev_type"); + if (it != metadata.end()) { + device_class = it->second; + } + return device_class; + } + static int get_block_device_fsid(CephContext* cct, const string& path, uuid_d *fsid); @@ -2184,16 +2205,14 @@ public: uint64_t offset, size_t len, bufferlist& bl, - uint32_t op_flags = 0, - bool allow_eio = false) override; + uint32_t op_flags = 0) override; int read( CollectionHandle &c, const ghobject_t& oid, uint64_t offset, size_t len, bufferlist& bl, - uint32_t op_flags = 0, - bool allow_eio = false) override; + uint32_t op_flags = 0) override; int _do_read( Collection *c, OnodeRef o, @@ -2369,6 +2388,11 @@ public: RWLock::WLocker l(debug_read_error_lock); debug_mdata_error_objects.insert(o); } + void compact() override { + assert(db); + db->compact(); + } + private: bool _debug_data_eio(const ghobject_t& o) { if (!cct->_conf->bluestore_debug_inject_read_err) { diff --git a/ceph/src/os/bluestore/KernelDevice.cc b/ceph/src/os/bluestore/KernelDevice.cc index c6b9e5ad2..3ae5be1ea 100644 --- a/ceph/src/os/bluestore/KernelDevice.cc +++ b/ceph/src/os/bluestore/KernelDevice.cc @@ -130,7 +130,6 @@ int KernelDevice::open(const string& p) } else { size = st.st_size; } - size &= ~(block_size); { char partition[PATH_MAX], devname[PATH_MAX]; @@ -340,7 +339,7 @@ void KernelDevice::_aio_thread() int inject_crash_count = 0; while (!aio_stop) { dout(40) << __func__ << " polling" << dendl; - int max = 16; + int max = cct->_conf->bdev_aio_reap_max; aio_t *aio[max]; int r = aio_queue.get_next_completed(cct->_conf->bdev_aio_poll_ms, aio, max); @@ -481,54 +480,46 @@ void KernelDevice::aio_submit(IOContext *ioc) << " pending " << ioc->num_pending.load() << " running " << ioc->num_running.load() << dendl; + if (ioc->num_pending.load() == 0) { return; } + // move these aside, and get our end iterator position now, as the // aios might complete as soon as they are submitted and queue more // wal aio's. list::iterator e = ioc->running_aios.begin(); ioc->running_aios.splice(e, ioc->pending_aios); - list::iterator p = ioc->running_aios.begin(); 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 + assert(ioc->pending_aios.size() == 0); + + if (cct->_conf->bdev_debug_aio) { + list::iterator p = ioc->running_aios.begin(); + while (p != e) { + for (auto& io : p->iov) + dout(30) << __func__ << " iov " << (void*)io.iov_base + << " len " << io.iov_len << dendl; - bool done = false; - while (!done) { - aio_t& aio = *p; - aio.priv = static_cast(ioc); - dout(20) << __func__ << " aio " << &aio << " fd " << aio.fd - << " 0x" << std::hex << aio.offset << "~" << aio.length - << std::dec << dendl; - for (auto& io : aio.iov) - dout(30) << __func__ << " iov " << (void*)io.iov_base - << " len " << io.iov_len << dendl; - - // be careful: as soon as we submit aio we race with completion. - // since we are holding a ref take care not to dereference txc at - // all after that point. - list::iterator cur = p; - ++p; - done = (p == e); - - // do not dereference txc (or it's contents) after we submit (if - // done == true and we don't loop) - int retries = 0; - if (cct->_conf->bdev_debug_aio) { std::lock_guard l(debug_queue_lock); - debug_aio_link(*cur); - } - int r = aio_queue.submit(*cur, &retries); - if (retries) - derr << __func__ << " retries " << retries << dendl; - if (r) { - derr << " aio submit got " << cpp_strerror(r) << dendl; - assert(r == 0); + debug_aio_link(*p++); } } + + void *priv = static_cast(ioc); + int r, retries = 0; + r = aio_queue.submit_batch(ioc->running_aios.begin(), e, + ioc->num_running.load(), priv, &retries); + + if (retries) + derr << __func__ << " retries " << retries << dendl; + if (r < 0) { + derr << " aio submit got " << cpp_strerror(r) << dendl; + assert(r == 0); + } } int KernelDevice::_sync_write(uint64_t off, bufferlist &bl, bool buffered) diff --git a/ceph/src/os/bluestore/NVMEDevice.cc b/ceph/src/os/bluestore/NVMEDevice.cc index 9d1a84066..2eb278aa0 100644 --- a/ceph/src/os/bluestore/NVMEDevice.cc +++ b/ceph/src/os/bluestore/NVMEDevice.cc @@ -1028,7 +1028,7 @@ int NVMEDevice::aio_write( int NVMEDevice::write(uint64_t off, bufferlist &bl, bool buffered) { // FIXME: there is presumably a more efficient way to do this... - IOContext ioc(NULL); + IOContext ioc(cct, NULL); aio_write(off, bl, &ioc, buffered); ioc.aio_wait(); return 0; diff --git a/ceph/src/os/bluestore/NVMEDevice.h b/ceph/src/os/bluestore/NVMEDevice.h index a44b1e1ec..40378eaec 100644 --- a/ceph/src/os/bluestore/NVMEDevice.h +++ b/ceph/src/os/bluestore/NVMEDevice.h @@ -28,6 +28,7 @@ #include "include/interval_set.h" #include "common/ceph_time.h" #include "common/Mutex.h" +#include "common/Cond.h" #include "BlockDevice.h" enum class IOCommand { diff --git a/ceph/src/os/filestore/CollectionIndex.h b/ceph/src/os/filestore/CollectionIndex.h index 7f7d7ffa2..7c57a38b5 100644 --- a/ceph/src/os/filestore/CollectionIndex.h +++ b/ceph/src/os/filestore/CollectionIndex.h @@ -193,6 +193,9 @@ protected: virtual int apply_layout_settings() { ceph_abort(); return 0; } + /// Read index-wide settings (should be called after construction) + virtual int read_settings() { return 0; } + /// Virtual destructor virtual ~CollectionIndex() {} }; diff --git a/ceph/src/os/filestore/DBObjectMap.h b/ceph/src/os/filestore/DBObjectMap.h index f60ae1753..3f6798d2e 100644 --- a/ceph/src/os/filestore/DBObjectMap.h +++ b/ceph/src/os/filestore/DBObjectMap.h @@ -230,6 +230,11 @@ public: /// Ensure that all previous operations are durable int sync(const ghobject_t *oid=0, const SequencerPosition *spos=0) override; + void compact() override { + assert(db); + db->compact(); + } + /// Util, get all objects, there must be no other concurrent access int list_objects(vector *objs ///< [out] objects ); diff --git a/ceph/src/os/filestore/FileJournal.cc b/ceph/src/os/filestore/FileJournal.cc index 7e6a19cbf..0491559ae 100644 --- a/ceph/src/os/filestore/FileJournal.cc +++ b/ceph/src/os/filestore/FileJournal.cc @@ -398,6 +398,7 @@ int FileJournal::open(uint64_t fs_op_seq) dout(2) << "open " << fn << " fsid " << fsid << " fs_op_seq " << fs_op_seq << dendl; uint64_t next_seq = fs_op_seq + 1; + uint64_t seq = -1; int err = _open(false); if (err) @@ -410,7 +411,7 @@ int FileJournal::open(uint64_t fs_op_seq) // read header? err = read_header(&header); if (err < 0) - return err; + goto out; // static zeroed buffer for alignment padding delete [] zero_buf; @@ -423,32 +424,38 @@ int FileJournal::open(uint64_t fs_op_seq) if (header.fsid != fsid) { derr << "FileJournal::open: ondisk fsid " << header.fsid << " doesn't match expected " << fsid << ", invalid (someone else's?) journal" << dendl; - return -EINVAL; + err = -EINVAL; + goto out; } if (header.max_size > max_size) { dout(2) << "open journal size " << header.max_size << " > current " << max_size << dendl; - return -EINVAL; + err = -EINVAL; + goto out; } if (header.block_size != block_size) { dout(2) << "open journal block size " << header.block_size << " != current " << block_size << dendl; - return -EINVAL; + err = -EINVAL; + goto out; } if (header.max_size % header.block_size) { dout(2) << "open journal max size " << header.max_size << " not a multiple of block size " << header.block_size << dendl; - return -EINVAL; + err = -EINVAL; + goto out; } if (header.alignment != block_size && directio) { dout(0) << "open journal alignment " << header.alignment << " does not match block size " << block_size << " (required for direct_io journal mode)" << dendl; - return -EINVAL; + err = -EINVAL; + goto out; } 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; + err = -EINVAL; + goto out; } // looks like a valid header. @@ -458,16 +465,7 @@ int FileJournal::open(uint64_t fs_op_seq) // find next entry read_pos = header.start; - uint64_t seq = header.start_seq; - - // last_committed_seq is 1 before the start of the journal or - // 0 if the start is 0 - last_committed_seq = seq > 0 ? seq - 1 : seq; - if (last_committed_seq < fs_op_seq) { - dout(2) << "open advancing committed_seq " << last_committed_seq - << " to fs op_seq " << fs_op_seq << dendl; - last_committed_seq = fs_op_seq; - } + seq = header.start_seq; while (1) { bufferlist bl; @@ -493,6 +491,9 @@ int FileJournal::open(uint64_t fs_op_seq) } return 0; +out: + close(); + return err; } void FileJournal::_close(int fd) const @@ -861,7 +862,7 @@ int FileJournal::prepare_multi_write(bufferlist& bl, uint64_t& orig_ops, uint64_ } print_header(header); } - + return -ENOSPC; // hrm, full on first op } if (eleft) { @@ -1417,7 +1418,7 @@ int FileJournal::write_aio_bl(off64_t& pos, bufferlist& bl, uint64_t seq) aio_lock.Unlock(); iocb *piocb = &aio.iocb; - + // 2^16 * 125us = ~8 seconds, so max sleep is ~16 seconds int attempts = 16; int delay = 125; diff --git a/ceph/src/os/filestore/FileStore.cc b/ceph/src/os/filestore/FileStore.cc index 1fb483945..f9b931a62 100644 --- a/ceph/src/os/filestore/FileStore.cc +++ b/ceph/src/os/filestore/FileStore.cc @@ -629,6 +629,7 @@ FileStore::FileStore(CephContext* cct, const std::string &base, plb.add_time_avg(l_filestore_commitcycle_latency, "commitcycle_latency", "Average latency of commit"); plb.add_u64_counter(l_filestore_journal_full, "journal_full", "Journal writes while full"); plb.add_time_avg(l_filestore_queue_transaction_latency_avg, "queue_transaction_latency_avg", "Store operation queue latency"); + plb.add_time(l_filestore_sync_pause_max_lat, "sync_pause_max_latency", "Max latency of op_wq pause before syncfs"); logger = plb.create_perf_counters(); @@ -819,7 +820,7 @@ int FileStore::mkfs() basedir_fd = ::open(basedir.c_str(), O_RDONLY); if (basedir_fd < 0) { ret = -errno; - derr << "mkfs failed to open base dir " << basedir << ": " << cpp_strerror(ret) << dendl; + derr << __FUNC__ << ": failed to open base dir " << basedir << ": " << cpp_strerror(ret) << dendl; return ret; } @@ -828,7 +829,7 @@ int FileStore::mkfs() fsid_fd = ::open(fsid_fn, O_RDWR|O_CREAT, 0644); if (fsid_fd < 0) { ret = -errno; - derr << "mkfs: failed to open " << fsid_fn << ": " << cpp_strerror(ret) << dendl; + derr << __FUNC__ << ": failed to open " << fsid_fn << ": " << cpp_strerror(ret) << dendl; goto close_basedir_fd; } @@ -840,9 +841,9 @@ int FileStore::mkfs() if (read_fsid(fsid_fd, &old_fsid) < 0 || old_fsid.is_zero()) { if (fsid.is_zero()) { fsid.generate_random(); - dout(1) << "mkfs generated fsid " << fsid << dendl; + dout(1) << __FUNC__ << ": generated fsid " << fsid << dendl; } else { - dout(1) << "mkfs using provided fsid " << fsid << dendl; + dout(1) << __FUNC__ << ": using provided fsid " << fsid << dendl; } fsid.print(fsid_str); @@ -866,7 +867,7 @@ int FileStore::mkfs() << cpp_strerror(ret) << dendl; goto close_fsid_fd; } - dout(10) << "mkfs fsid is " << fsid << dendl; + dout(10) << __FUNC__ << ": fsid is " << fsid << dendl; } else { if (!fsid.is_zero() && fsid != old_fsid) { derr << __FUNC__ << ": on-disk fsid " << old_fsid << " != provided " << fsid << dendl; @@ -903,6 +904,14 @@ int FileStore::mkfs() goto close_fsid_fd; } +#if defined(__linux__) + if (basefs.f_type == BTRFS_SUPER_MAGIC && + !g_ceph_context->check_experimental_feature_enabled("btrfs")) { + derr << __FUNC__ << ": deprecated btrfs support is not enabled" << dendl; + goto close_fsid_fd; + } +#endif + create_backend(basefs.f_type); ret = backend->create_current(); @@ -1157,6 +1166,14 @@ int FileStore::_detect_fs() blk_size = st.f_bsize; +#if defined(__linux__) + if (st.f_type == BTRFS_SUPER_MAGIC && + !g_ceph_context->check_experimental_feature_enabled("btrfs")) { + derr <<__FUNC__ << ": deprecated btrfs support is not enabled" << dendl; + return -EPERM; + } +#endif + create_backend(st.f_type); r = backend->detect_features(); @@ -3183,8 +3200,7 @@ int FileStore::read( uint64_t offset, size_t len, bufferlist& bl, - uint32_t op_flags, - bool allow_eio) + uint32_t op_flags) { int got; tracepoint(objectstore, read_enter, _cid.c_str(), offset, len); @@ -3220,10 +3236,6 @@ int FileStore::read( if (got < 0) { dout(10) << __FUNC__ << ": (" << cid << "/" << oid << ") pread error: " << cpp_strerror(got) << dendl; lfn_close(fd); - if (!(allow_eio || !m_filestore_fail_eio || got != -EIO)) { - derr << __FUNC__ << ": (" << cid << "/" << oid << ") pread error: " << cpp_strerror(got) << dendl; - assert(0 == "eio on pread"); - } return got; } bptr.set_length(got); // properly size the buffer @@ -3254,6 +3266,10 @@ int FileStore::read( if (cct->_conf->filestore_debug_inject_read_err && debug_data_eio(oid)) { return -EIO; + } else if (cct->_conf->filestore_debug_random_read_err && + (rand() % (int)(cct->_conf->filestore_debug_random_read_err * 100.0)) == 0) { + dout(0) << __func__ << ": inject random EIO" << dendl; + return -EIO; } else { tracepoint(objectstore, read_exit, got); return got; @@ -3968,7 +3984,10 @@ void FileStore::sync_entry() sync_entry_timeo_lock.Lock(); SyncEntryTimeout *sync_entry_timeo = new SyncEntryTimeout(cct, m_filestore_commit_timeout); - timer.add_event_after(m_filestore_commit_timeout, sync_entry_timeo); + if (!timer.add_event_after(m_filestore_commit_timeout, + sync_entry_timeo)) { + sync_entry_timeo = nullptr; + } sync_entry_timeo_lock.Unlock(); logger->set(l_filestore_committing, 1); @@ -4010,8 +4029,7 @@ void FileStore::sync_entry() } dout(20) << " done waiting for checkpoint " << cid << " to complete" << dendl; } - } else - { + } else { apply_manager.commit_started(); op_tp.unpause(); @@ -4043,6 +4061,10 @@ void FileStore::sync_entry() utime_t lat = done - start; utime_t dur = done - startwait; dout(10) << __FUNC__ << ": commit took " << lat << ", interval was " << dur << dendl; + utime_t max_pause_lat = logger->tget(l_filestore_sync_pause_max_lat); + if (max_pause_lat < dur - lat) { + logger->tinc(l_filestore_sync_pause_max_lat, dur - lat); + } logger->inc(l_filestore_commitcycle); logger->tinc(l_filestore_commitcycle_latency, lat); @@ -4072,9 +4094,10 @@ void FileStore::sync_entry() dout(15) << __FUNC__ << ": committed to op_seq " << cp << dendl; - sync_entry_timeo_lock.Lock(); - timer.cancel_event(sync_entry_timeo); - sync_entry_timeo_lock.Unlock(); + if (sync_entry_timeo) { + Mutex::Locker lock(sync_entry_timeo_lock); + timer.cancel_event(sync_entry_timeo); + } } else { op_tp.unpause(); } @@ -4333,6 +4356,7 @@ void FileStore::inject_mdata_error(const ghobject_t &oid) { dout(10) << __FUNC__ << ": init error on " << oid << dendl; mdata_error_set.insert(oid); } + void FileStore::debug_obj_on_delete(const ghobject_t &oid) { Mutex::Locker l(read_error_lock); dout(10) << __FUNC__ << ": clear error on " << oid << dendl; diff --git a/ceph/src/os/filestore/FileStore.h b/ceph/src/os/filestore/FileStore.h index 88a1d3170..020044a03 100644 --- a/ceph/src/os/filestore/FileStore.h +++ b/ceph/src/os/filestore/FileStore.h @@ -94,6 +94,7 @@ enum { l_filestore_bytes, l_filestore_apply_latency, l_filestore_queue_transaction_latency_avg, + l_filestore_sync_pause_max_lat, l_filestore_last, }; @@ -586,8 +587,7 @@ public: uint64_t offset, size_t len, bufferlist& bl, - uint32_t op_flags = 0, - bool allow_eio = false) override; + uint32_t op_flags = 0) override; int _do_fiemap(int fd, uint64_t offset, size_t len, map *m); int _do_seek_hole_data(int fd, uint64_t offset, size_t len, @@ -640,6 +640,12 @@ public: set mdata_error_set; // getattr(),stat() will return -EIO void inject_data_error(const ghobject_t &oid) override; void inject_mdata_error(const ghobject_t &oid) override; + + void compact() override { + assert(object_map); + object_map->compact(); + } + void debug_obj_on_delete(const ghobject_t &oid); bool debug_data_eio(const ghobject_t &oid); bool debug_mdata_eio(const ghobject_t &oid); diff --git a/ceph/src/os/filestore/HashIndex.cc b/ceph/src/os/filestore/HashIndex.cc index 0ebec36b6..b0f93b9e2 100644 --- a/ceph/src/os/filestore/HashIndex.cc +++ b/ceph/src/os/filestore/HashIndex.cc @@ -25,6 +25,7 @@ #define dout_subsys ceph_subsys_filestore const string HashIndex::SUBDIR_ATTR = "contents"; +const string HashIndex::SETTINGS_ATTR = "settings"; const string HashIndex::IN_PROGRESS_OP_TAG = "in_progress_op"; /// hex digit to integer value @@ -358,14 +359,50 @@ int HashIndex::split_dirs(const vector &path) { int HashIndex::apply_layout_settings() { vector path; dout(10) << __func__ << " split multiple = " << split_multiplier - << " merge threshold = " << merge_threshold << dendl; + << " merge threshold = " << merge_threshold + << " split rand factor = " << cct->_conf->filestore_split_rand_factor + << dendl; + int r = write_settings(); + if (r < 0) + return r; return split_dirs(path); } int HashIndex::_init() { subdir_info_s info; vector path; - return set_info(path, info); + int r = set_info(path, info); + if (r < 0) + return r; + return write_settings(); +} + +int HashIndex::write_settings() { + if (cct->_conf->filestore_split_rand_factor > 0) { + settings.split_rand_factor = rand() % cct->_conf->filestore_split_rand_factor; + } else { + settings.split_rand_factor = 0; + } + vector path; + bufferlist bl; + settings.encode(bl); + return add_attr_path(path, SETTINGS_ATTR, bl); +} + +int HashIndex::read_settings() { + vector path; + bufferlist bl; + int r = get_attr_path(path, SETTINGS_ATTR, bl); + if (r == -ENODATA) + return 0; + if (r < 0) { + derr << __func__ << " error reading settings: " << cpp_strerror(r) << dendl; + return r; + } + bufferlist::iterator it = bl.begin(); + settings.decode(it); + dout(20) << __func__ << " split_rand_factor = " << settings.split_rand_factor << dendl; + return 0; } /* LFNIndex virtual method implementations */ @@ -496,7 +533,7 @@ int HashIndex::pre_split_folder(uint32_t pg_num, uint64_t expected_num_objs) // Calculate the number of leaf folders (which actually store files) // need to be created - const uint64_t objs_per_folder = (uint64_t)(abs(merge_threshold)) * (uint64_t)split_multiplier * 16; + const uint64_t objs_per_folder = ((uint64_t)(abs(merge_threshold)) * (uint64_t)split_multiplier + settings.split_rand_factor) * 16; uint64_t leavies = expected_num_objs / objs_per_folder ; // No need to split if (leavies == 0 || expected_num_objs == objs_per_folder) @@ -705,7 +742,7 @@ bool HashIndex::must_merge(const subdir_info_s &info) { bool HashIndex::must_split(const subdir_info_s &info) { return (info.hash_level < (unsigned)MAX_HASH_LEVEL && - info.objs > ((unsigned)(abs(merge_threshold)) * 16 * split_multiplier)); + info.objs > ((unsigned)(abs(merge_threshold) * split_multiplier + settings.split_rand_factor) * 16)); } diff --git a/ceph/src/os/filestore/HashIndex.h b/ceph/src/os/filestore/HashIndex.h index f9922bcb5..216659bff 100644 --- a/ceph/src/os/filestore/HashIndex.h +++ b/ceph/src/os/filestore/HashIndex.h @@ -43,14 +43,17 @@ extern string reverse_hexdigit_bits_string(string l); * ex: ghobject_t("object", CEPH_NO_SNAP, 0xA4CEE0D2) * would be located in (root)/2/D/0/ * - * Subdirectories are created when the number of objects in a directory - * exceed (abs(merge_threshhold)) * 16 * split_multiplier. The number of objects in a directory - * is encoded as subdir_info_s in an xattr on the directory. + * Subdirectories are created when the number of objects in a + * directory exceed 16 * (abs(merge_threshhold)) * split_multiplier + + * split_rand_factor). The number of objects in a directory is encoded + * as subdir_info_s in an xattr on the directory. */ class HashIndex : public LFNIndex { private: /// Attribute name for storing subdir info @see subdir_info_s static const string SUBDIR_ATTR; + /// Attribute name for storing index-wide settings + static const string SETTINGS_ATTR; /// Attribute name for storing in progress op tag static const string IN_PROGRESS_OP_TAG; /// Size (bits) in object hash @@ -61,8 +64,12 @@ private: /** * Merges occur when the number of object drops below * merge_threshold and splits occur when the number of objects - * exceeds 16 * abs(merge_threshold) * split_multiplier. - * Please note if merge_threshold is less than zero, it will never do merging + * exceeds: + * + * 16 * (abs(merge_threshold) * split_multiplier + split_rand_factor) + * + * Please note if merge_threshold is less than zero, it will never + * do merging */ int merge_threshold; int split_multiplier; @@ -95,6 +102,23 @@ private: } }; + struct settings_s { + uint32_t split_rand_factor; ///< random factor added to split threshold (only on root of collection) + settings_s() : split_rand_factor(0) {} + void encode(bufferlist &bl) const + { + __u8 v = 1; + ::encode(v, bl); + ::encode(split_rand_factor, bl); + } + void decode(bufferlist::iterator &bl) + { + __u8 v; + ::decode(v, bl); + ::decode(split_rand_factor, bl); + } + } settings; + /// Encodes in progress split or merge struct InProgressOp { static const int SPLIT = 0; @@ -143,7 +167,10 @@ public: double retry_probability=0) ///< [in] retry probability : LFNIndex(cct, collection, base_path, index_version, retry_probability), merge_threshold(merge_at), - split_multiplier(split_multiple) {} + split_multiplier(split_multiple) + {} + + int read_settings() override; /// @see CollectionIndex uint32_t collection_version() override { return index_version; } @@ -410,6 +437,8 @@ private: /// split each dir below the given path int split_dirs(const vector &path); + + int write_settings(); }; #endif diff --git a/ceph/src/os/filestore/IndexManager.cc b/ceph/src/os/filestore/IndexManager.cc index c148afc46..74cc454ff 100644 --- a/ceph/src/os/filestore/IndexManager.cc +++ b/ceph/src/os/filestore/IndexManager.cc @@ -82,7 +82,10 @@ int IndexManager::init_index(coll_t c, const char *path, uint32_t version) { cct->_conf->filestore_split_multiple, version, cct->_conf->filestore_index_retry_probability); - return index.init(); + r = index.init(); + if (r < 0) + return r; + return index.read_settings(); } int IndexManager::build_index(coll_t c, const char *path, CollectionIndex **index) { @@ -102,8 +105,9 @@ int IndexManager::build_index(coll_t c, const char *path, CollectionIndex **inde // Must be a HashIndex *index = new HashIndex(cct, c, path, cct->_conf->filestore_merge_threshold, - cct->_conf->filestore_split_multiple, version); - return 0; + cct->_conf->filestore_split_multiple, + version); + return (*index)->read_settings(); } default: ceph_abort(); } @@ -114,7 +118,7 @@ int IndexManager::build_index(coll_t c, const char *path, CollectionIndex **inde cct->_conf->filestore_split_multiple, CollectionIndex::HOBJECT_WITH_POOL, cct->_conf->filestore_index_retry_probability); - return 0; + return (*index)->read_settings(); } } diff --git a/ceph/src/os/filestore/JournalingObjectStore.cc b/ceph/src/os/filestore/JournalingObjectStore.cc index 7679d8029..a9c528f04 100644 --- a/ceph/src/os/filestore/JournalingObjectStore.cc +++ b/ceph/src/os/filestore/JournalingObjectStore.cc @@ -111,6 +111,9 @@ int JournalingObjectStore::journal_replay(uint64_t fs_op_seq) if (err < 0) return err; + if (!count) + journal->committed_thru(fs_op_seq); + return count; } diff --git a/ceph/src/os/filestore/ZFSFileStoreBackend.cc b/ceph/src/os/filestore/ZFSFileStoreBackend.cc index 30cc6f9c3..45384781e 100644 --- a/ceph/src/os/filestore/ZFSFileStoreBackend.cc +++ b/ceph/src/os/filestore/ZFSFileStoreBackend.cc @@ -26,17 +26,16 @@ #include "common/config.h" #include "common/sync_filesystem.h" -#ifdef HAVE_LIBZFS - #include "ZFSFileStoreBackend.h" +#define dout_context cct() #define dout_subsys ceph_subsys_filestore #undef dout_prefix #define dout_prefix *_dout << "zfsfilestorebackend(" << get_basedir_path() << ") " ZFSFileStoreBackend::ZFSFileStoreBackend(FileStore *fs) : GenericFileStoreBackend(fs), base_zh(NULL), current_zh(NULL), - m_filestore_zfs_snap(cct->_conf->filestore_zfs_snap) + m_filestore_zfs_snap(cct()->_conf->filestore_zfs_snap) { int ret = zfs.init(); if (ret < 0) { @@ -257,4 +256,3 @@ int ZFSFileStoreBackend::destroy_checkpoint(const string& name) } return ret; } -#endif diff --git a/ceph/src/os/fs/aio.cc b/ceph/src/os/fs/aio.cc index a5edf6266..cfe0c5cf8 100644 --- a/ceph/src/os/fs/aio.cc +++ b/ceph/src/os/fs/aio.cc @@ -5,14 +5,16 @@ #if defined(HAVE_LIBAIO) + int aio_queue_t::submit(aio_t &aio, int *retries) { // 2^16 * 125us = ~8 seconds, so max sleep is ~16 seconds int attempts = 16; int delay = 125; iocb *piocb = &aio.iocb; + int r; while (true) { - int r = io_submit(ctx, 1, &piocb); + r = io_submit(ctx, 1, &piocb); if (r < 0) { if (r == -EAGAIN && attempts-- > 0) { usleep(delay); @@ -20,12 +22,43 @@ int aio_queue_t::submit(aio_t &aio, int *retries) (*retries)++; continue; } - return r; } assert(r == 1); break; } - return 0; + return r; +} + +int aio_queue_t::submit_batch(aio_iter begin, aio_iter end, + uint16_t aios_size, void *priv, + int *retries) +{ + // 2^16 * 125us = ~8 seconds, so max sleep is ~16 seconds + int attempts = 16; + int delay = 125; + + aio_iter cur = begin; + struct iocb *piocb[aios_size]; + int r, pos = 0; + while (cur != end) { + cur->priv = priv; + *(piocb+pos) = &cur->iocb; + ++pos; + ++cur; + } + while (true) { + r = io_submit(ctx, pos, piocb); + if (r < 0) { + if (r == -EAGAIN && attempts-- > 0) { + usleep(delay); + delay *= 2; + (*retries)++; + continue; + } + } + break; + } + return r; } int aio_queue_t::get_next_completed(int timeout_ms, aio_t **paio, int max) diff --git a/ceph/src/os/fs/aio.h b/ceph/src/os/fs/aio.h index c4757158c..2517e5f64 100644 --- a/ceph/src/os/fs/aio.h +++ b/ceph/src/os/fs/aio.h @@ -11,6 +11,7 @@ #include #include "include/buffer.h" +#include "include/types.h" struct aio_t { struct iocb iocb; // must be first element; see shenanigans in aio_queue_t @@ -55,6 +56,8 @@ struct aio_queue_t { int max_iodepth; io_context_t ctx; + typedef list::iterator aio_iter; + explicit aio_queue_t(unsigned max_iodepth) : max_iodepth(max_iodepth), ctx(0) { @@ -83,6 +86,8 @@ struct aio_queue_t { } int submit(aio_t &aio, int *retries); + int submit_batch(aio_iter begin, aio_iter end, uint16_t aios_size, + void *priv, int *retries); int get_next_completed(int timeout_ms, aio_t **paio, int max); }; diff --git a/ceph/src/os/kstore/KStore.cc b/ceph/src/os/kstore/KStore.cc index b06b06865..f7a4214a8 100755 --- a/ceph/src/os/kstore/KStore.cc +++ b/ceph/src/os/kstore/KStore.cc @@ -1169,8 +1169,7 @@ int KStore::read( uint64_t offset, size_t length, bufferlist& bl, - uint32_t op_flags, - bool allow_eio) + uint32_t op_flags) { dout(15) << __func__ << " " << cid << " " << oid << " " << offset << "~" << length diff --git a/ceph/src/os/kstore/KStore.h b/ceph/src/os/kstore/KStore.h index bfa119733..487d98470 100644 --- a/ceph/src/os/kstore/KStore.h +++ b/ceph/src/os/kstore/KStore.h @@ -461,8 +461,7 @@ public: uint64_t offset, size_t len, bufferlist& bl, - uint32_t op_flags = 0, - bool allow_eio = false) override; + uint32_t op_flags = 0) override; int _do_read( OnodeRef o, uint64_t offset, @@ -565,6 +564,11 @@ public: TrackedOpRef op = TrackedOpRef(), ThreadPool::TPHandle *handle = NULL) override; + void compact () override { + assert(db); + db->compact(); + } + private: // -------------------------------------------------------- // write ops diff --git a/ceph/src/os/memstore/MemStore.cc b/ceph/src/os/memstore/MemStore.cc index 4b1ca248a..08be76e65 100644 --- a/ceph/src/os/memstore/MemStore.cc +++ b/ceph/src/os/memstore/MemStore.cc @@ -316,13 +316,12 @@ int MemStore::read( uint64_t offset, size_t len, bufferlist& bl, - uint32_t op_flags, - bool allow_eio) + uint32_t op_flags) { CollectionHandle c = get_collection(cid); if (!c) return -ENOENT; - return read(c, oid, offset, len, bl, op_flags, allow_eio); + return read(c, oid, offset, len, bl, op_flags); } int MemStore::read( @@ -331,8 +330,7 @@ int MemStore::read( uint64_t offset, size_t len, bufferlist& bl, - uint32_t op_flags, - bool allow_eio) + uint32_t op_flags) { Collection *c = static_cast(c_.get()); dout(10) << __func__ << " " << c->cid << " " << oid << " " diff --git a/ceph/src/os/memstore/MemStore.h b/ceph/src/os/memstore/MemStore.h index 8bf5cc76a..e17574cc0 100644 --- a/ceph/src/os/memstore/MemStore.h +++ b/ceph/src/os/memstore/MemStore.h @@ -298,16 +298,14 @@ public: uint64_t offset, size_t len, bufferlist& bl, - uint32_t op_flags = 0, - bool allow_eio = false) override; + uint32_t op_flags = 0) override; int read( CollectionHandle &c, const ghobject_t& oid, uint64_t offset, size_t len, bufferlist& bl, - uint32_t op_flags = 0, - bool allow_eio = false) override; + uint32_t op_flags = 0) override; using ObjectStore::fiemap; int fiemap(const coll_t& cid, const ghobject_t& oid, uint64_t offset, size_t len, bufferlist& bl) override; int fiemap(const coll_t& cid, const ghobject_t& oid, uint64_t offset, size_t len, map& destmap) override; diff --git a/ceph/src/osd/CMakeLists.txt b/ceph/src/osd/CMakeLists.txt index 670223b6c..3ec6f31a6 100644 --- a/ceph/src/osd/CMakeLists.txt +++ b/ceph/src/osd/CMakeLists.txt @@ -29,6 +29,9 @@ set(osd_srcs osd_types.cc ECUtil.cc ExtentCache.cc + mClockOpClassQueue.cc + mClockClientQueue.cc + PGQueueable.cc ${CMAKE_SOURCE_DIR}/src/common/TrackedOp.cc ${osd_cyg_functions_src} ${osdc_osd_srcs}) @@ -40,7 +43,7 @@ add_library(osd STATIC ${osd_srcs} $ $ $) -target_link_libraries(osd ${LEVELDB_LIBRARIES} ${CMAKE_DL_LIBS} ${ALLOC_LIBS}) +target_link_libraries(osd ${LEVELDB_LIBRARIES} dmclock ${CMAKE_DL_LIBS} ${ALLOC_LIBS}) if(WITH_LTTNG) add_dependencies(osd osd-tp pg-tp) endif() diff --git a/ceph/src/osd/ECBackend.cc b/ceph/src/osd/ECBackend.cc index c35bf1ae2..166edc659 100644 --- a/ceph/src/osd/ECBackend.cc +++ b/ceph/src/osd/ECBackend.cc @@ -689,7 +689,7 @@ void ECBackend::run_recovery_op( delete _h; } -void ECBackend::recover_object( +int ECBackend::recover_object( const hobject_t &hoid, eversion_t v, ObjectContextRef head, @@ -730,6 +730,7 @@ void ECBackend::recover_object( } } dout(10) << __func__ << ": built op " << h->ops.back() << dendl; + return 0; } bool ECBackend::can_handle_while_inactive( @@ -1003,8 +1004,7 @@ void ECBackend::handle_sub_read( ghobject_t(i->first, ghobject_t::NO_GEN, shard), j->get<0>(), j->get<1>(), - bl, j->get<2>(), - true); // Allow EIO return + bl, j->get<2>()); if (r < 0) { get_parent()->clog_error() << __func__ << ": Error " << r @@ -2403,7 +2403,7 @@ void ECBackend::be_deep_scrub( poid, ghobject_t::NO_GEN, get_parent()->whoami_shard().shard), pos, stride, bl, - fadvise_flags, true); + fadvise_flags); if (r < 0) break; if (bl.length() % sinfo.get_chunk_size()) { diff --git a/ceph/src/osd/ECBackend.h b/ceph/src/osd/ECBackend.h index f659675d9..8a9c5a30c 100644 --- a/ceph/src/osd/ECBackend.h +++ b/ceph/src/osd/ECBackend.h @@ -41,7 +41,7 @@ public: int priority ) override; - void recover_object( + int recover_object( const hobject_t &hoid, eversion_t v, ObjectContextRef head, diff --git a/ceph/src/osd/ECTransaction.h b/ceph/src/osd/ECTransaction.h index 036c8ca8d..ff49202bf 100644 --- a/ceph/src/osd/ECTransaction.h +++ b/ceph/src/osd/ECTransaction.h @@ -51,10 +51,6 @@ namespace ECTransaction { uint64_t projected_size = hinfo->get_projected_total_logical_size(sinfo); - if (i.second.has_source()) { - plan.invalidates_cache = true; - } - if (i.second.deletes_first()) { ldpp_dout(dpp, 20) << __func__ << ": delete, setting projected size" << " to 0" << dendl; @@ -63,6 +59,8 @@ namespace ECTransaction { hobject_t source; if (i.second.has_source(&source)) { + plan.invalidates_cache = true; + ECUtil::HashInfoRef shinfo = get_hinfo(source); projected_size = shinfo->get_projected_total_logical_size(sinfo); plan.hash_infos[source] = shinfo; diff --git a/ceph/src/osd/OSD.cc b/ceph/src/osd/OSD.cc index fb77b0777..5b979c8c9 100644 --- a/ceph/src/osd/OSD.cc +++ b/ceph/src/osd/OSD.cc @@ -42,6 +42,7 @@ #include "common/errno.h" #include "common/ceph_argparse.h" +#include "common/ceph_time.h" #include "common/version.h" #include "common/io_priority.h" @@ -61,7 +62,6 @@ #include "messages/MLog.h" #include "messages/MGenericMessage.h" -#include "messages/MPing.h" #include "messages/MOSDPing.h" #include "messages/MOSDFailure.h" #include "messages/MOSDMarkMeDown.h" @@ -160,28 +160,13 @@ #undef dout_prefix #define dout_prefix _prefix(_dout, whoami, get_osdmap_epoch()) + const double OSD::OSD_TICK_INTERVAL = 1.0; static ostream& _prefix(std::ostream* _dout, int whoami, epoch_t epoch) { return *_dout << "osd." << whoami << " " << epoch << " "; } -void PGQueueable::RunVis::operator()(const OpRequestRef &op) { - return osd->dequeue_op(pg, op, handle); -} - -void PGQueueable::RunVis::operator()(const PGSnapTrim &op) { - return pg->snap_trimmer(op.epoch_queued); -} - -void PGQueueable::RunVis::operator()(const PGScrub &op) { - return pg->scrub(op.epoch_queued, handle); -} - -void PGQueueable::RunVis::operator()(const PGRecovery &op) { - return osd->do_recovery(pg.get(), op.epoch_queued, op.reserved_pushes, handle); -} - //Initial features in new superblock. //Features here are also automatically upgraded CompatSet OSD::get_osd_initial_compat_set() { @@ -766,11 +751,10 @@ float OSDService::get_failsafe_full_ratio() return full_ratio; } -void OSDService::check_full_status(const osd_stat_t &osd_stat) +void OSDService::check_full_status(float ratio) { Mutex::Locker l(full_status_lock); - float ratio = ((float)osd_stat.kb_used) / ((float)osd_stat.kb); cur_ratio = ratio; // The OSDMap ratios take precendence. So if the failsafe is .95 and @@ -936,15 +920,31 @@ void OSDService::set_injectfull(s_names type, int64_t count) injectfull = count; } -void OSDService::update_osd_stat(vector& hb_peers) +osd_stat_t OSDService::set_osd_stat(const struct store_statfs_t &stbuf, + vector& hb_peers) { - Mutex::Locker lock(stat_lock); + uint64_t bytes = stbuf.total; + uint64_t used = bytes - stbuf.available; + uint64_t avail = stbuf.available; - osd_stat.hb_peers.swap(hb_peers); + osd->logger->set(l_osd_stat_bytes, bytes); + osd->logger->set(l_osd_stat_bytes_used, used); + osd->logger->set(l_osd_stat_bytes_avail, avail); - osd->op_tracker.get_age_ms_histogram(&osd_stat.op_queue_age_hist); + { + Mutex::Locker l(stat_lock); + osd_stat.hb_peers.swap(hb_peers); + osd->op_tracker.get_age_ms_histogram(&osd_stat.op_queue_age_hist); + osd_stat.kb = bytes >> 10; + osd_stat.kb_used = used >> 10; + osd_stat.kb_avail = avail >> 10; + return osd_stat; + } +} - // fill in osd stats too +void OSDService::update_osd_stat(vector& hb_peers) +{ + // load osd stats first struct store_statfs_t stbuf; int r = osd->store->statfs(&stbuf); if (r < 0) { @@ -952,21 +952,11 @@ void OSDService::update_osd_stat(vector& hb_peers) return; } - uint64_t bytes = stbuf.total; - uint64_t used = bytes - stbuf.available; - uint64_t avail = stbuf.available; - - osd_stat.kb = bytes >> 10; - osd_stat.kb_used = used >> 10; - osd_stat.kb_avail = avail >> 10; - - osd->logger->set(l_osd_stat_bytes, bytes); - osd->logger->set(l_osd_stat_bytes_used, used); - osd->logger->set(l_osd_stat_bytes_avail, avail); - - dout(20) << "update_osd_stat " << osd_stat << dendl; - - check_full_status(osd_stat); + auto new_stat = set_osd_stat(stbuf, hb_peers); + dout(20) << "update_osd_stat " << new_stat << dendl; + assert(new_stat.kb); + float ratio = ((float)new_stat.kb_used) / ((float)new_stat.kb); + check_full_status(ratio); } bool OSDService::check_osdmap_full(const set &missing_on) @@ -1729,7 +1719,8 @@ int OSD::mkfs(CephContext *cct, ObjectStore *store, const string &dev, ret = store->mkfs(); if (ret) { - derr << "OSD::mkfs: ObjectStore::mkfs failed with error " << ret << dendl; + derr << "OSD::mkfs: ObjectStore::mkfs failed with error " + << cpp_strerror(ret) << dendl; goto free_store; } @@ -1737,7 +1728,8 @@ int OSD::mkfs(CephContext *cct, ObjectStore *store, const string &dev, ret = store->mount(); if (ret) { - derr << "OSD::mkfs: couldn't mount ObjectStore: error " << ret << dendl; + derr << "OSD::mkfs: couldn't mount ObjectStore: error " + << cpp_strerror(ret) << dendl; goto free_store; } @@ -1776,7 +1768,7 @@ int OSD::mkfs(CephContext *cct, ObjectStore *store, const string &dev, ret = store->apply_transaction(osr.get(), std::move(t)); if (ret) { derr << "OSD::mkfs: error while writing OSD_SUPERBLOCK_GOBJECT: " - << "apply_transaction returned " << ret << dendl; + << "apply_transaction returned " << cpp_strerror(ret) << dendl; goto umount_store; } } @@ -1787,7 +1779,8 @@ int OSD::mkfs(CephContext *cct, ObjectStore *store, const string &dev, ret = write_meta(store, sb.cluster_fsid, sb.osd_fsid, whoami); if (ret) { - derr << "OSD::mkfs: failed to write fsid file: error " << ret << dendl; + derr << "OSD::mkfs: failed to write fsid file: error " + << cpp_strerror(ret) << dendl; goto umount_store; } @@ -2086,7 +2079,7 @@ bool OSD::asok_command(string admin_command, cmdmap_t& cmdmap, string format, curmap->get_blacklist(&bl); for (list >::iterator it = bl.begin(); it != bl.end(); ++it) { - f->open_array_section("entry"); + f->open_object_section("entry"); f->open_object_section("entity_addr_t"); it->first.dump(f); f->close_section(); //entity_addr_t @@ -2117,7 +2110,7 @@ bool OSD::asok_command(string admin_command, cmdmap_t& cmdmap, string format, for (list::iterator it = watchers.begin(); it != watchers.end(); ++it) { - f->open_array_section("watch"); + f->open_object_section("watch"); f->dump_string("namespace", it->obj.nspace); f->dump_string("object", it->obj.oid.name); @@ -2126,8 +2119,8 @@ bool OSD::asok_command(string admin_command, cmdmap_t& cmdmap, string format, it->wi.name.dump(f); f->close_section(); //entity_name_t - f->dump_int("cookie", it->wi.cookie); - f->dump_int("timeout", it->wi.timeout_seconds); + f->dump_unsigned("cookie", it->wi.cookie); + f->dump_unsigned("timeout", it->wi.timeout_seconds); f->open_object_section("entity_addr_t"); it->wi.addr.dump(f); @@ -2221,6 +2214,18 @@ bool OSD::asok_command(string admin_command, cmdmap_t& cmdmap, string format, pg->unlock(); } f->close_section(); + } else if (admin_command == "compact") { + dout(1) << "triggering manual compaction" << dendl; + auto start = ceph::coarse_mono_clock::now(); + store->compact(); + auto end = ceph::coarse_mono_clock::now(); + auto time_span = chrono::duration_cast>(end - start); + dout(1) << "finished manual compaction in " + << time_span.count() + << " seconds" << dendl; + f->open_object_section("compact_result"); + f->dump_float("elapsed_time", time_span.count()); + f->close_section(); } else { assert(0 == "broken asok registration"); } @@ -2758,6 +2763,12 @@ void OSD::final_init() "show recent state history"); assert(r == 0); + r = admin_socket->register_command("compact", "compact", + asok_hook, + "Commpact object store's omap." + " WARNING: Compaction probably slows your requests"); + assert(r == 0); + test_ops_hook = new TestOpsSocketHook(&(this->service), this->store); // Note: pools are CephString instead of CephPoolname because // these commands traditionally support both pool names and numbers @@ -2964,6 +2975,11 @@ void OSD::create_logger() l_osd_op_rw_prepare_lat, "op_rw_prepare_latency", "Latency of read-modify-write operations (excluding queue time and wait for finished)"); + osd_plb.add_time_avg(l_osd_op_before_queue_op_lat, "op_before_queue_op_lat", + "Latency of IO before calling queue(before really queue into ShardedOpWq)"); // client io before queue op_wq latency + osd_plb.add_time_avg(l_osd_op_before_dequeue_op_lat, "op_before_dequeue_op_lat", + "Latency of IO before calling dequeue_op(already dequeued and get PG lock)"); // client io before dequeue_op latency + osd_plb.add_u64_counter( l_osd_sop, "subop", "Suboperations"); osd_plb.add_u64_counter( @@ -3218,12 +3234,15 @@ int OSD::shutdown() cct->get_admin_socket()->unregister_command("dump_watchers"); cct->get_admin_socket()->unregister_command("dump_reservations"); cct->get_admin_socket()->unregister_command("get_latest_osdmap"); + cct->get_admin_socket()->unregister_command("heap"); cct->get_admin_socket()->unregister_command("set_heap_property"); cct->get_admin_socket()->unregister_command("get_heap_property"); cct->get_admin_socket()->unregister_command("dump_objectstore_kv_stats"); + cct->get_admin_socket()->unregister_command("dump_scrubs"); cct->get_admin_socket()->unregister_command("calc_objectstore_db_histogram"); cct->get_admin_socket()->unregister_command("flush_store_cache"); cct->get_admin_socket()->unregister_command("dump_pgstate_history"); + cct->get_admin_socket()->unregister_command("compact"); delete asok_hook; asok_hook = NULL; @@ -3235,6 +3254,8 @@ int OSD::shutdown() cct->get_admin_socket()->unregister_command("injectdataerr"); cct->get_admin_socket()->unregister_command("injectmdataerr"); cct->get_admin_socket()->unregister_command("set_recovery_delay"); + cct->get_admin_socket()->unregister_command("trigger_scrub"); + cct->get_admin_socket()->unregister_command("injectfull"); delete test_ops_hook; test_ops_hook = NULL; @@ -3443,17 +3464,32 @@ int OSD::update_crush_location() int OSD::update_crush_device_class() { + if (!cct->_conf->osd_class_update_on_start) { + dout(10) << __func__ << " osd_class_update_on_start = false" << dendl; + return 0; + } + string device_class; int r = store->read_meta("crush_device_class", &device_class); - if (r < 0) + if (r < 0 || device_class.empty()) { + device_class = store->get_default_device_class(); + } + + if (device_class.empty()) { return 0; + } string cmd = string("{\"prefix\": \"osd crush set-device-class\", ") + - string("\"id\": ") + stringify(whoami) + string(", ") + - string("\"class\": \"") + device_class + string("\"}"); + string("\"class\": \"") + device_class + string("\", ") + + string("\"ids\": [\"") + stringify(whoami) + string("\"]}"); - return mon_cmd_maybe_osd_create(cmd); + r = mon_cmd_maybe_osd_create(cmd); + if (r == -EPERM) { + r = 0; + } + + return r; } void OSD::write_superblock(ObjectStore::Transaction& t) @@ -4976,20 +5012,17 @@ void OSD::tick() if (is_waiting_for_healthy()) { start_boot(); + } else if (is_preboot() && + waiting_for_luminous_mons && + monc->monmap.get_required_features().contains_all( + ceph::features::mon::FEATURE_LUMINOUS)) { + // mon upgrade finished! + start_boot(); } do_waiters(); tick_timer.add_event_after(OSD_TICK_INTERVAL, new C_Tick(this)); - - if (is_active()) { - const auto now = ceph::coarse_mono_clock::now(); - const auto elapsed = now - last_sent_beacon; - if (chrono::duration_cast(elapsed).count() > - cct->_conf->osd_beacon_report_interval) { - send_beacon(now); - } - } } void OSD::tick_without_osd_lock() @@ -5078,6 +5111,20 @@ void OSD::tick_without_osd_lock() sched_scrub(); } service.promote_throttle_recalibrate(); + bool need_send_beacon = false; + const auto now = ceph::coarse_mono_clock::now(); + { + // borrow lec lock to pretect last_sent_beacon from changing + Mutex::Locker l{min_last_epoch_clean_lock}; + const auto elapsed = now - last_sent_beacon; + if (chrono::duration_cast(elapsed).count() > + cct->_conf->osd_beacon_report_interval) { + need_send_beacon = true; + } + } + if (need_send_beacon) { + send_beacon(now); + } } check_ops_in_flight(); @@ -5583,6 +5630,7 @@ void OSD::start_boot() } dout(1) << __func__ << dendl; set_state(STATE_PREBOOT); + waiting_for_luminous_mons = false; dout(10) << "start_boot - have maps " << superblock.oldest_map << ".." << superblock.newest_map << dendl; C_OSD_GetVersion *c = new C_OSD_GetVersion(this); @@ -5621,6 +5669,7 @@ void OSD::_preboot(epoch_t oldest, epoch_t newest) ceph::features::mon::FEATURE_LUMINOUS)) { derr << "monmap REQUIRE_LUMINOUS is NOT set; must upgrade all monitors to " << "Luminous or later before Luminous OSDs will boot" << dendl; + waiting_for_luminous_mons = true; } else if (service.need_fullness_update()) { derr << "osdmap fullness state needs update" << dendl; send_full_update(); @@ -6056,12 +6105,12 @@ void OSD::send_beacon(const ceph::coarse_mono_clock::time_point& now) monmap.get_required_features().contains_all( ceph::features::mon::FEATURE_LUMINOUS)) { dout(20) << __func__ << " sending" << dendl; - last_sent_beacon = now; MOSDBeacon* beacon = nullptr; { Mutex::Locker l{min_last_epoch_clean_lock}; beacon = new MOSDBeacon(osdmap->get_epoch(), min_last_epoch_clean); std::swap(beacon->pgs, min_last_epoch_clean_pgs); + last_sent_beacon = now; } monc->send_mon_message(beacon); } else { @@ -6195,6 +6244,10 @@ COMMAND("dump_pg_recovery_stats", "dump pg recovery statistics", "osd", "r", "cli,rest") COMMAND("reset_pg_recovery_stats", "reset pg recovery statistics", "osd", "rw", "cli,rest") +COMMAND("compact", + "compact object store's omap. " + "WARNING: Compaction probably slows your requests", + "osd", "rw", "cli,rest") }; void OSD::do_command(Connection *con, ceph_tid_t tid, vector& cmd, bufferlist& data) @@ -6609,6 +6662,18 @@ void OSD::do_command(Connection *con, ceph_tid_t tid, vector& cmd, buffe } } + else if (prefix == "compact") { + dout(1) << "triggering manual compaction" << dendl; + auto start = ceph::coarse_mono_clock::now(); + store->compact(); + auto end = ceph::coarse_mono_clock::now(); + auto time_span = chrono::duration_cast>(end - start); + dout(1) << "finished manual compaction in " + << time_span.count() + << " seconds" << dendl; + ss << "compacted omap in " << time_span.count() << " seconds"; + } + else { ss << "unrecognized command! " << cmd; r = -EINVAL; @@ -7342,7 +7407,8 @@ void OSD::trim_maps(epoch_t oldest, int nreceived, bool skip_maps) if (num > 0) { service.publish_superblock(superblock); write_superblock(t); - store->queue_transaction(service.meta_osr.get(), std::move(t), nullptr); + int tr = store->queue_transaction(service.meta_osr.get(), std::move(t), nullptr); + assert(tr == 0); } // we should not remove the cached maps assert(min <= service.map_cache.cached_key_lower_bound()); @@ -7628,7 +7694,7 @@ void OSD::_committed_osd_maps(epoch_t first, epoch_t last, MOSDMap *m) dout(10) << __func__ << " require_osd_release reached luminous in " << newmap->get_epoch() << dendl; clear_pg_stat_queue(); - outstanding_pg_stats.clear(); + clear_outstanding_pg_stats(); } osdmap = newmap; @@ -9124,9 +9190,27 @@ void OSD::do_recovery( if (!more && pg->have_unfound()) { pg->discover_all_missing(*rctx.query_map); if (rctx.query_map->empty()) { - dout(10) << "do_recovery no luck, giving up on this pg for now" << dendl; + string action; + if (pg->state_test(PG_STATE_BACKFILL)) { + auto evt = PG::CephPeeringEvtRef(new PG::CephPeeringEvt( + queued, + queued, + PG::CancelBackfill())); + pg->queue_peering_event(evt); + action = "in backfill"; + } else if (pg->state_test(PG_STATE_RECOVERING)) { + auto evt = PG::CephPeeringEvtRef(new PG::CephPeeringEvt( + queued, + queued, + PG::CancelRecovery())); + pg->queue_peering_event(evt); + action = "in recovery"; + } else { + action = "already out of recovery/backfill"; + } + dout(10) << __func__ << ": no luck, giving up on this pg for now (" << action << ")" << dendl; } else { - dout(10) << "do_recovery no luck, giving up on this pg for now" << dendl; + dout(10) << __func__ << ": no luck, giving up on this pg for now (queue_recovery)" << dendl; pg->queue_recovery(); } } @@ -9180,10 +9264,8 @@ void OSDService::finish_recovery_op(PG *pg, const hobject_t& soid, bool dequeue) bool OSDService::is_recovery_active() { - if (recovery_ops_active > 0) - return true; - - return false; + Mutex::Locker l(recovery_lock); + return recovery_ops_active > 0; } // ========================================================= @@ -9211,6 +9293,7 @@ void OSD::enqueue_op(spg_t pg, OpRequestRef& op, epoch_t epoch) op->osd_trace.keyval("priority", op->get_req()->get_priority()); op->osd_trace.keyval("cost", op->get_req()->get_cost()); op->mark_queued_for_pg(); + logger->tinc(l_osd_op_before_queue_op_lat, latency); op_shardedwq.queue(make_pair(pg, PGQueueable(op, epoch))); } @@ -9235,6 +9318,8 @@ void OSD::dequeue_op( << " " << *(op->get_req()) << " pg " << *pg << dendl; + logger->tinc(l_osd_op_before_dequeue_op_lat, latency); + Session *session = static_cast( op->get_req()->get_connection()->get_priv()); if (session) { @@ -9344,8 +9429,13 @@ const char** OSD::get_tracked_conf_keys() const static const char* KEYS[] = { "osd_max_backfills", "osd_min_recovery_priority", - "osd_op_complaint_time", "osd_op_log_threshold", - "osd_op_history_size", "osd_op_history_duration", + "osd_max_trimming_pgs", + "osd_op_complaint_time", + "osd_op_log_threshold", + "osd_op_history_size", + "osd_op_history_duration", + "osd_op_history_slow_op_size", + "osd_op_history_slow_op_threshold", "osd_enable_op_tracker", "osd_map_cache_size", "osd_map_max_advance", @@ -9728,6 +9818,7 @@ void OSD::PeeringWQ::_dequeue(list *out) { in_use.insert(out->begin(), out->end()); } + // ============================================================= #undef dout_context @@ -9853,10 +9944,10 @@ void OSD::ShardedOpWQ::_process(uint32_t thread_index, heartbeat_handle_d *hb) if (sdata->pqueue->empty()) { dout(20) << __func__ << " empty q, waiting" << dendl; // optimistically sleep a moment; maybe another work item will come along. - sdata->sdata_op_ordering_lock.Unlock(); osd->cct->get_heartbeat_map()->reset_timeout(hb, osd->cct->_conf->threadpool_default_timeout, 0); sdata->sdata_lock.Lock(); + sdata->sdata_op_ordering_lock.Unlock(); sdata->sdata_cond.WaitInterval(sdata->sdata_lock, utime_t(osd->cct->_conf->threadpool_empty_queue_max_wait, 0)); sdata->sdata_lock.Unlock(); @@ -10120,3 +10211,21 @@ int heap(CephContext& cct, cmdmap_t& cmdmap, Formatter& f, std::ostream& os) }} // namespace ceph::osd_cmds + +std::ostream& operator<<(std::ostream& out, const OSD::io_queue& q) { + switch(q) { + case OSD::io_queue::prioritized: + out << "prioritized"; + break; + case OSD::io_queue::weightedpriority: + out << "weightedpriority"; + break; + case OSD::io_queue::mclock_opclass: + out << "mclock_opclass"; + break; + case OSD::io_queue::mclock_client: + out << "mclock_client"; + break; + } + return out; +} diff --git a/ceph/src/osd/OSD.h b/ceph/src/osd/OSD.h index 12a9d774c..bfa511e8b 100644 --- a/ceph/src/osd/OSD.h +++ b/ceph/src/osd/OSD.h @@ -40,6 +40,8 @@ #include "OpRequest.h" #include "Session.h" +#include "osd/PGQueueable.h" + #include #include #include @@ -53,6 +55,8 @@ using namespace std; #include "common/sharedptr_registry.hpp" #include "common/WeightedPriorityQueue.h" #include "common/PrioritizedQueue.h" +#include "osd/mClockOpClassQueue.h" +#include "osd/mClockClientQueue.h" #include "messages/MOSDOp.h" #include "include/Spinlock.h" #include "common/EventTrace.h" @@ -90,6 +94,9 @@ enum { l_osd_op_rw_process_lat, l_osd_op_rw_prepare_lat, + l_osd_op_before_queue_op_lat, + l_osd_op_before_dequeue_op_lat, + l_osd_sop, l_osd_sop_inb, l_osd_sop_lat, @@ -337,123 +344,6 @@ typedef ceph::shared_ptr DeletingStateRef; class OSD; -struct PGScrub { - epoch_t epoch_queued; - explicit PGScrub(epoch_t e) : epoch_queued(e) {} - ostream &operator<<(ostream &rhs) { - return rhs << "PGScrub"; - } -}; - -struct PGSnapTrim { - epoch_t epoch_queued; - explicit PGSnapTrim(epoch_t e) : epoch_queued(e) {} - ostream &operator<<(ostream &rhs) { - return rhs << "PGSnapTrim"; - } -}; - -struct PGRecovery { - epoch_t epoch_queued; - uint64_t reserved_pushes; - PGRecovery(epoch_t e, uint64_t reserved_pushes) - : epoch_queued(e), reserved_pushes(reserved_pushes) {} - ostream &operator<<(ostream &rhs) { - return rhs << "PGRecovery(epoch=" << epoch_queued - << ", reserved_pushes: " << reserved_pushes << ")"; - } -}; - -class PGQueueable { - typedef boost::variant< - OpRequestRef, - PGSnapTrim, - PGScrub, - PGRecovery - > QVariant; - QVariant qvariant; - int cost; - unsigned priority; - utime_t start_time; - entity_inst_t owner; - epoch_t map_epoch; ///< an epoch we expect the PG to exist in - - struct RunVis : public boost::static_visitor<> { - OSD *osd; - PGRef &pg; - ThreadPool::TPHandle &handle; - RunVis(OSD *osd, PGRef &pg, ThreadPool::TPHandle &handle) - : osd(osd), pg(pg), handle(handle) {} - void operator()(const OpRequestRef &op); - void operator()(const PGSnapTrim &op); - void operator()(const PGScrub &op); - void operator()(const PGRecovery &op); - }; - - struct StringifyVis : public boost::static_visitor { - std::string operator()(const OpRequestRef &op) { - return stringify(op); - } - std::string operator()(const PGSnapTrim &op) { - return "PGSnapTrim"; - } - std::string operator()(const PGScrub &op) { - return "PGScrub"; - } - std::string operator()(const PGRecovery &op) { - return "PGRecovery"; - } - }; - friend ostream& operator<<(ostream& out, const PGQueueable& q) { - StringifyVis v; - return out << "PGQueueable(" << boost::apply_visitor(v, q.qvariant) - << " prio " << q.priority << " cost " << q.cost - << " e" << q.map_epoch << ")"; - } - -public: - // cppcheck-suppress noExplicitConstructor - PGQueueable(OpRequestRef op, epoch_t e) - : qvariant(op), cost(op->get_req()->get_cost()), - priority(op->get_req()->get_priority()), - start_time(op->get_req()->get_recv_stamp()), - owner(op->get_req()->get_source_inst()), - map_epoch(e) - {} - PGQueueable( - const PGSnapTrim &op, int cost, unsigned priority, utime_t start_time, - const entity_inst_t &owner, epoch_t e) - : qvariant(op), cost(cost), priority(priority), start_time(start_time), - owner(owner), map_epoch(e) {} - PGQueueable( - const PGScrub &op, int cost, unsigned priority, utime_t start_time, - const entity_inst_t &owner, epoch_t e) - : qvariant(op), cost(cost), priority(priority), start_time(start_time), - owner(owner), map_epoch(e) {} - PGQueueable( - const PGRecovery &op, int cost, unsigned priority, utime_t start_time, - const entity_inst_t &owner, epoch_t e) - : qvariant(op), cost(cost), priority(priority), start_time(start_time), - owner(owner), map_epoch(e) {} - const boost::optional maybe_get_op() const { - const OpRequestRef *op = boost::get(&qvariant); - return op ? OpRequestRef(*op) : boost::optional(); - } - uint64_t get_reserved_pushes() const { - const PGRecovery *op = boost::get(&qvariant); - return op ? op->reserved_pushes : 0; - } - void run(OSD *osd, PGRef &pg, ThreadPool::TPHandle &handle) { - RunVis v(osd, pg, handle); - boost::apply_visitor(v, qvariant); - } - unsigned get_priority() const { return priority; } - int get_cost() const { return cost; } - utime_t get_start_time() const { return start_time; } - entity_inst_t get_owner() const { return owner; } - epoch_t get_map_epoch() const { return map_epoch; } -}; - class OSDService { public: OSD *osd; @@ -1154,6 +1044,8 @@ public: uint32_t seq = 0; void update_osd_stat(vector& hb_peers); + osd_stat_t set_osd_stat(const struct store_statfs_t &stbuf, + vector& hb_peers); osd_stat_t get_osd_stat() { Mutex::Locker l(stat_lock); ++seq; @@ -1199,7 +1091,7 @@ private: mutable int64_t injectfull = 0; s_names injectfull_state = NONE; float get_failsafe_full_ratio(); - void check_full_status(const osd_stat_t &stat); + void check_full_status(float ratio); bool _check_full(s_names type, ostream &ss) const; public: bool check_failsafe_full(ostream &ss) const; @@ -1450,6 +1342,7 @@ public: private: std::atomic_int state{STATE_INITIALIZING}; + bool waiting_for_luminous_mons = false; public: int get_state() const { @@ -1694,10 +1587,14 @@ private: friend struct C_OpenPGs; // -- op queue -- - enum io_queue { + enum class io_queue { prioritized, - weightedpriority + weightedpriority, + mclock_opclass, + mclock_client, }; + friend std::ostream& operator<<(std::ostream& out, const OSD::io_queue& q); + const io_queue op_queue; const unsigned int op_prio_cutoff; @@ -1722,6 +1619,7 @@ private: * and already requeued the items. */ friend class PGQueueable; + class ShardedOpWQ : public ShardedThreadPool::ShardedWQ> { @@ -1774,19 +1672,25 @@ private: : sdata_lock(lock_name.c_str(), false, true, false, cct), sdata_op_ordering_lock(ordering_lock.c_str(), false, true, false, cct) { - if (opqueue == weightedpriority) { + if (opqueue == io_queue::weightedpriority) { pqueue = std::unique_ptr ,entity_inst_t>>( new WeightedPriorityQueue,entity_inst_t>( max_tok_per_prio, min_cost)); - } else if (opqueue == prioritized) { + } else if (opqueue == io_queue::prioritized) { pqueue = std::unique_ptr ,entity_inst_t>>( new PrioritizedQueue,entity_inst_t>( max_tok_per_prio, min_cost)); + } else if (opqueue == io_queue::mclock_opclass) { + pqueue = std::unique_ptr + (new ceph::mClockOpClassQueue(cct)); + } else if (opqueue == io_queue::mclock_client) { + pqueue = std::unique_ptr + (new ceph::mClockClientQueue(cct)); } } - }; + }; // struct ShardData vector shard_list; OSD *osd; @@ -1977,7 +1881,7 @@ private: OSDMapRef get_osdmap() { return osdmap; } - epoch_t get_osdmap_epoch() { + epoch_t get_osdmap_epoch() const { return osdmap ? osdmap->get_epoch() : 0; } @@ -2212,6 +2116,10 @@ protected: } pg_stat_queue_lock.Unlock(); } + void clear_outstanding_pg_stats(){ + Mutex::Locker l(pg_stat_queue_lock); + outstanding_pg_stats.clear(); + } ceph_tid_t get_tid() { return service.get_tid(); @@ -2368,7 +2276,7 @@ protected: } } remove_wq; - private: +private: bool ms_can_fast_dispatch_any() const override { return true; } bool ms_can_fast_dispatch(const Message *m) const override { switch (m->get_type()) { @@ -2414,12 +2322,21 @@ protected: io_queue get_io_queue() const { if (cct->_conf->osd_op_queue == "debug_random") { + static io_queue index_lookup[] = { io_queue::prioritized, + io_queue::weightedpriority, + io_queue::mclock_opclass, + io_queue::mclock_client }; srand(time(NULL)); - return (rand() % 2 < 1) ? prioritized : weightedpriority; + unsigned which = rand() % (sizeof(index_lookup) / sizeof(index_lookup[0])); + return index_lookup[which]; } else if (cct->_conf->osd_op_queue == "wpq") { - return weightedpriority; + return io_queue::weightedpriority; + } else if (cct->_conf->osd_op_queue == "mclock_opclass") { + return io_queue::mclock_opclass; + } else if (cct->_conf->osd_op_queue == "mclock_client") { + return io_queue::mclock_client; } else { - return prioritized; + return io_queue::prioritized; } } @@ -2507,9 +2424,13 @@ public: friend class OSDService; }; + +std::ostream& operator<<(std::ostream& out, const OSD::io_queue& q); + + //compatibility of the executable extern const CompatSet::Feature ceph_osd_feature_compat[]; extern const CompatSet::Feature ceph_osd_feature_ro_compat[]; extern const CompatSet::Feature ceph_osd_feature_incompat[]; -#endif +#endif // CEPH_OSD_H diff --git a/ceph/src/osd/OSDMap.cc b/ceph/src/osd/OSDMap.cc index 594ff82fa..ea43ae773 100644 --- a/ceph/src/osd/OSDMap.cc +++ b/ceph/src/osd/OSDMap.cc @@ -15,6 +15,8 @@ * */ +#include + #include "OSDMap.h" #include #include "common/config.h" @@ -24,6 +26,7 @@ #include "include/str_map.h" #include "common/code_environment.h" +#include "mon/health_check.h" #include "crush/CrushTreeDumper.h" #include "common/Clock.h" @@ -294,8 +297,14 @@ bool OSDMap::containing_subtree_is_down(CephContext *cct, int id, int subtree_ty } } -bool OSDMap::subtree_type_is_down(CephContext *cct, int id, int subtree_type, set *down_in_osds, set *up_in_osds, - set *subtree_up, unordered_map > *subtree_type_down) const +bool OSDMap::subtree_type_is_down( + CephContext *cct, + int id, + int subtree_type, + set *down_in_osds, + set *up_in_osds, + set *subtree_up, + unordered_map > *subtree_type_down) const { if (id >= 0) { bool is_down_ret = is_down(id); @@ -317,7 +326,9 @@ bool OSDMap::subtree_type_is_down(CephContext *cct, int id, int subtree_type, se list children; crush->get_children(id, &children); for (const auto &child : children) { - if (!subtree_type_is_down(cct, child, crush->get_bucket_type(child), down_in_osds, up_in_osds, subtree_up, subtree_type_down)) { + if (!subtree_type_is_down( + cct, child, crush->get_bucket_type(child), + down_in_osds, up_in_osds, subtree_up, subtree_type_down)) { subtree_up->insert(id); return false; } @@ -1907,7 +1918,7 @@ int OSDMap::_pick_primary(const vector& osds) const return -1; } -void OSDMap::_apply_remap(const pg_pool_t& pi, pg_t raw_pg, vector *raw) const +void OSDMap::_apply_upmap(const pg_pool_t& pi, pg_t raw_pg, vector *raw) const { pg_t pg = pi.raw_pg_to_pg(raw_pg); auto p = pg_upmap.find(pg); @@ -1920,7 +1931,7 @@ void OSDMap::_apply_remap(const pg_pool_t& pi, pg_t raw_pg, vector *raw) co } } *raw = vector(p->second.begin(), p->second.end()); - return; + // continue to check and apply pg_upmap_items if any } auto q = pg_upmap_items.find(pg); @@ -1947,7 +1958,6 @@ void OSDMap::_apply_remap(const pg_pool_t& pi, pg_t raw_pg, vector *raw) co } if (!exists && pos >= 0) { (*raw)[pos] = r.second; - return; } } } @@ -2092,7 +2102,7 @@ void OSDMap::pg_to_raw_up(pg_t pg, vector *up, int *primary) const vector raw; ps_t pps; _pg_to_raw_osds(*pool, pg, &raw, &pps); - _apply_remap(*pool, pg, &raw); + _apply_upmap(*pool, pg, &raw); _raw_to_up_osds(*pool, raw, up); *primary = _pick_primary(raw); _apply_primary_affinity(pps, *pool, up, primary); @@ -2125,7 +2135,7 @@ void OSDMap::_pg_to_up_acting_osds( _get_temp_osds(*pool, pg, &_acting, &_acting_primary); if (_acting.empty() || up || up_primary) { _pg_to_raw_osds(*pool, pg, &raw, &pps); - _apply_remap(*pool, pg, &raw); + _apply_upmap(*pool, pg, &raw); _raw_to_up_osds(*pool, raw, &_up); _up_primary = _pick_primary(_up); _apply_primary_affinity(pps, *pool, &_up, &_up_primary); @@ -2894,7 +2904,7 @@ void OSDMap::generate_test_instances(list& o) CephContext *cct = new CephContext(CODE_ENVIRONMENT_UTILITY); o.push_back(new OSDMap); uuid_d fsid; - o.back()->build_simple(cct, 1, fsid, 16, 7, 8); + o.back()->build_simple(cct, 1, fsid, 16); o.back()->created = o.back()->modified = utime_t(1, 2); // fix timestamp o.back()->blacklist[entity_addr_t()] = utime_t(5, 6); cct->put(); @@ -2997,6 +3007,10 @@ void OSDMap::print(ostream& out) const } out << "min_compat_client " << ceph_release_name(get_min_compat_client()) << "\n"; + if (require_osd_release > 0) { + out << "require_osd_release " << ceph_release_name(require_osd_release) + << "\n"; + } if (get_cluster_snapshot().length()) out << "cluster_snapshot " << get_cluster_snapshot() << "\n"; out << "\n"; @@ -3069,11 +3083,12 @@ public: void dump(TextTable *tbl) { tbl->define_column("ID", TextTable::LEFT, TextTable::RIGHT); + tbl->define_column("CLASS", TextTable::LEFT, TextTable::RIGHT); tbl->define_column("WEIGHT", TextTable::LEFT, TextTable::RIGHT); tbl->define_column("TYPE NAME", TextTable::LEFT, TextTable::LEFT); tbl->define_column("UP/DOWN", TextTable::LEFT, TextTable::RIGHT); tbl->define_column("REWEIGHT", TextTable::LEFT, TextTable::RIGHT); - tbl->define_column("PRIMARY-AFFINITY", TextTable::LEFT, TextTable::RIGHT); + tbl->define_column("PRI-AFF", TextTable::LEFT, TextTable::RIGHT); Parent::dump(tbl); @@ -3086,8 +3101,11 @@ public: protected: void dump_item(const CrushTreeDumper::Item &qi, TextTable *tbl) override { - + const char *c = crush->get_item_class(qi.id); + if (!c) + c = ""; *tbl << qi.id + << c << weightf_t(qi.weight); ostringstream name; @@ -3182,7 +3200,8 @@ void OSDMap::print_tree(Formatter *f, ostream *out, unsigned filter) const } } -void OSDMap::print_summary(Formatter *f, ostream& out) const +void OSDMap::print_summary(Formatter *f, ostream& out, + const string& prefix) const { if (f) { f->open_object_section("osdmap"); @@ -3203,7 +3222,7 @@ void OSDMap::print_summary(Formatter *f, ostream& out) const out << "\n"; uint64_t important_flags = flags & ~CEPH_OSDMAP_SEMIHIDDEN_FLAGS; if (important_flags) - out << " flags " << get_flag_string(important_flags) << "\n"; + out << prefix << "flags " << get_flag_string(important_flags) << "\n"; } } @@ -3228,12 +3247,12 @@ bool OSDMap::crush_ruleset_in_use(int ruleset) const return false; } -int OSDMap::build_simple(CephContext *cct, epoch_t e, uuid_d &fsid, - int nosd, int pg_bits, int pgp_bits) +int OSDMap::build_simple_optioned(CephContext *cct, epoch_t e, uuid_d &fsid, + int nosd, int pg_bits, int pgp_bits, + bool default_pool) { - ldout(cct, 10) << "build_simple on " << num_osd - << " osds with " << pg_bits << " pg bits per osd, " - << dendl; + ldout(cct, 10) << "build_simple on " << nosd + << " osds" << dendl; epoch = e; set_fsid(fsid); created = modified = ceph_clock_now(); @@ -3269,12 +3288,6 @@ int OSDMap::build_simple(CephContext *cct, epoch_t e, uuid_d &fsid, set_max_osd(maxosd + 1); } - // pgp_num <= pg_num - if (pgp_bits > pg_bits) - pgp_bits = pg_bits; - - vector pool_names; - pool_names.push_back("rbd"); stringstream ss; int r; @@ -3286,31 +3299,38 @@ int OSDMap::build_simple(CephContext *cct, epoch_t e, uuid_d &fsid, int poolbase = get_max_osd() ? get_max_osd() : 1; - int const default_replicated_rule = - crush->get_osd_pool_default_crush_replicated_ruleset(cct); + int const default_replicated_rule = crush->get_osd_pool_default_crush_replicated_ruleset(cct); assert(default_replicated_rule >= 0); - for (auto &plname : pool_names) { - int64_t pool = ++pool_max; - pools[pool].type = pg_pool_t::TYPE_REPLICATED; - pools[pool].flags = cct->_conf->osd_pool_default_flags; - if (cct->_conf->osd_pool_default_flag_hashpspool) - pools[pool].set_flag(pg_pool_t::FLAG_HASHPSPOOL); - if (cct->_conf->osd_pool_default_flag_nodelete) - pools[pool].set_flag(pg_pool_t::FLAG_NODELETE); - if (cct->_conf->osd_pool_default_flag_nopgchange) - pools[pool].set_flag(pg_pool_t::FLAG_NOPGCHANGE); - if (cct->_conf->osd_pool_default_flag_nosizechange) - pools[pool].set_flag(pg_pool_t::FLAG_NOSIZECHANGE); - pools[pool].size = cct->_conf->osd_pool_default_size; - pools[pool].min_size = cct->_conf->get_osd_pool_default_min_size(); - pools[pool].crush_rule = default_replicated_rule; - pools[pool].object_hash = CEPH_STR_HASH_RJENKINS; - pools[pool].set_pg_num(poolbase << pg_bits); - pools[pool].set_pgp_num(poolbase << pgp_bits); - pools[pool].last_change = epoch; - pool_name[pool] = plname; - name_pool[plname] = pool; + if (default_pool) { + // pgp_num <= pg_num + if (pgp_bits > pg_bits) + pgp_bits = pg_bits; + + vector pool_names; + pool_names.push_back("rbd"); + for (auto &plname : pool_names) { + int64_t pool = ++pool_max; + pools[pool].type = pg_pool_t::TYPE_REPLICATED; + pools[pool].flags = cct->_conf->osd_pool_default_flags; + if (cct->_conf->osd_pool_default_flag_hashpspool) + pools[pool].set_flag(pg_pool_t::FLAG_HASHPSPOOL); + if (cct->_conf->osd_pool_default_flag_nodelete) + pools[pool].set_flag(pg_pool_t::FLAG_NODELETE); + if (cct->_conf->osd_pool_default_flag_nopgchange) + pools[pool].set_flag(pg_pool_t::FLAG_NOPGCHANGE); + if (cct->_conf->osd_pool_default_flag_nosizechange) + pools[pool].set_flag(pg_pool_t::FLAG_NOSIZECHANGE); + pools[pool].size = cct->_conf->osd_pool_default_size; + pools[pool].min_size = cct->_conf->get_osd_pool_default_min_size(); + pools[pool].crush_rule = default_replicated_rule; + pools[pool].object_hash = CEPH_STR_HASH_RJENKINS; + pools[pool].set_pg_num(poolbase << pg_bits); + pools[pool].set_pgp_num(poolbase << pgp_bits); + pools[pool].last_change = epoch; + pool_name[pool] = plname; + name_pool[plname] = pool; + } } for (int i=0; isecond; float deviation = p->first; float target = osd_weight[osd] * pgs_per_weight; + assert(target > 0); if (deviation/target < max_deviation_ratio) { ldout(cct, 10) << " osd." << osd << " target " << target @@ -4067,6 +4092,7 @@ public: void dump(TextTable *tbl) { tbl->define_column("ID", TextTable::LEFT, TextTable::RIGHT); + tbl->define_column("CLASS", TextTable::LEFT, TextTable::RIGHT); tbl->define_column("WEIGHT", TextTable::LEFT, TextTable::RIGHT); tbl->define_column("REWEIGHT", TextTable::LEFT, TextTable::RIGHT); tbl->define_column("SIZE", TextTable::LEFT, TextTable::RIGHT); @@ -4082,7 +4108,9 @@ public: dump_stray(tbl); - *tbl << "" << "" << "TOTAL" + *tbl << "" + << "" + << "" << "TOTAL" << si_t(pgs->get_osd_sum().kb << 10) << si_t(pgs->get_osd_sum().kb_used << 10) << si_t(pgs->get_osd_sum().kb_avail << 10) @@ -4108,7 +4136,11 @@ protected: double& var, const size_t num_pgs, TextTable *tbl) override { + const char *c = crush->get_item_class(qi.id); + if (!c) + c = ""; *tbl << qi.id + << c << weightf_t(qi.weight) << weightf_t(reweight) << si_t(kb << 10) @@ -4240,3 +4272,358 @@ void print_osd_utilization(const OSDMap& osdmap, out << tbl << d.summary() << "\n"; } } + +void OSDMap::check_health(health_check_map_t *checks) const +{ + int num_osds = get_num_osds(); + + // OSD_DOWN + // OSD_$subtree_DOWN + // OSD_ORPHAN + if (num_osds >= 0) { + int num_in_osds = 0; + int num_down_in_osds = 0; + set osds; + set down_in_osds; + set up_in_osds; + set subtree_up; + unordered_map > subtree_type_down; + unordered_map num_osds_subtree; + int max_type = crush->get_max_type_id(); + + for (int i = 0; i < get_max_osd(); i++) { + if (!exists(i)) { + if (crush->item_exists(i)) { + osds.insert(i); + } + continue; + } + if (is_out(i)) + continue; + ++num_in_osds; + if (down_in_osds.count(i) || up_in_osds.count(i)) + continue; + if (!is_up(i)) { + down_in_osds.insert(i); + int parent_id = 0; + int current = i; + for (int type = 0; type <= max_type; type++) { + if (!crush->get_type_name(type)) + continue; + int r = crush->get_immediate_parent_id(current, &parent_id); + if (r == -ENOENT) + break; + // break early if this parent is already marked as up + if (subtree_up.count(parent_id)) + break; + type = crush->get_bucket_type(parent_id); + if (!subtree_type_is_down( + g_ceph_context, parent_id, type, + &down_in_osds, &up_in_osds, &subtree_up, &subtree_type_down)) + break; + current = parent_id; + } + } + } + + // calculate the number of down osds in each down subtree and + // store it in num_osds_subtree + for (int type = 1; type <= max_type; type++) { + if (!crush->get_type_name(type)) + continue; + for (auto j = subtree_type_down[type].begin(); + j != subtree_type_down[type].end(); + ++j) { + list children; + int num = 0; + int num_children = crush->get_children(*j, &children); + if (num_children == 0) + continue; + for (auto l = children.begin(); l != children.end(); ++l) { + if (*l >= 0) { + ++num; + } else if (num_osds_subtree[*l] > 0) { + num = num + num_osds_subtree[*l]; + } + } + num_osds_subtree[*j] = num; + } + } + num_down_in_osds = down_in_osds.size(); + assert(num_down_in_osds <= num_in_osds); + if (num_down_in_osds > 0) { + // summary of down subtree types and osds + for (int type = max_type; type > 0; type--) { + if (!crush->get_type_name(type)) + continue; + if (subtree_type_down[type].size() > 0) { + ostringstream ss; + ss << subtree_type_down[type].size() << " " + << crush->get_type_name(type); + if (subtree_type_down[type].size() > 1) { + ss << "s"; + } + int sum_down_osds = 0; + for (auto j = subtree_type_down[type].begin(); + j != subtree_type_down[type].end(); + ++j) { + sum_down_osds = sum_down_osds + num_osds_subtree[*j]; + } + ss << " (" << sum_down_osds << " osds) down"; + string err = string("OSD_") + + string(crush->get_type_name(type)) + "_DOWN"; + boost::to_upper(err); + auto& d = checks->add(err, HEALTH_WARN, ss.str()); + for (auto j = subtree_type_down[type].rbegin(); + j != subtree_type_down[type].rend(); + ++j) { + ostringstream ss; + ss << crush->get_type_name(type); + ss << " "; + ss << crush->get_item_name(*j); + // at the top level, do not print location + if (type != max_type) { + ss << " ("; + ss << crush->get_full_location_ordered_string(*j); + ss << ")"; + } + int num = num_osds_subtree[*j]; + ss << " (" << num << " osds)"; + ss << " is down"; + d.detail.push_back(ss.str()); + } + } + } + ostringstream ss; + ss << down_in_osds.size() << " osds down"; + auto& d = checks->add("OSD_DOWN", HEALTH_WARN, ss.str()); + for (auto it = down_in_osds.begin(); it != down_in_osds.end(); ++it) { + ostringstream ss; + ss << "osd." << *it << " ("; + ss << crush->get_full_location_ordered_string(*it); + ss << ") is down"; + d.detail.push_back(ss.str()); + } + } + + if (!osds.empty()) { + ostringstream ss; + ss << osds.size() << " osds exist in the crush map but not in the osdmap"; + auto& d = checks->add("OSD_ORPHAN", HEALTH_WARN, ss.str()); + for (auto osd : osds) { + ostringstream ss; + ss << "osd." << osd << " exists in crush map but not in osdmap"; + d.detail.push_back(ss.str()); + } + } + } + + // OSD_OUT_OF_ORDER_FULL + { + // An osd could configure failsafe ratio, to something different + // but for now assume it is the same here. + float fsr = g_conf->osd_failsafe_full_ratio; + if (fsr > 1.0) fsr /= 100; + float fr = get_full_ratio(); + float br = get_backfillfull_ratio(); + float nr = get_nearfull_ratio(); + + list detail; + // These checks correspond to how OSDService::check_full_status() in an OSD + // handles the improper setting of these values. + if (br < nr) { + ostringstream ss; + ss << "backfillfull_ratio (" << br + << ") < nearfull_ratio (" << nr << "), increased"; + detail.push_back(ss.str()); + br = nr; + } + if (fr < br) { + ostringstream ss; + ss << "full_ratio (" << fr << ") < backfillfull_ratio (" << br + << "), increased"; + detail.push_back(ss.str()); + fr = br; + } + if (fsr < fr) { + ostringstream ss; + ss << "osd_failsafe_full_ratio (" << fsr << ") < full_ratio (" << fr + << "), increased"; + detail.push_back(ss.str()); + } + if (!detail.empty()) { + auto& d = checks->add("OSD_OUT_OF_ORDER_FULL", HEALTH_ERR, + "full ratio(s) out of order"); + d.detail.swap(detail); + } + } + + // OSD_FULL + // OSD_NEARFULL + // OSD_BACKFILLFULL + // OSD_FAILSAFE_FULL + { + set full, backfillfull, nearfull; + get_full_osd_counts(&full, &backfillfull, &nearfull); + if (full.size()) { + ostringstream ss; + ss << full.size() << " full osd(s)"; + auto& d = checks->add("OSD_FULL", HEALTH_ERR, ss.str()); + for (auto& i: full) { + ostringstream ss; + ss << "osd." << i << " is full"; + d.detail.push_back(ss.str()); + } + } + if (backfillfull.size()) { + ostringstream ss; + ss << backfillfull.size() << " backfillfull osd(s)"; + auto& d = checks->add("OSD_BACKFILLFULL", HEALTH_WARN, ss.str()); + for (auto& i: backfillfull) { + ostringstream ss; + ss << "osd." << i << " is backfill full"; + d.detail.push_back(ss.str()); + } + } + if (nearfull.size()) { + ostringstream ss; + ss << nearfull.size() << " nearfull osd(s)"; + auto& d = checks->add("OSD_NEARFULL", HEALTH_WARN, ss.str()); + for (auto& i: nearfull) { + ostringstream ss; + ss << "osd." << i << " is near full"; + d.detail.push_back(ss.str()); + } + } + } + + // OSDMAP_FLAGS + { + // warn about flags + uint64_t warn_flags = + CEPH_OSDMAP_FULL | + CEPH_OSDMAP_PAUSERD | + CEPH_OSDMAP_PAUSEWR | + CEPH_OSDMAP_PAUSEREC | + CEPH_OSDMAP_NOUP | + CEPH_OSDMAP_NODOWN | + CEPH_OSDMAP_NOIN | + CEPH_OSDMAP_NOOUT | + CEPH_OSDMAP_NOBACKFILL | + CEPH_OSDMAP_NORECOVER | + CEPH_OSDMAP_NOSCRUB | + CEPH_OSDMAP_NODEEP_SCRUB | + CEPH_OSDMAP_NOTIERAGENT | + CEPH_OSDMAP_NOREBALANCE; + if (test_flag(warn_flags)) { + ostringstream ss; + ss << get_flag_string(get_flags() & warn_flags) + << " flag(s) set"; + checks->add("OSDMAP_FLAGS", HEALTH_WARN, ss.str()); + } + } + + // OSD_FLAGS + { + list detail; + const unsigned flags = + CEPH_OSD_NOUP | + CEPH_OSD_NOIN | + CEPH_OSD_NODOWN | + CEPH_OSD_NOOUT; + for (int i = 0; i < max_osd; ++i) { + if (osd_state[i] & flags) { + ostringstream ss; + set states; + OSDMap::calc_state_set(osd_state[i] & flags, states); + ss << "osd." << i << " has flags " << states; + detail.push_back(ss.str()); + } + } + if (!detail.empty()) { + ostringstream ss; + ss << detail.size() << " osd(s) have {NOUP,NODOWN,NOIN,NOOUT} flags set"; + auto& d = checks->add("OSD_FLAGS", HEALTH_WARN, ss.str()); + d.detail.swap(detail); + } + } + + // OLD_CRUSH_TUNABLES + if (g_conf->mon_warn_on_legacy_crush_tunables) { + string min = 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 << ")"; + auto& d = checks->add("OLD_CRUSH_TUNABLES", HEALTH_WARN, ss.str()); + d.detail.push_back("see http://docs.ceph.com/docs/master/rados/operations/crush-map/#tunables"); + } + } + + // OLD_CRUSH_STRAW_CALC_VERSION + if (g_conf->mon_warn_on_crush_straw_calc_version_zero) { + if (crush->get_straw_calc_version() == 0) { + ostringstream ss; + ss << "crush map has straw_calc_version=0"; + auto& d = checks->add("OLD_CRUSH_STRAW_CALC_VERSION", HEALTH_WARN, ss.str()); + d.detail.push_back( + "see http://docs.ceph.com/docs/master/rados/operations/crush-map/#tunables"); + } + } + + // CACHE_POOL_NO_HIT_SET + if (g_conf->mon_warn_on_cache_pools_without_hit_sets) { + list detail; + for (map::const_iterator p = pools.begin(); + p != pools.end(); + ++p) { + const pg_pool_t& info = p->second; + if (info.cache_mode_requires_hit_set() && + info.hit_set_params.get_type() == HitSet::TYPE_NONE) { + ostringstream ss; + ss << "pool '" << get_pool_name(p->first) + << "' with cache_mode " << info.get_cache_mode_name() + << " needs hit_set_type to be set but it is not"; + detail.push_back(ss.str()); + } + } + if (!detail.empty()) { + ostringstream ss; + ss << detail.size() << " cache pools are missing hit_sets"; + auto& d = checks->add("CACHE_POOL_NO_HIT_SET", HEALTH_WARN, ss.str()); + d.detail.swap(detail); + } + } + + // OSD_NO_SORTBITWISE + if (!test_flag(CEPH_OSDMAP_SORTBITWISE) && + (get_up_osd_features() & + CEPH_FEATURE_OSD_BITWISE_HOBJ_SORT)) { + ostringstream ss; + ss << "no legacy OSD present but 'sortbitwise' flag is not set"; + checks->add("OSD_NO_SORTBITWISE", HEALTH_WARN, ss.str()); + } + + // OSD_UPGRADE_FINISHED + // none of these (yet) since we don't run until luminous upgrade is done. + + // POOL_FULL + { + list detail; + for (auto it : get_pools()) { + const pg_pool_t &pool = it.second; + if (pool.has_flag(pg_pool_t::FLAG_FULL)) { + const string& pool_name = get_pool_name(it.first); + stringstream ss; + ss << "pool '" << pool_name << "' is full"; + detail.push_back(ss.str()); + } + } + if (!detail.empty()) { + ostringstream ss; + ss << detail.size() << " pool(s) full"; + auto& d = checks->add("POOL_FULL", HEALTH_WARN, ss.str()); + d.detail.swap(detail); + } + } +} diff --git a/ceph/src/osd/OSDMap.h b/ceph/src/osd/OSDMap.h index 6639b4f65..6538c9e62 100644 --- a/ceph/src/osd/OSDMap.h +++ b/ceph/src/osd/OSDMap.h @@ -41,6 +41,7 @@ using namespace std; // forward declaration class CephContext; class CrushWrapper; +class health_check_map_t; // FIXME C++11 does not have std::equal for two differently-typed containers. // use this until we move to c++14 @@ -569,7 +570,7 @@ private: public: OSDMap() : epoch(0), - pool_max(-1), + pool_max(0), flags(0), num_osd(0), num_up_osd(0), num_in_osd(0), max_osd(0), @@ -1038,6 +1039,24 @@ public: return p && pgid.ps() < p->get_pg_num(); } + int get_pg_pool_min_size(pg_t pgid) const { + if (!pg_exists(pgid)) { + return -ENOENT; + } + const pg_pool_t *p = get_pg_pool(pgid.pool()); + assert(p); + return p->get_min_size(); + } + + int get_pg_pool_size(pg_t pgid) const { + if (!pg_exists(pgid)) { + return -ENOENT; + } + const pg_pool_t *p = get_pg_pool(pgid.pool()); + assert(p); + return p->get_size(); + } + private: /// pg -> (raw osd list) void _pg_to_raw_osds( @@ -1051,7 +1070,7 @@ private: vector *osds, int *primary) const; /// apply pg_upmap[_items] mappings - void _apply_remap(const pg_pool_t& pi, pg_t pg, vector *raw) const; + void _apply_upmap(const pg_pool_t& pi, pg_t pg, vector *raw) const; /// pg -> (up osd list) void _raw_to_up_osds(const pg_pool_t& pool, const vector& raw, @@ -1282,8 +1301,20 @@ public: * @param num_osd [in] number of OSDs if >= 0 or read from conf if < 0 * @return **0** on success, negative errno on error. */ +private: + int build_simple_optioned(CephContext *cct, epoch_t e, uuid_d &fsid, + int num_osd, int pg_bits, int pgp_bits, + bool default_pool); +public: int build_simple(CephContext *cct, epoch_t e, uuid_d &fsid, - int num_osd, int pg_bits, int pgp_bits); + int num_osd) { + return build_simple_optioned(cct, e, fsid, num_osd, 0, 0, false); + } + int build_simple_with_pool(CephContext *cct, epoch_t e, uuid_d &fsid, + int num_osd, int pg_bits, int pgp_bits) { + return build_simple_optioned(cct, e, fsid, num_osd, + pg_bits, pgp_bits, true); + } static int _build_crush_types(CrushWrapper& crush); static int build_simple_crush_map(CephContext *cct, CrushWrapper& crush, int num_osd, ostream *ss); @@ -1307,7 +1338,7 @@ private: public: void print(ostream& out) const; void print_pools(ostream& out) const; - void print_summary(Formatter *f, ostream& out) const; + void print_summary(Formatter *f, ostream& out, const string& prefix) const; void print_oneline_summary(ostream& out) const; enum { @@ -1332,6 +1363,8 @@ public: void dump(Formatter *f) const; static void generate_test_instances(list& o); bool check_new_blacklist_entries() const { return new_blacklist_entries; } + + void check_health(health_check_map_t *checks) const; }; WRITE_CLASS_ENCODER_FEATURES(OSDMap) WRITE_CLASS_ENCODER_FEATURES(OSDMap::Incremental) diff --git a/ceph/src/osd/OSDMapMapping.cc b/ceph/src/osd/OSDMapMapping.cc index 14165a156..bf9f4f99c 100644 --- a/ceph/src/osd/OSDMapMapping.cc +++ b/ceph/src/osd/OSDMapMapping.cc @@ -157,6 +157,7 @@ void ParallelPGMapper::queue( Job *job, unsigned pgs_per_item) { + bool any = false; for (auto& p : job->osdmap->get_pools()) { for (unsigned ps = 0; ps < p.second.get_pg_num(); ps += pgs_per_item) { unsigned ps_end = MIN(ps + pgs_per_item, p.second.get_pg_num()); @@ -164,6 +165,8 @@ void ParallelPGMapper::queue( wq.queue(new Item(job, p.first, ps, ps_end)); ldout(cct, 20) << __func__ << " " << job << " " << p.first << " [" << ps << "," << ps_end << ")" << dendl; + any = true; } } + assert(any); } diff --git a/ceph/src/osd/PG.cc b/ceph/src/osd/PG.cc index e75331053..05ad63c69 100644 --- a/ceph/src/osd/PG.cc +++ b/ceph/src/osd/PG.cc @@ -994,7 +994,7 @@ void PG::clear_primary_state() PG::Scrubber::Scrubber() : reserved(false), reserve_failed(false), epoch_start(0), - active(false), queue_snap_trim(false), + active(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), @@ -1677,7 +1677,7 @@ void PG::activate(ObjectStore::Transaction& t, * behind. */ // backfill - osd->clog->info() << info.pgid << " starting backfill to osd." << peer + osd->clog->debug() << info.pgid << " starting backfill to osd." << peer << " from (" << pi.log_tail << "," << pi.last_update << "] " << pi.last_backfill << " to " << info.last_update; @@ -2003,27 +2003,16 @@ struct C_PG_FinishRecovery : public Context { void PG::mark_clean() { - // only mark CLEAN if we have the desired number of replicas AND we - // are not remapped. - if (actingset.size() == get_osdmap()->get_pg_size(info.pgid.pgid) && - up == acting) + if (actingset.size() == get_osdmap()->get_pg_size(info.pgid.pgid)) { state_set(PG_STATE_CLEAN); - - // NOTE: this is actually a bit premature: we haven't purged the - // strays yet. - info.history.last_epoch_clean = get_osdmap()->get_epoch(); - info.history.last_interval_clean = info.history.same_interval_since; - - past_intervals.clear(); - dirty_big_info = true; - - if (is_active()) { - /* The check is needed because if we are below min_size we're not - * actually active */ - kick_snap_trim(); + info.history.last_epoch_clean = get_osdmap()->get_epoch(); + info.history.last_interval_clean = info.history.same_interval_since; + past_intervals.clear(); + dirty_big_info = true; + dirty_info = true; } - dirty_info = true; + kick_snap_trim(); } unsigned PG::get_recovery_priority() @@ -4034,6 +4023,52 @@ void PG::_scan_snaps(ScrubMap &smap) } } +void PG::_repair_oinfo_oid(ScrubMap &smap) +{ + for (map::reverse_iterator i = smap.objects.rbegin(); + i != smap.objects.rend(); + ++i) { + const hobject_t &hoid = i->first; + ScrubMap::object &o = i->second; + + bufferlist bl; + if (o.attrs.find(OI_ATTR) == o.attrs.end()) { + continue; + } + bl.push_back(o.attrs[OI_ATTR]); + object_info_t oi; + try { + oi.decode(bl); + } catch(...) { + continue; + } + if (oi.soid != hoid) { + ObjectStore::Transaction t; + OSDriver::OSTransaction _t(osdriver.get_transaction(&t)); + osd->clog->error() << "osd." << osd->whoami + << " found object info error on pg " + << info.pgid + << " oid " << hoid << " oid in object info: " + << oi.soid + << "...repaired"; + // Fix object info + oi.soid = hoid; + bl.clear(); + ::encode(oi, bl, get_osdmap()->get_features(CEPH_ENTITY_TYPE_OSD, nullptr)); + + bufferptr bp(bl.c_str(), bl.length()); + o.attrs[OI_ATTR] = bp; + + t.setattr(coll, ghobject_t(hoid), OI_ATTR, bl); + int r = osd->store->apply_transaction(osr.get(), std::move(t)); + if (r != 0) { + derr << __func__ << ": apply_transaction got " << cpp_strerror(r) + << dendl; + } + } + } +} + /* * build a scrub map over a chunk without releasing the lock * only used by chunky scrub @@ -4066,6 +4101,7 @@ int PG::build_scrub_map_chunk( get_pgbackend()->be_scan_list(map, ls, deep, seed, handle); _scan_rollback_obs(rollback_obs, handle); _scan_snaps(map); + _repair_oinfo_oid(map); dout(20) << __func__ << " done" << dendl; return 0; @@ -4100,7 +4136,14 @@ void PG::repair_object( eversion_t v; bufferlist bv; bv.push_back(po.attrs[OI_ATTR]); - object_info_t oi(bv); + object_info_t oi; + try { + bufferlist::iterator bliter = bv.begin(); + ::decode(oi, bliter); + } catch (...) { + dout(0) << __func__ << ": Need version of replica, bad object_info_t: " << soid << dendl; + assert(0); + } if (bad_peer != primary) { peer_missing[bad_peer].add(soid, oi.version, eversion_t()); } else { @@ -4611,6 +4654,11 @@ void PG::chunky_scrub(ThreadPool::TPHandle &handle) scrubber.state = PG::Scrubber::INACTIVE; done = true; + if (!snap_trimq.empty()) { + dout(10) << "scrub finished, requeuing snap_trimmer" << dendl; + snap_trimmer_scrub_complete(); + } + break; default: @@ -4635,11 +4683,6 @@ void PG::scrub_clear_state() requeue_ops(waiting_for_scrub); - if (scrubber.queue_snap_trim) { - dout(10) << "scrub finished, requeuing snap_trimmer" << dendl; - snap_trimmer_scrub_complete(); - } - scrubber.reset(); // type-specific state clear @@ -6266,6 +6309,37 @@ PG::RecoveryState::Backfilling::Backfilling(my_context ctx) pg->publish_stats_to_osd(); } +boost::statechart::result +PG::RecoveryState::Backfilling::react(const CancelBackfill &) +{ + PG *pg = context< RecoveryMachine >().pg; + pg->osd->local_reserver.cancel_reservation(pg->info.pgid); + // XXX: Add a new pg state so user can see why backfill isn't proceeding + // Can't use PG_STATE_BACKFILL_WAIT since it means waiting for reservations + //pg->state_set(PG_STATE_BACKFILL_STALLED????); + + for (set::iterator it = pg->backfill_targets.begin(); + it != pg->backfill_targets.end(); + ++it) { + assert(*it != pg->pg_whoami); + ConnectionRef con = pg->osd->get_con_osd_cluster( + it->osd, pg->get_osdmap()->get_epoch()); + if (con) { + pg->osd->send_message_osd_cluster( + new MBackfillReserve( + MBackfillReserve::REJECT, + spg_t(pg->info.pgid.pgid, it->shard), + pg->get_osdmap()->get_epoch()), + con.get()); + } + } + + pg->waiting_on_backfill.clear(); + + pg->schedule_backfill_full_retry(); + return transit(); +} + boost::statechart::result PG::RecoveryState::Backfilling::react(const RemoteReservationRejected &) { @@ -6736,10 +6810,10 @@ PG::RecoveryState::Recovering::Recovering(my_context ctx) pg->queue_recovery(); } -void PG::RecoveryState::Recovering::release_reservations() +void PG::RecoveryState::Recovering::release_reservations(bool cancel) { PG *pg = context< RecoveryMachine >().pg; - assert(!pg->pg_log.get_missing().have_missing()); + assert(cancel || !pg->pg_log.get_missing().have_missing()); // release remote reservations for (set::const_iterator i = @@ -6779,6 +6853,17 @@ PG::RecoveryState::Recovering::react(const RequestBackfill &evt) return transit(); } +boost::statechart::result +PG::RecoveryState::Recovering::react(const CancelRecovery &evt) +{ + PG *pg = context< RecoveryMachine >().pg; + pg->state_clear(PG_STATE_RECOVERING); + pg->osd->local_reserver.cancel_reservation(pg->info.pgid); + release_reservations(true); + pg->schedule_recovery_full_retry(); + return transit(); +} + void PG::RecoveryState::Recovering::exit() { context< RecoveryMachine >().log_exit(state_name, enter_time); @@ -6842,11 +6927,14 @@ PG::RecoveryState::Clean::Clean(my_context ctx) ceph_abort(); } pg->finish_recovery(*context< RecoveryMachine >().get_on_safe_context_list()); - pg->mark_clean(); + + if (pg->is_active()) { + pg->mark_clean(); + } pg->share_pg_info(); pg->publish_stats_to_osd(); - + pg->requeue_ops(pg->waiting_for_clean_to_primary_repair); } void PG::RecoveryState::Clean::exit() diff --git a/ceph/src/osd/PG.h b/ceph/src/osd/PG.h index e93549e9f..a033763b4 100644 --- a/ceph/src/osd/PG.h +++ b/ceph/src/osd/PG.h @@ -256,6 +256,7 @@ protected: CephContext *cct; OSDriver osdriver; SnapMapper snap_mapper; + bool eio_errors_to_process = false; virtual PGBackend *get_pgbackend() = 0; public: @@ -904,7 +905,7 @@ protected: list waiting_for_scrub; list waiting_for_cache_not_full; - list waiting_for_all_missing; + list waiting_for_clean_to_primary_repair; map> waiting_for_unreadable_object, waiting_for_degraded_object, waiting_for_blocked_object; @@ -1190,7 +1191,6 @@ public: // common to both scrubs bool active; - bool queue_snap_trim; int waiting_on; set waiting_on_whom; int shallow_errors; @@ -1292,7 +1292,6 @@ public: // clear all state void reset() { active = false; - queue_snap_trim = false; waiting_on = 0; waiting_on_whom.clear(); if (active_rep_scrub) { @@ -1348,6 +1347,7 @@ public: void scrub_finish(); void scrub_clear_state(); void _scan_snaps(ScrubMap &map); + void _repair_oinfo_oid(ScrubMap &map); void _scan_rollback_obs( const vector &rollback_obs, ThreadPool::TPHandle &handle); @@ -1559,11 +1559,13 @@ public: TrivialEvent(LocalBackfillReserved) TrivialEvent(RemoteBackfillReserved) TrivialEvent(RemoteReservationRejected) + TrivialEvent(CancelBackfill) TrivialEvent(RequestBackfill) TrivialEvent(RequestRecovery) TrivialEvent(RecoveryDone) TrivialEvent(BackfillTooFull) TrivialEvent(RecoveryTooFull) + TrivialEvent(CancelRecovery) TrivialEvent(AllReplicasRecovered) TrivialEvent(DoRecovery) @@ -1856,6 +1858,7 @@ public: struct Recovered : boost::statechart::state< Recovered, Active >, NamedState { typedef boost::mpl::list< boost::statechart::transition< GoClean, Clean >, + boost::statechart::transition< DoRecovery, WaitLocalRecoveryReserved >, boost::statechart::custom_reaction< AllReplicasActivated > > reactions; explicit Recovered(my_context ctx); @@ -1869,10 +1872,12 @@ public: struct Backfilling : boost::statechart::state< Backfilling, Active >, NamedState { typedef boost::mpl::list< boost::statechart::transition< Backfilled, Recovered >, + boost::statechart::custom_reaction< CancelBackfill >, boost::statechart::custom_reaction< RemoteReservationRejected > > reactions; explicit Backfilling(my_context ctx); boost::statechart::result react(const RemoteReservationRejected& evt); + boost::statechart::result react(const CancelBackfill& evt); void exit(); }; @@ -1983,12 +1988,14 @@ public: struct Recovering : boost::statechart::state< Recovering, Active >, NamedState { typedef boost::mpl::list < boost::statechart::custom_reaction< AllReplicasRecovered >, + boost::statechart::custom_reaction< CancelRecovery >, boost::statechart::custom_reaction< RequestBackfill > > reactions; explicit Recovering(my_context ctx); void exit(); - void release_reservations(); + void release_reservations(bool cancel = false); boost::statechart::result react(const AllReplicasRecovered &evt); + boost::statechart::result react(const CancelRecovery& evt); boost::statechart::result react(const RequestBackfill &evt); }; diff --git a/ceph/src/osd/PGBackend.h b/ceph/src/osd/PGBackend.h index b50f0d8c7..8fcc42ab3 100644 --- a/ceph/src/osd/PGBackend.h +++ b/ceph/src/osd/PGBackend.h @@ -104,6 +104,8 @@ typedef ceph::shared_ptr OSDMapRef; const hobject_t oid) = 0; virtual void failed_push(const list &from, const hobject_t &soid) = 0; + virtual void primary_failed(const hobject_t &soid) = 0; + virtual bool primary_error(const hobject_t& soid, eversion_t v) = 0; virtual void cancel_pull(const hobject_t &soid) = 0; @@ -111,6 +113,14 @@ typedef ceph::shared_ptr OSDMapRef; const hobject_t &soid, const object_stat_sum_t &delta_stats) = 0; + /** + * Called when a read on the primary fails when pushing + */ + virtual void on_primary_error( + const hobject_t &oid, + eversion_t v + ) = 0; + /** * Bless a context @@ -331,7 +341,7 @@ typedef ceph::shared_ptr OSDMapRef; * @param missing [in] set of info, missing pairs for queried nodes * @param overlaps [in] mapping of object to file offset overlaps */ - virtual void recover_object( + virtual int recover_object( const hobject_t &hoid, ///< [in] object to recover eversion_t v, ///< [in] version to recover ObjectContextRef head, ///< [in] context of the head/snapdir object diff --git a/ceph/src/osd/PGQueueable.cc b/ceph/src/osd/PGQueueable.cc new file mode 100644 index 000000000..844cdfc35 --- /dev/null +++ b/ceph/src/osd/PGQueueable.cc @@ -0,0 +1,35 @@ +// -*- 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 "PG.h" +#include "PGQueueable.h" +#include "OSD.h" + + +void PGQueueable::RunVis::operator()(const OpRequestRef &op) { + osd->dequeue_op(pg, op, handle); +} + +void PGQueueable::RunVis::operator()(const PGSnapTrim &op) { + pg->snap_trimmer(op.epoch_queued); +} + +void PGQueueable::RunVis::operator()(const PGScrub &op) { + pg->scrub(op.epoch_queued, handle); +} + +void PGQueueable::RunVis::operator()(const PGRecovery &op) { + osd->do_recovery(pg.get(), op.epoch_queued, op.reserved_pushes, handle); +} diff --git a/ceph/src/osd/PGQueueable.h b/ceph/src/osd/PGQueueable.h new file mode 100644 index 000000000..cb32e52b7 --- /dev/null +++ b/ceph/src/osd/PGQueueable.h @@ -0,0 +1,148 @@ +// -*- 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. + * + */ + + +#pragma once + +#include + +#include "include/types.h" +#include "include/utime.h" +#include "osd/OpRequest.h" +#include "osd/PG.h" + + +class OSD; + + +struct PGScrub { + epoch_t epoch_queued; + explicit PGScrub(epoch_t e) : epoch_queued(e) {} + ostream &operator<<(ostream &rhs) { + return rhs << "PGScrub"; + } +}; + +struct PGSnapTrim { + epoch_t epoch_queued; + explicit PGSnapTrim(epoch_t e) : epoch_queued(e) {} + ostream &operator<<(ostream &rhs) { + return rhs << "PGSnapTrim"; + } +}; + +struct PGRecovery { + epoch_t epoch_queued; + uint64_t reserved_pushes; + PGRecovery(epoch_t e, uint64_t reserved_pushes) + : epoch_queued(e), reserved_pushes(reserved_pushes) {} + ostream &operator<<(ostream &rhs) { + return rhs << "PGRecovery(epoch=" << epoch_queued + << ", reserved_pushes: " << reserved_pushes << ")"; + } +}; + + +class PGQueueable { + typedef boost::variant< + OpRequestRef, + PGSnapTrim, + PGScrub, + PGRecovery + > QVariant; + QVariant qvariant; + int cost; + unsigned priority; + utime_t start_time; + entity_inst_t owner; + epoch_t map_epoch; ///< an epoch we expect the PG to exist in + + struct RunVis : public boost::static_visitor<> { + OSD *osd; + PGRef &pg; + ThreadPool::TPHandle &handle; + RunVis(OSD *osd, PGRef &pg, ThreadPool::TPHandle &handle) + : osd(osd), pg(pg), handle(handle) {} + void operator()(const OpRequestRef &op); + void operator()(const PGSnapTrim &op); + void operator()(const PGScrub &op); + void operator()(const PGRecovery &op); + }; // struct RunVis + + struct StringifyVis : public boost::static_visitor { + std::string operator()(const OpRequestRef &op) { + return stringify(op); + } + std::string operator()(const PGSnapTrim &op) { + return "PGSnapTrim"; + } + std::string operator()(const PGScrub &op) { + return "PGScrub"; + } + std::string operator()(const PGRecovery &op) { + return "PGRecovery"; + } + }; + + friend ostream& operator<<(ostream& out, const PGQueueable& q) { + StringifyVis v; + return out << "PGQueueable(" << boost::apply_visitor(v, q.qvariant) + << " prio " << q.priority << " cost " << q.cost + << " e" << q.map_epoch << ")"; + } + +public: + + PGQueueable(OpRequestRef op, epoch_t e) + : qvariant(op), cost(op->get_req()->get_cost()), + priority(op->get_req()->get_priority()), + start_time(op->get_req()->get_recv_stamp()), + owner(op->get_req()->get_source_inst()), + map_epoch(e) + {} + PGQueueable( + const PGSnapTrim &op, int cost, unsigned priority, utime_t start_time, + const entity_inst_t &owner, epoch_t e) + : qvariant(op), cost(cost), priority(priority), start_time(start_time), + owner(owner), map_epoch(e) {} + PGQueueable( + const PGScrub &op, int cost, unsigned priority, utime_t start_time, + const entity_inst_t &owner, epoch_t e) + : qvariant(op), cost(cost), priority(priority), start_time(start_time), + owner(owner), map_epoch(e) {} + PGQueueable( + const PGRecovery &op, int cost, unsigned priority, utime_t start_time, + const entity_inst_t &owner, epoch_t e) + : qvariant(op), cost(cost), priority(priority), start_time(start_time), + owner(owner), map_epoch(e) {} + + const boost::optional maybe_get_op() const { + const OpRequestRef *op = boost::get(&qvariant); + return op ? OpRequestRef(*op) : boost::optional(); + } + uint64_t get_reserved_pushes() const { + const PGRecovery *op = boost::get(&qvariant); + return op ? op->reserved_pushes : 0; + } + void run(OSD *osd, PGRef &pg, ThreadPool::TPHandle &handle) { + RunVis v(osd, pg, handle); + boost::apply_visitor(v, qvariant); + } + unsigned get_priority() const { return priority; } + int get_cost() const { return cost; } + utime_t get_start_time() const { return start_time; } + entity_inst_t get_owner() const { return owner; } + epoch_t get_map_epoch() const { return map_epoch; } + const QVariant& get_variant() const { return qvariant; } +}; // struct PGQueueable diff --git a/ceph/src/osd/PrimaryLogPG.cc b/ceph/src/osd/PrimaryLogPG.cc index b50624963..33ef908f6 100644 --- a/ceph/src/osd/PrimaryLogPG.cc +++ b/ceph/src/osd/PrimaryLogPG.cc @@ -418,10 +418,6 @@ void PrimaryLogPG::on_local_recover( waiting_for_unreadable_object.erase(unreadable_object_entry); } } - if (pg_log.get_missing().get_items().size() == 0) { - requeue_ops(waiting_for_all_missing); - waiting_for_all_missing.clear(); - } } else { t->register_on_applied( new C_OSD_AppliedRecoveredObjectReplica(this)); @@ -518,6 +514,17 @@ void PrimaryLogPG::send_message_osd_cluster( osd->send_message_osd_cluster(m, con); } +void PrimaryLogPG::on_primary_error( + const hobject_t &oid, + eversion_t v) +{ + dout(0) << __func__ << ": oid " << oid << " version " << v << dendl; + primary_failed(oid); + primary_error(oid, v); + backfills_in_flight.erase(oid); + missing_loc.add_missing(oid, v, eversion_t()); +} + ConnectionRef PrimaryLogPG::get_con_osd_cluster( int peer, epoch_t from_epoch) { @@ -571,12 +578,6 @@ void PrimaryLogPG::wait_for_unreadable_object( op->mark_delayed("waiting for missing object"); } -void PrimaryLogPG::wait_for_all_missing(OpRequestRef op) -{ - waiting_for_all_missing.push_back(op); - op->mark_delayed("waiting for all missing"); -} - bool PrimaryLogPG::is_degraded_or_backfilling_object(const hobject_t& soid) { /* The conditions below may clear (on_local_recover, before we queue @@ -629,6 +630,15 @@ void PrimaryLogPG::block_write_on_full_cache( op->mark_delayed("waiting for cache not full"); } +void PrimaryLogPG::block_for_clean( + const hobject_t& oid, OpRequestRef op) +{ + dout(20) << __func__ << ": blocking object " << oid + << " on primary repair" << dendl; + waiting_for_clean_to_primary_repair.push_back(op); + op->mark_delayed("waiting for clean to repair"); +} + void PrimaryLogPG::block_write_on_snap_rollback( const hobject_t& oid, ObjectContextRef obc, OpRequestRef op) { @@ -1989,6 +1999,10 @@ void PrimaryLogPG::do_op(OpRequestRef& op) // missing object? if (is_unreadable_object(head)) { + if (!is_primary()) { + osd->reply_op_error(op, -EAGAIN); + return; + } if (can_backoff && (g_conf->osd_backoff_on_degraded || (g_conf->osd_backoff_on_unfound && missing_loc.is_unfound(head)))) { @@ -2173,7 +2187,7 @@ void PrimaryLogPG::do_op(OpRequestRef& op) fill_in_copy_get_noent(op, oid, m->ops[0]); return; } - dout(20) << __func__ << "find_object_context got error " << r << dendl; + dout(20) << __func__ << ": find_object_context got error " << r << dendl; if (op->may_write() && get_osdmap()->require_osd_release >= CEPH_RELEASE_KRAKEN) { record_write_error(op, oid, nullptr, r); @@ -3612,24 +3626,29 @@ void PrimaryLogPG::do_backfill_remove(OpRequestRef op) assert(r == 0); } -PrimaryLogPG::OpContextUPtr PrimaryLogPG::trim_object( - bool first, const hobject_t &coid) +int PrimaryLogPG::trim_object( + bool first, const hobject_t &coid, PrimaryLogPG::OpContextUPtr *ctxp) { + *ctxp = NULL; // load clone info bufferlist bl; ObjectContextRef obc = get_object_context(coid, false, NULL); - if (!obc) { - derr << __func__ << " could not find coid " << coid << dendl; - ceph_abort(); + if (!obc || !obc->ssc || !obc->ssc->exists) { + osd->clog->error() << __func__ << ": Can not trim " << coid + << " repair needed " << (obc ? "(no obc->ssc or !exists)" : "(no obc)"); + return -ENOENT; } - assert(obc->ssc); 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); - assert(snapset_obc); + if (!snapset_obc) { + osd->clog->error() << __func__ << ": Can not trim " << coid + << " repair needed, no snapset obc for " << snapoid; + return -ENOENT; + } SnapSet& snapset = obc->ssc->snapset; @@ -3645,21 +3664,21 @@ PrimaryLogPG::OpContextUPtr PrimaryLogPG::trim_object( if (p == snapset.clone_snaps.end()) { osd->clog->error() << __func__ << " No clone_snaps in snapset " << snapset << " for " << coid << "\n"; - return NULL; + return -ENOENT; } old_snaps.insert(snapset.clone_snaps[coid.snap].begin(), snapset.clone_snaps[coid.snap].end()); } if (old_snaps.empty()) { osd->clog->error() << __func__ << " No object info snaps for " << coid; - return NULL; + return -ENOENT; } dout(10) << coid << " old_snaps " << old_snaps << " old snapset " << snapset << dendl; if (snapset.seq == 0) { osd->clog->error() << __func__ << " No snapset.seq for " << coid; - return NULL; + return -ENOENT; } set new_snaps; @@ -3676,7 +3695,7 @@ PrimaryLogPG::OpContextUPtr PrimaryLogPG::trim_object( p = std::find(snapset.clones.begin(), snapset.clones.end(), coid.snap); if (p == snapset.clones.end()) { osd->clog->error() << __func__ << " Snap " << coid.snap << " not in clones"; - return NULL; + return -ENOENT; } } @@ -3689,7 +3708,7 @@ PrimaryLogPG::OpContextUPtr PrimaryLogPG::trim_object( first)) { close_op_ctx(ctx.release()); dout(10) << __func__ << ": Unable to get a wlock on " << coid << dendl; - return NULL; + return -ENOLCK; } if (!ctx->lock_manager.get_snaptrimmer_write( @@ -3698,7 +3717,7 @@ PrimaryLogPG::OpContextUPtr PrimaryLogPG::trim_object( first)) { close_op_ctx(ctx.release()); dout(10) << __func__ << ": Unable to get a wlock on " << snapoid << dendl; - return NULL; + return -ENOLCK; } ctx->at_version = get_next_version(); @@ -3885,7 +3904,8 @@ PrimaryLogPG::OpContextUPtr PrimaryLogPG::trim_object( t->setattrs(snapoid, attrs); } - return ctx; + *ctxp = std::move(ctx); + return 0; } void PrimaryLogPG::kick_snap_trim() @@ -4762,6 +4782,9 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector& ops) } else { int r = pgbackend->objects_read_sync( soid, op.extent.offset, op.extent.length, op.flags, &osd_op.outdata); + if (r == -EIO) { + r = rep_repair_primary_object(soid, ctx->op); + } if (r >= 0) op.extent.length = r; else { @@ -4894,6 +4917,9 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector& ops) bufferlist t; uint64_t len = miter->first - last; r = pgbackend->objects_read_sync(soid, last, len, op.flags, &t); + if (r == -EIO) { + r = rep_repair_primary_object(soid, ctx->op); + } if (r < 0) { osd->clog->error() << coll << " " << soid << " sparse-read failed to read: " @@ -9215,6 +9241,7 @@ void PrimaryLogPG::simple_opc_submit(OpContextUPtr ctx) dout(20) << __func__ << " " << repop << dendl; issue_repop(repop, ctx.get()); eval_repop(repop); + calc_trim_to(); repop->put(); } @@ -9581,6 +9608,7 @@ ObjectContextRef PrimaryLogPG::get_object_context( object_info_t oi(soid); SnapSetContext *ssc = get_snapset_context( soid, true, 0, false); + assert(ssc); obc = create_object_context(oi, ssc); dout(10) << __func__ << ": " << obc << " " << soid << " " << obc->rwstate @@ -9628,7 +9656,13 @@ ObjectContextRef PrimaryLogPG::get_object_context( dout(10) << __func__ << ": creating obc from disk: " << obc << dendl; } - assert(obc->ssc); + + // XXX: Caller doesn't expect this + if (obc->ssc == NULL) { + derr << __func__ << ": obc->ssc not available, not returning context" << dendl; + return ObjectContextRef(); // -ENOENT! + } + dout(10) << __func__ << ": " << obc << " " << soid << " " << obc->rwstate << " oi: " << obc->obs.oi @@ -10005,7 +10039,12 @@ SnapSetContext *PrimaryLogPG::get_snapset_context( _register_snapset_context(ssc); if (bv.length()) { bufferlist::iterator bvp = bv.begin(); - ssc->snapset.decode(bvp); + try { + ssc->snapset.decode(bvp); + } catch (buffer::error& e) { + dout(0) << __func__ << " Can't decode snapset: " << e << dendl; + return NULL; + } ssc->exists = true; } else { ssc->exists = false; @@ -10099,12 +10138,14 @@ int PrimaryLogPG::recover_missing( start_recovery_op(soid); assert(!recovering.count(soid)); recovering.insert(make_pair(soid, obc)); - pgbackend->recover_object( + int r = pgbackend->recover_object( soid, v, head_obc, obc, h); + // This is only a pull which shouldn't return an error + assert(r >= 0); return PULL_YES; } @@ -10239,6 +10280,12 @@ void PrimaryLogPG::recover_got(hobject_t oid, eversion_t v) } } +void PrimaryLogPG::primary_failed(const hobject_t &soid) +{ + list fl = { pg_whoami }; + failed_push(fl, soid); +} + void PrimaryLogPG::failed_push(const list &from, const hobject_t &soid) { dout(20) << __func__ << ": " << soid << dendl; @@ -10288,7 +10335,6 @@ eversion_t PrimaryLogPG::pick_newest_available(const hobject_t& oid) if (*i == get_primary()) continue; pg_shard_t peer = *i; if (!peer_missing[peer].is_missing(oid)) { - assert(is_backfill_targets(peer)); continue; } eversion_t h = peer_missing[peer].get_items().at(oid).have; @@ -10389,6 +10435,7 @@ void PrimaryLogPG::mark_all_unfound_lost( ceph_tid_t tid) { dout(3) << __func__ << " " << pg_log_entry_t::get_op_name(what) << dendl; + list oids; dout(30) << __func__ << ": log before:\n"; pg_log.get_log().print(*_dout); @@ -10453,6 +10500,7 @@ void PrimaryLogPG::mark_all_unfound_lost( } // otherwise, just do what we used to do dout(10) << e << dendl; log_entries.push_back(e); + oids.push_back(oid); ++v.version; ++m; @@ -10470,9 +10518,9 @@ void PrimaryLogPG::mark_all_unfound_lost( log_entries, std::move(manager), boost::optional >( - [=]() { - requeue_ops(waiting_for_all_missing); - waiting_for_all_missing.clear(); + [this, oids, con, num_unfound, tid]() { + for (auto oid: oids) + missing_loc.recovered(oid); for (auto& p : waiting_for_unreadable_object) { release_backoffs(p.first); } @@ -10614,6 +10662,11 @@ void PrimaryLogPG::on_shutdown() // handles queue races deleting = true; + if (recovery_queued) { + recovery_queued = false; + osd->clear_queued_recovery(this); + } + clear_scrub_reserved(); scrub_clear_state(); @@ -10661,6 +10714,7 @@ void PrimaryLogPG::on_activate() RequestBackfill()))); } else { dout(10) << "activate all replicas clean, no recovery" << dendl; + eio_errors_to_process = false; queue_peering_event( CephPeeringEvtRef( std::make_shared( @@ -10759,10 +10813,8 @@ void PrimaryLogPG::on_change(ObjectStore::Transaction *t) if (is_primary()) { requeue_ops(waiting_for_cache_not_full); - requeue_ops(waiting_for_all_missing); } else { waiting_for_cache_not_full.clear(); - waiting_for_all_missing.clear(); } objects_blocked_on_cache_full.clear(); @@ -11083,6 +11135,7 @@ bool PrimaryLogPG::start_recovery_ops( RequestBackfill()))); } else { dout(10) << "recovery done, no backfill" << dendl; + eio_errors_to_process = false; queue_peering_event( CephPeeringEvtRef( std::make_shared( @@ -11093,6 +11146,7 @@ bool PrimaryLogPG::start_recovery_ops( } else { // backfilling state_clear(PG_STATE_BACKFILL); dout(10) << "recovery done, backfill done" << dendl; + eio_errors_to_process = false; queue_peering_event( CephPeeringEvtRef( std::make_shared( @@ -11143,8 +11197,7 @@ uint64_t PrimaryLogPG::recover_primary(uint64_t max, ThreadPool::TPHandle &handl const pg_missing_item& item = missing.get_items().find(p->second)->second; ++p; - hobject_t head = soid; - head.snap = CEPH_NOSNAP; + hobject_t head = soid.get_head(); eversion_t need = item.need; @@ -11264,6 +11317,34 @@ uint64_t PrimaryLogPG::recover_primary(uint64_t max, ThreadPool::TPHandle &handl return started; } +bool PrimaryLogPG::primary_error( + const hobject_t& soid, eversion_t v) +{ + pg_log.missing_add(soid, v, eversion_t()); + pg_log.set_last_requested(0); + missing_loc.remove_location(soid, pg_whoami); + bool uhoh = true; + assert(!actingbackfill.empty()); + for (set::iterator i = actingbackfill.begin(); + i != actingbackfill.end(); + ++i) { + if (*i == get_primary()) continue; + pg_shard_t peer = *i; + if (!peer_missing[peer].is_missing(soid, v)) { + missing_loc.add_location(soid, peer); + dout(10) << info.pgid << " unexpectedly missing " << soid << " v" << v + << ", there should be a copy on shard " << peer << dendl; + uhoh = false; + } + } + if (uhoh) + osd->clog->error() << info.pgid << " missing primary copy of " << soid << ", unfound"; + else + osd->clog->error() << info.pgid << " missing primary copy of " << soid + << ", will try copies on " << missing_loc.get_locations(soid); + return uhoh; +} + int PrimaryLogPG::prep_object_replica_pushes( const hobject_t& soid, eversion_t v, PGBackend::RecoveryHandle *h) @@ -11274,27 +11355,7 @@ int PrimaryLogPG::prep_object_replica_pushes( // NOTE: we know we will get a valid oloc off of disk here. ObjectContextRef obc = get_object_context(soid, false); if (!obc) { - pg_log.missing_add(soid, v, eversion_t()); - missing_loc.remove_location(soid, pg_whoami); - bool uhoh = true; - assert(!actingbackfill.empty()); - for (set::iterator i = actingbackfill.begin(); - i != actingbackfill.end(); - ++i) { - if (*i == get_primary()) continue; - pg_shard_t peer = *i; - if (!peer_missing[peer].is_missing(soid, v)) { - missing_loc.add_location(soid, peer); - dout(10) << info.pgid << " unexpectedly missing " << soid << " v" << v - << ", there should be a copy on shard " << peer << dendl; - uhoh = false; - } - } - if (uhoh) - osd->clog->error() << info.pgid << " missing primary copy of " << soid << ", unfound"; - else - osd->clog->error() << info.pgid << " missing primary copy of " << soid - << ", will try copies on " << missing_loc.get_locations(soid); + primary_error(soid, v); return 0; } @@ -11317,13 +11378,19 @@ int PrimaryLogPG::prep_object_replica_pushes( * In almost all cases, therefore, this lock should be uncontended. */ obc->ondisk_read_lock(); - pgbackend->recover_object( + int r = pgbackend->recover_object( soid, v, ObjectContextRef(), obc, // has snapset context h); obc->ondisk_read_unlock(); + if (r < 0) { + dout(0) << __func__ << " Error " << r << " on oid " << soid << dendl; + primary_failed(soid); + primary_error(soid, v); + return 0; + } return 1; } @@ -11358,8 +11425,14 @@ uint64_t PrimaryLogPG::recover_replicas(uint64_t max, ThreadPool::TPHandle &hand handle.reset_tp_timeout(); const hobject_t soid(p->second); + if (missing_loc.is_unfound(soid)) { + dout(10) << __func__ << ": " << soid << " still unfound" << dendl; + continue; + } + if (soid > pi->second.last_backfill) { if (!recovering.count(soid)) { + derr << __func__ << ": object " << soid << " last_backfill " << pi->second.last_backfill << dendl; derr << __func__ << ": object added to missing set for backfill, but " << "is not in recovering, error!" << dendl; ceph_abort(); @@ -11372,11 +11445,6 @@ uint64_t PrimaryLogPG::recover_replicas(uint64_t max, ThreadPool::TPHandle &hand continue; } - if (missing_loc.is_unfound(soid)) { - dout(10) << __func__ << ": " << soid << " still unfound" << dendl; - continue; - } - if (soid.is_snap() && pg_log.get_missing().is_missing(soid.get_head())) { dout(10) << __func__ << ": " << soid.get_head() << " still missing on primary" << dendl; @@ -11514,8 +11582,6 @@ uint64_t PrimaryLogPG::recover_backfill( update_range(&backfill_info, handle); unsigned ops = 0; - vector > > to_push; vector > to_remove; set add_to_stat; @@ -11527,6 +11593,7 @@ uint64_t PrimaryLogPG::recover_backfill( } backfill_info.trim_to(last_backfill_started); + PGBackend::RecoveryHandle *h = pgbackend->open_recovery_op(); while (ops < max) { if (backfill_info.begin <= earliest_peer_backfill() && !backfill_info.extends_to_end() && backfill_info.empty()) { @@ -11706,10 +11773,13 @@ uint64_t PrimaryLogPG::recover_backfill( vector all_push = need_ver_targs; all_push.insert(all_push.end(), missing_targs.begin(), missing_targs.end()); - to_push.push_back( - boost::tuple > - (backfill_info.begin, obj_v, obc, all_push)); - // Count all simultaneous pushes of the same object as a single op + handle.reset_tp_timeout(); + int r = prep_backfill_object_push(backfill_info.begin, obj_v, obc, all_push, h); + if (r < 0) { + *work_started = true; + dout(0) << __func__ << " Error " << r << " trying to backfill " << backfill_info.begin << dendl; + break; + } ops++; } else { *work_started = true; @@ -11790,12 +11860,6 @@ uint64_t PrimaryLogPG::recover_backfill( } } - PGBackend::RecoveryHandle *h = pgbackend->open_recovery_op(); - for (unsigned i = 0; i < to_push.size(); ++i) { - handle.reset_tp_timeout(); - prep_backfill_object_push(to_push[i].get<0>(), to_push[i].get<1>(), - to_push[i].get<2>(), to_push[i].get<3>(), h); - } pgbackend->run_recovery_op(h, get_recovery_op_priority()); dout(5) << "backfill_pos is " << backfill_pos << dendl; @@ -11886,13 +11950,13 @@ uint64_t PrimaryLogPG::recover_backfill( return ops; } -void PrimaryLogPG::prep_backfill_object_push( +int PrimaryLogPG::prep_backfill_object_push( hobject_t oid, eversion_t v, ObjectContextRef obc, vector peers, PGBackend::RecoveryHandle *h) { - dout(10) << "push_backfill_object " << oid << " v " << v << " to peers " << peers << dendl; + dout(10) << __func__ << " " << oid << " v " << v << " to peers " << peers << dendl; assert(!peers.empty()); backfills_in_flight.insert(oid); @@ -11909,13 +11973,21 @@ void PrimaryLogPG::prep_backfill_object_push( // We need to take the read_lock here in order to flush in-progress writes obc->ondisk_read_lock(); - pgbackend->recover_object( + int r = pgbackend->recover_object( oid, v, ObjectContextRef(), obc, h); obc->ondisk_read_unlock(); + if (r < 0) { + dout(0) << __func__ << " Error " << r << " on oid " << oid << dendl; + primary_failed(oid); + primary_error(oid, v); + backfills_in_flight.erase(oid); + missing_loc.add_missing(oid, v, eversion_t()); + } + return r; } void PrimaryLogPG::update_range( @@ -13828,6 +13900,9 @@ void PrimaryLogPG::_scrub_finish() publish_stats_to_osd(); share_pg_info(); } + // Clear object context cache to get repair information + if (repair) + object_contexts.clear(); } bool PrimaryLogPG::check_osdmap_full(const set &missing_on) @@ -13835,6 +13910,73 @@ bool PrimaryLogPG::check_osdmap_full(const set &missing_on) return osd->check_osdmap_full(missing_on); } +int PrimaryLogPG::rep_repair_primary_object(const hobject_t& soid, OpRequestRef op) +{ + // Only supports replicated pools + assert(!pool.info.require_rollback()); + assert(is_primary()); + + dout(10) << __func__ << " " << soid + << " peers osd.{" << actingbackfill << "}" << dendl; + + if (!is_clean()) { + block_for_clean(soid, op); + return -EAGAIN; + } + + assert(!pg_log.get_missing().is_missing(soid)); + bufferlist bv; + object_info_t oi; + eversion_t v; + int r = get_pgbackend()->objects_get_attr(soid, OI_ATTR, &bv); + if (r < 0) { + // Leave v and try to repair without a version, getting attr failed + dout(0) << __func__ << ": Need version of replica, objects_get_attr failed: " + << soid << " error=" << r << dendl; + } else try { + bufferlist::iterator bliter = bv.begin(); + ::decode(oi, bliter); + v = oi.version; + } catch (...) { + // Leave v as default constructed. This will fail when sent to older OSDs, but + // not much worse than failing here. + dout(0) << __func__ << ": Need version of replica, bad object_info_t: " << soid << dendl; + } + + missing_loc.add_missing(soid, v, eversion_t()); + if (primary_error(soid, v)) { + dout(0) << __func__ << " No other replicas available for " << soid << dendl; + // XXX: If we knew that there is no down osd which could include this + // object, it would be nice if we could return EIO here. + // If a "never fail" flag was available, that could be used + // for rbd to NOT return EIO until object marked lost. + + // Drop through to save this op in case an osd comes up with the object. + } + + // Restart the op after object becomes readable again + waiting_for_unreadable_object[soid].push_back(op); + op->mark_delayed("waiting for missing object"); + + if (!eio_errors_to_process) { + eio_errors_to_process = true; + assert(is_clean()); + queue_peering_event( + CephPeeringEvtRef( + std::make_shared( + get_osdmap()->get_epoch(), + get_osdmap()->get_epoch(), + DoRecovery()))); + } else { + // A prior error must have already cleared clean state and queued recovery + // or a map change has triggered re-peering. + // Not inlining the recovery by calling maybe_kick_recovery(soid); + dout(5) << __func__<< ": Read error on " << soid << ", but already seen errors" << dendl; + } + + return -EAGAIN; +} + /*---SnapTrimmer Logging---*/ #undef dout_prefix #define dout_prefix *_dout << pg->gen_prefix() @@ -13883,7 +14025,6 @@ boost::statechart::result PrimaryLogPG::NotTrimming::react(const KickTrim&) } if (pg->scrubber.active) { ldout(pg->cct, 10) << " scrubbing, will requeue snap_trimmer after" << dendl; - pg->scrubber.queue_snap_trim = true; return transit< WaitScrub >(); } else { return transit< Trimming >(); @@ -13917,6 +14058,7 @@ PrimaryLogPG::AwaitAsyncWork::AwaitAsyncWork(my_context ctx) context< SnapTrimmer >().log_enter(state_name); context< SnapTrimmer >().pg->osd->queue_for_snap_trim(pg); pg->state_set(PG_STATE_SNAPTRIM); + pg->state_clear(PG_STATE_SNAPTRIM_ERROR); pg->publish_stats_to_osd(); } @@ -13975,18 +14117,26 @@ boost::statechart::result PrimaryLogPG::AwaitAsyncWork::react(const DoSnapWork&) for (auto &&object: to_trim) { // Get next ldout(pg->cct, 10) << "AwaitAsyncWork react trimming " << object << dendl; - OpContextUPtr ctx = pg->trim_object(in_flight.empty(), object); - if (!ctx) { - ldout(pg->cct, 10) << "could not get write lock on obj " - << object << dendl; - if (in_flight.empty()) { + OpContextUPtr ctx; + int error = pg->trim_object(in_flight.empty(), object, &ctx); + if (error) { + if (error == -ENOLCK) { + ldout(pg->cct, 10) << "could not get write lock on obj " + << object << dendl; + } else { + pg->state_set(PG_STATE_SNAPTRIM_ERROR); + ldout(pg->cct, 10) << "Snaptrim error=" << error << dendl; + } + if (!in_flight.empty()) { + ldout(pg->cct, 10) << "letting the ones we already started finish" << dendl; + return transit< WaitRepops >(); + } + if (error == -ENOLCK) { ldout(pg->cct, 10) << "waiting for it to clear" << dendl; return transit< WaitRWLock >(); - } else { - ldout(pg->cct, 10) << "letting the ones we already started finish" << dendl; - return transit< WaitRepops >(); + return transit< NotTrimming >(); } } @@ -13995,8 +14145,13 @@ boost::statechart::result PrimaryLogPG::AwaitAsyncWork::react(const DoSnapWork&) [pg, object, &in_flight]() { assert(in_flight.find(object) != in_flight.end()); in_flight.erase(object); - if (in_flight.empty()) - pg->snap_trimmer_machine.process_event(RepopsComplete()); + if (in_flight.empty()) { + if (pg->state_test(PG_STATE_SNAPTRIM_ERROR)) { + pg->snap_trimmer_machine.process_event(Reset()); + } else { + pg->snap_trimmer_machine.process_event(RepopsComplete()); + } + } }); pg->simple_opc_submit(std::move(ctx)); diff --git a/ceph/src/osd/PrimaryLogPG.h b/ceph/src/osd/PrimaryLogPG.h index f6c1b97d8..a8f7db5df 100644 --- a/ceph/src/osd/PrimaryLogPG.h +++ b/ceph/src/osd/PrimaryLogPG.h @@ -263,10 +263,13 @@ public: const hobject_t &oid, const object_stat_sum_t &stat_diff) override; void failed_push(const list &from, const hobject_t &soid) override; + void primary_failed(const hobject_t &soid) override; + bool primary_error(const hobject_t& soid, eversion_t v) override; void cancel_pull(const hobject_t &soid) override; void apply_stats( const hobject_t &soid, const object_stat_sum_t &delta_stats) override; + void on_primary_error(const hobject_t &oid, eversion_t v) override; template class BlessedGenContext; class BlessedContext; @@ -1221,7 +1224,7 @@ protected: ThreadPool::TPHandle &handle ///< [in] tp handle ); - void prep_backfill_object_push( + int prep_backfill_object_push( hobject_t oid, eversion_t v, ObjectContextRef obc, vector peers, PGBackend::RecoveryHandle *h); @@ -1386,7 +1389,7 @@ public: void handle_backoff(OpRequestRef& op); - OpContextUPtr trim_object(bool first, const hobject_t &coid); + int trim_object(bool first, const hobject_t &coid, OpContextUPtr *ctxp); void snap_trimmer(epoch_t e) override; void kick_snap_trim() override; void snap_trimmer_scrub_complete() override; @@ -1672,6 +1675,7 @@ private: pending = nullptr; auto *pg = context< SnapTrimmer >().pg; pg->state_clear(PG_STATE_SNAPTRIM_WAIT); + pg->state_clear(PG_STATE_SNAPTRIM_ERROR); pg->publish_stats_to_osd(); } }; @@ -1731,6 +1735,8 @@ public: void block_write_on_full_cache( const hobject_t& oid, OpRequestRef op); + void block_for_clean( + const hobject_t& oid, OpRequestRef op); void block_write_on_snap_rollback( const hobject_t& oid, ObjectContextRef obc, OpRequestRef op); void block_write_on_degraded_snap(const hobject_t& oid, OpRequestRef op); @@ -1763,6 +1769,7 @@ public: void on_shutdown() override; bool check_failsafe_full(ostream &ss) override; bool check_osdmap_full(const set &missing_on) override; + int rep_repair_primary_object(const hobject_t& soid, OpRequestRef op); // attr cache handling void setattr_maybe_cache( diff --git a/ceph/src/osd/ReplicatedBackend.cc b/ceph/src/osd/ReplicatedBackend.cc index 07c0d316c..7739602ae 100644 --- a/ceph/src/osd/ReplicatedBackend.cc +++ b/ceph/src/osd/ReplicatedBackend.cc @@ -127,7 +127,7 @@ void ReplicatedBackend::run_recovery_op( delete h; } -void ReplicatedBackend::recover_object( +int ReplicatedBackend::recover_object( const hobject_t &hoid, eversion_t v, ObjectContextRef head, @@ -145,15 +145,18 @@ void ReplicatedBackend::recover_object( hoid, head, h); - return; } else { assert(obc); int started = start_pushes( hoid, obc, h); - assert(started > 0); + if (started < 0) { + pushing[hoid].clear(); + return started; + } } + return 0; } void ReplicatedBackend::check_recovery_sources(const OSDMapRef& osdmap) @@ -722,7 +725,7 @@ void ReplicatedBackend::be_deep_scrub( poid, ghobject_t::NO_GEN, get_parent()->whoami_shard().shard), pos, cct->_conf->osd_deep_scrub_stride, bl, - fadvise_flags, true); + fadvise_flags); if (r <= 0) break; @@ -770,14 +773,9 @@ void ReplicatedBackend::be_deep_scrub( ghobject_t( poid, ghobject_t::NO_GEN, get_parent()->whoami_shard().shard)); assert(iter); - uint64_t keys_scanned = 0; for (iter->seek_to_first(); iter->status() == 0 && iter->valid(); iter->next(false)) { - if (cct->_conf->osd_scan_list_ping_tp_interval && - (keys_scanned % cct->_conf->osd_scan_list_ping_tp_interval == 0)) { - handle.reset_tp_timeout(); - } - ++keys_scanned; + handle.reset_tp_timeout(); dout(25) << "CRC key " << iter->key() << " value:\n"; iter->value().hexdump(*_dout); @@ -855,7 +853,12 @@ struct C_ReplicatedBackend_OnPullComplete : GenContext { assert(j != bc->pulling.end()); ObjectContextRef obc = j->second.obc; bc->clear_pull(j, false /* already did it */); - if (!bc->start_pushes(i.hoid, obc, h)) { + int started = bc->start_pushes(i.hoid, obc, h); + if (started < 0) { + bc->pushing[i.hoid].clear(); + bc->get_parent()->primary_failed(i.hoid); + bc->get_parent()->primary_error(i.hoid, obc->obs.oi.version); + } else if (!started) { bc->get_parent()->on_global_recover( i.hoid, i.stat); } @@ -1474,7 +1477,7 @@ void ReplicatedBackend::prepare_pull( * intelligently push an object to a replica. make use of existing * clones/heads and dup data ranges where possible. */ -void ReplicatedBackend::prep_push_to_replica( +int ReplicatedBackend::prep_push_to_replica( ObjectContextRef obc, const hobject_t& soid, pg_shard_t peer, PushOp *pop, bool cache_dont_need) { @@ -1537,7 +1540,7 @@ void ReplicatedBackend::prep_push_to_replica( lock_manager); } - prep_push( + return prep_push( obc, soid, peer, @@ -1549,7 +1552,7 @@ void ReplicatedBackend::prep_push_to_replica( std::move(lock_manager)); } -void ReplicatedBackend::prep_push(ObjectContextRef obc, +int ReplicatedBackend::prep_push(ObjectContextRef obc, const hobject_t& soid, pg_shard_t peer, PushOp *pop, bool cache_dont_need) { @@ -1558,12 +1561,12 @@ void ReplicatedBackend::prep_push(ObjectContextRef obc, data_subset.insert(0, obc->obs.oi.size); map> clone_subsets; - prep_push(obc, soid, peer, + return prep_push(obc, soid, peer, obc->obs.oi.version, data_subset, clone_subsets, pop, cache_dont_need, ObcLockManager()); } -void ReplicatedBackend::prep_push( +int ReplicatedBackend::prep_push( ObjectContextRef obc, const hobject_t& soid, pg_shard_t peer, eversion_t version, @@ -1592,8 +1595,10 @@ void ReplicatedBackend::prep_push( &new_progress, pop, &(pi.stat), cache_dont_need); - assert(r == 0); + if (r < 0) + return r; pi.recovery_progress = new_progress; + return 0; } void ReplicatedBackend::submit_push_data( @@ -1723,7 +1728,7 @@ bool ReplicatedBackend::handle_pull_response( << dendl; if (pop.version == eversion_t()) { // replica doesn't have it! - _failed_push(from, pop.soid); + _failed_pull(from, pop.soid); return false; } @@ -1742,6 +1747,10 @@ bool ReplicatedBackend::handle_pull_response( pi.recovery_info.copy_subset.intersection_of( pop.recovery_info.copy_subset); } + // If primary doesn't have object info and didn't know version + if (pi.recovery_info.version == eversion_t()) { + pi.recovery_info.version = pop.version; + } bool first = pi.recovery_progress.first; if (first) { @@ -1917,12 +1926,13 @@ int ReplicatedBackend::build_push_op(const ObjectRecoveryInfo &recovery_info, ObjectRecoveryProgress &new_progress = *out_progress; new_progress = progress; - dout(7) << "send_push_op " << recovery_info.soid + dout(7) << __func__ << " " << recovery_info.soid << " v " << recovery_info.version << " size " << recovery_info.size << " recovery_info: " << recovery_info << dendl; + eversion_t v = recovery_info.version; if (progress.first) { int r = store->omap_get_header(coll, ghobject_t(recovery_info.soid), &out_op->omap_header); if(r < 0) { @@ -1937,9 +1947,19 @@ int ReplicatedBackend::build_push_op(const ObjectRecoveryInfo &recovery_info, // Debug bufferlist bv = out_op->attrset[OI_ATTR]; - object_info_t oi(bv); + object_info_t oi; + try { + bufferlist::iterator bliter = bv.begin(); + ::decode(oi, bliter); + } catch (...) { + dout(0) << __func__ << ": bad object_info_t: " << recovery_info.soid << dendl; + return -EINVAL; + } - if (oi.version != recovery_info.version) { + // If requestor didn't know the version, use ours + if (v == eversion_t()) { + v = oi.version; + } else if (oi.version != v) { get_parent()->clog_error() << get_info().pgid << " push " << recovery_info.soid << " v " << recovery_info.version @@ -1950,6 +1970,9 @@ int ReplicatedBackend::build_push_op(const ObjectRecoveryInfo &recovery_info, new_progress.first = false; } + // Once we provide the version subsequent requests will have it, so + // at this point it must be known. + assert(v != eversion_t()); uint64_t available = cct->_conf->osd_recovery_max_chunk; if (!progress.omap_complete) { @@ -2007,9 +2030,17 @@ int ReplicatedBackend::build_push_op(const ObjectRecoveryInfo &recovery_info, p != out_op->data_included.end(); ++p) { bufferlist bit; - store->read(ch, ghobject_t(recovery_info.soid), + int r = store->read(ch, ghobject_t(recovery_info.soid), p.get_start(), p.get_len(), bit, cache_dont_need ? CEPH_OSD_OP_FLAG_FADVISE_DONTNEED: 0); + if (cct->_conf->osd_debug_random_push_read_error && + (rand() % (int)(cct->_conf->osd_debug_random_push_read_error * 100.0)) == 0) { + dout(0) << __func__ << ": inject EIO " << recovery_info.soid << dendl; + r = -EIO; + } + if (r < 0) { + return r; + } if (p.get_len() != bit.length()) { dout(10) << " extent " << p.get_start() << "~" << p.get_len() << " is actually " << p.get_start() << "~" << bit.length() @@ -2046,7 +2077,7 @@ int ReplicatedBackend::build_push_op(const ObjectRecoveryInfo &recovery_info, get_parent()->get_logger()->inc(l_osd_push_outb, out_op->data.length()); // send - out_op->version = recovery_info.version; + out_op->version = v; out_op->soid = recovery_info.soid; out_op->recovery_info = recovery_info; out_op->after_progress = new_progress; @@ -2076,8 +2107,9 @@ bool ReplicatedBackend::handle_push_reply( return false; } else { PushInfo *pi = &pushing[soid][peer]; + bool error = pushing[soid].begin()->second.recovery_progress.error; - if (!pi->recovery_progress.data_complete) { + if (!pi->recovery_progress.data_complete && !error) { dout(10) << " pushing more from, " << pi->recovery_progress.data_recovered_to << " of " << pi->recovery_info.copy_subset << dendl; @@ -2086,23 +2118,40 @@ bool ReplicatedBackend::handle_push_reply( pi->recovery_info, pi->recovery_progress, &new_progress, reply, &(pi->stat)); - assert(r == 0); + // Handle the case of a read error right after we wrote, which is + // hopefuilly extremely rare. + if (r < 0) { + dout(5) << __func__ << ": oid " << soid << " error " << r << dendl; + + error = true; + goto done; + } pi->recovery_progress = new_progress; return true; } else { // done! - get_parent()->on_peer_recover( - peer, soid, pi->recovery_info); +done: + if (!error) + get_parent()->on_peer_recover( peer, soid, pi->recovery_info); get_parent()->release_locks(pi->lock_manager); object_stat_sum_t stat = pi->stat; + eversion_t v = pi->recovery_info.version; pushing[soid].erase(peer); pi = NULL; if (pushing[soid].empty()) { - get_parent()->on_global_recover(soid, stat); + if (!error) + get_parent()->on_global_recover(soid, stat); + else + get_parent()->on_primary_error(soid, v); + pushing.erase(soid); } else { + // This looks weird, but we erased the current peer and need to remember + // the error on any other one, while getting more acks. + if (error) + pushing[soid].begin()->second.recovery_progress.error = true; dout(10) << "pushed " << soid << ", still waiting for push ack from " << pushing[soid].size() << " others" << dendl; } @@ -2183,8 +2232,9 @@ void ReplicatedBackend::trim_pushed_data( } } -void ReplicatedBackend::_failed_push(pg_shard_t from, const hobject_t &soid) +void ReplicatedBackend::_failed_pull(pg_shard_t from, const hobject_t &soid) { + dout(20) << __func__ << ": " << soid << " from " << from << dendl; list fl = { from }; get_parent()->failed_push(fl, soid); @@ -2216,7 +2266,9 @@ int ReplicatedBackend::start_pushes( ObjectContextRef obc, RPGHandle *h) { - int pushes = 0; + list< map::const_iterator > shards; + + dout(20) << __func__ << " soid " << soid << dendl; // who needs it? assert(get_parent()->get_actingbackfill_shards().size() > 0); for (set::iterator i = @@ -2229,11 +2281,28 @@ int ReplicatedBackend::start_pushes( get_parent()->get_shard_missing().find(peer); assert(j != get_parent()->get_shard_missing().end()); if (j->second.is_missing(soid)) { - ++pushes; - h->pushes[peer].push_back(PushOp()); - prep_push_to_replica(obc, soid, peer, - &(h->pushes[peer].back()), h->cache_dont_need); + shards.push_back(j); + } + } + + // If more than 1 read will occur ignore possible request to not cache + bool cache = shards.size() == 1 ? h->cache_dont_need : false; + + for (auto j : shards) { + pg_shard_t peer = j->first; + h->pushes[peer].push_back(PushOp()); + int r = prep_push_to_replica(obc, soid, peer, + &(h->pushes[peer].back()), cache); + if (r < 0) { + // Back out all failed reads + for (auto k : shards) { + pg_shard_t p = k->first; + dout(10) << __func__ << " clean up peer " << p << dendl; + h->pushes[p].pop_back(); + if (p == peer) break; + } + return r; } } - return pushes; + return shards.size(); } diff --git a/ceph/src/osd/ReplicatedBackend.h b/ceph/src/osd/ReplicatedBackend.h index 55966325f..c2a9282be 100644 --- a/ceph/src/osd/ReplicatedBackend.h +++ b/ceph/src/osd/ReplicatedBackend.h @@ -48,7 +48,7 @@ public: int priority) override; /// @see PGBackend::recover_object - void recover_object( + int recover_object( const hobject_t &hoid, eversion_t v, ObjectContextRef head, @@ -255,7 +255,7 @@ private: bufferlist data_received, interval_set *intervals_usable, bufferlist *data_usable); - void _failed_push(pg_shard_t from, const hobject_t &soid); + void _failed_pull(pg_shard_t from, const hobject_t &soid); void send_pushes(int prio, map > &pushes); void prep_push_op_blank(const hobject_t& soid, PushOp *op); @@ -297,15 +297,15 @@ private: const hobject_t &soid, ObjectContextRef obj, RPGHandle *h); - void prep_push_to_replica( + int prep_push_to_replica( ObjectContextRef obc, const hobject_t& soid, pg_shard_t peer, PushOp *pop, bool cache_dont_need = true); - void prep_push( + int prep_push( ObjectContextRef obc, const hobject_t& oid, pg_shard_t dest, PushOp *op, bool cache_dont_need); - void prep_push( + int prep_push( ObjectContextRef obc, const hobject_t& soid, pg_shard_t peer, eversion_t version, diff --git a/ceph/src/osd/mClockClientQueue.cc b/ceph/src/osd/mClockClientQueue.cc new file mode 100644 index 000000000..71a6631f2 --- /dev/null +++ b/ceph/src/osd/mClockClientQueue.cc @@ -0,0 +1,165 @@ +// -*- 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 + +#include "osd/mClockClientQueue.h" +#include "common/dout.h" + + +namespace dmc = crimson::dmclock; + + +#define dout_context cct +#define dout_subsys ceph_subsys_osd +#undef dout_prefix +#define dout_prefix *_dout + + +namespace ceph { + + mClockClientQueue::mclock_op_tags_t::mclock_op_tags_t(CephContext *cct) : + client_op(cct->_conf->osd_op_queue_mclock_client_op_res, + cct->_conf->osd_op_queue_mclock_client_op_wgt, + cct->_conf->osd_op_queue_mclock_client_op_lim), + osd_subop(cct->_conf->osd_op_queue_mclock_osd_subop_res, + cct->_conf->osd_op_queue_mclock_osd_subop_wgt, + cct->_conf->osd_op_queue_mclock_osd_subop_lim), + snaptrim(cct->_conf->osd_op_queue_mclock_snap_res, + cct->_conf->osd_op_queue_mclock_snap_wgt, + cct->_conf->osd_op_queue_mclock_snap_lim), + recov(cct->_conf->osd_op_queue_mclock_recov_res, + cct->_conf->osd_op_queue_mclock_recov_wgt, + cct->_conf->osd_op_queue_mclock_recov_lim), + scrub(cct->_conf->osd_op_queue_mclock_scrub_res, + cct->_conf->osd_op_queue_mclock_scrub_wgt, + cct->_conf->osd_op_queue_mclock_scrub_lim) + { + dout(20) << + "mClockClientQueue settings:: " << + "client_op:" << client_op << + "; osd_subop:" << osd_subop << + "; snaptrim:" << snaptrim << + "; recov:" << recov << + "; scrub:" << scrub << + dendl; + } + + + dmc::ClientInfo + mClockClientQueue::op_class_client_info_f( + const mClockClientQueue::InnerClient& client) + { + switch(client.second) { + case osd_op_type_t::client_op: + return mclock_op_tags->client_op; + case osd_op_type_t::osd_subop: + return mclock_op_tags->osd_subop; + case osd_op_type_t::bg_snaptrim: + return mclock_op_tags->snaptrim; + case osd_op_type_t::bg_recovery: + return mclock_op_tags->recov; + case osd_op_type_t::bg_scrub: + return mclock_op_tags->scrub; + default: + assert(0); + return dmc::ClientInfo(-1, -1, -1); + } + } + + + /* + * class mClockClientQueue + */ + + std::unique_ptr + mClockClientQueue::mclock_op_tags(nullptr); + + mClockClientQueue::pg_queueable_visitor_t + mClockClientQueue::pg_queueable_visitor; + + mClockClientQueue::mClockClientQueue(CephContext *cct) : + queue(&mClockClientQueue::op_class_client_info_f) + { + // manage the singleton + if (!mclock_op_tags) { + mclock_op_tags.reset(new mclock_op_tags_t(cct)); + } + } + + mClockClientQueue::osd_op_type_t + mClockClientQueue::get_osd_op_type(const Request& request) { + osd_op_type_t type = + boost::apply_visitor(pg_queueable_visitor, request.second.get_variant()); + + // if we got client_op back then we need to distinguish between + // a client op and an osd subop. + + if (osd_op_type_t::client_op != type) { + return type; + } else if (MSG_OSD_SUBOP == + boost::get( + request.second.get_variant())->get_req()->get_header().type) { + return osd_op_type_t::osd_subop; + } else { + return osd_op_type_t::client_op; + } + } + + mClockClientQueue::InnerClient + inline mClockClientQueue::get_inner_client(const Client& cl, + const Request& request) { + return InnerClient(cl, get_osd_op_type(request)); + } + + // Formatted output of the queue + inline void mClockClientQueue::dump(ceph::Formatter *f) const { + queue.dump(f); + } + + inline void mClockClientQueue::enqueue_strict(Client cl, + unsigned priority, + Request item) { + queue.enqueue_strict(get_inner_client(cl, item), priority, item); + } + + // Enqueue op in the front of the strict queue + inline void mClockClientQueue::enqueue_strict_front(Client cl, + unsigned priority, + Request item) { + queue.enqueue_strict_front(get_inner_client(cl, item), priority, item); + } + + // Enqueue op in the back of the regular queue + inline void mClockClientQueue::enqueue(Client cl, + unsigned priority, + unsigned cost, + Request item) { + queue.enqueue(get_inner_client(cl, item), priority, cost, item); + } + + // Enqueue the op in the front of the regular queue + inline void mClockClientQueue::enqueue_front(Client cl, + unsigned priority, + unsigned cost, + Request item) { + queue.enqueue_front(get_inner_client(cl, item), priority, cost, item); + } + + // Return an op to be dispatched + inline Request mClockClientQueue::dequeue() { + return queue.dequeue(); + } +} // namespace ceph diff --git a/ceph/src/osd/mClockClientQueue.h b/ceph/src/osd/mClockClientQueue.h new file mode 100644 index 000000000..49b58c832 --- /dev/null +++ b/ceph/src/osd/mClockClientQueue.h @@ -0,0 +1,146 @@ +// -*- 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. + * + */ + + +#pragma once + +#include + +#include "boost/variant.hpp" + +#include "common/config.h" +#include "common/ceph_context.h" +#include "osd/PGQueueable.h" + +#include "common/mClockPriorityQueue.h" + + +namespace ceph { + + using Request = std::pair; + using Client = entity_inst_t; + + + // This class exists to bridge the ceph code, which treats the class + // as the client, and the queue, where the class is + // osd_op_type_t. So this adpater class will transform calls + // appropriately. + class mClockClientQueue : public OpQueue { + + enum class osd_op_type_t { + client_op, osd_subop, bg_snaptrim, bg_recovery, bg_scrub }; + + using InnerClient = std::pair; + + using queue_t = mClockQueue; + + queue_t queue; + + struct mclock_op_tags_t { + crimson::dmclock::ClientInfo client_op; + crimson::dmclock::ClientInfo osd_subop; + crimson::dmclock::ClientInfo snaptrim; + crimson::dmclock::ClientInfo recov; + crimson::dmclock::ClientInfo scrub; + + mclock_op_tags_t(CephContext *cct); + }; + + static std::unique_ptr mclock_op_tags; + + public: + + mClockClientQueue(CephContext *cct); + + static crimson::dmclock::ClientInfo + op_class_client_info_f(const InnerClient& client); + + inline unsigned length() const override final { + return queue.length(); + } + + // Ops of this priority should be deleted immediately + inline void remove_by_class(Client cl, + std::list *out) override final { + queue.remove_by_filter( + [&cl, out] (const Request& r) -> bool { + if (cl == r.second.get_owner()) { + out->push_front(r); + return true; + } else { + return false; + } + }); + } + + void enqueue_strict(Client cl, + unsigned priority, + Request item) override final; + + // Enqueue op in the front of the strict queue + void enqueue_strict_front(Client cl, + unsigned priority, + Request item) override final; + + // Enqueue op in the back of the regular queue + void enqueue(Client cl, + unsigned priority, + unsigned cost, + Request item) override final; + + // Enqueue the op in the front of the regular queue + void enqueue_front(Client cl, + unsigned priority, + unsigned cost, + Request item) override final; + + // Return an op to be dispatch + Request dequeue() override final; + + // Returns if the queue is empty + inline bool empty() const override final { + return queue.empty(); + } + + // Formatted output of the queue + void dump(ceph::Formatter *f) const override final; + + protected: + + struct pg_queueable_visitor_t : public boost::static_visitor { + osd_op_type_t operator()(const OpRequestRef& o) const { + // don't know if it's a client_op or a + return osd_op_type_t::client_op; + } + + osd_op_type_t operator()(const PGSnapTrim& o) const { + return osd_op_type_t::bg_snaptrim; + } + + osd_op_type_t operator()(const PGScrub& o) const { + return osd_op_type_t::bg_scrub; + } + + osd_op_type_t operator()(const PGRecovery& o) const { + return osd_op_type_t::bg_recovery; + } + }; // class pg_queueable_visitor_t + + static pg_queueable_visitor_t pg_queueable_visitor; + + osd_op_type_t get_osd_op_type(const Request& request); + InnerClient get_inner_client(const Client& cl, const Request& request); + }; // class mClockClientAdapter + +} // namespace ceph diff --git a/ceph/src/osd/mClockOpClassQueue.cc b/ceph/src/osd/mClockOpClassQueue.cc new file mode 100644 index 000000000..848d8d699 --- /dev/null +++ b/ceph/src/osd/mClockOpClassQueue.cc @@ -0,0 +1,123 @@ +// -*- 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 + +#include "osd/mClockOpClassQueue.h" +#include "common/dout.h" + + +namespace dmc = crimson::dmclock; + + +#define dout_context cct +#define dout_subsys ceph_subsys_osd +#undef dout_prefix +#define dout_prefix *_dout + + +namespace ceph { + + mClockOpClassQueue::mclock_op_tags_t::mclock_op_tags_t(CephContext *cct) : + client_op(cct->_conf->osd_op_queue_mclock_client_op_res, + cct->_conf->osd_op_queue_mclock_client_op_wgt, + cct->_conf->osd_op_queue_mclock_client_op_lim), + osd_subop(cct->_conf->osd_op_queue_mclock_osd_subop_res, + cct->_conf->osd_op_queue_mclock_osd_subop_wgt, + cct->_conf->osd_op_queue_mclock_osd_subop_lim), + snaptrim(cct->_conf->osd_op_queue_mclock_snap_res, + cct->_conf->osd_op_queue_mclock_snap_wgt, + cct->_conf->osd_op_queue_mclock_snap_lim), + recov(cct->_conf->osd_op_queue_mclock_recov_res, + cct->_conf->osd_op_queue_mclock_recov_wgt, + cct->_conf->osd_op_queue_mclock_recov_lim), + scrub(cct->_conf->osd_op_queue_mclock_scrub_res, + cct->_conf->osd_op_queue_mclock_scrub_wgt, + cct->_conf->osd_op_queue_mclock_scrub_lim) + { + dout(20) << + "mClockOpClassQueue settings:: " << + "client_op:" << client_op << + "; osd_subop:" << osd_subop << + "; snaptrim:" << snaptrim << + "; recov:" << recov << + "; scrub:" << scrub << + dendl; + } + + + dmc::ClientInfo + mClockOpClassQueue::op_class_client_info_f(const osd_op_type_t& op_type) { + switch(op_type) { + case osd_op_type_t::client_op: + return mclock_op_tags->client_op; + case osd_op_type_t::osd_subop: + return mclock_op_tags->osd_subop; + case osd_op_type_t::bg_snaptrim: + return mclock_op_tags->snaptrim; + case osd_op_type_t::bg_recovery: + return mclock_op_tags->recov; + case osd_op_type_t::bg_scrub: + return mclock_op_tags->scrub; + default: + assert(0); + return dmc::ClientInfo(-1, -1, -1); + } + } + + /* + * class mClockOpClassQueue + */ + + std::unique_ptr + mClockOpClassQueue::mclock_op_tags(nullptr); + + mClockOpClassQueue::pg_queueable_visitor_t + mClockOpClassQueue::pg_queueable_visitor; + + mClockOpClassQueue::mClockOpClassQueue(CephContext *cct) : + queue(&mClockOpClassQueue::op_class_client_info_f) + { + // manage the singleton + if (!mclock_op_tags) { + mclock_op_tags.reset(new mclock_op_tags_t(cct)); + } + } + + mClockOpClassQueue::osd_op_type_t + mClockOpClassQueue::get_osd_op_type(const Request& request) { + osd_op_type_t type = + boost::apply_visitor(pg_queueable_visitor, request.second.get_variant()); + + // if we got client_op back then we need to distinguish between + // a client op and an osd subop. + + if (osd_op_type_t::client_op != type) { + return type; + } else if (MSG_OSD_SUBOP == + boost::get( + request.second.get_variant())->get_req()->get_header().type) { + return osd_op_type_t::osd_subop; + } else { + return osd_op_type_t::client_op; + } + } + + // Formatted output of the queue + void mClockOpClassQueue::dump(ceph::Formatter *f) const { + queue.dump(f); + } + +} // namespace ceph diff --git a/ceph/src/osd/mClockOpClassQueue.h b/ceph/src/osd/mClockOpClassQueue.h new file mode 100644 index 000000000..1b386fe2d --- /dev/null +++ b/ceph/src/osd/mClockOpClassQueue.h @@ -0,0 +1,153 @@ +// -*- 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. + * + */ + + +#pragma once + +#include + +#include "boost/variant.hpp" + +#include "common/config.h" +#include "common/ceph_context.h" +#include "osd/PGQueueable.h" + +#include "common/mClockPriorityQueue.h" + + +namespace ceph { + + using Request = std::pair; + using Client = entity_inst_t; + + + // This class exists to bridge the ceph code, which treats the class + // as the client, and the queue, where the class is + // osd_op_type_t. So this adpater class will transform calls + // appropriately. + class mClockOpClassQueue : public OpQueue { + + enum class osd_op_type_t { + client_op, osd_subop, bg_snaptrim, bg_recovery, bg_scrub }; + + using queue_t = mClockQueue; + + queue_t queue; + + struct mclock_op_tags_t { + crimson::dmclock::ClientInfo client_op; + crimson::dmclock::ClientInfo osd_subop; + crimson::dmclock::ClientInfo snaptrim; + crimson::dmclock::ClientInfo recov; + crimson::dmclock::ClientInfo scrub; + + mclock_op_tags_t(CephContext *cct); + }; + + static std::unique_ptr mclock_op_tags; + + public: + + mClockOpClassQueue(CephContext *cct); + + static crimson::dmclock::ClientInfo + op_class_client_info_f(const osd_op_type_t& op_type); + + inline unsigned length() const override final { + return queue.length(); + } + + // Ops of this priority should be deleted immediately + inline void remove_by_class(Client cl, + std::list *out) override final { + queue.remove_by_filter( + [&cl, out] (const Request& r) -> bool { + if (cl == r.second.get_owner()) { + out->push_front(r); + return true; + } else { + return false; + } + }); + } + + inline void enqueue_strict(Client cl, + unsigned priority, + Request item) override final { + queue.enqueue_strict(get_osd_op_type(item), priority, item); + } + + // Enqueue op in the front of the strict queue + inline void enqueue_strict_front(Client cl, + unsigned priority, + Request item) override final { + queue.enqueue_strict_front(get_osd_op_type(item), priority, item); + } + + // Enqueue op in the back of the regular queue + inline void enqueue(Client cl, + unsigned priority, + unsigned cost, + Request item) override final { + queue.enqueue(get_osd_op_type(item), priority, cost, item); + } + + // Enqueue the op in the front of the regular queue + inline void enqueue_front(Client cl, + unsigned priority, + unsigned cost, + Request item) override final { + queue.enqueue_front(get_osd_op_type(item), priority, cost, item); + } + + // Returns if the queue is empty + inline bool empty() const override final { + return queue.empty(); + } + + // Return an op to be dispatch + inline Request dequeue() override final { + return queue.dequeue(); + } + + // Formatted output of the queue + void dump(ceph::Formatter *f) const override final; + + protected: + + struct pg_queueable_visitor_t : public boost::static_visitor { + osd_op_type_t operator()(const OpRequestRef& o) const { + // don't know if it's a client_op or a + return osd_op_type_t::client_op; + } + + osd_op_type_t operator()(const PGSnapTrim& o) const { + return osd_op_type_t::bg_snaptrim; + } + + osd_op_type_t operator()(const PGScrub& o) const { + return osd_op_type_t::bg_scrub; + } + + osd_op_type_t operator()(const PGRecovery& o) const { + return osd_op_type_t::bg_recovery; + } + }; // class pg_queueable_visitor_t + + static pg_queueable_visitor_t pg_queueable_visitor; + + osd_op_type_t get_osd_op_type(const Request& request); + }; // class mClockOpClassAdapter + +} // namespace ceph diff --git a/ceph/src/osd/osd_types.cc b/ceph/src/osd/osd_types.cc index 40d3138f4..bbacdb38a 100644 --- a/ceph/src/osd/osd_types.cc +++ b/ceph/src/osd/osd_types.cc @@ -54,6 +54,7 @@ const char *ceph_osd_flag_name(unsigned flag) case CEPH_OSD_FLAG_KNOWN_REDIR: return "known_if_redirected"; case CEPH_OSD_FLAG_FULL_TRY: return "full_try"; case CEPH_OSD_FLAG_FULL_FORCE: return "full_force"; + case CEPH_OSD_FLAG_IGNORE_REDIRECT: return "ignore_redirect"; default: return "???"; } } @@ -834,6 +835,8 @@ std::string pg_state_string(int state) oss << "snaptrim+"; if (state & PG_STATE_SNAPTRIM_WAIT) oss << "snaptrim_wait+"; + if (state & PG_STATE_SNAPTRIM_ERROR) + oss << "snaptrim_error+"; string ret(oss.str()); if (ret.length() > 0) ret.resize(ret.length() - 1); @@ -891,6 +894,8 @@ int pg_string_state(const std::string& state) type = PG_STATE_SNAPTRIM; else if (state == "snaptrim_wait") type = PG_STATE_SNAPTRIM_WAIT; + else if (state == "snaptrim_error") + type = PG_STATE_SNAPTRIM_ERROR; else type = -1; return type; @@ -986,7 +991,7 @@ static opt_mapping_t opt_mapping = boost::assign::map_list_of pool_opts_t::CSUM_MIN_BLOCK, pool_opts_t::INT)); bool pool_opts_t::is_opt_name(const std::string& name) { - return opt_mapping.find(name) != opt_mapping.end(); + return opt_mapping.count(name); } pool_opts_t::opt_desc_t pool_opts_t::get_opt_desc(const std::string& name) { @@ -996,7 +1001,7 @@ pool_opts_t::opt_desc_t pool_opts_t::get_opt_desc(const std::string& name) { } bool pool_opts_t::is_set(pool_opts_t::key_t key) const { - return opts.find(key) != opts.end(); + return opts.count(key); } const pool_opts_t::value_t& pool_opts_t::get(pool_opts_t::key_t key) const { @@ -5279,6 +5284,7 @@ ostream &ObjectRecoveryProgress::print(ostream &out) const << ", data_complete:" << ( data_complete ? "true" : "false" ) << ", omap_recovered_to:" << omap_recovered_to << ", omap_complete:" << ( omap_complete ? "true" : "false" ) + << ", error:" << ( error ? "true" : "false" ) << ")"; } @@ -5948,3 +5954,33 @@ ostream& operator<<(ostream& out, const store_statfs_t &s) << ")"; return out; } + +void OSDOp::clear_data(vector& ops) +{ + for (unsigned i = 0; i < ops.size(); i++) { + OSDOp& op = ops[i]; + op.outdata.clear(); + if (ceph_osd_op_type_attr(op.op.op) && + op.op.xattr.name_len && + op.indata.length() >= op.op.xattr.name_len) { + bufferptr bp(op.op.xattr.name_len); + bufferlist bl; + bl.append(bp); + bl.copy_in(0, op.op.xattr.name_len, op.indata); + op.indata.claim(bl); + } else if (ceph_osd_op_type_exec(op.op.op) && + op.op.cls.class_len && + op.indata.length() > + (op.op.cls.class_len + op.op.cls.method_len)) { + __u8 len = op.op.cls.class_len + op.op.cls.method_len; + bufferptr bp(len); + bufferlist bl; + bl.append(bp); + bl.copy_in(0, len, op.indata); + op.indata.claim(bl); + } else { + op.indata.clear(); + } + } +} + diff --git a/ceph/src/osd/osd_types.h b/ceph/src/osd/osd_types.h index 92cc7c569..2507e64b8 100644 --- a/ceph/src/osd/osd_types.h +++ b/ceph/src/osd/osd_types.h @@ -981,6 +981,7 @@ inline ostream& operator<<(ostream& out, const osd_stat_t& s) { #define PG_STATE_SNAPTRIM (1<<26) // trimming snaps #define PG_STATE_SNAPTRIM_WAIT (1<<27) // queued to trim snaps #define PG_STATE_RECOVERY_TOOFULL (1<<28) // recovery can't proceed: too full +#define PG_STATE_SNAPTRIM_ERROR (1<<29) // error stopped trimming snaps std::string pg_state_string(int state); std::string pg_vector_string(const vector &a); @@ -1114,9 +1115,6 @@ struct pg_pool_t { const char *get_type_name() const { return get_type_name(type); } - static const char* get_default_type() { - return "replicated"; - } enum { FLAG_HASHPSPOOL = 1<<0, // hash pg seed and pool together (instead of adding) @@ -4658,6 +4656,7 @@ struct ObjectRecoveryProgress { bool first; bool data_complete; bool omap_complete; + bool error = false; ObjectRecoveryProgress() : data_recovered_to(0), @@ -4795,7 +4794,7 @@ struct OSDOp { sobject_t soid; bufferlist indata, outdata; - int32_t rval; + errorcode32_t rval; OSDOp() : rval(0) { memset(&op, 0, sizeof(ceph_osd_op)); @@ -4835,6 +4834,13 @@ struct OSDOp { * @param out [out] combined data buffer */ static void merge_osd_op_vector_out_data(vector& ops, bufferlist& out); + + /** + * Clear data as much as possible, leave minimal data for historical op dump + * + * @param ops [in] vector of OSDOps + */ + static void clear_data(vector& ops); }; ostream& operator<<(ostream& out, const OSDOp& op); diff --git a/ceph/src/osdc/Objecter.cc b/ceph/src/osdc/Objecter.cc index 97f97e027..fde68cd1b 100644 --- a/ceph/src/osdc/Objecter.cc +++ b/ceph/src/osdc/Objecter.cc @@ -3412,6 +3412,22 @@ void Objecter::handle_osd_op_reply(MOSDOpReply *m) if (rc == -EAGAIN) { ldout(cct, 7) << " got -EAGAIN, resubmitting" << dendl; + if ((op->target.flags & CEPH_OSD_FLAG_BALANCE_READS) + && (op->target.acting_primary != op->target.osd)) { + if (op->onfinish) + num_in_flight--; + _session_op_remove(s, op); + sl.unlock(); + put_session(s); + + op->tid = 0; + op->target.flags &= ~CEPH_OSD_FLAG_BALANCE_READS; + op->target.pgid = pg_t(); + _op_submit(op, sul, NULL); + m->put(); + return; + } + // new tid s->ops.erase(op->tid); op->tid = ++last_tid; diff --git a/ceph/src/osdc/Objecter.h b/ceph/src/osdc/Objecter.h index 4efdb9d08..ee40e76a5 100644 --- a/ceph/src/osdc/Objecter.h +++ b/ceph/src/osdc/Objecter.h @@ -2083,7 +2083,9 @@ private: } } void ms_fast_dispatch(Message *m) override { - ms_dispatch(m); + if (!ms_dispatch(m)) { + m->put(); + } } void handle_osd_op_reply(class MOSDOpReply *m); @@ -2201,7 +2203,7 @@ public: onfinish); submit_command(c, ptid); } - void pg_command(pg_t pgid, vector& cmd, + void pg_command(pg_t pgid, const vector& cmd, const bufferlist& inbl, ceph_tid_t *ptid, bufferlist *poutbl, string *prs, Context *onfinish) { CommandOp *c = new CommandOp( diff --git a/ceph/src/pybind/ceph_rest_api.py b/ceph/src/pybind/ceph_rest_api.py index 6ca217798..a4c6c8ab6 100755 --- a/ceph/src/pybind/ceph_rest_api.py +++ b/ceph/src/pybind/ceph_rest_api.py @@ -20,7 +20,7 @@ from ceph_argparse import \ # Globals and defaults # -DEFAULT_ADDR = '0.0.0.0' +DEFAULT_ADDR = '::' DEFAULT_PORT = '5000' DEFAULT_ID = 'restapi' diff --git a/ceph/src/pybind/mgr/dashboard/README.rst b/ceph/src/pybind/mgr/dashboard/README.rst index 1b0276632..34158849c 100644 --- a/ceph/src/pybind/mgr/dashboard/README.rst +++ b/ceph/src/pybind/mgr/dashboard/README.rst @@ -24,15 +24,23 @@ If you had already enabled the module, restart ceph-mgr after installing depende Enabling ======== -Add this to your ceph.conf on nodes where you run ceph-mgr: +Enable the module with:: -:: + ceph mgr module enable dashboard + +You can see currently enabled modules with:: - [mgr] - mgr modules = dashboard + ceph mgr module ls If you use any other ceph-mgr modules, make sure they're in the list too. +An address where the dashboard will listen on needs to be configured as well, set this to ``::`` to listen on all +IPv4 and IPv6 addresses. + +:: + + ceph config-key put mgr/dashboard/server_addr :: + Restart the ceph-mgr daemon after modifying the setting to load the module. Accessing diff --git a/ceph/src/pybind/mgr/dashboard/base.html b/ceph/src/pybind/mgr/dashboard/base.html index 41d059347..efe09260e 100644 --- a/ceph/src/pybind/mgr/dashboard/base.html +++ b/ceph/src/pybind/mgr/dashboard/base.html @@ -39,7 +39,7 @@ var refresh = function() { $.get("/toplevel_data", function(data) { - _.extend(toplevel_data.health, data.health); + _.extend(toplevel_data, data); setTimeout(refresh, refresh_interval); }); }; @@ -60,6 +60,14 @@ } } + rivets.formatters.health_ok = function(status_str) { + if (status_str == "HEALTH_OK") { + return true; + } else { + return false; + } + } + var truncate = function(n, max_width) { var stringized = n.toString(); var parts = stringized.split("."); @@ -78,29 +86,38 @@ } } - rivets.formatters.dimless = function(n){ + var format_number = function(n, divisor, units) { var width=4; - var units = [' ', 'k', 'M', 'G', 'T', 'P']; var unit = 0; - while (Math.floor(n / (1000**unit)).toString().length > width - 1) { + while (Math.floor(n / (divisor**unit)).toString().length > width - 1) { unit = unit + 1; } var truncated_float; if (unit > 0) { - truncated_float = truncate((n / Math.pow(1000.0, unit)).toString(), width); + truncated_float = truncate((n / Math.pow(divisor, unit)).toString(), width); } else { truncated_float = truncate(n, width); } return truncated_float + units[unit]; + } + + rivets.formatters.dimless = function(n){ + return format_number(n, 1000, [' ', 'k', 'M', 'G', 'T', 'P']) + }; + rivets.formatters.dimless_binary = function(n){ + return format_number(n, 1024, ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB']); }; - - + /* This is useful if you need to display some alternative text + * when a collection is empty using rv-hide */ + rivets.formatters.length = function(val) { + return val.length; + } - rivets.bind($("#health"), toplevel_data.health); + rivets.bind($("#health"), toplevel_data); rivets.bind($("section.sidebar"), toplevel_data); setTimeout(refresh, refresh_interval); }); @@ -108,22 +125,102 @@ + + + - +
- +
@@ -134,10 +231,11 @@ Toggle navigation -
- Health:  - - {overall_status} +
+ + + {health_status} +
@@ -150,19 +248,34 @@
-