summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Lang <sam.lang@inktank.com>2012-12-14 09:00:24 -1000
committerSam Lang <sam.lang@inktank.com>2012-12-14 09:00:24 -1000
commitb63940caa11cdf549962ca4eae404c55f7784eac (patch)
treee282a038324264044564507fb8198ba5b03332dc
parent8d73f3e946a86fcc29120f4e778308580943fd3d (diff)
parentf16e571757ef2ce860ed955936257569edb9f9fb (diff)
downloadceph-b63940caa11cdf549962ca4eae404c55f7784eac.tar.gz
Merge branch 'wip-3610' into next
-rw-r--r--doc/architecture.rst185
-rw-r--r--doc/install/os-recommendations.rst23
-rw-r--r--doc/rados/configuration/filestore-config-ref.rst12
-rw-r--r--doc/rados/configuration/ms-ref.rst20
-rw-r--r--doc/rados/deployment/mkcephfs.rst23
-rw-r--r--doc/rados/operations/add-or-rm-osds.rst5
-rw-r--r--doc/rados/operations/control.rst6
-rw-r--r--doc/radosgw/admin/adminops.rst1507
-rw-r--r--doc/radosgw/config.rst4
-rw-r--r--doc/radosgw/s3/python.rst6
-rw-r--r--qa/run_xfstests.sh2
-rw-r--r--qa/run_xfstests_qemu.sh6
-rw-r--r--src/Makefile.am3
-rw-r--r--src/client/Client.cc6
-rw-r--r--src/common/config_opts.h1
-rw-r--r--src/os/FileStore.cc6
-rw-r--r--src/rgw/rgw_cache.h5
-rw-r--r--src/rgw/rgw_tools.cc19
-rw-r--r--src/test/libcephfs/caps.cc50
19 files changed, 1689 insertions, 200 deletions
diff --git a/doc/architecture.rst b/doc/architecture.rst
index e944192ef7e..116ec4110f3 100644
--- a/doc/architecture.rst
+++ b/doc/architecture.rst
@@ -146,15 +146,30 @@ appropriate placement groups in the secondary and tertiary OSDs (as many OSDs as
additional replicas), and responds to the client once it has confirmed the
object was stored successfully.
-.. ditaa:: +--------+ Write +--------------+ Replica 1 +----------------+
- | Client |*-------------->| Primary OSD |*---------------->| Secondary OSD |
- | |<--------------*| |<----------------*| |
- +--------+ Write Ack +--------------+ Replica 1 Ack +----------------+
- ^ *
- | | Replica 2 +----------------+
- | +----------------------->| Tertiary OSD |
- +--------------------------*| |
- Replica 2 Ack +----------------+
+
+.. ditaa::
+ +----------+
+ | Client |
+ | |
+ +----------+
+ * ^
+ Write (1) | | Ack (6)
+ | |
+ v *
+ +-------------+
+ | Primary OSD |
+ | |
+ +-------------+
+ * ^ ^ *
+ Write (2) | | | | Write (3)
+ +------+ | | +------+
+ | +------+ +------+ |
+ | | Ack (4) Ack (5)| |
+ v * * v
+ +---------------+ +---------------+
+ | Secondary OSD | | Tertiary OSD |
+ | | | |
+ +---------------+ +---------------+
Since any network device has a limit to the number of concurrent connections it
@@ -222,82 +237,84 @@ of striping:
If you anticipate large images sizes, large S3 or Swift objects (video), or
-large CephFS files, you may see considerable read/write performance improvements
-by striping client data over mulitple objects within an object set. Significant
-write performance occurs when the client writes the stripe units to their
-corresponding objects simultaneously. Since objects get mapped to different
-placement groups and further mapped to different OSDs, each write occurs
-simultaneously at the maximum write speed. So the stripe count may serve as a
-proxy for the multiple of the performance improvement. Read performance is
-similarly affected. However, setting up connections between the client and the
-OSDs and the network latency also play a role in the overall performance.
+large CephFS directories, you may see considerable read/write performance
+improvements by striping client data over mulitple objects within an object set.
+Significant write performance occurs when the client writes the stripe units to
+their corresponding objects in parallel. Since objects get mapped to different
+placement groups and further mapped to different OSDs, each write occurs in
+parallel at the maximum write speed. A write to a single disk would be limited
+by the head movement (e.g. 6ms per seek) and bandwidth of that one device (e.g.
+100MB/s). By spreading that write over multiple objects (which map to different
+placement groups and OSDs) Ceph can reduce the number of seeks per drive and
+combine the throughput of multiple drives to achieve much faster write (or read)
+speeds.
In the following diagram, client data gets striped across an object set
(``object set 1`` in the following diagram) consisting of 4 objects, where the
-first stripe unit is ``stripe 0`` in ``object 0``, and the fourth stripe unit is
-``stripe 3`` in ``object 3``. After writing the fourth stripe, the client
-determines if the object set is full. If the object set is not full, the client
-begins writing a stripe to the first object again (``object 0`` in the following
-diagram). If the object set is full, the client creates a new object set
-(``object set 2`` in the following diagram), and begins writing to the first
-stripe (``stripe 4``) in the first object in the new object set (``object 4`` in
-the diagram below).
+first stripe unit is ``stripe unit 0`` in ``object 0``, and the fourth stripe
+unit is ``stripe unit 3`` in ``object 3``. After writing the fourth stripe, the
+client determines if the object set is full. If the object set is not full, the
+client begins writing a stripe to the first object again (``object 0`` in the
+following diagram). If the object set is full, the client creates a new object
+set (``object set 2`` in the following diagram), and begins writing to the first
+stripe (``stripe unit 16``) in the first object in the new object set (``object
+4`` in the diagram below).
.. ditaa::
- +---------------+
- | Client Data |
- | Format |
- | cCCC |
- +---------------+
- |
- +-----------------+--------+--------+-----------------+
- | | | | +--\
- v v v v |
- /-----------\ /-----------\ /-----------\ /-----------\ |
- | Begin cCCC| | Begin cCCC| | Begin cCCC| | Begin cCCC| |
- | Object 0 | | Object 1 | | Object 2 | | Object 3 | |
- +-----------+ +-----------+ +-----------+ +-----------+ |
- | stripe | | stripe | | stripe | | stripe | |
- | unit 0 | | unit 1 | | unit 2 | | unit 3 | |
- +-----------+ +-----------+ +-----------+ +-----------+ |
- | stripe | | stripe | | stripe | | stripe | +-\
- | unit 4 | | unit 5 | | unit 6 | | unit 7 | | Object
- +-----------+ +-----------+ +-----------+ +-----------+ +- Set
- | stripe | | stripe | | stripe | | stripe | | 1
- | unit 8 | | unit 9 | | unit 10 | | unit 11 | +-/
- +-----------+ +-----------+ +-----------+ +-----------+ |
- | stripe | | stripe | | stripe | | stripe | |
- | unit 12 | | unit 13 | | unit 14 | | unit 15 | |
- +-----------+ +-----------+ +-----------+ +-----------+ |
- | End cCCC | | End cCCC | | End cCCC | | End cCCC | |
- | Object 0 | | Object 1 | | Object 2 | | Object 3 | |
- \-----------/ \-----------/ \-----------/ \-----------/ |
- |
- +--/
+ +---------------+
+ | Client Data |
+ | Format |
+ | cCCC |
+ +---------------+
+ |
+ +-----------------+--------+--------+-----------------+
+ | | | | +--\
+ v v v v |
+ /-----------\ /-----------\ /-----------\ /-----------\ |
+ | Begin cCCC| | Begin cCCC| | Begin cCCC| | Begin cCCC| |
+ | Object 0 | | Object 1 | | Object 2 | | Object 3 | |
+ +-----------+ +-----------+ +-----------+ +-----------+ |
+ | stripe | | stripe | | stripe | | stripe | |
+ | unit 0 | | unit 1 | | unit 2 | | unit 3 | |
+ +-----------+ +-----------+ +-----------+ +-----------+ |
+ | stripe | | stripe | | stripe | | stripe | +-\
+ | unit 4 | | unit 5 | | unit 6 | | unit 7 | | Object
+ +-----------+ +-----------+ +-----------+ +-----------+ +- Set
+ | stripe | | stripe | | stripe | | stripe | | 1
+ | unit 8 | | unit 9 | | unit 10 | | unit 11 | +-/
+ +-----------+ +-----------+ +-----------+ +-----------+ |
+ | stripe | | stripe | | stripe | | stripe | |
+ | unit 12 | | unit 13 | | unit 14 | | unit 15 | |
+ +-----------+ +-----------+ +-----------+ +-----------+ |
+ | End cCCC | | End cCCC | | End cCCC | | End cCCC | |
+ | Object 0 | | Object 1 | | Object 2 | | Object 3 | |
+ \-----------/ \-----------/ \-----------/ \-----------/ |
+ |
+ +--/
- +--\
- |
- /-----------\ /-----------\ /-----------\ /-----------\ |
- | Begin cCCC| | Begin cCCC| | Begin cCCC| | Begin cCCC| |
- | Object 4 | | Object 5 | | Object 6 | | Object 7 | |
- +-----------+ +-----------+ +-----------+ +-----------+ |
- | stripe | | stripe | | stripe | | stripe | |
- | unit 15 | | unit 16 | | unit 17 | | unit 18 | |
- +-----------+ +-----------+ +-----------+ +-----------+ |
- | stripe | | stripe | | stripe | | stripe | +-\
- | unit 19 | | unit 20 | | unit 21 | | unit 22 | | Object
- +-----------+ +-----------+ +-----------+ +-----------+ +- Set
- | stripe | | stripe | | stripe | | stripe | | 2
- | unit 23 | | unit 24 | | unit 25 | | unit 26 | +-/
- +-----------+ +-----------+ +-----------+ +-----------+ |
- | stripe | | stripe | | stripe | | stripe | |
- | unit 27 | | unit 28 | | unit 29 | | unit 30 | |
- +-----------+ +-----------+ +-----------+ +-----------+ |
- | End cCCC | | End cCCC | | End cCCC | | End cCCC | |
- | Object 4 | | Object 5 | | Object 6 | | Object 7 | |
- \-----------/ \-----------/ \-----------/ \-----------/ |
- |
- +--/
+ +--\
+ |
+ /-----------\ /-----------\ /-----------\ /-----------\ |
+ | Begin cCCC| | Begin cCCC| | Begin cCCC| | Begin cCCC| |
+ | Object 4 | | Object 5 | | Object 6 | | Object 7 | |
+ +-----------+ +-----------+ +-----------+ +-----------+ |
+ | stripe | | stripe | | stripe | | stripe | |
+ | unit 16 | | unit 17 | | unit 18 | | unit 19 | |
+ +-----------+ +-----------+ +-----------+ +-----------+ |
+ | stripe | | stripe | | stripe | | stripe | +-\
+ | unit 20 | | unit 21 | | unit 22 | | unit 23 | | Object
+ +-----------+ +-----------+ +-----------+ +-----------+ +- Set
+ | stripe | | stripe | | stripe | | stripe | | 2
+ | unit 24 | | unit 25 | | unit 26 | | unit 27 | +-/
+ +-----------+ +-----------+ +-----------+ +-----------+ |
+ | stripe | | stripe | | stripe | | stripe | |
+ | unit 28 | | unit 29 | | unit 30 | | unit 31 | |
+ +-----------+ +-----------+ +-----------+ +-----------+ |
+ | End cCCC | | End cCCC | | End cCCC | | End cCCC | |
+ | Object 4 | | Object 5 | | Object 6 | | Object 7 | |
+ \-----------/ \-----------/ \-----------/ \-----------/ |
+ |
+ +--/
Three important variables determine how Ceph stripes data:
@@ -306,9 +323,9 @@ Three important variables determine how Ceph stripes data:
enough to accomodate many stripe units, and should be a multiple of
the stripe unit.
-- **Stripe Unit:** Stripes have a configurable unit size (e.g., 64kb).
+- **Stripe Width:** Stripes have a configurable unit size (e.g., 64kb).
The Ceph client divides the data it will write to objects into equally
- sized stripe units, except for the last stripe unit. A stripe unit,
+ sized stripe units, except for the last stripe unit. A stripe width,
should be a fraction of the Object Size so that an object may contain
many stripe units.
@@ -347,7 +364,11 @@ storage disk. See `How Ceph Scales`_ for details.
get mapped to placement groups in the same pool. So they use the same CRUSH
map and the same access controls.
-.. tip:: The objects Ceph stores in the Object Store are not striped.
+.. tip:: The objects Ceph stores in the Object Store are not striped. RGW, RBD
+ and CephFS automatically stripe their data over multiple RADOS objects.
+ Clients that write directly to the Object Store via ``librados`` must
+ peform the the striping (and parallel I/O) for themselves to obtain these
+ benefits.
Data Consistency
diff --git a/doc/install/os-recommendations.rst b/doc/install/os-recommendations.rst
index 52e9c2fff89..2f101dc4271 100644
--- a/doc/install/os-recommendations.rst
+++ b/doc/install/os-recommendations.rst
@@ -24,7 +24,8 @@ glibc
- **syncfs(2)**: For non-btrfs filesystems such as XFS and ext4 where
more than one ``ceph-osd`` daemon is used on a single server, Ceph
performs signficantly better with the ``syncfs(2)`` system call
- (added in kernel 2.6.39 and glibc 2.14).
+ (added in kernel 2.6.39 and glibc 2.14). New versions of Ceph (v0.55 and
+ later) do not depend on glibc support.
Platforms
@@ -49,12 +50,12 @@ Argonaut (0.48)
+----------+----------+--------------------+--------------+---------+------------+
| Ubuntu | 12.10 | Quantal Quetzal | linux-3.5.4 | 2 | B |
+----------+----------+--------------------+--------------+---------+------------+
-| Debian | 6.0 | Squeeze | linux-2.6.32 | 1, 2 | B |
+| Debian | 6.0 | Squeeze | linux-2.6.32 | 1, 2, 3 | B |
+----------+----------+--------------------+--------------+---------+------------+
-| Debian | 7.0 | Wheezy | linux-3.2.0 | 1, 2 | B |
+| Debian | 7.0 | Wheezy | linux-3.2.0 | 1, 2, 3 | B |
+----------+----------+--------------------+--------------+---------+------------+
-Bobtail (0.55)
+Bobtail (0.56)
--------------
+----------+----------+--------------------+--------------+---------+------------+
@@ -62,17 +63,17 @@ Bobtail (0.55)
+==========+==========+====================+==============+=========+============+
| Ubuntu | 11.04 | Natty Narwhal | linux-2.6.38 | 1, 2, 3 | B |
+----------+----------+--------------------+--------------+---------+------------+
-| Ubuntu | 11.10 | Oneric Ocelot | linux-3.0.0 | 1, 2, 3 | B |
+| Ubuntu | 11.10 | Oneric Ocelot | linux-3.0.0 | 1, 2 | B |
+----------+----------+--------------------+--------------+---------+------------+
| Ubuntu | 12.04 | Precise Pangolin | linux-3.2.0 | 1, 2 | B, I, C |
+----------+----------+--------------------+--------------+---------+------------+
| Ubuntu | 12.10 | Quantal Quetzal | linux-3.5.4 | 2 | B |
+----------+----------+--------------------+--------------+---------+------------+
-| Debian | 6.0 | Squeeze | linux-2.6.32 | 1, 2 | B |
+| Debian | 6.0 | Squeeze | linux-2.6.32 | 1, 2, 3 | B |
+----------+----------+--------------------+--------------+---------+------------+
| Debian | 7.0 | Wheezy | linux-3.2.0 | 1, 2 | B |
+----------+----------+--------------------+--------------+---------+------------+
-| CentOS | 6.3 | N/A | linux-2.6.32 | 1, 2, 3 | B, I |
+| CentOS | 6.3 | N/A | linux-2.6.32 | 1, 2 | B, I |
+----------+----------+--------------------+--------------+---------+------------+
| Fedora | 17.0 | Beefy Miracle | linux-3.3.4 | 1, 2 | B |
+----------+----------+--------------------+--------------+---------+------------+
@@ -93,10 +94,10 @@ Notes
for kernel client (kernel RBD or the Ceph file system). Upgrade to a
recommended kernel.
-- **3**: The installed version of ``glibc`` does not support the
- ``syncfs(2)`` system call. Putting multiple ``ceph-osd`` daemons
- using ``XFS`` or ``ext4`` on the same host will not perform as well as
- they could.
+- **3**: The default kernel or installed version of ``glibc`` does not
+ support the ``syncfs(2)`` system call. Putting multiple
+ ``ceph-osd`` daemons using ``XFS`` or ``ext4`` on the same host will
+ not perform as well as they could.
Testing
-------
diff --git a/doc/rados/configuration/filestore-config-ref.rst b/doc/rados/configuration/filestore-config-ref.rst
index e45c0f7a9fc..80aed8e81a4 100644
--- a/doc/rados/configuration/filestore-config-ref.rst
+++ b/doc/rados/configuration/filestore-config-ref.rst
@@ -205,7 +205,7 @@ Journal
``filestore journal parallel``
-:Description:
+:Description: Enables parallel journaling, default for btrfs.
:Type: Boolean
:Required: No
:Default: ``false``
@@ -213,7 +213,7 @@ Journal
``filestore journal writeahead``
-:Description:
+:Description: Enables writeahead journaling, default for xfs.
:Type: Boolean
:Required: No
:Default: ``false``
@@ -221,7 +221,7 @@ Journal
``filestore journal trailing``
-:Description:
+:Description: Deprecated, never use.
:Type: Boolean
:Required: No
:Default: ``false``
@@ -233,7 +233,7 @@ Misc
``filestore merge threshold``
-:Description:
+:Description: Min number of files in a subdir before merging into parent
:Type: Integer
:Required: No
:Default: ``10``
@@ -241,7 +241,7 @@ Misc
``filestore split multiple``
-:Description:
+:Description: filestore_split_multiple*filestore_merge_threshold*16 is the max files in a subdir before splitting into child directories.
:Type: Integer
:Required: No
:Default: ``2``
@@ -249,7 +249,7 @@ Misc
``filestore update to``
-:Description:
+:Description: Limits filestore auto upgrade to specified version.
:Type: Integer
:Required: No
:Default: ``1000``
diff --git a/doc/rados/configuration/ms-ref.rst b/doc/rados/configuration/ms-ref.rst
index d76f7f3bb25..d0b1b172d7f 100644
--- a/doc/rados/configuration/ms-ref.rst
+++ b/doc/rados/configuration/ms-ref.rst
@@ -5,7 +5,7 @@
``ms tcp nodelay``
-:Description:
+:Description: Disables nagle's algorithm on messenger tcp sessions.
:Type: Boolean
:Required: No
:Default: ``true``
@@ -13,7 +13,7 @@
``ms initial backoff``
-:Description:
+:Description: The initial time to wait before reconnecting on a fault.
:Type: Double
:Required: No
:Default: ``.2``
@@ -21,7 +21,7 @@
``ms max backoff``
-:Description:
+:Description: The maximum time to wait before reconnecting on a fault.
:Type: Double
:Required: No
:Default: ``15.0``
@@ -29,7 +29,7 @@
``ms nocrc``
-:Description:
+:Description: Disables crc on network messages. May increase performance if cpu limited.
:Type: Boolean
:Required: No
:Default: ``false``
@@ -37,7 +37,7 @@
``ms die on bad msg``
-:Description:
+:Description: Debug option; do not configure.
:Type: Boolean
:Required: No
:Default: ``false``
@@ -45,7 +45,7 @@
``ms dispatch throttle bytes``
-:Description:
+:Description: Throttles total size of messages waiting to be dispatched.
:Type: 64-bit Unsigned Integer
:Required: No
:Default: ``100 << 20``
@@ -53,7 +53,7 @@
``ms bind ipv6``
-:Description:
+:Description: Enable if you want your daemons to bind to IPv6 address instead of IPv4 ones. (Not required if you specify a daemon or cluster IP.)
:Type: Boolean
:Required: No
:Default: ``false``
@@ -61,7 +61,7 @@
``ms rwthread stack bytes``
-:Description:
+:Description: Debug option for stack size; do not configure.
:Type: 64-bit Unsigned Integer
:Required: No
:Default: ``1024 << 10``
@@ -69,7 +69,7 @@
``ms tcp read timeout``
-:Description:
+:Description: Controls how long (in seconds) the messenger will wait before closing an idle connection.
:Type: 64-bit Unsigned Integer
:Required: No
:Default: ``900``
@@ -77,7 +77,7 @@
``ms inject socket failures``
-:Description:
+:Description: Debug option; do not configure.
:Type: 64-bit Unsigned Integer
:Required: No
:Default: ``0``
diff --git a/doc/rados/deployment/mkcephfs.rst b/doc/rados/deployment/mkcephfs.rst
index a6531ec84d7..fc37c7b7922 100644
--- a/doc/rados/deployment/mkcephfs.rst
+++ b/doc/rados/deployment/mkcephfs.rst
@@ -19,7 +19,7 @@ Enter a password for the root user.
On the admin host, generate an ``ssh`` key without specifying a passphrase
and use the default locations. ::
- sudo -s
+ sudo -i
ssh-keygen
Generating public/private key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
@@ -27,14 +27,8 @@ and use the default locations. ::
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
-
-You may use RSA or DSA keys. Once you generate your keys, copy them to each
-OSD host. For example::
-
- ssh-copy-id root@myserver01
- ssh-copy-id root@myserver02
-Modify your ``~/.ssh/config`` file to login as ``root``, as follows::
+Modify your ``/root/.ssh/config`` file to login as ``root``, as follows::
Host myserver01
Hostname myserver01.fully-qualified-domain.com
@@ -43,6 +37,11 @@ Modify your ``~/.ssh/config`` file to login as ``root``, as follows::
Hostname myserver02.fully-qualified-domain.com
User root
+You may use RSA or DSA keys. Once you generate your keys, copy them to each
+OSD host. For example::
+
+ ssh-copy-id root@myserver01
+ ssh-copy-id root@myserver02
Copy Configuration File to All Hosts
====================================
@@ -55,9 +54,9 @@ if you are using ``mkcephfs`` to deploy Ceph.
::
- ssh myserver01 sudo tee /etc/ceph/ceph.conf < /etc/ceph/ceph.conf
- ssh myserver02 sudo tee /etc/ceph/ceph.conf < /etc/ceph/ceph.conf
- ssh myserver03 sudo tee /etc/ceph/ceph.conf < /etc/ceph/ceph.conf
+ sudo ssh myserver01 tee /etc/ceph/ceph.conf < /etc/ceph/ceph.conf
+ sudo ssh myserver02 tee /etc/ceph/ceph.conf < /etc/ceph/ceph.conf
+ sudo ssh myserver03 tee /etc/ceph/ceph.conf < /etc/ceph/ceph.conf
Create the Default Directories
@@ -115,7 +114,7 @@ root password. See `Authentication`_ when running with ``cephx`` enabled.
When you start or stop your cluster, you will not have to use ``sudo`` or
provide passwords. For example::
- service ceph -a start
+ sudo service ceph -a start
See `Operating a Cluster`_ for details.
diff --git a/doc/rados/operations/add-or-rm-osds.rst b/doc/rados/operations/add-or-rm-osds.rst
index fa377b3c58f..f60ddc6970f 100644
--- a/doc/rados/operations/add-or-rm-osds.rst
+++ b/doc/rados/operations/add-or-rm-osds.rst
@@ -107,10 +107,9 @@ hard disks than older hosts in the cluster (i.e., they may have greater weight).
ssh {new-osd} sudo tee /etc/ceph/ceph.conf < /etc/ceph/ceph.conf
-#. Create the OSD. ::
+#. Create the OSD. If no UUID is given, it will be set automatically when the OSD starts up. ::
- ceph osd create {osd-num}
- ceph osd create 123 #for example
+ ceph osd create [{uuid}]
#. Initialize the OSD data directory. ::
diff --git a/doc/rados/operations/control.rst b/doc/rados/operations/control.rst
index 4a88955d3f4..ced336d376c 100644
--- a/doc/rados/operations/control.rst
+++ b/doc/rados/operations/control.rst
@@ -151,10 +151,10 @@ Mark an OSD as lost. This may result in permanent data loss. Use with caution. :
ceph osd lost [--yes-i-really-mean-it]
-Create a new OSD. If no ID is given, a new ID is automatically selected
-if possible. ::
+Create a new OSD. If no UUID is given, it will be set automatically when the OSD
+starts up. ::
- ceph osd create [{id}]
+ ceph osd create [{uuid}]
Remove the given OSD(s). ::
diff --git a/doc/radosgw/admin/adminops.rst b/doc/radosgw/admin/adminops.rst
index 211a8e21259..b90c8a93f86 100644
--- a/doc/radosgw/admin/adminops.rst
+++ b/doc/radosgw/admin/adminops.rst
@@ -67,17 +67,17 @@ If successful, the response contains the requested information.
``usage``
-:Description: A container for the usage information
+:Description: A container for the usage information.
:Type: Container
``entries``
-:Description: A container for the usage entries information
+:Description: A container for the usage entries information.
:Type: Container
``user``
-:Description: A container for the user data information
+:Description: A container for the user data information.
:Type: Container
``owner``
@@ -192,3 +192,1504 @@ Request Parameters
:Required: No
+Get User Info
+=============
+
+Get user information.
+
+Syntax
+~~~~~~
+
+::
+
+ GET /{admin}/user HTTP/1.1
+ Host: {fqdn}
+
+
+Request Parameters
+~~~~~~~~~~~~~~~~~~
+
+``uid``
+
+:Description: The user for which the information is requested.
+:Type: String
+:Required: Yes
+
+
+Response Entities
+~~~~~~~~~~~~~~~~~
+
+If successful, the response contains the user information.
+
+``user``
+
+:Description: A container for the user data information.
+:Type: Container
+
+``user_id``
+
+:Description: The user id.
+:Type: String
+
+``display_name``
+
+:Description: Display name for the user.
+:Type: String
+
+``suspended``
+
+:Description: True if the user is suspended.
+:Type: Boolean
+
+``max_buckets``
+
+:Description: The maximum number of buckets to be owned by the user.
+:Type: Integer
+
+``subusers``
+
+:Description: Subusers associated with this user account.
+:Type: Container
+
+``keys``
+
+:Description: S3 keys associated with this user account.
+:Type: Container
+
+``swift_keys``
+
+:Description: Swift keys associated with this user account.
+:Type: Container
+
+``caps``
+
+:Description: User capabilities.
+:Type: Container
+
+
+Create User
+===========
+
+Create a new user.
+
+Syntax
+~~~~~~
+
+::
+
+ PUT /{admin}/user HTTP/1.1
+ Host: {fqdn}
+
+
+
+Request Parameters
+~~~~~~~~~~~~~~~~~~
+
+``uid``
+
+:Description: The user ID to be created.
+:Type: String
+:Example ``foo_user``
+:Required: Yes
+
+``display-name``
+
+:Description: The display name of the user to be created.
+:Type: String
+:Example: ``foo user``
+:Required: Yes
+
+
+``email``
+
+:Description: The email address associated with the user.
+:Type: String
+:Example" ``foo@bar.com``
+:Required: No
+
+``key-type``
+
+:Description: Key type to be generated, options are: swift, s3 (default)
+:Type: String
+:Example: ``s3``
+:Required: No
+
+``secret``
+
+:Description: Specify secret key
+:Type: String
+:Example: ``0AbCDEFg1h2i34JklM5nop6QrSTUV+WxyzaBC7D8``
+:Required: No
+
+
+Response Entities
+~~~~~~~~~~~~~~~~~
+
+If successful, the response contains the user information.
+
+``user``
+
+:Description: A container for the user data information.
+:Type: Container
+
+``user_id``
+
+:Description: The user id.
+:Type: String
+
+``display_name``
+
+:Description: Display name for the user.
+:Type: String
+
+``suspended``
+
+:Description: True if the user is suspended.
+:Type: Boolean
+
+``max_buckets``
+
+:Description: The maximum number of buckets to be owned by the user.
+:Type: Integer
+
+``subusers``
+
+:Description: Subusers associated with this user account.
+:Type: Container
+
+``keys``
+
+:Description: S3 keys associated with this user account.
+:Type: Container
+
+``swift_keys``
+
+:Description: Swift keys associated with this user account.
+:Type: Container
+
+``caps``
+
+:Description: User capabilities.
+:Type: Container
+
+Modify User
+===========
+
+Modify a user.
+
+Syntax
+~~~~~~
+
+::
+
+ POST /{admin}/user HTTP/1.1
+ Host: {fqdn}
+
+
+Request Parameters
+~~~~~~~~~~~~~~~~~~
+
+``uid``
+
+:Description: The user ID to be modified.
+:Type: String
+:Example ``foo_user``
+:Required: No
+
+``display-name``
+
+:Description: The display name of the user to be modified.
+:Type: String
+:Example: ``foo user``
+:Required: No
+
+``email``
+
+:Description: The email address to be associated with the user.
+:Type: String
+:Example" ``foo@bar.com``
+:Required: No
+
+``gen-secret``
+
+:Description: Generate a new secret key.
+:Type: Boolean
+:Example: True
+:Required: No
+
+``key-type``
+
+:Description: Key type to be generated, options are: swift, s3 (default)
+:Type: String
+:Example: ``s3``
+:Required: No
+
+
+Response Entities
+~~~~~~~~~~~~~~~~~
+
+If successful, the response contains the user information.
+
+``user``
+
+:Description: A container for the user data information.
+:Type: Container
+
+``user_id``
+
+:Description: The user id.
+:Type: String
+
+``display_name``
+
+:Description: Display name for the user.
+:Type: String
+
+``suspended``
+
+:Description: True if the user is suspended.
+:Type: Boolean
+
+``max_buckets``
+
+:Description: The maximum number of buckets to be owned by the user.
+:Type: Integer
+
+``subusers``
+
+:Description: Subusers associated with this user account.
+:Type: Container
+
+``keys``
+
+:Description: S3 keys associated with this user account.
+:Type: Container
+
+``swift_keys``
+
+:Description: Swift keys associated with this user account.
+:Type: Container
+
+``caps``
+
+:Description: User capabilities.
+:Type: Container
+
+Remove User
+===========
+
+Remove an existing user.
+
+Syntax
+~~~~~~
+
+::
+
+ DELETE /{admin}/user HTTP/1.1
+ Host: {fqdn}
+
+
+Request Parameters
+~~~~~~~~~~~~~~~~~~
+
+``uid``
+
+:Description: The user ID to be removed.
+:Type: String
+:Example ``foo_user``
+:Required: Yes.
+
+``purge-data``
+
+:Description: When specified the buckets and objects belonging
+ to the user will also be removed.
+:Type: Boolean
+:Example: True
+:Required: No
+
+Response Entities
+~~~~~~~~~~~~~~~~~
+
+TBD.
+
+Create Subuser
+==============
+
+Create a new subuser (primarily useful for clients using the Swift API)
+
+Syntax
+~~~~~~
+
+::
+
+ PUT /{admin}/user/?subuser
+ Host {fqdn}
+
+
+Request Parameters
+~~~~~~~~~~~~~~~~~~
+
+``uid``
+
+:Description: The user ID under which a subuser is to be created.
+:Type: String
+:Example ``foo_user``
+:Required: Yes
+
+
+``subuser``
+
+:Description: The subuser ID to be created
+:Type: String
+:Example: ``sub_foo``
+:Required: Yes
+
+``gen-secret``
+
+:Description: Generate a secret key for the subuser.
+:Type: Boolean
+:Example: True
+:Required: No
+
+``key-type``
+
+:Description: Key type to be generated, options are: swift, s3 (default)
+:Type: String
+:Example: ``swift``
+:Required: No
+
+``access``
+
+:Description: Set access permissions for sub-user, should be one
+ of read, write, readwrite, full
+:Type: String
+:Example: ``read``
+:Required: No
+
+
+Response Entities
+~~~~~~~~~~~~~~~~~
+
+If successful, the response contains the user information.
+
+``user``
+
+:Description: A container for the user data information.
+:Type: Container
+
+``user_id``
+
+:Description: The user id.
+:Type: String
+
+``display_name``
+
+:Description: Display name for the user.
+:Type: String
+
+``suspended``
+
+:Description: True if the user is suspended.
+:Type: Boolean
+
+``max_buckets``
+
+:Description: The maximum number of buckets to be owned by the user.
+:Type: Integer
+
+``subusers``
+
+:Description: Subusers associated with this user account.
+:Type: Container
+
+``keys``
+
+:Description: S3 keys associated with this user account.
+:Type: Container
+
+``swift_keys``
+
+:Description: Swift keys associated with this user account.
+:Type: Container
+
+``caps``
+
+:Description: User capabilities.
+:Type: Container
+
+Modify Subuser
+==============
+
+Modify an existing subuser
+
+Syntax
+~~~~~~
+
+::
+
+ POST /{admin}/user/?subuser
+ Host {fqdn}
+
+
+Request Parameters
+~~~~~~~~~~~~~~~~~~
+
+``uid``
+
+:Description: The user ID under which the subuser is to be modified.
+:Type: String
+:Example ``foo_user``
+:Required: Yes
+
+
+``subuser``
+
+:Description: The subuser ID to be modified.
+:Type: String
+:Example: ``sub_foo``
+:Required: Yes
+
+``gen-secret``
+
+:Description: Generate a new secret key for the subuser.
+:Type: Boolean
+:Example: True
+:Required: No
+
+``key-type``
+
+:Description: Key type to be generated, options are: swift, s3 (default)
+:Type: String
+:Example: ``s3``
+:Required: No
+
+``access``
+
+:Description: Set access permissions for sub-user, should be one
+ of read, write, readwrite, full
+:Type: String
+:Example: ``read``
+:Required: No
+
+
+Response Entities
+~~~~~~~~~~~~~~~~~
+
+If successful, the response contains the user information.
+
+``user``
+
+:Description: A container for the user data information.
+:Type: Container
+
+``user_id``
+
+:Description: The user id.
+:Type: String
+
+``display_name``
+
+:Description: Display name for the user.
+:Type: String
+
+``suspended``
+
+:Description: True if the user is suspended.
+:Type: Boolean
+
+``max_buckets``
+
+:Description: The maximum number of buckets to be owned by the user.
+:Type: Integer
+
+``subusers``
+
+:Description: Subusers associated with this user account.
+:Type: Container
+
+``keys``
+
+:Description: S3 keys associated with this user account.
+:Type: Container
+
+``swift_keys``
+
+:Description: Swift keys associated with this user account.
+:Type: Container
+
+``caps``
+
+:Description: User capabilities.
+:Type: Container
+
+Remove Subuser
+==============
+
+Remove an existing subuser
+
+Syntax
+~~~~~~
+
+::
+
+ DELETE /{admin}/subuser
+ Host {fqdn}
+
+
+Request Parameters
+~~~~~~~~~~~~~~~~~~
+
+``uid``
+
+:Description: The user ID under which the subuser is to be removed.
+:Type: String
+:Example ``foo_user``
+:Required: Yes
+
+
+``subuser``
+
+:Description: The subuser ID to be removed.
+:Type: String
+:Example: ``sub_foo``
+:Required: Yes
+
+``purge-keys``
+
+:Description: Remove keys belonging to the subuser.
+:Type: Boolean
+:Example: True
+:Required: No
+
+``purge-data``
+:Description: Remove data belonging to the subuser.
+:Type: Boolean
+:Example: True
+:Required: No
+
+Response Entities
+~~~~~~~~~~~~~~~~~
+
+If successful, the response contains the user information.
+
+``user``
+
+:Description: A container for the user data information.
+:Type: Container
+
+``user_id``
+
+:Description: The user id.
+:Type: String
+
+``display_name``
+
+:Description: Display name for the user.
+:Type: String
+
+``suspended``
+
+:Description: True if the user is suspended.
+:Type: Boolean
+
+``max_buckets``
+
+:Description: The maximum number of buckets to be owned by the user.
+:Type: Integer
+
+``subusers``
+
+:Description: Subusers associated with this user account.
+:Type: Container
+
+``keys``
+
+:Description: S3 keys associated with this user account.
+:Type: Container
+
+``swift_keys``
+
+:Description: Swift keys associated with this user account.
+:Type: Container
+
+``caps``
+
+:Description: User capabilities.
+:Type: Container
+
+Create Key
+==========
+
+Create a new key.
+
+Syntax
+~~~~~~
+
+::
+
+ PUT /{admin}/key
+ Host {fqdn}
+
+
+Request Parameters
+~~~~~~~~~~~~~~~~~~
+
+``uid``
+
+:Description: The user ID to receive the new key.
+:Type: String
+:Example ``foo_user``
+:Required: Yes
+
+``subuser``
+
+:Description: The subuser ID to receive the new key.
+:Type: String
+:Example: ``sub_foo``
+:Required: No
+
+``key-type``
+
+:Description: Key type to be generated, options are: swift, s3 (default).
+:Type: String
+:Example: ``s3``
+:Required: No
+
+``secret``
+
+:Description: Specify the secret key
+:Type: String
+:Example: ``0ab/CdeFGhij1klmnopqRSTUv1WxyZabcDEFgHij``
+:Required: No
+
+Remove Key
+==========
+
+Remove an existing key.
+
+Syntax
+~~~~~~
+
+::
+
+ DELETE /{admin}/key
+ Host {fqdn}
+
+
+Request Parameters
+~~~~~~~~~~~~~~~~~~
+
+``access-key``
+
+:Description: The S3 access key belonging to the S3 keypair to remove.
+:Type: String
+:Example: ``AB01C2D3EF45G6H7IJ8K``
+:Required: Yes
+
+``uid``
+
+:Description: The user to remove the key from.
+:Type: String
+:Example ``foo_user``
+:Required: No
+
+``subuser``
+
+:Description: The subuser to remove the key from.
+:Type: String
+:Example: ``sub_foo``
+:Required: No
+
+``key-type``
+
+:Description: Key type to be removed, options are: swift, s3.
+ NOTE: Required to remove swift key.
+:Type: String
+:Example: ``swift``
+:Required: No
+
+
+Get Bucket
+==========
+
+Get information for an existing bucket, if no request parameters are
+included lists buckets.
+
+Syntax
+~~~~~~
+
+::
+
+ GET /{admin}/bucket
+ Host {fqdn}
+
+
+Request Parameters
+~~~~~~~~~~~~~~~~~~
+
+``bucket``
+
+:Description: The bucket to return info on.
+:Type: String
+:Example: ``foo_bucket``
+:Required: Yes
+
+
+``list``
+
+:Description: Return list of buckets.
+:Type: Boolean
+:Example: True
+:Required: No
+
+``stats``
+
+:Description: Return bucket statistics.
+:Type: Boolean
+:Example: True
+:Required: No
+
+``check``
+
+:Description: Check bucket index.
+:Type: Boolean
+:Example: False
+:Required: No
+
+``fix``
+
+:Description: Also fix the bucket index when checking.
+:Type: Boolean
+:Example: False
+:Required: No
+
+Response Entities
+~~~~~~~~~~~~~~~~~
+
+If successful the request returns a buckets container containing
+the desired bucket information.
+
+``buckets``
+
+:Description: Contains a list of one or more bucket containers.
+:Type: Container
+
+``stats``
+
+:Description: Per bucket information.
+:Type: Container
+
+``bucket``
+
+:Description: The name of the bucket.
+:Type: String
+
+``pool``
+
+:Desciption: The pool the bucket is stored in.
+:Type: String
+
+``id``
+
+:Description: The unique bucket id.
+:Type: String
+
+``marker``
+
+:Description:
+:Type: String
+
+``owner``
+
+:Description: The user id of the bucket owner.
+:Type: String
+
+``usage``
+
+:Description: Storage usage information.
+:Type: Container
+
+Check Bucket Index
+==================
+
+Check the index of an existing bucket.
+
+Syntax
+~~~~~~
+
+::
+
+ GET /{admin}/bucket/?index
+ Host {fqdn}
+
+
+Request Parameters
+~~~~~~~~~~~~~~~~~~
+
+``bucket``
+
+:Description: The bucket to return info on.
+:Type: String
+:Example: ``foo_bucket``
+:Required: Yes
+
+``fix``
+
+:Description: Also fix the bucket index when checking.
+:Type: Boolean
+:Example: False
+:Required: No
+
+Response Entities
+~~~~~~~~~~~~~~~~~
+
+TBD
+
+Remove Bucket
+=============
+
+Delete an existing bucket.
+
+Syntax
+~~~~~~
+
+::
+
+ DELETE /{admin}/bucket
+ Host {fqdn}
+
+
+
+Request Parameters
+~~~~~~~~~~~~~~~~~~
+
+``bucket``
+
+:Description: The bucket to remove.
+:Type: String
+:Example: ``foo_bucket``
+:Required: Yes
+
+``delete``
+
+:Description: Parameter specifying the bucket is to be removed.
+:Type: Boolean
+:Example: True
+:Required: Yes
+
+``purge-objects``
+
+:Description: Remove a buckets objects before deletion.
+:Type: Boolean
+:Example: True
+:Required: No
+
+
+Unlink Bucket
+=============
+
+Unlink a bucket from a specified user.
+
+Syntax
+~~~~~~
+
+::
+
+ DELETE /{admin}/bucket
+ Host {fqdn}
+
+
+Request Parameters
+~~~~~~~~~~~~~~~~~~
+
+``bucket``
+
+:Description: The bucket to unlink.
+:Type: String
+:Example: ``foo_bucket``
+:Required: Yes
+
+``unlink``
+
+:Description: Parameter specifying that the bucket is to
+ be unlinked, not removed.
+:Type: Boolean
+:Example: True
+:Required: Yes
+
+``uid``
+
+:Description: The user ID to unlink the bucket from.
+:Type: String
+:Example ``foo_user``
+:Required: Yes
+
+Response Entities
+~~~~~~~~~~~~~~~~~
+
+TBD.
+
+Link Bucket
+===========
+
+Link a bucket to a specified user.
+
+Syntax
+~~~~~~
+
+::
+
+ PUT /{admin}/bucket
+ Host {fqdn}
+
+
+Request Parameters
+~~~~~~~~~~~~~~~~~~
+
+``bucket``
+
+:Description: The bucket to unlink.
+:Type: String
+:Example: ``foo_bucket``
+:Required: Yes
+
+``uid``
+
+:Description: The user ID to link the bucket to.
+:Type: String
+:Example ``foo_user``
+:Required: Yes
+
+Response Entities
+~~~~~~~~~~~~~~~~~
+
+TBD.
+
+Get Object
+==========
+
+Get an existing object.
+
+Syntax
+~~~~~~
+
+::
+
+ GET /{admin}/object
+ Host {fqdn}
+
+Request Parameters
+~~~~~~~~~~~~~~~~~~
+
+``bucket``
+
+:Description: The bucket containing the object to be retrieved.
+:Type: String
+:Example: ``foo_bucket``
+:Required: Yes
+
+``object``
+
+:Description: The object to be retrieved.
+:Type: String
+:Example: ``foo.txt``
+:Required: Yes
+
+Response Entities
+~~~~~~~~~~~~~~~~~
+
+If successful, returns the desired object.
+
+``object``
+
+:Description: The desired object.
+:Type: Object
+
+Remove Object
+=============
+
+Remove an existing object.
+
+Syntax
+~~~~~~
+
+::
+
+ DELETE /{admin}/object
+ Host {fqdn}
+
+Request Parameters
+~~~~~~~~~~~~~~~~~~
+
+``bucket``
+
+:Description: The bucket containing the object to be removed.
+:Type: String
+:Example: ``foo_bucket``
+:Required: Yes
+
+``object``
+
+:Description: The object to remove.
+:Type: String
+:Example: ``foo.txt``
+:Required: Yes
+
+Response Entities
+~~~~~~~~~~~~~~~~~
+
+TBD.
+
+Get Cluster Info
+================
+
+Get cluster information.
+
+Syntax
+~~~~~~
+
+::
+
+ GET /{admin}/cluster
+ Host {fqdn}
+
+
+Response Entities
+~~~~~~~~~~~~~~~~~
+
+If successful, returns cluster pool configuration.
+
+``cluster``
+
+:Description: Contains current cluster pool configuration.
+:Type: Container
+
+
+Add Placement Pool
+==================
+
+Make a pool available for data placement.
+
+Syntax
+~~~~~~
+
+::
+
+ PUT /{admin}/pool
+ Host {fqdn}
+
+
+Request Parameters
+~~~~~~~~~~~~~~~~~~
+
+``pool``
+
+:Description: The pool to be made available for data placement.
+:Type: String
+:Example: ``foo_pool``
+:Required: Yes
+
+``create``
+
+:Description: Creates the data pool if it does not exist.
+:Type: Boolean
+:Example: False
+:Required: No
+
+Response Entities
+~~~~~~~~~~~~~~~~~
+
+TBD.
+
+Remove Placement Pool
+=====================
+
+Make a pool unavailable for data placement.
+
+Syntax
+~~~~~~
+
+::
+
+ DELETE /{admin}/pool
+ Host {fqdn}
+
+
+Request Parameters
+~~~~~~~~~~~~~~~~~~
+
+``pool``
+
+:Description: The existing pool to be made available for data placement.
+:Type: String
+:Example: ``foo_pool``
+:Required: Yes
+
+``destroy``
+
+:Description: Destroys the pool after removing it from the active set.
+:Type: Boolean
+:Example: False
+:Required: No
+
+Response Entities
+~~~~~~~~~~~~~~~~~
+
+TBD.
+
+List Available Data Placement Pools
+===================================
+
+List current pools available for data placement.
+
+Syntax
+~~~~~~
+
+::
+
+ GET /{admin}/pool
+ Host {fqdn}
+
+
+Response Entities
+~~~~~~~~~~~~~~~~~
+
+If successful, returns a list of pools available for data placement.
+
+``pools``
+
+:Description: Contains currently available pools for data placement.
+:Type: Container
+
+Get Bucket or Object Policy
+===========================
+
+Read the policy of an object or bucket.
+
+Syntax
+~~~~~~
+
+::
+
+ GET /{admin}/policy
+ Host {fqdn}
+
+
+Request Parameters
+~~~~~~~~~~~~~~~~~~
+
+``bucket``
+
+:Description: The bucket to read the policy from.
+:Type: String
+:Example: ``foo_bucket``
+:Required: No
+
+``object``
+
+:Description: The object to read the policy from.
+:Type: String
+:Example: ``foo.txt``
+:Required: No
+
+Response Entities
+~~~~~~~~~~~~~~~~~
+
+If successful, returns the object or bucket policy
+
+``policy``
+
+:Description: Access control policy.
+:Type: Container
+
+Add A User Capability
+=====================
+
+Add an administrative capability to a specified user.
+
+Syntax
+~~~~~~
+
+::
+
+ PUT /{admin}/caps
+ Host {fqdn}
+
+Request Parameters
+~~~~~~~~~~~~~~~~~~
+
+``uid``
+
+:Description: The user ID to add an administrative capability to.
+:Type: String
+:Example ``foo_user``
+:Required: Yes
+
+``caps``
+
+:Description: The administrative capability to add to the user.
+:Type: String
+:Example: ``usage=read, write``
+:Required: Yes
+
+Response Entities
+~~~~~~~~~~~~~~~~~
+
+If successful, the response contains the user information.
+
+``user``
+
+:Description: A container for the user data information.
+:Type: Container
+
+``user_id``
+
+:Description: The user id.
+:Type: String
+
+``display_name``
+
+:Description: Display name for the user.
+:Type: String
+
+``suspended``
+
+:Description: True if the user is suspended.
+:Type: Boolean
+
+``max_buckets``
+
+:Description: The maximum number of buckets to be owned by the user.
+:Type: Integer
+
+``subusers``
+
+:Description: Subusers associated with this user account.
+:Type: Container
+
+``keys``
+
+:Description: S3 keys associated with this user account.
+:Type: Container
+
+``swift_keys``
+
+:Description: Swift keys associated with this user account.
+:Type: Container
+
+``caps``
+
+:Description: User capabilities.
+:Type: Container
+
+Remove A User Capability
+========================
+
+Remove an administrative capability from a specified user.
+
+Syntax
+~~~~~~
+
+::
+
+ DELETE /{admin}/caps
+ Host {fqdn}
+
+Request Parameters
+~~~~~~~~~~~~~~~~~~
+
+``uid``
+
+:Description: The user ID to remove an administrative capability from.
+:Type: String
+:Example ``foo_user``
+:Required: Yes
+
+``caps``
+
+:Description: The administrative capabilities to remove from the user.
+:Type: String
+:Example: ``usage=read, write``
+:Required: Yes
+
+Response Entities
+~~~~~~~~~~~~~~~~~
+
+If successful, the response contains the user information.
+
+``user``
+
+:Description: A container for the user data information.
+:Type: Container
+
+``user_id``
+
+:Description: The user id.
+:Type: String
+
+``display_name``
+
+:Description: Display name for the user.
+:Type: String
+
+``suspended``
+
+:Description: True if the user is suspended.
+:Type: Boolean
+
+``max_buckets``
+
+:Description: The maximum number of buckets to be owned by the user.
+:Type: Integer
+
+``subusers``
+
+:Description: Subusers associated with this user account.
+:Type: Container
+
+``keys``
+
+:Description: S3 keys associated with this user account.
+:Type: Container
+
+``swift_keys``
+
+:Description: Swift keys associated with this user account.
+:Type: Container
+
+``caps``
+
+:Description: User capabilities.
+:Type: Container
+
+
+List Expired Garbage Collection Items
+=====================================
+
+List objects scheduled for garbage collection.
+
+Syntax
+~~~~~~
+
+::
+
+ GET /{admin}/garbage
+ Host {fqdn}
+
+Request Parameters
+~~~~~~~~~~~~~~~~~~
+
+None.
+
+Response Entities
+~~~~~~~~~~~~~~~~~
+
+If expired garbage collection items exist, a list of such objects
+will be returned.
+
+``garbage``
+
+:Description: Expired garbage collection items.
+:Type: Container
+
+``object``
+
+:Description: A container garbage collection object information.
+:Type: Container
+
+``name``
+
+:Description: The name of the object.
+:Type: String
+
+``expired``
+
+:Description: The date at which the object expired.
+:Type: String
+
+Manually Processes Garbage Collection Items
+===========================================
+
+List objects scheduled for garbage collection.
+
+Syntax
+~~~~~~
+
+::
+
+ DELETE /{admin}/garbage
+ Host {fqdn}
+
+Request Parameters
+~~~~~~~~~~~~~~~~~~
+
+None.
+
+Response Entities
+~~~~~~~~~~~~~~~~~
+
+If expired garbage collection items exist, a list of removed objects
+will be returned.
+
+``garbage``
+
+:Description: Expired garbage collection items.
+:Type: Container
+
+``object``
+
+:Description: A container garbage collection object information.
+:Type: Container
+
+``name``
+
+:Description: The name of the object.
+:Type: String
+
+``expired``
+
+:Description: The date at which the object expired.
+:Type: String
+
+Show Log Objects
+================
+
+Show log objects
+
+Syntax
+~~~~~~
+
+::
+
+ GET /{admin}/log
+ Host {fqdn}
+
+Request Parameters
+~~~~~~~~~~~~~~~~~~
+
+``object``
+
+:Description: The log object to return.
+:Type: String:
+:Example: ``2012-10-11-09-4165.2-foo_bucket``
+:Required: No
+
+Response Entities
+~~~~~~~~~~~~~~~~~
+
+If no object is specified, returns the full list of log objects.
+
+``log-objects``
+
+:Description: A list of log objects.
+:Type: Container
+
+``object``
+
+:Description: The name of the log object.
+:Type: String
+
+``log``
+
+:Description: The contents of the log object.
+:Type: Container
diff --git a/doc/radosgw/config.rst b/doc/radosgw/config.rst
index 32ce66d0426..12cca0168a9 100644
--- a/doc/radosgw/config.rst
+++ b/doc/radosgw/config.rst
@@ -113,7 +113,7 @@ See `<IfModule> Directive`_ for additional details.
.. _<IfModule> Directive: http://httpd.apache.org/docs/2.2/mod/core.html#ifmodule
Finally, you should configure Apache to allow encoded slashes, provide paths for
-log files and to trun off server signatures. ::
+log files and to turn off server signatures. ::
<VirtualHost *:80>
...
@@ -171,7 +171,7 @@ Add to Ceph Keyring Entries
Once you have created a keyring and key for RADOS GW, add it as an entry in
the Ceph keyring. For example::
- ceph -k /etc/ceph/ceph.keyring auth add client.radosgw.gateway -i /etc/ceph/keyring.radosgw.gateway
+ sudo ceph -k /etc/ceph/ceph.keyring auth add client.radosgw.gateway -i /etc/ceph/keyring.radosgw.gateway
Restart Services and Start the RADOS Gateway
diff --git a/doc/radosgw/s3/python.rst b/doc/radosgw/s3/python.rst
index 35261694538..c5a8432485a 100644
--- a/doc/radosgw/s3/python.rst
+++ b/doc/radosgw/s3/python.rst
@@ -32,9 +32,9 @@ This also prints out the bucket name and creation date of each bucket.
.. code-block:: python
for bucket in conn.get_all_buckets():
- print "{name}\t{created}".format(
- name = bucket.name,
- created = bucket.creation_date,
+ print "{name}\t{created}".format(
+ name = bucket.name,
+ created = bucket.creation_date,
)
The output will look something like this::
diff --git a/qa/run_xfstests.sh b/qa/run_xfstests.sh
index 1eba38a248d..3bcd8b5a636 100644
--- a/qa/run_xfstests.sh
+++ b/qa/run_xfstests.sh
@@ -49,7 +49,7 @@ XFS_MKFS_OPTIONS="-l su=32k"
# until we can work through getting them all passing reliably.
TESTS="1-9 11-15 17 19-21 26-29 31-34 41 46-48 50-54 56 61 63-67 69-70 74-76"
TESTS="${TESTS} 78 79 84-89 91-92 100 103 105 108 110 116-121 124 126"
-TESTS="${TESTS} 129-135 137-141 164-167 179 182-184 186-190 192 194"
+TESTS="${TESTS} 129-135 137-141 164-167 182 184 186-190 192 194"
TESTS="${TESTS} 196 199 201 203 214-216 220-227 234 236-238 241 243-249"
TESTS="${TESTS} 253 257-259 261 262 269 273 275 277 278 280 285 286"
# 275 was the highest available test as of 4/10/12.
diff --git a/qa/run_xfstests_qemu.sh b/qa/run_xfstests_qemu.sh
index 0b5b86de090..d2df8a563ba 100644
--- a/qa/run_xfstests_qemu.sh
+++ b/qa/run_xfstests_qemu.sh
@@ -3,5 +3,7 @@
mkdir /tmp/cephtest
wget https://raw.github.com/ceph/ceph/master/qa/run_xfstests.sh
chmod +x run_xfstests.sh
-# tests excluded require extra packages for advanced acl and quota support
-./run_xfstests.sh -c 1 -f xfs -t /dev/vdb -s /dev/vdc 1-26 28-49 51-63 65-83 85-233 235-291
+# tests excluded fail in the current testing vm regardless of whether
+# rbd is used
+
+./run_xfstests.sh -c 1 -f xfs -t /dev/vdb -s /dev/vdc 1-17 19-26 28-49 51-61 63 66-79 83 85-105 108-110 112-135 137-170 172-204 206-217 220-227 230-231 233 235-241 243-249 251-262 264-278 281-286 288-289
diff --git a/src/Makefile.am b/src/Makefile.am
index 2a874e71635..1497b9dd341 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -228,10 +228,12 @@ bin_DEBUGPROGRAMS += smalliobench
smalliobenchfs_SOURCES = test/bench/small_io_bench_fs.cc test/bench/filestore_backend.cc test/bench/detailed_stat_collector.cc test/bench/bencher.cc
smalliobenchfs_LDADD = librados.la -lboost_program_options $(LIBOS_LDA) $(LIBGLOBAL_LDA)
+smalliobenchfs_CXXFLAGS = ${CRYPTO_CXXFLAGS} ${AM_CXXFLAGS}
bin_DEBUGPROGRAMS += smalliobenchfs
smalliobenchdumb_SOURCES = test/bench/small_io_bench_dumb.cc test/bench/dumb_backend.cc test/bench/detailed_stat_collector.cc test/bench/bencher.cc
smalliobenchdumb_LDADD = librados.la -lboost_program_options $(LIBOS_LDA) $(LIBGLOBAL_LDA)
+smalliobenchdumb_CXXFLAGS = ${CRYPTO_CXXFLAGS} ${AM_CXXFLAGS}
bin_DEBUGPROGRAMS += smalliobenchdumb
tpbench_SOURCES = test/bench/tp_bench.cc test/bench/detailed_stat_collector.cc
@@ -862,6 +864,7 @@ test_mon_workloadgen_SOURCES = \
osdc/Objecter.cc \
osdc/Striper.cc
test_mon_workloadgen_LDADD = $(LIBOS_LDA) $(LIBGLOBAL_LDA)
+test_mon_workloadgen_CXXFLAGS = ${CRYPTO_CXXFLAGS} ${AM_CXXFLAGS}
bin_DEBUGPROGRAMS += test_mon_workloadgen
test_rados_api_io_SOURCES = test/librados/io.cc test/librados/test.cc
diff --git a/src/client/Client.cc b/src/client/Client.cc
index 0ca174b4536..d876454f0f4 100644
--- a/src/client/Client.cc
+++ b/src/client/Client.cc
@@ -3656,6 +3656,12 @@ void Client::flush_cap_releases()
void Client::tick()
{
+ if (cct->_conf->client_debug_inject_tick_delay > 0) {
+ sleep(cct->_conf->client_debug_inject_tick_delay);
+ assert(0 == cct->_conf->set_val("client_debug_inject_tick_delay", "0"));
+ cct->_conf->apply_changes(NULL);
+ }
+
ldout(cct, 21) << "tick" << dendl;
tick_event = new C_C_Tick(this);
timer.add_event_after(cct->_conf->client_tick_interval, tick_event);
diff --git a/src/common/config_opts.h b/src/common/config_opts.h
index b9e317b82dc..bd5b733bd64 100644
--- a/src/common/config_opts.h
+++ b/src/common/config_opts.h
@@ -183,6 +183,7 @@ OPTION(client_oc_target_dirty, OPT_INT, 1024*1024* 8) // target dirty (keep this
OPTION(client_oc_max_dirty_age, OPT_DOUBLE, 5.0) // max age in cache before writeback
OPTION(client_oc_max_objects, OPT_INT, 1000) // max objects in cache
OPTION(client_debug_force_sync_read, OPT_BOOL, false) // always read synchronously (go to osds)
+OPTION(client_debug_inject_tick_delay, OPT_INT, 0) // delay the client tick for a number of seconds
// note: the max amount of "in flight" dirty data is roughly (max - target)
OPTION(fuse_use_invalidate_cb, OPT_BOOL, false) // use fuse 2.8+ invalidate callback to keep page cache consistent
OPTION(fuse_big_writes, OPT_BOOL, true)
diff --git a/src/os/FileStore.cc b/src/os/FileStore.cc
index 8cb8720738e..99cea7f22da 100644
--- a/src/os/FileStore.cc
+++ b/src/os/FileStore.cc
@@ -1227,16 +1227,14 @@ int FileStore::_detect_fs()
} else {
dout(0) << "mount syncfs(2) syscall supported by glibc BUT NOT the kernel" << dendl;
}
-#endif
-#ifdef SYS_syncfs
+#elif defined(SYS_syncfs)
if (syscall(SYS_syncfs, fd) == 0) {
dout(0) << "mount syscall(SYS_syncfs, fd) fully supported" << dendl;
have_syncfs = true;
} else {
dout(0) << "mount syscall(SYS_syncfs, fd) supported by libc BUT NOT the kernel" << dendl;
}
-#endif
-#ifdef __NR_syncfs
+#elif defined(__NR_syncfs)
if (syscall(__NR_syncfs, fd) == 0) {
dout(0) << "mount syscall(__NR_syncfs, fd) fully supported" << dendl;
have_syncfs = true;
diff --git a/src/rgw/rgw_cache.h b/src/rgw/rgw_cache.h
index fb6ca10692d..e4002f6af25 100644
--- a/src/rgw/rgw_cache.h
+++ b/src/rgw/rgw_cache.h
@@ -268,6 +268,11 @@ int RGWCache<T>::get_obj(void *ctx, void **handle, rgw_obj& obj, bufferlist& obl
return r;
}
+ if (obl.length() == end + 1) {
+ /* in this case, most likely object contains more data, we can't cache it */
+ return r;
+ }
+
bufferptr p(r);
bufferlist& bl = info.data;
bl.clear();
diff --git a/src/rgw/rgw_tools.cc b/src/rgw/rgw_tools.cc
index b6d9f284771..e83e49a0652 100644
--- a/src/rgw/rgw_tools.cc
+++ b/src/rgw/rgw_tools.cc
@@ -10,7 +10,7 @@
#define dout_subsys ceph_subsys_rgw
-#define READ_CHUNK_LEN (16 * 1024)
+#define READ_CHUNK_LEN (512 * 1024)
static map<string, string> ext_mime_map;
@@ -41,25 +41,24 @@ int rgw_get_obj(RGWRados *rgwstore, void *ctx, rgw_bucket& bucket, string& key,
bufferlist::iterator iter;
int request_len = READ_CHUNK_LEN;
rgw_obj obj(bucket, key);
- ret = rgwstore->prepare_get_obj(ctx, obj, NULL, NULL, pattrs, NULL,
+ do {
+ ret = rgwstore->prepare_get_obj(ctx, obj, NULL, NULL, pattrs, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, &handle, &err);
- if (ret < 0)
- return ret;
+ if (ret < 0)
+ return ret;
- do {
ret = rgwstore->get_obj(ctx, &handle, obj, bl, 0, request_len - 1);
+ rgwstore->finish_get_obj(&handle);
if (ret < 0)
- goto done;
+ return ret;
+
if (ret < request_len)
break;
bl.clear();
request_len *= 2;
} while (true);
- ret = 0;
-done:
- rgwstore->finish_get_obj(&handle);
- return ret;
+ return 0;
}
void parse_mime_map_line(const char *start, const char *end)
diff --git a/src/test/libcephfs/caps.cc b/src/test/libcephfs/caps.cc
index 5a421ea410c..96f1a90024d 100644
--- a/src/test/libcephfs/caps.cc
+++ b/src/test/libcephfs/caps.cc
@@ -26,60 +26,14 @@
#include <sys/xattr.h>
#include <signal.h>
-void do_sigusr1(int s) {}
-
-// wait_and_suspend() forks the process, waits for the
-// child to signal SIGUSR1, suspends the child with SIGSTOP
-// sleeps for s seconds, and then unsuspends the child,
-// waits for the child to exit, and then returns the exit code
-// of the child
-static int _wait_and_suspend(int s) {
-
- int fpid = fork();
- if (fpid != 0) {
- // wait for child to signal
- signal(SIGUSR1, &do_sigusr1);
- sigset_t set;
- sigaddset(&set, SIGUSR1);
- int sig;
- sigwait(&set, &sig);
-
- // fork and suspend child, sleep for 20 secs, and resume
- kill(fpid, SIGSTOP);
- sleep(s);
- kill(fpid, SIGCONT);
- int status;
- wait(&status);
- if (WIFEXITED(status))
- return WEXITSTATUS(status);
- return 1;
- }
- return -1;
-}
-
-// signal_for_suspend sends the parent the SIGUSR1 signal
-// and sleeps for 1 second so that it can be suspended at the
-// point of the call
-static void _signal_for_suspend() {
- kill(getppid(), SIGUSR1);
-}
-
TEST(Caps, ReadZero) {
- int w = _wait_and_suspend(20);
- if (w >= 0) {
- ASSERT_EQ(0, w);
- return;
- }
-
- pid_t mypid = getpid();
+ int mypid = getpid();
struct ceph_mount_info *cmount;
ASSERT_EQ(0, ceph_create(&cmount, NULL));
ASSERT_EQ(0, ceph_conf_read_file(cmount, NULL));
ASSERT_EQ(0, ceph_mount(cmount, "/"));
- ASSERT_EQ(0, ceph_conf_set(cmount, "client_cache_size", "10"));
-
int i = 0;
for(; i < 30; ++i) {
@@ -114,7 +68,7 @@ TEST(Caps, ReadZero) {
ASSERT_EQ(expect, caps & expect);
}
- _signal_for_suspend();
+ ASSERT_EQ(0, ceph_conf_set(cmount, "client_debug_inject_tick_delay", "20"));
for(i = 0; i < 30; ++i) {