diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 00000000..55ade448
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,110 @@
+image: 192.168.178.73:6088/ceph-dovecot-combined:fe6a06c8907bd7635018205c7eae05dc4c363575
+
+services:
+ - docker:19.03.13-dind
+
+variables:
+ DOCKER_REGISTRY_URL: "192.168.178.73:6088"
+ LC_ALL: "en_US.UTF-8"
+ LANG: "en_US.UTF-8"
+ DOCKER_DRIVER: overlay2
+ DOCKER_TLS_CERTDIR: ""
+ PROJECT_NAME: dovecot-ceph-plugin
+ GIT_SUBMODULE_STRATEGY: recursive
+ ROOT_PATH: "apps/develop/apps/"
+
+stages:
+ - build
+ - docker
+ - publish
+
+build:
+ stage: build
+ tags: ["kubernetes"]
+ artifacts:
+ paths:
+ - imaptest.log
+ - dovecot.log
+ script:
+ - /opt/ceph-container/bin/entrypoint.sh demo &
+ - ./autogen.sh
+ - ./configure --with-dovecot=/usr/local/lib/dovecot --enable-maintainer-mode --enable-debug --with-integration-tests --enable-valgrind --enable-debug
+ - make clean install
+ - ps -aux
+ - ceph df
+ - ./setup.sh
+ - dovecot
+ - ldconfig
+ - smtp-source -v -L -s 1 -m 1 -c -F /root/lmtp_test_mail.tld -f test@example.com -t t1 inet:127.0.0.1:1024
+ - imaptest user=t%d pass=t port=10143 users=10 clients=10 error_quit secs=30 output=./imaptest.log
+ - doveadm -Dv backup -u t1 -m INBOX mdbox:/usr/local/var/mail/mdbox/t1
+ - doveadm -D fetch -u t1 "guid date.received date.sent flags pop3.uidl seq size.virtual uid user mailbox-guid mailbox" ALL > /root/rbox.t1.mails
+ - doveadm -D -c /usr/local/etc/dovecot_mdbox/dovecot.conf fetch -u t1 "guid date.received date.sent flags pop3.uidl seq size.virtual uid user mailbox-guid mailbox" ALL > /root/mdbox.t1.mails
+
+
+ - src/scripts/sort.sh /root/rbox.t1.mails /root/rbox.t1.mails.sorted
+ - src/scripts/sort.sh /root/mdbox.t1.mails /root/mdbox.t1.mails.sorted
+ - type diff
+ - diff -y -W 1500 /root/rbox.t1.mails.sorted /root/mdbox.t1.mails.sorted
+ - echo $?
+
+ - rm -rf /usr/local/var/mail/rbox/t1
+ - doveadm -Dv -c /usr/local/etc/dovecot_mdbox/dovecot.conf backup -u t1 -m INBOX rbox:/usr/local/var/mail/rbox/t1
+ - doveadm -D fetch -u t1 "guid date.received date.sent flags pop3.uidl seq size.virtual uid user mailbox-guid mailbox" ALL > /root/rbox.t1.mails
+ - src/scripts/sort.sh /root/rbox.t1.mails /root/rbox.t1.mails.sorted
+ - diff -y -W 1500 /root/rbox.t1.mails.sorted /root/mdbox.t1.mails.sorted
+ - echo $?
+ - rm -rf /usr/local/var/mail/rbox
+ - imaptest user=t%d pass=t port=10143 error_quit secs=15 copybox=INBOX.Drafts output=./imaptest.log
+ - doveadm -D force-resync -u t1 INBOX
+
+ # - git grep -c "Error" -- ./dovecot.log
+ # - git grep -c "failed" -- ./dovecot.log
+ # - git grep -c "Internal error" -- ./dovecot.log
+ # - git grep -c "killed" -- ./dovecot.log
+ # - git grep -c "Panic" -- ./dovecot.log
+ # - git grep -c "Fatal" -- ./dovecot.log
+ # - git grep -c "BUG" -- ./dovecot.log
+ # - ceph df
+ # - make check
+build_image:
+ tags:
+ - kubernetes
+ stage: docker
+ image:
+ name: gcr.io/kaniko-project/executor:v1.14.0-debug
+ entrypoint: [""]
+ before_script:
+ - |
+ echo "$NEXUS_IMAGE_REGISTRY_SSH_KEY" >> /kaniko/ssl/certs/ca-certificates.crt
+ script:
+ - /kaniko/executor
+ --context "$CI_PROJECT_DIR"
+ --dockerfile "${CI_PROJECT_DIR}/Dockerfile"
+ --destination "$DOCKER_REGISTRY_URL/$PROJECT_NAME:$CI_COMMIT_SHA"
+ --skip-tls-verify
+
+publish_to_master:
+ dependencies:
+ - build_image
+ stage: publish
+ tags:
+ - shell
+ before_script:
+ - mkdir dev_temp
+ - cd dev_temp
+ - git clone http://${CI_USERNAME}:${CI_PUSH_TOKEN}@${CI_SERVER_HOST}/devops/dev.git
+ - git config --global user.email "gitlab@gitlab.com"
+ - git config --global user.name "GitLab CI/CD"
+ script:
+ - cd dev
+ - git checkout develop
+ - git stash
+ - cd $ROOT_PATH
+ - cd $PROJECT_NAME
+ - export image2="yq e -i '.spec.template.spec.containers[0].image = \""$DOCKER_REGISTRY_URL/$PROJECT_NAME:$CI_COMMIT_SHA\""' deployment.yaml"
+ - eval "$image2"
+ - git commit -am 'kubernetes-deployment.yaml has been updated with new image'
+ - git push origin develop
+ - cd ../../../../../..
+ - rm -r dev_temp
diff --git a/.travis.yml b/.travis.yml
index 341995fa..5473b9fc 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -23,43 +23,43 @@ script:
- docker exec ceph_demo sh -c 'cp -r /etc/ceph/* /root/cfg'
- docker exec build sh -c 'chmod 777 /etc/ceph/*'
- docker exec ceph_demo sh -c 'ceph tell mon.\* injectargs "--mon-allow-pool-delete=true"'
-- travis_wait 30 docker exec build sh -c 'cd repo/src/tests; make check-valgrind'
-- docker exec build sh -c 'cd repo; cat src/tests/test-suite-memcheck.log'
+#- travis_wait 30 docker exec build sh -c 'cd repo/src/tests; make check-valgrind'
+#- docker exec build sh -c 'cd repo; cat src/tests/test-suite-memcheck.log'
#- travis_wait 30 docker exec build sh -c 'cd repo/src/tests; make check'
- docker exec build sh -c 'ldconfig'
- docker exec build sh -c 'chmod -R 777 /usr/local/var/'
- docker exec --detach build sh -c 'service dovecot.service start'
-- docker exec build sh -c 'cd /usr/local/bin; ./imaptest user=t%d pass=t port=10143 users=100 clients=25 error_quit secs=15 output=/var/log/imaptest.log'
-- docker exec build sh -c 'smtp-source -v -L -s 1 -m 1 -c -F /root/lmtp_test_mail.tld -f test@example.com -t t1 inet:127.0.0.1:1024'
-- docker exec build sh -c 'doveadm -D altmove -u t2 ALL'
-- docker exec build sh -c 'doveadm -D altmove -r -u t2 ALL'
+#- docker exec build sh -c 'cd /usr/local/bin; ./imaptest user=t%d pass=t port=10143 users=100 clients=25 error_quit secs=15 output=/var/log/imaptest.log'
+#- docker exec build sh -c 'smtp-source -v -L -s 1 -m 1 -c -F /root/lmtp_test_mail.tld -f test@example.com -t t1 inet:127.0.0.1:1024'
+#- docker exec build sh -c 'doveadm -D altmove -u t2 ALL'
+#- docker exec build sh -c 'doveadm -D altmove -r -u t2 ALL'
-- docker exec build sh -c 'doveadm -Dv backup -u t1 -m INBOX mdbox:/usr/local/var/mail/mdbox/t1'
-- docker exec build sh -c 'doveadm -D fetch -u t1 "guid date.received date.sent flags pop3.uidl seq size.virtual uid user mailbox-guid mailbox" ALL > /root/rbox.t1.mails'
-- docker exec build sh -c 'doveadm -D -c /usr/local/etc/dovecot_mdbox/dovecot.conf fetch -u t1 "guid date.received date.sent flags pop3.uidl seq size.virtual uid user mailbox-guid mailbox" ALL > /root/mdbox.t1.mails'
-- docker exec build sh -c 'cd repo/src/scripts; ./sort.sh /root/rbox.t1.mails /root/rbox.t1.mails.sorted'
-- docker exec build sh -c 'cd repo/src/scripts; ./sort.sh /root/mdbox.t1.mails /root/mdbox.t1.mails.sorted'
+#- docker exec build sh -c 'doveadm -Dv backup -u t1 -m INBOX mdbox:/usr/local/var/mail/mdbox/t1'
+#- docker exec build sh -c 'doveadm -D fetch -u t1 "guid date.received date.sent flags pop3.uidl seq size.virtual uid user mailbox-guid mailbox" ALL > /root/rbox.t1.mails'
+#- docker exec build sh -c 'doveadm -D -c /usr/local/etc/dovecot_mdbox/dovecot.conf fetch -u t1 "guid date.received date.sent flags pop3.uidl seq size.virtual uid user mailbox-guid mailbox" ALL > /root/mdbox.t1.mails'
+#- docker exec build sh -c 'cd repo/src/scripts; ./sort.sh /root/rbox.t1.mails /root/rbox.t1.mails.sorted'
+#- docker exec build sh -c 'cd repo/src/scripts; ./sort.sh /root/mdbox.t1.mails /root/mdbox.t1.mails.sorted'
-- docker exec build sh -c 'diff -y -W 1500 /root/rbox.t1.mails.sorted /root/mdbox.t1.mails.sorted'
-- docker exec build sh -c 'rm -r /usr/local/var/mail/rbox/t1'
-- docker exec build sh -c 'doveadm -Dv -c /usr/local/etc/dovecot_mdbox/dovecot.conf backup -u t1 -m INBOX rbox:/usr/local/var/mail/rbox/t1'
-- docker exec build sh -c 'doveadm -D fetch -u t1 "guid date.received date.sent flags pop3.uidl seq size.virtual uid user mailbox-guid mailbox" ALL > /root/rbox.t1.mails'
-- docker exec build sh -c 'cd repo/src/scripts; ./sort.sh /root/rbox.t1.mails /root/rbox.t1.mails.sorted'
-- docker exec build sh -c 'diff -y -W 1500 /root/rbox.t1.mails.sorted /root/mdbox.t1.mails.sorted'
+#- docker exec build sh -c 'diff -y -W 1500 /root/rbox.t1.mails.sorted /root/mdbox.t1.mails.sorted'
+#- docker exec build sh -c 'rm -r /usr/local/var/mail/rbox/t1'
+#- docker exec build sh -c 'doveadm -Dv -c /usr/local/etc/dovecot_mdbox/dovecot.conf backup -u t1 -m INBOX rbox:/usr/local/var/mail/rbox/t1'
+#- docker exec build sh -c 'doveadm -D fetch -u t1 "guid date.received date.sent flags pop3.uidl seq size.virtual uid user mailbox-guid mailbox" ALL > /root/rbox.t1.mails'
+#- docker exec build sh -c 'cd repo/src/scripts; ./sort.sh /root/rbox.t1.mails /root/rbox.t1.mails.sorted'
+#- docker exec build sh -c 'diff -y -W 1500 /root/rbox.t1.mails.sorted /root/mdbox.t1.mails.sorted'
-- docker exec build sh -c 'rm -r /usr/local/var/mail/rbox'
-- docker exec build sh -c 'cd /usr/local/bin; ./imaptest user=t%d pass=t port=10110 profile=/root/pop3-profile.conf users=100 clients=10 error_quit secs=15 output=/var/log/imaptest.log'
+#- docker exec build sh -c 'rm -r /usr/local/var/mail/rbox'
+#- docker exec build sh -c 'cd /usr/local/bin; ./imaptest user=t%d pass=t port=10110 profile=/root/pop3-profile.conf users=100 clients=10 error_quit secs=15 output=/var/log/imaptest.log'
-- docker exec build sh -c 'rm -r /usr/local/var/mail/rbox'
-- docker exec build sh -c 'cd /usr/local/bin; ./imaptest user=t%d pass=t port=10143 error_quit secs=15 copybox=INBOX.Drafts output=/var/log/imaptest.log'
-- docker exec build sh -c 'doveadm -D force-resync -u t1 INBOX'
-- docker exec build bash -c '/usr/local/bin/exec.sh "cat /var/log/dovecot.log | grep \"Error:\""'
-- docker exec build bash -c '/usr/local/bin/exec.sh "cat /var/log/dovecot.log | grep \"failed:\""'
-- docker exec build bash -c '/usr/local/bin/exec.sh "cat /var/log/dovecot.log | grep \"Internal error\""'
-- docker exec build bash -c '/usr/local/bin/exec.sh "cat /var/log/dovecot.log | grep \"killed\""'
-- docker exec build bash -c '/usr/local/bin/exec.sh "cat /var/log/dovecot.log | grep \"Panic:\""'
-- docker exec build bash -c '/usr/local/bin/exec.sh "cat /var/log/dovecot.log | grep \"Fatal:\""'
-- docker exec build bash -c '/usr/local/bin/exec.sh "cat /var/log/imaptest.log | grep \"BUG:\""'
+#- docker exec build sh -c 'rm -r /usr/local/var/mail/rbox'
+# #- docker exec build sh -c 'cd /usr/local/bin; ./imaptest user=t%d pass=t port=10143 error_quit secs=15 copybox=INBOX.Drafts output=/var/log/imaptest.log'
+# - docker exec build sh -c 'doveadm -D force-resync -u t1 INBOX'
+# - docker exec build bash -c '/usr/local/bin/exec.sh "cat /var/log/dovecot.log | grep \"Error:\""'
+# - docker exec build bash -c '/usr/local/bin/exec.sh "cat /var/log/dovecot.log | grep \"failed:\""'
+# - docker exec build bash -c '/usr/local/bin/exec.sh "cat /var/log/dovecot.log | grep \"Internal error\""'
+# - docker exec build bash -c '/usr/local/bin/exec.sh "cat /var/log/dovecot.log | grep \"killed\""'
+# - docker exec build bash -c '/usr/local/bin/exec.sh "cat /var/log/dovecot.log | grep \"Panic:\""'
+# - docker exec build bash -c '/usr/local/bin/exec.sh "cat /var/log/dovecot.log | grep \"Fatal:\""'
+# - docker exec build bash -c '/usr/local/bin/exec.sh "cat /var/log/imaptest.log | grep \"BUG:\""'
after_script:
- docker stop build ceph_demo
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2c5eb577..a8536b6f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,11 @@
# Change Log
## [0.0.47](https://github.com/ceph-dovecot/dovecot-ceph-plugin/tree/0.0.47) (2022-12-05)
- #355 fix gzip trailer when stream is empty
+ fix save_method 1+2 buffersize (1 byte short)
+ bugfix-355-fix-buffersize-write-method
+
+## [0.0.46](https://github.com/ceph-dovecot/dovecot-ceph-plugin/tree/0.0.45) (2022-11-22)
- #349 bugfix doveadm rmb create ceph index validate object metadata
## [0.0.45](https://github.com/ceph-dovecot/dovecot-ceph-plugin/tree/0.0.45) (2022-11-22)
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 00000000..922e1063
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,141 @@
+# CLAUDE.md
+
+This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
+
+## Project Overview
+
+This is a Dovecot plugin that enables email storage in Ceph RADOS objects. It provides two main plugins:
+- **RADOS Storage Plugin (rbox)**: Stores emails as RADOS objects while keeping metadata in filesystem/CephFS
+- **RADOS Dictionary Plugin**: Stores Dovecot dictionaries in Ceph OMAP key/value store
+
+The project uses a hybrid storage model where emails are immutable RADOS objects and index/cache data remains in the filesystem for performance.
+
+## Build System
+
+The project uses GNU Autotools (autoconf/automake) for configuration and building:
+
+### Build Commands
+```bash
+# Generate build system
+./autogen.sh
+
+# Configure build (standard installation)
+./configure
+
+# Configure with custom dovecot location
+./configure --with-dovecot=/path/to/dovecot
+
+# Configure with custom prefix
+./configure --prefix=/usr/local
+
+# Build
+make
+
+# Install
+make install
+```
+
+### Build Options
+- `--with-dict=yes/no`: Build RADOS dictionary plugin (default: yes)
+- `--with-storage=yes/no`: Build RADOS storage plugin (default: yes)
+- `--with-tests=yes/no`: Build tests (default: yes)
+- `--with-integration-tests=yes/no`: Build integration tests (default: no)
+
+## Dependencies
+
+Required packages:
+- `libjansson-devel` (>= 2.9)
+- `librados2-devel` (>= 10.2.5)
+- `dovecot-devel`
+- `spdlog` (optional, for logging)
+
+## Testing
+
+### Unit Tests
+```bash
+# Run individual test executables from src/tests/
+./src/tests/storage-rbox/it_test_storage_rbox
+./src/tests/storage-rbox/it_test_read_mail_rbox
+./src/tests/librmb/it_test_librmb
+```
+
+### Integration Tests
+Enable with `--with-integration-tests=yes` during configure.
+
+### Docker Development Environment
+```bash
+cd docker
+docker-compose up
+# Access container: docker exec -it dovecot-dev bash
+```
+
+## Code Architecture
+
+### Core Components
+
+#### librmb (src/librmb/)
+Core library providing RADOS abstractions:
+- `rados-cluster-impl`: Ceph cluster connection management
+- `rados-storage-impl`: RADOS storage operations
+- `rados-mail-impl`: Mail object handling
+- `rados-dictionary-impl`: Dictionary operations
+- `rados-metadata-*`: Metadata storage implementations
+
+#### Storage Plugin (src/storage-rbox/)
+Dovecot storage plugin implementation:
+- `rbox-storage.cpp`: Main storage backend
+- `rbox-mail.cpp`: Mail object interface
+- `rbox-save.cpp`: Mail saving logic
+- `rbox-sync.cpp`: Mailbox synchronization
+- `rbox-copy.cpp`: Mail copying operations
+
+#### Dictionary Plugin (src/dict-rados/)
+Dovecot dictionary plugin for OMAP storage:
+- `dict-rados.cpp`: Dictionary implementation
+- `libdict-rados-plugin.c`: Plugin interface
+
+#### Tools (src/librmb/tools/rmb/)
+Command-line tools for managing RADOS mailboxes:
+- `rmb.cpp`: Main RMB tool
+- `rmb-commands-impl.cpp`: Command implementations
+
+### Key Interfaces
+
+The code implements Dovecot's plugin interfaces:
+- `mail_storage_vfuncs`: Storage operations
+- `mail_vfuncs`: Mail object operations
+- `dict_vfuncs`: Dictionary operations
+
+### Configuration
+
+Configuration is handled through:
+- Dovecot configuration files
+- Ceph configuration files (`ceph.conf`)
+- JSON configuration for advanced settings
+
+## Development Guidelines
+
+### Code Style
+- C++11 standard
+- Line length: 120 characters (see CPPLINT.cfg)
+- Use existing code patterns and conventions
+- Headers are organized by component
+
+### Testing Strategy
+- Unit tests for individual components
+- Integration tests for end-to-end functionality
+- Manual testing with IMAP clients (Thunderbird, telnet)
+- Performance testing with imaptest
+
+### Memory Management
+- RAII patterns for resource management
+- Proper cleanup of Ceph contexts
+- Buffer management for large mail objects
+
+## Important Notes
+
+- This is experimental code, not production-ready
+- Mail objects are immutable once stored
+- Index data should be on fast storage (SSD/CephFS)
+- Mail objects can use erasure coding for efficiency
+- The plugin supports both standalone and clustered Dovecot deployments
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 00000000..f67cc989
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,8 @@
+FROM 192.168.178.73:6088/ceph-dovecot-runtime:f3031c31a2aae0bcfcb504d660a6d4dc555e804d
+WORKDIR /repo
+COPY ./ /repo
+RUN ./autogen.sh
+RUN ./configure --with-dovecot=/usr/local/lib/dovecot --enable-maintainer-mode --enable-debug --with-integration-tests --enable-valgrind --enable-debug
+RUN make install
+ENTRYPOINT ["/bin/bash", "-c", "./startup.sh" ]
+
diff --git a/Dockerfile.dev b/Dockerfile.dev
new file mode 100644
index 00000000..b6c974ab
--- /dev/null
+++ b/Dockerfile.dev
@@ -0,0 +1,7 @@
+FROM 192.168.178.73:6088/ceph-dovecot-combined:f551f222f7890a89a2261dcc024e720ba9239bf9
+WORKDIR /repo
+COPY ./ /repo
+RUN ./autogen.sh
+RUN ./configure --with-dovecot=/usr/local/lib/dovecot --enable-maintainer-mode --enable-debug --with-integration-tests --enable-valgrind --enable-debug
+RUN make clean install
+RUN ./setup.sh
diff --git a/README.md b/README.md
index 7c95998e..c0a10439 100644
--- a/README.md
+++ b/README.md
@@ -79,6 +79,9 @@ If you are using CentOS make sure you also have the following package installed:
./configure --with-dovecot=/home/user/workspace/core
make install
+### Docker compose run with dovecot and ceph cluster
+ cd docker
+ docker-compose up
## Thanks
diff --git a/configure.ac b/configure.ac
index bcb784e5..570a396b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -53,6 +53,22 @@ AC_CHECK_HEADER([rados/librados.h], [
LIBS="$LIBS -lrados"
], [AC_MSG_ERROR([cannot build without RADOS support: librados.h not found])])
+AC_ARG_WITH([SPDLOG],
+ AS_HELP_STRING([--with-SPDLOG=warn|error], [set action for missing spdlog package]),
+ [SPDLOG_ACTION="$withval"],
+ [SPDLOG_ACTION="error"])
+
+# Check for the presence of spdlog library
+PKG_CHECK_MODULES([SPDLOG], [spdlog], [$SPDLOG_ACTION], [SPDLOG_ACTION="error"])
+
+# Check if spdlog is found and add it to LDFLAGS
+if test "x$SPDLOG_LIBS" != "x"; then
+ LDFLAGS="$LDFLAGS $SPDLOG_LIBS"
+ AC_DEFINE([SPD_LOGGING_FRAMEWORK], [1], [Define if spdlog is found])
+else
+ AC_DEFINE([NO_LOGGING_FRAMEWORK], [1], [Define if spdlog is not found])
+fi
+
AC_CHECK_FUNC(rados_read_op_omap_get_vals2, AC_DEFINE(HAVE_OMAP_GET_VALS2, 1, [Define if you have the `rados_read_op_omap_get_vals2' function]))
AC_CHECK_FUNC(rados_set_alloc_hint2, AC_DEFINE(HAVE_ALLOC_HINT_2, 1, [Define if you have the `set_alloc_hint2' function]))
AC_CHECK_FUNC(rados_read_op_omap_get_keys2, AC_DEFINE(HAVE_OMAP_GET_KEYS_2, 1, [Define if you have the `omap_get_keys2' function]))
@@ -232,6 +248,9 @@ src/storage-rbox/Makefile
src/librmb/tools/Makefile
src/librmb/tools/rmb/Makefile
src/tests/Makefile
+src/storage-interface/Makefile
+src/storage-interface/tools/Makefile
+src/storage-interface/tools/rmb/Makefile
])
AC_OUTPUT
diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml
index bf5df74e..3028da63 100644
--- a/docker/docker-compose.yml
+++ b/docker/docker-compose.yml
@@ -1,44 +1,17 @@
-version: '2'
+version: '3'
services:
- ceph:
- image: ceph/daemon:latest
- command: "demo"
- container_name: 'ceph_demo'
- volumes:
- - ceph-data:/etc/ceph/
- environment:
- - MON_IP=192.168.100.2
- - CEPH_PUBLIC_NETWORK=192.168.100.0/24
- - CEPH_DEMO_UID=demo_uid
- ports:
- - 3300:3300
- networks:
- - ceph_network
-
dovecot:
- # image: cephdovecot/travis-build-master-2.3:latest
- image: cephdovecot/travis-build:master-2.3
+ build:
+ context: ../
+ dockerfile: Dockerfile.dev
command: tail -f /dev/null
- container_name: 'build'
+ container_name: 'dovecot-dev'
volumes:
- - ceph-data:/etc/ceph/
- - ./../:/repo
- environment:
- - SOURCE_VERSION=master-2.3
+ - mail-data:/usr/local/var/mail/
+ - ../:/repo
ports:
- 10143:10143
- 1024:1024
- 10110:10110
- networks:
- - ceph_network
-
volumes:
- ceph-data:
- external: false
-
-networks:
- ceph_network:
- ipam:
- config:
- - subnet: 192.168.100.0/24
- gateway: 192.168.100.1
+ mail-data:
diff --git a/setup.sh b/setup.sh
new file mode 100755
index 00000000..682c4eb5
--- /dev/null
+++ b/setup.sh
@@ -0,0 +1,4 @@
+chmod 777 /etc/ceph/*
+ceph tell mon.\* injectargs "--mon-allow-pool-delete=true"
+chmod -R 777 /usr/local/var/
+ldconfig
\ No newline at end of file
diff --git a/src/dict-rados/dict-rados.cpp b/src/dict-rados/dict-rados.cpp
index b1f66f53..ce0c3a1f 100644
--- a/src/dict-rados/dict-rados.cpp
+++ b/src/dict-rados/dict-rados.cpp
@@ -45,9 +45,10 @@ extern "C" {
#include "libdict-rados-plugin.h"
#include "../librmb/rados-cluster-impl.h"
#include "../librmb/rados-dictionary-impl.h"
-#include "../librmb/rados-cluster.h"
-#include "../librmb/rados-guid-generator.h"
-#include "../librmb/rados-util.h"
+#include "../storage-interface/rados-cluster.h"
+#include "../storage-interface/rados-guid-generator.h"
+#include "../storage-interface/rados-util.h"
+#include "../storage-engine/storage-backend-factory.h"
#if DOVECOT_PREREQ(2, 3)
#define dict_lookup(dict, pool, key, value_r, error_r) dict_lookup(dict, pool, key, value_r, error_r)
@@ -70,9 +71,9 @@ using librados::AioCompletion;
using librados::ObjectWriteOperation;
using librados::completion_t;
-using librmb::RadosCluster;
-using librmb::RadosDictionary;
-using librmb::RadosGuidGenerator;
+using storage_interface::RadosCluster;
+using storage_interface::RadosDictionary;
+using storage_interface::RadosGuidGenerator;
#define DICT_USERNAME_SEPARATOR '/'
@@ -83,7 +84,7 @@ struct rados_dict {
RadosGuidGenerator *guid_generator;
};
-class DictGuidGenerator : public librmb::RadosGuidGenerator {
+class DictGuidGenerator : public storage_interface::RadosGuidGenerator {
void generate_guid(std::string *guid) override {
guid_128_t namespace_guid;
guid_128_generate(namespace_guid);
@@ -216,7 +217,7 @@ int rados_dict_wait(struct dict *_dict)
class rados_dict_lookup_context {
public:
- RadosDictionary *dict;
+ storage_interface::RadosDictionary *dict;
ObjectReadOperation read_op;
map result_map;
int r_val = -1;
@@ -289,7 +290,7 @@ void rados_dict_lookup_async(struct dict *_dict, const char *key, dict_lookup_ca
lc->callback = callback;
lc->read_op.omap_get_vals_by_keys(keys, &lc->result_map, &lc->r_val);
- int err = d->get_io_ctx(key).aio_operate(d->get_full_oid(key), lc->completion, &lc->read_op,
+ int err = d->get_io_ctx_wrapper(key)->aio_operate(d->get_full_oid(key), lc->completion, &lc->read_op,
LIBRADOS_OPERATION_NOFLAG, &lc->bl);
if (err < 0) {
@@ -303,7 +304,8 @@ void rados_dict_lookup_async(struct dict *_dict, const char *key, dict_lookup_ca
delete lc;
lc = nullptr;
} else {
- d->push_back_completion(lc->completion);
+ d->push_back_completion_wrapper->set_push_back_completion(*lc->completion);
+ d->push_back_completion(d->push_back_completion_wrapper);
}
}
@@ -323,7 +325,7 @@ int rados_dict_lookup(struct dict *_dict, pool_t pool, const char *key, const ch
*value_r = nullptr;
*error_r = nullptr;
- int err = d->get_io_ctx(key).omap_get_vals_by_keys(d->get_full_oid(key), keys, &result_map);
+ int err = d->get_io_ctx_wrapper(key)->omap_get_vals_by_keys(d->get_full_oid(key), keys, &result_map);
if (err == 0) {
auto value = result_map.find(key);
if (value != result_map.end()) {
@@ -452,7 +454,7 @@ class rados_dict_transaction_context {
#ifdef DEBUG
i_debug("deploy_set_map_value: %s , oid=%s", bl.to_str().c_str(), oid.c_str());
#endif
- if ((is_private(key) ? d->get_private_io_ctx() : d->get_shared_io_ctx()).omap_set(oid, map) < 0) {
+ if ((is_private(key) ? d->get_private_io_ctx_wrapper()->get_io_ctx() : d->get_shared_io_ctx_wrapper()->get_io_ctx()).omap_set(oid, map) < 0) {
i_error("unable to set key(%s), oid(%s), is_private(%d)", key.c_str(), oid.c_str(), is_private(key));
}
}
@@ -473,8 +475,13 @@ class rados_dict_transaction_context {
const string key = it->first;
std::string oid = is_private(key) ? d->get_private_oid() : d->get_shared_oid();
// it->second is a signed long int
- librmb::RadosUtils::osd_add(&(is_private(key) ? d->get_private_io_ctx() : d->get_shared_io_ctx()), oid, key,
+ storage_interface::RadosUtils *rados_util=
+ storage_engine::StorageBackendFactory::create_rados_utils(
+ storage_engine::CEPH);
+ rados_util->osd_add(is_private(key) ? d->get_private_io_ctx_wrapper() : d->get_shared_io_ctx_wrapper(), oid, key,
it->second);
+ delete rados_util;
+ rados_util=nullptr;
}
atomic_inc_map.clear();
}
@@ -495,7 +502,7 @@ class rados_dict_transaction_context {
#ifdef DEBUG
i_debug("deploy_unset_map_value key: %s , oid=%s", key.c_str(), oid.c_str());
#endif
- if ((is_private(key) ? d->get_private_io_ctx() : d->get_shared_io_ctx()).omap_rm_keys(oid, keys) < 0) {
+ if ((is_private(key) ? d->get_private_io_ctx_wrapper()->get_io_ctx() : d->get_shared_io_ctx_wrapper()->get_io_ctx()).omap_rm_keys(oid, keys) < 0) {
i_error("unable to unset key(%s), oid(%s), is_private(%d)", key.c_str(), oid.c_str(), is_private(key));
}
}
@@ -715,7 +722,7 @@ struct dict_iterate_context *rados_dict_iterate_init(struct dict *_dict, const c
}
}
- int err = d->get_private_io_ctx().aio_operate(d->get_private_oid(), private_read_completion, &private_read_op,
+ int err = d->get_private_io_ctx_wrapper()->aio_operate(d->get_private_oid(), private_read_completion, &private_read_op,
&bl_private);
#ifdef DEBUG
i_debug("rados_dict_iterate_init(): private err=%d(%s)", err, strerror(-err));
@@ -746,7 +753,7 @@ struct dict_iterate_context *rados_dict_iterate_init(struct dict *_dict, const c
}
int err =
- d->get_shared_io_ctx().aio_operate(d->get_shared_oid(), shared_read_completion, &shared_read_op, &bl_shared);
+ d->get_shared_io_ctx_wrapper()->aio_operate(d->get_shared_oid(), shared_read_completion, &shared_read_op, &bl_shared);
#ifdef DEBUG
i_debug("rados_dict_iterate_init(): shared err=%d(%s)", err, strerror(-err));
#endif
diff --git a/src/librmb/Makefile.am b/src/librmb/Makefile.am
index 60f1c1c2..cd85195f 100644
--- a/src/librmb/Makefile.am
+++ b/src/librmb/Makefile.am
@@ -12,30 +12,24 @@ lib_LTLIBRARIES = \
librmb.la
headers = \
- rados-cluster.h \
- rados-dictionary.h \
- rados-storage.h \
encoding.h \
rados-cluster-impl.h \
rados-storage-impl.h \
rados-dictionary-impl.h \
- rados-mail.h \
- rados-util.h \
- rados-metadata.h \
- rados-types.h \
+ rados-mail-impl.h \
+ rados-util-impl.h \
+ rados-metadata-impl.h \
rados-dovecot-config.h \
- rados-namespace-manager.h \
- rados-dovecot-ceph-cfg.h \
+ rados-namespace-manager-impl.h\
rados-dovecot-ceph-cfg-impl.h \
- rados-ceph-config.h \
- rados-ceph-json-config.h \
- rados-guid-generator.h \
- rados-metadata-storage.h \
+ rados-ceph-config-impl.h \
+ rados-ceph-json-config-impl.h \
rados-metadata-storage-impl.h \
- rados-metadata-storage-module.h \
rados-metadata-storage-default.h \
rados-metadata-storage-ima.h \
- rados-save-log.h
+ rados-save-log-impl.h \
+ rbox-io-ctx-impl.h
+
librmb_la_SOURCES = \
@@ -43,16 +37,16 @@ librmb_la_SOURCES = \
rados-cluster-impl.cpp \
rados-storage-impl.cpp \
rados-dictionary-impl.cpp \
- rados-mail.cpp \
- rados-util.cpp \
+ rados-mail-impl.cpp \
+ rados-util-impl.cpp \
rados-dovecot-config.cpp \
- rados-namespace-manager.cpp\
- rados-ceph-config.cpp \
+ rados-namespace-manager-impl.cpp\
+ rados-ceph-config-impl.cpp \
rados-dovecot-ceph-cfg-impl.cpp \
- rados-ceph-json-config.cpp \
+ rados-ceph-json-config-impl.cpp \
rados-metadata-storage-default.cpp \
rados-metadata-storage-ima.cpp \
- rados-save-log.cpp
+ rados-save-log-impl.cpp
AM_LDFLAGS = $(JANSSON_LIBS)
AM_CFLAGS = $(JANSSON_CFLAGS)
diff --git a/src/librmb/rados-ceph-config.cpp b/src/librmb/rados-ceph-config-impl.cpp
similarity index 71%
rename from src/librmb/rados-ceph-config.cpp
rename to src/librmb/rados-ceph-config-impl.cpp
index dae707a7..028374d1 100644
--- a/src/librmb/rados-ceph-config.cpp
+++ b/src/librmb/rados-ceph-config-impl.cpp
@@ -9,35 +9,41 @@
* Foundation. See file COPYING.
*/
-#include "rados-ceph-config.h"
+#include "rados-ceph-config-impl.h"
#include
#include
#include
+#include "rados-ceph-json-config-impl.h"
namespace librmb {
-RadosCephConfig::RadosCephConfig(librados::IoCtx *io_ctx_) { io_ctx = io_ctx_; }
+RadosCephConfigImpl::RadosCephConfigImpl(storage_interface::RboxIoCtx *io_ctx_) {
+ io_ctx = io_ctx_;
+ if(config==nullptr){
+ config = new librmb::RadosCephJsonConfigImpl();
+ }
+}
-int RadosCephConfig::save_cfg() {
- ceph::bufferlist buffer;
- bool success = config.to_json(&buffer) ? save_object(config.get_cfg_object_name(), buffer) >= 0 : false;
+int RadosCephConfigImpl::save_cfg() {
+ void* buffer=(void*)new ceph::bufferlist();
+ bool success = config->to_json(buffer) ? save_object(config->get_cfg_object_name(), buffer) >= 0 : false;
return success ? 0 : -1;
}
-int RadosCephConfig::load_cfg() {
- if (config.is_valid()) {
+int RadosCephConfigImpl::load_cfg() {
+ if (config->is_valid()) {
return 0;
}
- ceph::bufferlist buffer;
- int ret = read_object(config.get_cfg_object_name(), &buffer);
+ void* buffer=(void*)new ceph::bufferlist();
+ int ret = read_object(config->get_cfg_object_name(), buffer);
if (ret < 0) {
- return ret;
+ return ret;
}
- config.set_valid(true);
- return config.from_json(&buffer) ? 0 : -1;
+ config->set_valid(true);
+ return config->from_json(buffer) ? 0 : -1;
}
-bool RadosCephConfig::is_valid_key_value(const std::string &key, const std::string &value) {
+bool RadosCephConfigImpl::is_valid_key_value(const std::string &key, const std::string &value) {
bool success = false;
if (value.empty() || key.empty()) {
return false;
@@ -65,7 +71,7 @@ bool RadosCephConfig::is_valid_key_value(const std::string &key, const std::stri
return success;
}
-bool RadosCephConfig::update_valid_key_value(const std::string &key, const std::string &value) {
+bool RadosCephConfigImpl::update_valid_key_value(const std::string &key, const std::string &value) {
bool success = false;
if (value.empty() || key.empty()) {
return false;
@@ -101,13 +107,17 @@ bool RadosCephConfig::update_valid_key_value(const std::string &key, const std::
return success;
}
-int RadosCephConfig::save_object(const std::string &oid, librados::bufferlist &buffer) {
+int RadosCephConfigImpl::save_object(const std::string &oid, void* buffer) {
if (io_ctx == nullptr) {
return -1;
}
- return io_ctx->write_full(oid, buffer);
+ ceph::bufferlist *bl=(ceph::bufferlist*)buffer;
+ ceph::bufferlist &bl_ref=*bl;
+ int ret= io_ctx->write_full(oid,bl_ref);
+ delete buffer;
+ return ret;
}
-int RadosCephConfig::read_object(const std::string &oid, librados::bufferlist *buffer) {
+int RadosCephConfigImpl::read_object(const std::string &oid, void* buffer) {
size_t max = INT_MAX;
if (io_ctx == nullptr) {
return -1;
@@ -115,22 +125,22 @@ int RadosCephConfig::read_object(const std::string &oid, librados::bufferlist *b
// retry max times to read the object.
int max_retry = 10;
int ret_read = -1;
-
+ ceph::bufferlist *bl=(ceph::bufferlist*)buffer;
+ ceph::bufferlist &bl_ref=*bl;
for(int i = 0;iread(oid, *buffer, max, 0);
+ ret_read = io_ctx->read(oid,bl_ref, max, 0);
if(ret_read >= 0 || ret_read == -ENOENT ){
// exit here if the file does not exist, or we were successful
break;
}
- buffer->clear();
+ bl_ref.clear();
// wait random time before try again!!
usleep(((rand() % 5) + 1) * 10000);
}
-
return ret_read;
}
-void RadosCephConfig::set_io_ctx_namespace(const std::string &namespace_) {
+void RadosCephConfigImpl::set_io_ctx_namespace(const std::string &namespace_) {
if (io_ctx != nullptr) {
io_ctx->set_namespace(namespace_);
}
diff --git a/src/librmb/rados-ceph-config-impl.h b/src/librmb/rados-ceph-config-impl.h
new file mode 100644
index 00000000..4c909b88
--- /dev/null
+++ b/src/librmb/rados-ceph-config-impl.h
@@ -0,0 +1,94 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Copyright (c) override2017-2018 Tallence AG and the authors
+ *
+ * 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 SRC_LIBRMB_RADOS_CEPH_CONFIG_H_
+#define SRC_LIBRMB_RADOS_CEPH_CONFIG_H_
+
+#include
+#include "../storage-interface/rados-ceph-json-config.h"
+#include "rados-ceph-json-config-impl.h"
+#include "../storage-interface/rados-types.h"
+#include
+#include "../storage-interface/rados-storage.h"
+#include "../storage-interface/rados-ceph-config.h"
+namespace librmb {
+/**
+ * RadosCephConfig
+ *
+ * read Plugin configuration from rados storage
+ */
+class RadosCephConfigImpl : public storage_interface::RadosCephConfig{
+ public:
+ explicit RadosCephConfigImpl(storage_interface::RboxIoCtx *io_ctx_);
+ RadosCephConfigImpl() {
+ io_ctx = nullptr;
+ if(config==nullptr){
+ config=new librmb::RadosCephJsonConfigImpl();
+ }
+ }
+ virtual ~RadosCephConfigImpl() {
+ if(config!=nullptr){
+ delete config;
+ config=nullptr;
+ }
+ }
+
+ // load settings from rados cfg_object
+ int load_cfg() override;
+ int save_cfg() override;
+
+ void set_io_ctx(storage_interface::RboxIoCtx *io_ctx_) override{ io_ctx = io_ctx_; }
+ bool is_config_valid() override{ return config->is_valid(); }
+ void set_config_valid(bool valid_) override{ config->set_valid(valid_); }
+ bool is_user_mapping() override{ return !config->get_user_mapping().compare("true"); }
+ void set_user_mapping(bool value_) override{ config->set_user_mapping(value_ ? "true" : "false"); }
+ void set_user_ns(const std::string &ns_) override{ config->set_user_ns(ns_); }
+ std::string &get_user_ns() override{ return config->get_user_ns(); }
+ void set_user_suffix(const std::string &ns_suffix_) override{ config->set_user_suffix(ns_suffix_); }
+ std::string &get_user_suffix() override{ return config->get_user_suffix(); }
+ const std::string &get_public_namespace()const override { return config->get_public_namespace(); }
+ void set_public_namespace(const std::string &public_namespace_) override{ config->set_public_namespace(public_namespace_); }
+
+ void set_cfg_object_name(const std::string &cfg_object_name_) override{ config->set_cfg_object_name(cfg_object_name_); }
+ std::string get_cfg_object_name() override{ return config->get_cfg_object_name(); }
+ storage_interface::RadosCephJsonConfig *get_config() override{ return config; }
+
+ bool is_valid_key_value(const std::string &key, const std::string &value) override;
+ bool update_valid_key_value(const std::string &key, const std::string &value) override;
+ // bool is_ceph_posix_bugfix_enabled() override;
+ bool is_mail_attribute(storage_interface::rbox_metadata_key key) override{ return config->is_mail_attribute(key); }
+ bool is_updateable_attribute(storage_interface::rbox_metadata_key key) override{ return config->is_updateable_attribute(key); }
+ bool is_update_attributes() override{ return config->is_update_attributes(); }
+ void set_update_attributes(const std::string &update_attributes_) override{
+ config->set_update_attributes(update_attributes_);
+ }
+
+ void update_mail_attribute(const char *value) override{ config->update_mail_attribute(value); }
+ void update_updateable_attribute(const char *value) override{ config->update_updateable_attribute(value); }
+
+ const std::string &get_metadata_storage_module() override{ return config->get_metadata_storage_module(); }
+ const std::string &get_metadata_storage_attribute() override{ return config->get_metadata_storage_attribute(); }
+
+ const std::string &get_mail_attribute_key() override{ return config->get_mail_attribute_key(); }
+ const std::string &get_updateable_attribute_key() override{ return config->get_updateable_attribute_key(); }
+ const std::string &get_update_attributes_key() override{ return config->get_update_attributes_key(); }
+
+ int save_object(const std::string &oid, void* buffer) override;
+ int read_object(const std::string &oid, void* buffer) override;
+ void set_io_ctx_namespace(const std::string &namespace_) override;
+
+ private:
+ storage_interface::RadosCephJsonConfig *config = nullptr;
+ storage_interface::RboxIoCtx *io_ctx = nullptr;
+};
+
+} /* namespace librmb */
+
+#endif /* SRC_LIBRMB_RADOS_CEPH_CONFIG_H_ */
diff --git a/src/librmb/rados-ceph-config.h b/src/librmb/rados-ceph-config.h
deleted file mode 100644
index e9cbccde..00000000
--- a/src/librmb/rados-ceph-config.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-/*
- * Copyright (c) 2017-2018 Tallence AG and the authors
- *
- * 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 SRC_LIBRMB_RADOS_CEPH_CONFIG_H_
-#define SRC_LIBRMB_RADOS_CEPH_CONFIG_H_
-
-#include
-#include "rados-ceph-json-config.h"
-#include "rados-types.h"
-#include
-#include "rados-storage.h"
-
-namespace librmb {
-/**
- * RadosCephConfig
- *
- * read Plugin configuration from rados storage
- */
-class RadosCephConfig {
- public:
- explicit RadosCephConfig(librados::IoCtx *io_ctx_);
- RadosCephConfig() { io_ctx = nullptr; }
- virtual ~RadosCephConfig() {}
-
- // load settings from rados cfg_object
- int load_cfg();
- int save_cfg();
-
- void set_io_ctx(librados::IoCtx *io_ctx_) { io_ctx = io_ctx_; }
- bool is_config_valid() { return config.is_valid(); }
- void set_config_valid(bool valid_) { config.set_valid(valid_); }
- bool is_user_mapping() { return !config.get_user_mapping().compare("true"); }
- void set_user_mapping(bool value_) { config.set_user_mapping(value_ ? "true" : "false"); }
- void set_user_ns(const std::string &ns_) { config.set_user_ns(ns_); }
- std::string &get_user_ns() { return config.get_user_ns(); }
- void set_user_suffix(const std::string &ns_suffix_) { config.set_user_suffix(ns_suffix_); }
- std::string &get_user_suffix() { return config.get_user_suffix(); }
- const std::string &get_public_namespace() const { return config.get_public_namespace(); }
- void set_public_namespace(const std::string &public_namespace_) { config.set_public_namespace(public_namespace_); }
-
- void set_cfg_object_name(const std::string &cfg_object_name_) { config.set_cfg_object_name(cfg_object_name_); }
- std::string get_cfg_object_name() { return config.get_cfg_object_name(); }
- RadosCephJsonConfig *get_config() { return &config; }
-
- bool is_valid_key_value(const std::string &key, const std::string &value);
- bool update_valid_key_value(const std::string &key, const std::string &value);
- bool is_ceph_posix_bugfix_enabled();
- bool is_mail_attribute(enum rbox_metadata_key key) { return config.is_mail_attribute(key); }
- bool is_updateable_attribute(enum rbox_metadata_key key) { return config.is_updateable_attribute(key); }
- bool is_update_attributes() { return config.is_update_attributes(); }
- void set_update_attributes(const std::string &update_attributes_) {
- config.set_update_attributes(update_attributes_);
- }
-
- void update_mail_attribute(const char *value) { config.update_mail_attribute(value); }
- void update_updateable_attribute(const char *value) { config.update_updateable_attribute(value); }
-
- const std::string &get_metadata_storage_module() { return config.get_metadata_storage_module(); }
- const std::string &get_metadata_storage_attribute() { return config.get_metadata_storage_attribute(); }
-
- const std::string &get_mail_attribute_key() { return config.get_mail_attribute_key(); }
- const std::string &get_updateable_attribute_key() { return config.get_updateable_attribute_key(); }
- const std::string &get_update_attributes_key() { return config.get_update_attributes_key(); }
-
- int save_object(const std::string &oid, librados::bufferlist &buffer);
- int read_object(const std::string &oid, librados::bufferlist *buffer);
- void set_io_ctx_namespace(const std::string &namespace_);
-
- private:
- RadosCephJsonConfig config;
- librados::IoCtx *io_ctx;
-};
-
-} /* namespace tallence */
-
-#endif /* SRC_LIBRMB_RADOS_CEPH_CONFIG_H_ */
diff --git a/src/librmb/rados-ceph-json-config.cpp b/src/librmb/rados-ceph-json-config-impl.cpp
similarity index 68%
rename from src/librmb/rados-ceph-json-config.cpp
rename to src/librmb/rados-ceph-json-config-impl.cpp
index 3128a1d0..4e9040aa 100644
--- a/src/librmb/rados-ceph-json-config.cpp
+++ b/src/librmb/rados-ceph-json-config-impl.cpp
@@ -9,14 +9,14 @@
* Foundation. See file COPYING.
*/
-#include "rados-ceph-json-config.h"
+#include "rados-ceph-json-config-impl.h"
#include
#include
#include
namespace librmb {
-RadosCephJsonConfig::RadosCephJsonConfig()
+RadosCephJsonConfigImpl::RadosCephJsonConfigImpl()
: cfg_object_name("rbox_cfg"),
valid(false),
user_mapping("false"),
@@ -39,28 +39,28 @@ RadosCephJsonConfig::RadosCephJsonConfig()
set_default_updateable_attributes();
}
-void RadosCephJsonConfig::set_default_mail_attributes() {
- mail_attributes.append(std::string(1, static_cast(RBOX_METADATA_MAILBOX_GUID)));
- mail_attributes.append(std::string(1, static_cast(RBOX_METADATA_GUID)));
- mail_attributes.append(std::string(1, static_cast(RBOX_METADATA_POP3_UIDL)));
- mail_attributes.append(std::string(1, static_cast(RBOX_METADATA_POP3_ORDER)));
- mail_attributes.append(std::string(1, static_cast(RBOX_METADATA_RECEIVED_TIME)));
- mail_attributes.append(std::string(1, static_cast(RBOX_METADATA_PHYSICAL_SIZE)));
- mail_attributes.append(std::string(1, static_cast(RBOX_METADATA_VIRTUAL_SIZE)));
- mail_attributes.append(std::string(1, static_cast(RBOX_METADATA_ORIG_MAILBOX)));
- mail_attributes.append(std::string(1, static_cast(RBOX_METADATA_MAIL_UID)));
- mail_attributes.append(std::string(1, static_cast(RBOX_METADATA_VERSION)));
+void RadosCephJsonConfigImpl::set_default_mail_attributes() {
+ mail_attributes.append(std::string(1, static_cast(storage_interface::RBOX_METADATA_MAILBOX_GUID)));
+ mail_attributes.append(std::string(1, static_cast(storage_interface::RBOX_METADATA_GUID)));
+ mail_attributes.append(std::string(1, static_cast(storage_interface::RBOX_METADATA_POP3_UIDL)));
+ mail_attributes.append(std::string(1, static_cast(storage_interface::RBOX_METADATA_POP3_ORDER)));
+ mail_attributes.append(std::string(1, static_cast(storage_interface::RBOX_METADATA_RECEIVED_TIME)));
+ mail_attributes.append(std::string(1, static_cast(storage_interface::RBOX_METADATA_PHYSICAL_SIZE)));
+ mail_attributes.append(std::string(1, static_cast(storage_interface::RBOX_METADATA_VIRTUAL_SIZE)));
+ mail_attributes.append(std::string(1, static_cast(storage_interface::RBOX_METADATA_ORIG_MAILBOX)));
+ mail_attributes.append(std::string(1, static_cast(storage_interface::RBOX_METADATA_MAIL_UID)));
+ mail_attributes.append(std::string(1, static_cast(storage_interface::RBOX_METADATA_VERSION)));
}
-void RadosCephJsonConfig::set_default_updateable_attributes() {
- updateable_attributes.append(std::string(1, static_cast(RBOX_METADATA_ORIG_MAILBOX)));
+void RadosCephJsonConfigImpl::set_default_updateable_attributes() {
+ updateable_attributes.append(std::string(1, static_cast(storage_interface::RBOX_METADATA_ORIG_MAILBOX)));
}
-bool RadosCephJsonConfig::from_json(librados::bufferlist *buffer) {
+bool RadosCephJsonConfigImpl::from_json(void* buffer) {
json_t *root;
json_error_t error;
bool ret = false;
- root = json_loads(buffer->to_str().c_str(), 0, &error);
+ root = json_loads(((ceph::bufferlist*)buffer)->to_str().c_str(), 0, &error);
if (root) {
json_t *ns = json_object_get(root, key_user_mapping.c_str());
@@ -93,11 +93,11 @@ bool RadosCephJsonConfig::from_json(librados::bufferlist *buffer) {
ret = valid = true;
json_decref(root);
}
-
+ delete buffer;
return ret;
}
-bool RadosCephJsonConfig::to_json(librados::bufferlist *buffer) {
+bool RadosCephJsonConfigImpl::to_json(void* buffer) {
json_t *root = json_object();
json_object_set_new(root, key_user_mapping.c_str(), json_string(user_mapping.c_str()));
@@ -112,13 +112,13 @@ bool RadosCephJsonConfig::to_json(librados::bufferlist *buffer) {
json_object_set_new(root, key_metadata_storage_attribute.c_str(), json_string(metadata_storage_attribute.c_str()));
char *s = json_dumps(root, 0);
- buffer->append(s);
+ ((ceph::bufferlist*)buffer)->append(s);
free(s);
json_decref(root);
return true;
}
-std::string RadosCephJsonConfig::to_string() {
+std::string RadosCephJsonConfigImpl::to_string() {
std::ostringstream ss;
ss << "Configuration : " << cfg_object_name << std::endl;
ss << " " << key_user_mapping << "=" << user_mapping << std::endl;
@@ -133,21 +133,21 @@ std::string RadosCephJsonConfig::to_string() {
return ss.str();
}
-bool RadosCephJsonConfig::is_mail_attribute(enum rbox_metadata_key key) {
- return mail_attributes.find_first_of(librmb::rbox_metadata_key_to_char(key), 0) != std::string::npos;
+bool RadosCephJsonConfigImpl::is_mail_attribute(storage_interface::rbox_metadata_key key) {
+ return mail_attributes.find_first_of(storage_interface::rbox_metadata_key_to_char(key), 0) != std::string::npos;
}
-bool RadosCephJsonConfig::is_updateable_attribute(enum rbox_metadata_key key) {
- return updateable_attributes.find_first_of(librmb::rbox_metadata_key_to_char(key), 0) != std::string::npos;
+bool RadosCephJsonConfigImpl::is_updateable_attribute(storage_interface::rbox_metadata_key key) {
+ return updateable_attributes.find_first_of(storage_interface::rbox_metadata_key_to_char(key), 0) != std::string::npos;
}
-void RadosCephJsonConfig::update_mail_attribute(const char *value) {
+void RadosCephJsonConfigImpl::update_mail_attribute(const char *value) {
if (value == NULL) {
return;
}
mail_attributes = value;
}
-void RadosCephJsonConfig::update_updateable_attribute(const char *value) {
+void RadosCephJsonConfigImpl::update_updateable_attribute(const char *value) {
if (value == NULL) {
return;
}
diff --git a/src/librmb/rados-ceph-json-config-impl.h b/src/librmb/rados-ceph-json-config-impl.h
new file mode 100644
index 00000000..9191ee1e
--- /dev/null
+++ b/src/librmb/rados-ceph-json-config-impl.h
@@ -0,0 +1,132 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Copyright (c) 2017-2018 Tallence AG and the authors
+ *
+ * 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 SRC_LIBRMB_RADOS_CEPH_JSON_CONFIG_IMPL_H_
+#define SRC_LIBRMB_RADOS_CEPH_JSON_CONFIG_IMPL_H_
+
+#include
+
+#include
+#include "../storage-interface/rados-types.h"
+#include "../storage-interface/rados-ceph-json-config.h"
+
+namespace librmb {
+/**
+ * Rados CephJsonConfig
+ *
+ * Dovecot-Ceph-plugin configuration
+ * Ceph Configuration is json object, class
+ * provides access to json object / Serialize / Deserialize
+ *
+ */
+class RadosCephJsonConfigImpl : public storage_interface::RadosCephJsonConfig {
+ public:
+ RadosCephJsonConfigImpl();
+ virtual ~RadosCephJsonConfigImpl() {}
+
+ bool from_json(void* buffer) override;
+ bool to_json(void* buffer) override;
+ std::string to_string();
+
+ const std::string& get_cfg_object_name() const override{ return cfg_object_name; }
+
+ void set_cfg_object_name(const std::string& cfgObjectName) override{ cfg_object_name = cfgObjectName; }
+
+ const std::string& get_user_mapping() const override{ return user_mapping; }
+
+ void set_user_mapping(const std::string& user_mapping_) override{ user_mapping = user_mapping_; }
+
+ bool is_valid() const override{ return valid; }
+
+ void set_valid(bool isValid) override{ valid = isValid; }
+
+ std::string& get_user_ns() override{ return user_ns; }
+
+ void set_user_ns(const std::string& user_ns_) override{ user_ns = user_ns_; }
+
+ std::string& get_user_suffix() override{ return user_suffix; }
+
+ void set_user_suffix(const std::string& user_suffix_) override{ user_suffix = user_suffix_; }
+
+ const std::string& get_public_namespace() const override{ return public_namespace; }
+
+ void set_public_namespace(const std::string& public_namespace_) override{ public_namespace = public_namespace_; }
+
+ void set_mail_attributes(const std::string& mail_attributes_) override{ mail_attributes = mail_attributes_; }
+ void set_update_attributes(const std::string& update_attributes_) override{ update_attributes = update_attributes_; }
+ void set_updateable_attributes(const std::string& updateable_attributes_) override{
+ updateable_attributes = updateable_attributes_;
+ }
+
+ bool is_mail_attribute(storage_interface::rbox_metadata_key key) override;
+ bool is_updateable_attribute(storage_interface::rbox_metadata_key key) override;
+ bool is_update_attributes() override{ return update_attributes.compare("true") == 0; }
+
+ void set_metadata_storage_module(const std::string& metadata_storage_module_) override{
+ metadata_storage_module = metadata_storage_module_;
+ }
+ const std::string& get_metadata_storage_module() override{ return metadata_storage_module; }
+
+ void set_metadata_storage_attribute(const std::string& metadata_storage_attribute_) override{
+ metadata_storage_attribute = metadata_storage_attribute_;
+ }
+ const std::string& get_metadata_storage_attribute() override{ return metadata_storage_attribute; }
+
+ void update_mail_attribute(const char* value) override;
+ void update_updateable_attribute(const char* value) override;
+
+ const std::string& get_key_user_mapping() const override{ return key_user_mapping; }
+ const std::string& get_key_ns_cfg() const override{ return key_user_ns; }
+ const std::string& get_key_ns_suffix() const override{ return key_user_suffix; }
+ const std::string& get_key_public_namespace() const override{ return key_public_namespace; }
+
+ const std::string& get_mail_attribute_key() override{ return key_mail_attributes; }
+ const std::string& get_updateable_attribute_key() override{ return key_updateable_attributes; }
+ const std::string& get_update_attributes_key() override{ return key_update_attributes; }
+
+ const std::string& get_metadata_storage_module_key() override{ return key_metadata_storage_module; }
+ const std::string& get_metadata_storage_attribute_key() override{ return key_metadata_storage_attribute; }
+
+ private:
+ void set_default_mail_attributes();
+ void set_default_updateable_attributes();
+
+ private:
+ std::string cfg_object_name;
+ bool valid;
+ std::string user_mapping;
+ std::string user_ns;
+ std::string user_suffix;
+ std::string public_namespace;
+
+ std::string mail_attributes;
+ std::string update_attributes;
+ std::string updateable_attributes;
+
+ std::string metadata_storage_module;
+ std::string metadata_storage_attribute;
+
+ std::string key_user_mapping;
+ std::string key_user_ns;
+ std::string key_user_suffix;
+ std::string key_public_namespace;
+
+ std::string key_mail_attributes;
+ std::string key_update_attributes;
+ std::string key_updateable_attributes;
+
+ std::string key_metadata_storage_module;
+ std::string key_metadata_storage_attribute;
+};
+
+} /* namespace librmb */
+
+#endif // SRC_LIBRMB_RADOS_CEPH_JSON_CONFIG_IMPL_H_
diff --git a/src/librmb/rados-ceph-json-config.h b/src/librmb/rados-ceph-json-config.h
deleted file mode 100644
index 8cdffbb6..00000000
--- a/src/librmb/rados-ceph-json-config.h
+++ /dev/null
@@ -1,131 +0,0 @@
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-/*
- * Copyright (c) 2017-2018 Tallence AG and the authors
- *
- * 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 SRC_LIBRMB_RADOS_CEPH_JSON_CONFIG_H_
-#define SRC_LIBRMB_RADOS_CEPH_JSON_CONFIG_H_
-
-#include
-
-#include
-#include "rados-types.h"
-
-namespace librmb {
-/**
- * Rados CephJsonConfig
- *
- * Dovecot-Ceph-plugin configuration
- * Ceph Configuration is json object, class
- * provides access to json object / Serialize / Deserialize
- *
- */
-class RadosCephJsonConfig {
- public:
- RadosCephJsonConfig();
- virtual ~RadosCephJsonConfig() {}
-
- bool from_json(librados::bufferlist* buffer);
- bool to_json(librados::bufferlist* buffer);
- std::string to_string();
-
- const std::string& get_cfg_object_name() const { return cfg_object_name; }
-
- void set_cfg_object_name(const std::string& cfgObjectName) { cfg_object_name = cfgObjectName; }
-
- const std::string& get_user_mapping() const { return user_mapping; }
-
- void set_user_mapping(const std::string& user_mapping_) { user_mapping = user_mapping_; }
-
- bool is_valid() const { return valid; }
-
- void set_valid(bool isValid) { valid = isValid; }
-
- std::string& get_user_ns() { return user_ns; }
-
- void set_user_ns(const std::string& user_ns_) { user_ns = user_ns_; }
-
- std::string& get_user_suffix() { return user_suffix; }
-
- void set_user_suffix(const std::string& user_suffix_) { user_suffix = user_suffix_; }
-
- const std::string& get_public_namespace() const { return public_namespace; }
-
- void set_public_namespace(const std::string& public_namespace_) { public_namespace = public_namespace_; }
-
- void set_mail_attributes(const std::string& mail_attributes_) { mail_attributes = mail_attributes_; }
- void set_update_attributes(const std::string& update_attributes_) { update_attributes = update_attributes_; }
- void set_updateable_attributes(const std::string& updateable_attributes_) {
- updateable_attributes = updateable_attributes_;
- }
-
- bool is_mail_attribute(enum rbox_metadata_key key);
- bool is_updateable_attribute(enum rbox_metadata_key key);
- bool is_update_attributes() { return update_attributes.compare("true") == 0; }
-
- void set_metadata_storage_module(const std::string& metadata_storage_module_) {
- metadata_storage_module = metadata_storage_module_;
- }
- const std::string& get_metadata_storage_module() { return metadata_storage_module; }
-
- void set_metadata_storage_attribute(const std::string& metadata_storage_attribute_) {
- metadata_storage_attribute = metadata_storage_attribute_;
- }
- const std::string& get_metadata_storage_attribute() { return metadata_storage_attribute; }
-
- void update_mail_attribute(const char* value);
- void update_updateable_attribute(const char* value);
-
- const std::string& get_key_user_mapping() const { return key_user_mapping; }
- const std::string& get_key_ns_cfg() const { return key_user_ns; }
- const std::string& get_key_ns_suffix() const { return key_user_suffix; }
- const std::string& get_key_public_namespace() const { return key_public_namespace; }
-
- const std::string& get_mail_attribute_key() { return key_mail_attributes; }
- const std::string& get_updateable_attribute_key() { return key_updateable_attributes; }
- const std::string& get_update_attributes_key() { return key_update_attributes; }
-
- const std::string& get_metadata_storage_module_key() { return key_metadata_storage_module; }
- const std::string& get_metadata_storage_attribute_key() { return key_metadata_storage_attribute; }
-
- private:
- void set_default_mail_attributes();
- void set_default_updateable_attributes();
-
- private:
- std::string cfg_object_name;
- bool valid;
- std::string user_mapping;
- std::string user_ns;
- std::string user_suffix;
- std::string public_namespace;
-
- std::string mail_attributes;
- std::string update_attributes;
- std::string updateable_attributes;
-
- std::string metadata_storage_module;
- std::string metadata_storage_attribute;
-
- std::string key_user_mapping;
- std::string key_user_ns;
- std::string key_user_suffix;
- std::string key_public_namespace;
-
- std::string key_mail_attributes;
- std::string key_update_attributes;
- std::string key_updateable_attributes;
-
- std::string key_metadata_storage_module;
- std::string key_metadata_storage_attribute;
-};
-
-} /* namespace librmb */
-
-#endif // SRC_LIBRMB_RADOS_CEPH_JSON_CONFIG_H_
diff --git a/src/librmb/rados-cluster-impl.cpp b/src/librmb/rados-cluster-impl.cpp
index 64d5347f..1daa52bf 100644
--- a/src/librmb/rados-cluster-impl.cpp
+++ b/src/librmb/rados-cluster-impl.cpp
@@ -17,7 +17,9 @@
#include "rados-dictionary-impl.h"
#include "rados-storage-impl.h"
-#include "rados-util.h"
+#include "rados-util-impl.h"
+#include "rbox-io-ctx-impl.h"
+
using std::list;
using std::pair;
using std::string;
@@ -92,8 +94,8 @@ std::vector RadosClusterImpl::list_pgs_for_pool(std::string &pool_n
librados::bufferlist inbl;
librados::bufferlist outbl;
RadosClusterImpl::cluster->mon_command(cmd, inbl, &outbl, nullptr);
-
- std::vector list = RadosUtils::extractPgs(std::string(outbl.c_str()));
+ librmb::RadosUtilsImpl rados_utils;
+ std::vector list = rados_utils.extractPgs(std::string(outbl.c_str()));
for (auto const &token: list) {
std::cout << token << std::endl;
@@ -116,7 +118,8 @@ std::map> RadosClusterImpl::list_pgs_osd_f
librados::bufferlist inbl;
librados::bufferlist outbl;
RadosClusterImpl::cluster->mon_command(cmd, inbl, &outbl, nullptr);
- return RadosUtils::extractPgAndPrimaryOsd(std::string(outbl.c_str()));
+ librmb::RadosUtilsImpl rados_utils;
+ return rados_utils.extractPgAndPrimaryOsd(std::string(outbl.c_str()));
}
int RadosClusterImpl::initialize() {
int ret = 0;
@@ -200,11 +203,11 @@ int RadosClusterImpl::pool_create(const string &pool) {
return ret;
}
-int RadosClusterImpl::io_ctx_create(const string &pool, librados::IoCtx *io_ctx) {
+int RadosClusterImpl::io_ctx_create(const string &pool, storage_interface::RboxIoCtx *io_ctx_wrapper) {
int ret = 0;
-
- assert(io_ctx != nullptr);
-
+ librados::IoCtx *io_ctx_create=&io_ctx_wrapper->get_io_ctx();
+ assert(io_ctx_create != nullptr);
+
if (RadosClusterImpl::cluster_ref_count == 0) {
ret = -ENOENT;
return ret;
@@ -218,19 +221,20 @@ int RadosClusterImpl::io_ctx_create(const string &pool, librados::IoCtx *io_ctx)
// pool exists? else create
ret = pool_create(pool);
if (ret == 0) {
- ret = RadosClusterImpl::cluster->ioctx_create(pool.c_str(), *io_ctx);
+ ret = RadosClusterImpl::cluster->ioctx_create(pool.c_str(), *io_ctx_create);
}
return ret;
}
int RadosClusterImpl::recovery_index_io_ctx(const std::string &pool,
- librados::IoCtx *io_ctx) {
+ storage_interface::RboxIoCtx *io_ctx_wrapper) {
+ librados::IoCtx *io_ctx_recovery=&io_ctx_wrapper->get_recovery_io_ctx();
if(!is_connected()) {
return -1;
}
// pool exists? else create
int ret = pool_create(pool);
if (ret == 0) {
- ret = RadosClusterImpl::cluster->ioctx_create(pool.c_str(), *io_ctx);
+ ret = RadosClusterImpl::cluster->ioctx_create(pool.c_str(), *io_ctx_recovery);
}
return ret;
}
diff --git a/src/librmb/rados-cluster-impl.h b/src/librmb/rados-cluster-impl.h
index 5fd57016..977142d8 100644
--- a/src/librmb/rados-cluster-impl.h
+++ b/src/librmb/rados-cluster-impl.h
@@ -17,10 +17,11 @@
#include
#include