From 9aa69c904cbd7c4928f65dcbbed1782611d48b91 Mon Sep 17 00:00:00 2001 From: Drunkard Zhang <gongfan193@gmail.com> Date: Thu, 23 Mar 2017 13:53:09 +0800 Subject: [PATCH] doc: sync with mainline Updated to: "2016-04-12" Signed-off-by: Drunkard Zhang <gongfan193@gmail.com> --- cephfs/capabilities.rst | 115 +++ cephfs/experimental-features.rst | 117 +++ cephfs/index.rst | 13 + cephfs/mantle.rst | 264 +++++ dev/cephfs-snapshots.rst | 116 +++ dev/filestore-filesystem-compat.rst | 57 -- man/8/ceph-authtool.rst | 73 +- man/8/radosgw-admin.rst | 2 +- rados/operations/add-or-rm-osds.rst | 28 +- radosgw/adminops.rst | 1463 ++++++++++++++------------- radosgw/config-ref.rst | 22 +- rbd/rbd-openstack.rst | 23 +- update-doc.sh | 2 +- 13 files changed, 1460 insertions(+), 835 deletions(-) create mode 100644 cephfs/capabilities.rst create mode 100644 cephfs/experimental-features.rst create mode 100644 cephfs/mantle.rst create mode 100644 dev/cephfs-snapshots.rst delete mode 100644 dev/filestore-filesystem-compat.rst diff --git a/cephfs/capabilities.rst b/cephfs/capabilities.rst new file mode 100644 index 00000000..dd824c8a --- /dev/null +++ b/cephfs/capabilities.rst @@ -0,0 +1,115 @@ +.. _Capabilities in CephFS: + +=================== + CephFS 支持的能力 +=================== + +When a client wants to operate on an inode, it will query the MDS in various +ways, which will then grant the client a set of **capabilities**. These +grant the client permissions to operate on the inode in various ways. One +of the major differences from other network filesystems (e.g NFS or SMB) is +that the capabilities granted are quite granular, and it's possible that +multiple clients can hold different capabilities on the same inodes. + +.. _Types of Capabilities: + +能力的种类 +---------- + +There are several "generic" capability bits. These denote what sort of ability +the capability grants. + +.. code-block:: cpp + + /* generic cap bits */ + #define CEPH_CAP_GSHARED 1 /* client can reads (s) */ + #define CEPH_CAP_GEXCL 2 /* client can read and update (x) */ + #define CEPH_CAP_GCACHE 4 /* (file) client can cache reads (c) */ + #define CEPH_CAP_GRD 8 /* (file) client can read (r) */ + #define CEPH_CAP_GWR 16 /* (file) client can write (w) */ + #define CEPH_CAP_GBUFFER 32 /* (file) client can buffer writes (b) */ + #define CEPH_CAP_GWREXTEND 64 /* (file) client can extend EOF (a) */ + #define CEPH_CAP_GLAZYIO 128 /* (file) client can perform lazy io (l) */ + +These are then shifted by a particular number of bits. These denote a part of +the inode's data or metadata on which the capability is being granted: + +.. code-block:: cpp + + /* per-lock shift */ + #define CEPH_CAP_SAUTH 2 /* A */ + #define CEPH_CAP_SLINK 4 /* L */ + #define CEPH_CAP_SXATTR 6 /* X */ + #define CEPH_CAP_SFILE 8 /* F */ + +Only certain generic cap types are ever granted for some of those "shifts", +however. In particular, only the FILE shift ever has more than the first two +bits. :: + + | AUTH | LINK | XATTR | FILE + 2 4 6 8 + +From the above, we get a number of constants, that are generated by taking +each bit value and shifting to the correct bit in the word: + +.. code-block:: cpp + + #define CEPH_CAP_AUTH_SHARED (CEPH_CAP_GSHARED << CEPH_CAP_SAUTH) + +These bits can then be or'ed together to make a bitmask denoting a set of +capabilities. + +There is one exception: + +.. code-block:: cpp + + #define CEPH_CAP_PIN 1 /* no specific capabilities beyond the pin */ + +The "pin" just pins the inode into memory, without granting any other caps. + +图形化就是: :: + + +---+---+---+---+---+---+---+---+ + | p | _ |As x |Ls x |Xs x | + +---+---+---+---+---+---+---+---+ + |Fs x c r w b a l | + +---+---+---+---+---+---+---+---+ + +当前尚未使用第二个 bit 。 + +.. _Abilities granted by each cap: + +各个 cap 授予的能力: +--------------------- +While that is how capabilities are granted (and communicated), the important +bit is what they actually allow the client to do: + +* PIN: this just pins the inode into memory. This is sufficient to allow the + client to get to the inode number, as well as other immutable things like + major or minor numbers in a device inode, or symlink contents. + +* AUTH: this grants the ability to get to the authentication-related metadata. + In particular, the owner, group and mode. Note that doing a full permission + check may require getting at ACLs as well, which are stored in xattrs. + +* LINK: the link count of the inode + +* XATTR: ability to access or manipulate xattrs. Note that since ACLs are + stored in xattrs, it's also sometimes necessary to access them when checking + permissions. + +* FILE: this is the big one. These allow the client to access and manipulate + file data. It also covers certain metadata relating to file data -- the + size, mtime, atime and ctime, in particular. + +.. _Shorthand: + +简写 +---- + +需要注意的是,客户端日志里会紧凑地表达各个能力,例如: :: + + pAsLsXsFs + +其中, p 表示 pin ,各大写字母对应位移值,而位移值后面的小写\ +字母是真正赋予此位置的的能力。 diff --git a/cephfs/experimental-features.rst b/cephfs/experimental-features.rst new file mode 100644 index 00000000..8c97a901 --- /dev/null +++ b/cephfs/experimental-features.rst @@ -0,0 +1,117 @@ +.. _Experimental Features: + +实验性功能 +========== + +CephFS includes a number of experimental features which are not fully stabilized +or qualified for users to turn on in real deployments. We generally do our best +to clearly demarcate these and fence them off so they can't be used by mistake. + +Some of these features are closer to being done than others, though. We describe +each of them with an approximation of how risky they are and briefly describe +what is required to enable them. Note that doing so will *irrevocably* flag maps +in the monitor as having once enabled this flag to improve debugging and +support processes. + + +.. _Directory Fragmentation: + +目录分片 +-------- + +CephFS directories are generally stored within a single RADOS object. But this has +certain negative results once they become large enough. The filesystem is capable +of "fragmenting" these directories into multiple objects. There are no known bugs +with doing so but it is not sufficiently tested to support at this time. + +Directory fragmentation has always been off by default and required setting +```mds bal frag = true`` in the MDS' config file. It has been further protected +by requiring the user to set the "allow_dirfrags" flag for Jewel. + + +.. _Inline data: + +内联数据 +-------- +By default, all CephFS file data is stored in RADOS objects. The inline data +feature enables small files (generally <2KB) to be stored in the inode +and served out of the MDS. This may improve small-file performance but increases +load on the MDS. It is not sufficiently tested to support at this time, although +failures within it are unlikely to make non-inlined data inaccessible + +Inline data has always been off by default and requires setting +the "inline_data" flag. + + +.. _Multi-MDS filesystem clusters: + +多个 MDS 驱动文件系统 +--------------------- +CephFS has been designed from the ground up to support fragmenting the metadata +hierarchy across multiple active metadata servers, to allow horizontal scaling +to arbitrary throughput requirements. Unfortunately, doing so requires a lot +more working code than having a single MDS which is authoritative over the +entire filesystem namespace. + +Multiple active MDSes are generally stable under trivial workloads, but often +break in the presence of any failure, and do not have enough testing to offer +any stability guarantees. If a filesystem with multiple active MDSes does +experience failure, it will require (generally extensive) manual intervention. +There are serious known bugs. + +Multi-MDS filesystems have always required explicitly increasing the "max_mds" +value and have been further protected with the "allow_multimds" flag for Jewel. + + +.. _`Mantle: Programmable Metadata Load Balancer`: + +Mantle: 可编程的元数据负载均衡器 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Mantle is a programmable metadata balancer built into the MDS. The idea is to +protect the mechanisms for balancing load (migration, replication, +fragmentation) but stub out the balancing policies using Lua. For details, see +:doc:`/cephfs/mantle`. + +.. _Snapshots: + +快照 +---- +Like multiple active MDSes, CephFS is designed from the ground up to support +snapshotting of arbitrary directories. There are no known bugs at the time of +writing, but there is insufficient testing to provide stability guarantees and +every expansion of testing has generally revealed new issues. If you do enable +snapshots and experience failure, manual intervention will be needed. + +Snapshots are known not to work properly with multiple filesystems (below) in +some cases. Specifically, if you share a pool for multiple FSes and delete +a snapshot in one FS, expect to lose snapshotted file data in any other FS using +snapshots. See the :doc:`/dev/cephfs-snapshots` page for more information. + +Snapshots are known not to work with multi-MDS filesystems. + +Snapshotting was blocked off with the "allow_new_snaps" flag prior to Firefly. + + +.. _Multiple filesystems within a Ceph cluster: + +Ceph 单集群、多个文件系统 +------------------------- +Code was merged prior to the Jewel release which enables administrators +to create multiple independent CephFS filesystems within a single Ceph cluster. +These independent filesystems have their own set of active MDSes, cluster maps, +and data. But the feature required extensive changes to data structures which +are not yet fully qualified, and has security implications which are not all +apparent nor resolved. + +There are no known bugs, but any failures which do result from having multiple +active filesystems in your cluster will require manual intervention and, so far, +will not have been experienced by anybody else -- knowledgeable help will be +extremely limited. You also probably do not have the security or isolation +guarantees you want or think you have upon doing so. + +Note that snapshots and multiple filesystems are *not* tested in combination +and may not work together; see above. + +Multiple filesystems were available starting in the Jewel release candidates +but were protected behind the "enable_multiple" flag before the final release. diff --git a/cephfs/index.rst b/cephfs/index.rst index cdf9fd54..14c06c99 100644 --- a/cephfs/index.rst +++ b/cephfs/index.rst @@ -78,6 +78,7 @@ Ceph 文件系统要求 Ceph 存储集群内至少有一个 :term:`Ceph 元数 CephFS 管理命令 <administration> POSIX 兼容性 <posix> + 实验性功能 <experimental-features> CephFS 配额管理 <quota> 在 Ceph 上使用 Hadoop <hadoop> libcephfs <../../api/libcephfs-java/> @@ -93,3 +94,15 @@ Ceph 文件系统要求 Ceph 存储集群内至少有一个 :term:`Ceph 元数 .. raw:: html </td></tr></tbody></table> + +.. _For developers: + +开发者文档 +========== + +.. toctree:: + :maxdepth: 1 + + 客户端的能力 <capabilities> + libcephfs <../../api/libcephfs-java/> + Mantle <mantle> diff --git a/cephfs/mantle.rst b/cephfs/mantle.rst new file mode 100644 index 00000000..a07227f9 --- /dev/null +++ b/cephfs/mantle.rst @@ -0,0 +1,264 @@ +Mantle +====== + +.. warning:: + + Mantle 的本意是用于研究和开发元数据均衡算法,不是给 CephFS + 生产集群用的。 + +Multiple, active MDSs can migrate directories to balance metadata load. The +policies for when, where, and how much to migrate are hard-coded into the +metadata balancing module. Mantle is a programmable metadata balancer built +into the MDS. The idea is to protect the mechanisms for balancing load +(migration, replication, fragmentation) but stub out the balancing policies +using Lua. Mantle is based on [1] but the current implementation does *NOT* +have the following features from that paper: + +1. Balancing API: in the paper, the user fills in when, where, how much, and + load calculation policies; currently, Mantle only requires that Lua policies + return a table of target loads (e.g., how much load to send to each MDS) +2. "How much" hook: in the paper, there was a hook that let the user control + the fragment selector policy; currently, Mantle does not have this hook +3. Instantaneous CPU utilization as a metric + +[1] Supercomputing '15 Paper: +http://sc15.supercomputing.org/schedule/event_detail-evid=pap168.html + +.. _Quickstart with vstart: + +vstart 快速入门 +--------------- + +.. warning:: + + Developing balancers with vstart is difficult because running all daemons + and clients on one node can overload the system. Let it run for a while, even + though you will likely see a bunch of lost heartbeat and laggy MDS warnings. + Most of the time this guide will work but sometimes all MDSs lock up and you + cannot actually see them spill. It is much better to run this on a cluster. + +As a pre-requistie, we assume you've installed `mdtest +<https://sourceforge.net/projects/mdtest/>`_ or pulled the `Docker image +<https://hub.docker.com/r/michaelsevilla/mdtest/>`_. We use mdtest because we +need to generate enough load to get over the MIN_OFFLOAD threshold that is +arbitrarily set in the balancer. For example, this does not create enough +metadata load: + +:: + + while true; do + touch "/cephfs/blah-`date`" + done + + +Mantle with `vstart.sh` +~~~~~~~~~~~~~~~~~~~~~~~ + +1. Start Ceph and tune the logging so we can see migrations happen: + +:: + + cd build + ../src/vstart.sh -n -l + for i in a b c; do + bin/ceph --admin-daemon out/mds.$i.asok config set debug_ms 0 + bin/ceph --admin-daemon out/mds.$i.asok config set debug_mds 2 + bin/ceph --admin-daemon out/mds.$i.asok config set mds_beacon_grace 1500 + done + + +2. Put the balancer into RADOS: + +:: + + bin/rados put --pool=cephfs_metadata_a greedyspill.lua ../src/mds/balancers/greedyspill.lua + + +3. Activate Mantle: + +:: + + bin/ceph fs set cephfs allow_multimds true --yes-i-really-mean-it + bin/ceph fs set cephfs max_mds 5 + bin/ceph fs set cephfs_a balancer greedyspill.lua + + +4. Mount CephFS in another window: + +:: + + bin/ceph-fuse /cephfs -o allow_other & + tail -f out/mds.a.log + + + Note that if you look at the last MDS (which could be a, b, or c -- it's + random), you will see an an attempt to index a nil value. This is because the + last MDS tries to check the load of its neighbor, which does not exist. + +5. Run a simple benchmark. In our case, we use the Docker mdtest image to + create load: + +:: + + for i in 0 1 2; do + docker run -d \ + --name=client$i \ + -v /cephfs:/cephfs \ + michaelsevilla/mdtest \ + -F -C -n 100000 -d "/cephfs/client-test$i" + done + + +6. When you're done, you can kill all the clients with: + +:: + + for i in 0 1 2 3; do docker rm -f client$i; done + + +.. _Output: + +输出解析 +~~~~~~~~ + +Looking at the log for the first MDS (could be a, b, or c), we see that +everyone has no load:: + + 2016-08-21 06:44:01.763930 7fd03aaf7700 0 lua.balancer MDS0: < auth.meta_load=0.0 all.meta_load=0.0 req_rate=1.0 queue_len=0.0 cpu_load_avg=1.35 > load=0.0 + 2016-08-21 06:44:01.763966 7fd03aaf7700 0 lua.balancer MDS1: < auth.meta_load=0.0 all.meta_load=0.0 req_rate=0.0 queue_len=0.0 cpu_load_avg=1.35 > load=0.0 + 2016-08-21 06:44:01.763982 7fd03aaf7700 0 lua.balancer MDS2: < auth.meta_load=0.0 all.meta_load=0.0 req_rate=0.0 queue_len=0.0 cpu_load_avg=1.35 > load=0.0 + 2016-08-21 06:44:01.764010 7fd03aaf7700 2 lua.balancer when: not migrating! my_load=0.0 hisload=0.0 + 2016-08-21 06:44:01.764033 7fd03aaf7700 2 mds.0.bal mantle decided that new targets={} + + +After the jobs starts, MDS0 gets about 1953 units of load. The greedy spill +balancer dictates that half the load goes to your neighbor MDS, so we see that +Mantle tries to send 1953 load units to MDS1. :: + + 2016-08-21 06:45:21.869994 7fd03aaf7700 0 lua.balancer MDS0: < auth.meta_load=5834.188908912 all.meta_load=1953.3492228857 req_rate=12591.0 queue_len=1075.0 cpu_load_avg=3.05 > load=1953.3492228857 + 2016-08-21 06:45:21.870017 7fd03aaf7700 0 lua.balancer MDS1: < auth.meta_load=0.0 all.meta_load=0.0 req_rate=0.0 queue_len=0.0 cpu_load_avg=3.05 > load=0.0 + 2016-08-21 06:45:21.870027 7fd03aaf7700 0 lua.balancer MDS2: < auth.meta_load=0.0 all.meta_load=0.0 req_rate=0.0 queue_len=0.0 cpu_load_avg=3.05 > load=0.0 + 2016-08-21 06:45:21.870034 7fd03aaf7700 2 lua.balancer when: migrating! my_load=1953.3492228857 hisload=0.0 + 2016-08-21 06:45:21.870050 7fd03aaf7700 2 mds.0.bal mantle decided that new targets={0=0,1=976.675,2=0} + 2016-08-21 06:45:21.870094 7fd03aaf7700 0 mds.0.bal - exporting [0,0.52287 1.04574] 1030.88 to mds.1 [dir 100000006ab /client-test2/ [2,head] auth pv=33 v=32 cv=32/0 ap=2+3+4 state=1610612802|complete f(v0 m2016-08-21 06:44:20.366935 1=0+1) n(v2 rc2016-08-21 06:44:30.946816 3790=3788+2) hs=1+0,ss=0+0 dirty=1 | child=1 dirty=1 authpin=1 0x55d2762fd690] + 2016-08-21 06:45:21.870151 7fd03aaf7700 0 mds.0.migrator nicely exporting to mds.1 [dir 100000006ab /client-test2/ [2,head] auth pv=33 v=32 cv=32/0 ap=2+3+4 state=1610612802|complete f(v0 m2016-08-21 06:44:20.366935 1=0+1) n(v2 rc2016-08-21 06:44:30.946816 3790=3788+2) hs=1+0,ss=0+0 dirty=1 | child=1 dirty=1 authpin=1 0x55d2762fd690] + + +Eventually load moves around:: + + 2016-08-21 06:47:10.210253 7fd03aaf7700 0 lua.balancer MDS0: < auth.meta_load=415.77414300449 all.meta_load=415.79000078186 req_rate=82813.0 queue_len=0.0 cpu_load_avg=11.97 > load=415.79000078186 + 2016-08-21 06:47:10.210277 7fd03aaf7700 0 lua.balancer MDS1: < auth.meta_load=228.72023977691 all.meta_load=186.5606496623 req_rate=28580.0 queue_len=0.0 cpu_load_avg=11.97 > load=186.5606496623 + 2016-08-21 06:47:10.210290 7fd03aaf7700 0 lua.balancer MDS2: < auth.meta_load=0.0 all.meta_load=0.0 req_rate=1.0 queue_len=0.0 cpu_load_avg=11.97 > load=0.0 + 2016-08-21 06:47:10.210298 7fd03aaf7700 2 lua.balancer when: not migrating! my_load=415.79000078186 hisload=186.5606496623 + 2016-08-21 06:47:10.210311 7fd03aaf7700 2 mds.0.bal mantle decided that new targets={} + + +.. _Implementation Details: + +实现细节 +-------- + +Most of the implementation is in MDBalancer. Metrics are passed to the balancer +policies via the Lua stack and a list of loads is returned back to MDBalancer. +It sits alongside the current balancer implementation and it's enabled with a +Ceph CLI command ("ceph fs set cephfs balancer mybalancer.lua"). If the Lua policy +fails (for whatever reason), we fall back to the original metadata load +balancer. The balancer is stored in the RADOS metadata pool and a string in the +MDSMap tells the MDSs which balancer to use. + +Exposing Metrics to Lua +~~~~~~~~~~~~~~~~~~~~~~~ + +Metrics are exposed directly to the Lua code as global variables instead of +using a well-defined function signature. There is a global "mds" table, where +each index is an MDS number (e.g., 0) and each value is a dictionary of metrics +and values. The Lua code can grab metrics using something like this: + +:: + + mds[0]["queue_len"] + + +This is in contrast to cls-lua in the OSDs, which has well-defined arguments +(e.g., input/output bufferlists). Exposing the metrics directly makes it easier +to add new metrics without having to change the API on the Lua side; we want +the API to grow and shrink as we explore which metrics matter. The downside of +this approach is that the person programming Lua balancer policies has to look +at the Ceph source code to see which metrics are exposed. We figure that the +Mantle developer will be in touch with MDS internals anyways. + +The metrics exposed to the Lua policy are the same ones that are already stored +in mds_load_t: auth.meta_load(), all.meta_load(), req_rate, queue_length, +cpu_load_avg. + +Compile/Execute the Balancer +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Here we use `lua_pcall` instead of `lua_call` because we want to handle errors +in the MDBalancer. We do not want the error propagating up the call chain. The +cls_lua class wants to handle the error itself because it must fail gracefully. +For Mantle, we don't care if a Lua error crashes our balancer -- in that case, +we'll fall back to the original balancer. + +The performance improvement of using `lua_call` over `lua_pcall` would not be +leveraged here because the balancer is invoked every 10 seconds by default. + +Returning Policy Decision to C++ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +We force the Lua policy engine to return a table of values, corresponding to +the amount of load to send to each MDS. These loads are inserted directly into +the MDBalancer "my_targets" vector. We do not allow the MDS to return a table +of MDSs and metrics because we want the decision to be completely made on the +Lua side. + +Iterating through tables returned by Lua is done through the stack. In Lua +jargon: a dummy value is pushed onto the stack and the next iterator replaces +the top of the stack with a (k, v) pair. After reading each value, pop that +value but keep the key for the next call to `lua_next`. + +Reading from RADOS +~~~~~~~~~~~~~~~~~~ + +All MDSs will read balancing code from RADOS when the balancer version changes +in the MDS Map. The balancer pulls the Lua code from RADOS synchronously. We do +this with a timeout: if the asynchronous read does not come back within half +the balancing tick interval the operation is cancelled and a Connection Timeout +error is returned. By default, the balancing tick interval is 10 seconds, so +Mantle will use a 5 second second timeout. This design allows Mantle to +immediately return an error if anything RADOS-related goes wrong. + +We use this implementation because we do not want to do a blocking OSD read +from inside the global MDS lock. Doing so would bring down the MDS cluster if +any of the OSDs are not responsive -- this is tested in the ceph-qa-suite by +setting all OSDs to down/out and making sure the MDS cluster stays active. + +One approach would be to asynchronously fire the read when handling the MDS Map +and fill in the Lua code in the background. We cannot do this because the MDS +does not support daemon-local fallbacks and the balancer assumes that all MDSs +come to the same decision at the same time (e.g., importers, exporters, etc.). + +Debugging +~~~~~~~~~ + +Logging in a Lua policy will appear in the MDS log. The syntax is the same as +the cls logging interface: + +:: + + BAL_LOG(0, "this is a log message") + + +It is implemented by passing a function that wraps the `dout` logging framework +(`dout_wrapper`) to Lua with the `lua_register()` primitive. The Lua code is +actually calling the `dout` function in C++. + +Warning and Info messages are centralized using the clog/Beacon. Successful +messages are only sent on version changes by the first MDS to avoid spamming +the `ceph -w` utility. These messages are used for the integration tests. + +Testing +~~~~~~~ + +Testing is done with the ceph-qa-suite (tasks.cephfs.test_mantle). We do not +test invalid balancer logging and loading the actual Lua VM. diff --git a/dev/cephfs-snapshots.rst b/dev/cephfs-snapshots.rst new file mode 100644 index 00000000..bb0790ea --- /dev/null +++ b/dev/cephfs-snapshots.rst @@ -0,0 +1,116 @@ +.. _CephFS Snapshots: + +CephFS 快照 +=========== + +CephFS supports snapshots, generally created by invoking mkdir against the +(hidden, special) .snap directory. + +Overview +----------- + +Generally, snapshots do what they sound like: they create an immutable view +of the filesystem at the point in time they're taken. There are some headline +features that make CephFS snapshots different from what you might expect: + +* Arbitrary subtrees. Snapshots are created within any directory you choose, + and cover all data in the filesystem under that directory. +* Asynchronous. If you create a snapshot, buffered data is flushed out lazily, + including from other clients. As a result, "creating" the snapshot is + very fast. + +Important Data Structures +------------------------- +* SnapRealm: A `SnapRealm` is created whenever you create a snapshot at a new + point in the hierarchy (or, when a snapshotted inode is moved outside of its + parent snapshot). SnapRealms contain an `sr_t srnode`, links to `past_parents` + and `past_children`, and all `inodes_with_caps` that are part of the snapshot. + Clients also have a SnapRealm concept that maintains less data but is used to + associate a `SnapContext` with each open file for writing. +* sr_t: An `sr_t` is the on-disk snapshot metadata. It is part of the containing + directory and contains sequence counters, timestamps, the list of associated + snapshot IDs, and `past_parents`. +* snaplink_t: `past_parents` et al are stored on-disk as a `snaplink_t`, holding + the inode number and first `snapid` of the inode/snapshot referenced. + +Creating a snapshot +------------------- +To make a snapshot on directory "/1/2/3/foo", the client invokes "mkdir" on +"/1/2/3/foo/.snaps" directory. This is transmitted to the MDS Server as a +CEPH_MDS_OP_MKSNAP-tagged `MClientRequest`, and initially handled in +Server::handle_client_mksnap(). It allocates a `snapid` from the `SnapServer`, +projects a new inode with the new SnapRealm, and commits it to the MDLog as +usual. When committed, it invokes +`MDCache::do_realm_invalidate_and_update_notify()`, which triggers most of the +real work of the snapshot. + +If there were already snapshots above directory "foo" (rooted at "/1", say), +the new SnapRealm adds its most immediate ancestor as a `past_parent` on +creation. After committing to the MDLog, all clients with caps on files in +"/1/2/3/foo/" are notified (MDCache::send_snaps()) of the new SnapRealm, and +update the `SnapContext` they are using with that data. Note that this +*is not* a synchronous part of the snapshot creation! + +Updating a snapshot +------------------- +If you delete a snapshot, or move data out of the parent snapshot's hierarchy, +a similar process is followed. Extra code paths check to see if we can break +the `past_parent` links between SnapRealms, or eliminate them entirely. + +Generating a SnapContext +------------------------ +A RADOS `SnapContext` consists of a snapshot sequence ID (`snapid`) and all +the snapshot IDs that an object is already part of. To generate that list, we +generate a list of all `snapids` associated with the SnapRealm and all its +`past_parents`. + +Storing snapshot data +--------------------- +File data is stored in RADOS "self-managed" snapshots. Clients are careful to +use the correct `SnapContext` when writing file data to the OSDs. + +Storing snapshot metadata +------------------------- +Snapshotted dentries (and their inodes) are stored in-line as part of the +directory they were in at the time of the snapshot. *All dentries* include a +`first` and `last` snapid for which they are valid. (Non-snapshotted dentries +will have their `last` set to CEPH_NOSNAP). + +Snapshot writeback +------------------ +There is a great deal of code to handle writeback efficiently. When a Client +receives an `MClientSnap` message, it updates the local `SnapRealm` +representation and its links to specific `Inodes`, and generates a `CapSnap` +for the `Inode`. The `CapSnap` is flushed out as part of capability writeback, +and if there is dirty data the `CapSnap` is used to block fresh data writes +until the snapshot is completely flushed to the OSDs. + +In the MDS, we generate snapshot-representing dentries as part of the regular +process for flushing them. Dentries with outstanding `CapSnap` data is kept +pinned and in the journal. + +Deleting snapshots +------------------ +Snapshots are deleted by invoking "rmdir" on the ".snaps" directory they are +rooted in. (Attempts to delete a directory which roots snapshots *will fail*; +you must delete the snapshots first.) Once deleted, they are entered into the +`OSDMap` list of deleted snapshots and the file data is removed by the OSDs. +Metadata is cleaned up as the directory objects are read in and written back +out again. + +Hard links +---------- +Hard links do not interact well with snapshots. A file is snapshotted when its +primary link is part of a SnapRealm; other links *will not* preserve data. +Generally the location where a file was first created will be its primary link, +but if the original link has been deleted it is not easy (nor always +determnistic) to find which link is now the primary. + +Multi-FS +--------- +Snapshots and multiiple filesystems don't interact well. Specifically, each +MDS cluster allocates `snapids` independently; if you have multiple filesystems +sharing a single pool (via namespaces), their snapshots *will* collide and +deleting one will result in missing file data for others. (This may even be +invisible, not throwing errors to the user.) If each FS gets its own +pool things probably work, but this isn't tested and may not be true. diff --git a/dev/filestore-filesystem-compat.rst b/dev/filestore-filesystem-compat.rst deleted file mode 100644 index fae35234..00000000 --- a/dev/filestore-filesystem-compat.rst +++ /dev/null @@ -1,57 +0,0 @@ -==================================== - Filestore filesystem compatilibity -==================================== - -http://marc.info/?l=ceph-devel&m=131942130322957&w=2 - -Although running on ext4, xfs, or whatever other non-btrfs you want mostly -works, there are a few important remaining issues: - -OSD journal replay of non-idempotent transactions -================================================= - -**Resolved** with full sync but not ideal. -See http://tracker.newdream.net/issues/213 - -On non-btrfs backends, the Ceph OSDs use a write-ahead journal. After -restart, the OSD does not know exactly which transactions in the -journal may have already been committed to disk, and may reapply a -transaction again during replay. For most operations (write, delete, -truncate) this is fine. - -Some operations, though, are non-idempotent. The simplest example is -CLONE, which copies (efficiently, on btrfs) data from one object to -another. If the source object is modified, the osd restarts, and then -the clone is replayed, the target will get incorrect (newer) data. For -example, - -- clone A -> B -- modify A -- <osd crash, replay from 1> - -B will get new instead of old contents. - -(This doesn't happen on btrfs because the snapshots allow us to replay -from a known consistent point in time.) - -Possibilities: - -- full sync after any non-idempotent operation -- re-evaluate the lower level interface based on needs from higher - levels, construct only safe operations, be very careful; brittle -- use xattrs to add sequence numbers to objects: - - - on non-btrfs, we set a xattr on every modified object with the - op_seq, the unique sequence number for the transaction. - - for any (potentially) non-idempotent operation, we fsync() before - continuing to the next transaction, to ensure that xattr hits disk. - - on replay, we skip a transaction if the xattr indicates we already - performed this transaction. - - Because every 'transaction' only modifies on a single object (file), - this ought to work. It'll make things like clone slow, but let's - face it: they're already slow on non-btrfs file systems because they - actually copy the data (instead of duplicating the extent refs in - btrfs). And it should make the full ObjectStore interface safe, - without upper layers having to worry about the kinds and orders of - transactions they perform. diff --git a/man/8/ceph-authtool.rst b/man/8/ceph-authtool.rst index af0d2bec..c6f7cf62 100644 --- a/man/8/ceph-authtool.rst +++ b/man/8/ceph-authtool.rst @@ -9,21 +9,31 @@ 提纲 ==== -| **ceph-authtool** *keyringfile* [ -l | --list ] [ -C | --create-keyring - ] [ -p | --print ] [ -n | --name *entityname* ] [ --gen-key ] [ -a | - --add-key *base64_key* ] [ --caps *capfile* ] +| **ceph-authtool** *keyringfile* + [ -l | --list ] + [ -p | --print-key ] + [ -C | --create-keyring ] + [ -g | --gen-key ] + [ --gen-print-key ] + [ --import-keyring *otherkeyringfile* ] + [ -n | --name *entityname* ] + [ -u | --set-uid *auid* ] + [ -a | --add-key *base64_key* ] + [ --cap *subsystem* *capability* ] + [ --caps *capfile* ] 描述 ==== -**ceph-authtool** 工具用于创建、查看和修改 Ceph 密钥环文件。密钥环文件内存储\ -着一或多个 Ceph 认证密钥、可能还有被授予的能力。每个密钥都与其类型名关联,格\ -式为 ``{client,mon,mds,osd}.name`` 。 +**ceph-authtool** 工具用于创建、查看和修改 Ceph 密钥环文件。\ +密钥环文件内存储着一或多个 Ceph 认证密钥、可能还有被授予的能\ +力。每个密钥都与其类型名关联,格式为 +``{client,mon,mds,osd}.name`` 。 -**警告:** 在私钥保护得当的前提下, Ceph 能提供认证和防中间人攻击的保护。然\ -而,传输中的数据是未加密的,这些数据中可能就有配置密钥的消息。此系统意在运行\ -于可信环境中。 +**警告:** 在私钥保护得当的前提下, Ceph 能提供认证和防中间\ +人攻击的保护。然而,传输中的数据是未加密的,这些数据中可能就\ +有配置密钥的消息。此系统意在运行于可信环境中。 选项 @@ -35,25 +45,43 @@ .. option:: -p, --print - 打印指定条目的已编码密钥,它适合作为 ``mount -o secret=`` 的参数 + 打印指定条目的已编码密钥,它适合作为 ``mount -o secret=`` + 的参数 .. option:: -C, --create-keyring 创建新密钥环,覆盖已有密钥环文件 -.. option:: --gen-key +.. option:: -g, --gen-key 为指定实体名生成新私钥 -.. option:: --add-key +.. option:: --gen-print-key - 把已编码密钥加进密钥环 + 为指定条目( entityname )生成新密钥,不会修改密钥环文件( + keyringfile ),只打印到标准输出。 -.. option:: --cap subsystem capability +.. option:: --import-keyring *secondkeyringfile* + + 把此选项所指定密钥环的内容导入密钥环( keyringfile ) + +.. option:: -n, --name *name* + + 指定要操作的条目名( entityname ) + +.. option:: -u, --set-uid *auid* + + 设置指定条目( entityname )的 auid (已认证用户的标识符) + +.. option:: -a, --add-key *base64_key* + + 把编码好的密钥加进密钥环 + +.. option:: --cap *subsystem* *capability* 设置指定子系统的能力 -.. option:: --caps capsfile +.. option:: --caps *capsfile* 在所有子系统内设置与给定密钥相关的所有能力 @@ -61,21 +89,22 @@ 能力 ==== -subsystem 代表 Ceph 子系统的名字: ``mon`` 、 ``mds`` 、 ``osd`` 。 +subsystem 代表 Ceph 子系统的名字: ``mon`` 、 ``mds`` 、或 +``osd`` 。 -能力是一个字符串,描述了允许此用户干什么。格式为逗号分隔的允许声明列表,此声\ -明包含一或多个 rwx (分别表示读、写、执行权限)。 ``allow *`` 将在指定子系统\ -下授予完整的超级用户权限。 +能力是一个字符串,描述了允许此用户干什么。格式为逗号分隔的允\ +许声明列表,此声明包含一或多个 rwx (分别表示读、写、执行权\ +限)。 ``allow *`` 将在指定子系统下授予完整的超级用户权限。 例如: :: - # 可读、写、执行对象 + # 可读、写、执行对象 osd = "allow rwx" - # 可访问 MDS 服务器 + # 可访问 MDS 服务器 mds = "allow" - # 可更改集群状态(即它是服务器守护进程) + # 可更改集群状态(即它是服务器守护进程) mon = "allow rwx" 被限定到单个存储池的 librados 用户的能力大致如此: :: diff --git a/man/8/radosgw-admin.rst b/man/8/radosgw-admin.rst index e3e9e26a..a07cc595 100644 --- a/man/8/radosgw-admin.rst +++ b/man/8/radosgw-admin.rst @@ -104,7 +104,7 @@ :command:`region get` 显示 region 信息。 -:command:`regions list` +:command:`region list` 列出本集群配置的所有 region 。 :command:`region set` diff --git a/rados/operations/add-or-rm-osds.rst b/rados/operations/add-or-rm-osds.rst index 662f9810..9ad391ec 100644 --- a/rados/operations/add-or-rm-osds.rst +++ b/rados/operations/add-or-rm-osds.rst @@ -156,36 +156,40 @@ CRUSH 图。 观察数据迁移 ------------ -把新 OSD 加入 CRUSH 图后, Ceph 会重新均衡服务器,一些归置组会迁移到新 OSD 里,你\ -可以用 `ceph`_ 命令观察此过程。 :: +把新 OSD 加入 CRUSH 图后, Ceph 会重新均衡服务器,一些归置组会\ +迁移到新 OSD 里,你可以用 `ceph`_ 命令观察此过程。 :: ceph -w -你会看到归置组状态从 ``active+clean`` 变为 ``active, some degraded objects`` \ -(有降级的对象)、且迁移完成后回到 ``active+clean`` 状态。( Ctrl-c 退出) +你会看到归置组状态从 ``active+clean`` 变为 +``active, some degraded objects`` (有降级的对象)、且迁移完成\ +后回到 ``active+clean`` 状态。( Ctrl-c 退出) .. _增加/移动 OSD: ../crush-map#addosd .. _ceph: ../monitoring +.. _Removing OSDs (Manual): + 删除 OSD (手动) ================= -要想缩减集群尺寸或替换硬件,可在运行时删除 OSD 。在 Ceph 里,一个 OSD 通常是一台主\ -机上的一个 ``ceph-osd`` 守护进程、它运行在一个硬盘之上。如果一台主机上有多个数据\ -盘,你得挨个删除其对应 ``ceph-osd`` 。通常,操作前应该检查集群容量,看是否快达到上\ -限了,确保删除 OSD 后不会使集群达到 ``near full`` 比率。 +要想缩减集群尺寸或替换硬件,可在运行时删除 OSD 。在 Ceph 里,\ +一个 OSD 通常是一台主机上的一个 ``ceph-osd`` 守护进程、它运行\ +在一个硬盘之上。如果一台主机上有多个数据盘,你得挨个删除其对应 +``ceph-osd`` 。通常,操作前应该检查集群容量,看是否快达到上限\ +了,确保删除 OSD 后不会使集群达到 ``near full`` 比率。 -.. warning:: 删除 OSD 时不要让集群达到 ``full ratio`` 值,删除 OSD 可能导致集群达\ - 到或超过 ``full ratio`` 值。 +.. warning:: 删除 OSD 时不要让集群达到 ``full ratio`` 值,删除 + OSD 可能导致集群达到或超过 ``full ratio`` 值。 把 OSD 踢出集群 --------------- -删除 OSD 前,它通常是 ``up`` 且 ``in`` 的,要先把它踢出集群,以使 Ceph 启动重新均\ -衡、把数据拷贝到其他 OSD 。 :: +删除 OSD 前,它通常是 ``up`` 且 ``in`` 的,要先把它踢出集群,\ +以使 Ceph 启动重新均衡、把数据拷贝到其他 OSD 。 :: ceph osd out {osd-num} diff --git a/radosgw/adminops.rst b/radosgw/adminops.rst index 393f999c..f07d1296 100644 --- a/radosgw/adminops.rst +++ b/radosgw/adminops.rst @@ -9,8 +9,10 @@ The response entity type (XML or JSON) may be specified as the 'format' option i request and defaults to JSON if not specified. -Get Usage -========= +.. _Get Usage: + +GET 用法 +======== 请求带宽利用率信息。 @@ -30,143 +32,146 @@ Get Usage ``uid`` -:Description: The user for which the information is requested. If not specified will apply to all users. -:Type: String -:Example: ``foo_user`` -:Required: No +:描述: The user for which the information is requested. If not specified will apply to all users. +:类型: String +:实例: ``foo_user`` +:是否必需: No ``start`` -:Description: Date and (optional) time that specifies the start time of the requested data. -:Type: String -:Example: ``2012-09-25 16:00:00`` -:Required: No +:描述: Date and (optional) time that specifies the start time of the requested data. +:类型: String +:实例: ``2012-09-25 16:00:00`` +:是否必需: No ``end`` -:Description: Date and (optional) time that specifies the end time of the requested data (non-inclusive). -:Type: String -:Example: ``2012-09-25 16:00:00`` -:Required: No +:描述: Date and (optional) time that specifies the end time of the requested data (non-inclusive). +:类型: String +:实例: ``2012-09-25 16:00:00`` +:是否必需: No ``show-entries`` -:Description: Specifies whether data entries should be returned. -:Type: Boolean -:Example: True [False] -:Required: No +:描述: Specifies whether data entries should be returned. +:类型: Boolean +:实例: True [False] +:是否必需: No ``show-summary`` -:Description: Specifies whether data summary should be returned. -:Type: Boolean -:Example: True [False] -:Required: No - +:描述: Specifies whether data summary should be returned. +:类型: Boolean +:实例: True [False] +:是否必需: No -Response Entities -~~~~~~~~~~~~~~~~~ +响应内容解析 +~~~~~~~~~~~~ -If successful, the response contains the requested information. +如果成功,响应会包含请求的信息。 ``usage`` -:Description: A container for the usage information. -:Type: Container +:描述: A container for the usage information. +:类型: Container ``entries`` -:Description: A container for the usage entries information. -:Type: Container +:描述: A container for the usage entries information. +:类型: Container ``user`` -:Description: A container for the user data information. -:Type: Container +:描述: A container for the user data information. +:类型: Container ``owner`` -:Description: The name of the user that owns the buckets. -:Type: String +:描述: The name of the user that owns the buckets. +:类型: String ``bucket`` -:Description: The bucket name. -:Type: String +:描述: The bucket name. +:类型: String ``time`` -:Description: Time lower bound for which data is being specified (rounded to the beginning of the first relevant hour). -:Type: String +:描述: Time lower bound for which data is being specified (rounded to the beginning of the first relevant hour). +:类型: String ``epoch`` -:Description: The time specified in seconds since 1/1/1970. -:Type: String +:描述: The time specified in seconds since 1/1/1970. +:类型: String ``categories`` -:Description: A container for stats categories. -:Type: Container +:描述: A container for stats categories. +:类型: Container ``entry`` -:Description: A container for stats entry. -:Type: Container +:描述: A container for stats entry. +:类型: Container ``category`` -:Description: Name of request category for which the stats are provided. -:Type: String +:描述: Name of request category for which the stats are provided. +:类型: String ``bytes_sent`` -:Description: Number of bytes sent by the RADOS Gateway. -:Type: Integer +:描述: Number of bytes sent by the RADOS Gateway. +:类型: Integer ``bytes_received`` -:Description: Number of bytes received by the RADOS Gateway. -:Type: Integer +:描述: Number of bytes received by the RADOS Gateway. +:类型: Integer ``ops`` -:Description: Number of operations. -:Type: Integer +:描述: Number of operations. +:类型: Integer ``successful_ops`` -:Description: Number of successful operations. -:Type: Integer +:描述: Number of successful operations. +:类型: Integer ``summary`` -:Description: A container for stats summary. -:Type: Container +:描述: A container for stats summary. +:类型: Container ``total`` -:Description: A container for stats summary aggregated total. -:Type: Container +:描述: A container for stats summary aggregated total. +:类型: Container -Special Error Responses -~~~~~~~~~~~~~~~~~~~~~~~ + +特殊错误响应 +~~~~~~~~~~~~ TBD. -Trim Usage -========== + +.. _Trim Usage: + +裁剪用法 +======== Remove usage information. With no dates specified, removes all usage information. :caps: usage=write -Syntax -~~~~~~ +语法 +~~~~ :: @@ -174,44 +179,44 @@ Syntax Host: {fqdn} - -Request Parameters -~~~~~~~~~~~~~~~~~~ +请求参数 +~~~~~~~~ ``uid`` -:Description: The user for which the information is requested. If not specified will apply to all users. -:Type: String -:Example: ``foo_user`` -:Required: No +:描述: The user for which the information is requested. If not specified will apply to all users. +:类型: String +:实例: ``foo_user`` +:是否必需: No ``start`` -:Description: Date and (optional) time that specifies the start time of the requested data. -:Type: String -:Example: ``2012-09-25 16:00:00`` -:Required: No +:描述: Date and (optional) time that specifies the start time of the requested data. +:类型: String +:实例: ``2012-09-25 16:00:00`` +:是否必需: No ``end`` -:Description: Date and (optional) time that specifies the end time of the requested data (none inclusive). -:Type: String -:Example: ``2012-09-25 16:00:00`` -:Required: No +:描述: Date and (optional) time that specifies the end time of the requested data (none inclusive). +:类型: String +:实例: ``2012-09-25 16:00:00`` +:是否必需: No ``remove-all`` -:Description: Required when uid is not specified, in order to acknowledge multi user data removal. -:Type: Boolean -:Example: True [False] -:Required: No +:描述: 是否必需 when uid is not specified, in order to acknowledge multi user data removal. +:类型: Boolean +:实例: True [False] +:是否必需: No -Special Error Responses -~~~~~~~~~~~~~~~~~~~~~~~ +特殊错误响应 +~~~~~~~~~~~~ TBD. + Get User Info ============= @@ -221,8 +226,8 @@ information. :caps: users=read -Syntax -~~~~~~ +语法 +~~~~ :: @@ -235,72 +240,72 @@ Request Parameters ``uid`` -:Description: The user for which the information is requested. -:Type: String -:Example: ``foo_user`` -:Required: No +:描述: The user for which the information is requested. +:类型: String +:实例: ``foo_user`` +:是否必需: Yes -Response Entities -~~~~~~~~~~~~~~~~~ +响应内容解析 +~~~~~~~~~~~~ -If successful, the response contains the user information. +如果成功了,这个响应会包含此用户的信息。 ``user`` -:Description: A container for the user data information. -:Type: Container +:描述: 用户数据信息的一个容器。 +:类型: Container ``user_id`` -:Description: The user id. -:Type: String -:Parent: ``user`` +:描述: 此用户的标识符。 +:类型: String +:父节点: ``user`` ``display_name`` -:Description: Display name for the user. -:Type: String -:Parent: ``user`` +:描述: 用户对外显示的名字。 +:类型: String +:父节点: ``user`` ``suspended`` -:Description: True if the user is suspended. -:Type: Boolean -:Parent: ``user`` +:描述: 如果此用户被暂停,其值为 True 。 +:类型: Boolean +:父节点: ``user`` ``max_buckets`` -:Description: The maximum number of buckets to be owned by the user. -:Type: Integer -:Parent: ``user`` +:描述: The maximum number of buckets to be owned by the user. +:类型: Integer +:父节点: ``user`` ``subusers`` -:Description: Subusers associated with this user account. -:Type: Container -:Parent: ``user`` +:描述: Subusers associated with this user account. +:类型: Container +:父节点: ``user`` ``keys`` -:Description: S3 keys associated with this user account. -:Type: Container -:Parent: ``user`` +:描述: S3 keys associated with this user account. +:类型: Container +:父节点: ``user`` ``swift_keys`` -:Description: Swift keys associated with this user account. -:Type: Container -:Parent: ``user`` +:描述: Swift keys associated with this user account. +:类型: Container +:父节点: ``user`` ``caps`` -:Description: User capabilities. -:Type: Container -:Parent: ``user`` +:描述: User capabilities. +:类型: Container +:父节点: ``user`` -Special Error Responses -~~~~~~~~~~~~~~~~~~~~~~~ +特殊错误响应 +~~~~~~~~~~~~ None. @@ -316,8 +321,8 @@ then it will be modified. :caps: users=write -Syntax -~~~~~~ +语法 +~~~~ :: @@ -331,75 +336,75 @@ Request Parameters ``uid`` -:Description: The user ID to be created. -:Type: String -:Example: ``foo_user`` -:Required: Yes +:描述: The user ID to be created. +:类型: String +:实例: ``foo_user`` +:是否必需: Yes ``display-name`` -:Description: The display name of the user to be created. -:Type: String -:Example: ``foo user`` -:Required: Yes +:描述: The display name of the user to be created. +:类型: String +:实例: ``foo user`` +:是否必需: Yes ``email`` -:Description: The email address associated with the user. -:Type: String -:Example: ``foo@bar.com`` -:Required: No +:描述: The email address associated with the user. +:类型: String +:实例: ``foo@bar.com`` +:是否必需: No ``key-type`` -:Description: Key type to be generated, options are: swift, s3 (default). -:Type: String -:Example: ``s3`` [``s3``] -:Required: No +:描述: Key type to be generated, options are: swift, s3 (default). +:类型: String +:实例: ``s3`` [``s3``] +:是否必需: No ``access-key`` -:Description: Specify access key. -:Type: String -:Example: ``ABCD0EF12GHIJ2K34LMN`` -:Required: No +:描述: Specify access key. +:类型: String +:实例: ``ABCD0EF12GHIJ2K34LMN`` +:是否必需: No ``secret-key`` -:Description: Specify secret key. -:Type: String -:Example: ``0AbCDEFg1h2i34JklM5nop6QrSTUV+WxyzaBC7D8`` -:Required: No +:描述: Specify secret key. +:类型: String +:实例: ``0AbCDEFg1h2i34JklM5nop6QrSTUV+WxyzaBC7D8`` +:是否必需: No ``user-caps`` -:Description: User capabilities. -:Type: String -:Example: ``usage=read, write; users=read`` -:Required: No +:描述: User capabilities. +:类型: String +:实例: ``usage=read, write; users=read`` +:是否必需: No ``generate-key`` -:Description: Generate a new key pair and add to the existing keyring. -:Type: Boolean -:Example: True [True] -:Required: No +:描述: Generate a new key pair and add to the existing keyring. +:类型: Boolean +:实例: True [True] +:是否必需: No ``max-buckets`` -:Description: Specify the maximum number of buckets the user can own. -:Type: Integer -:Example: 500 [1000] -:Required: No +:描述: Specify the maximum number of buckets the user can own. +:类型: Integer +:实例: 500 [1000] +:是否必需: No ``suspended`` -:Description: Specify whether the user should be suspended. -:Type: Boolean -:Example: False [False] -:Required: No +:描述: Specify whether the user should be suspended. +:类型: Boolean +:实例: False [False] +:是否必需: No Response Entities ~~~~~~~~~~~~~~~~~ @@ -408,99 +413,99 @@ If successful, the response contains the user information. ``user`` -:Description: A container for the user data information. -:Type: Container +:描述: A container for the user data information. +:类型: Container ``user_id`` -:Description: The user id. -:Type: String -:Parent: ``user`` +:描述: The user id. +:类型: String +:父节点: ``user`` ``display_name`` -:Description: Display name for the user. -:Type: String -:Parent: ``user`` +:描述: Display name for the user. +:类型: String +:父节点: ``user`` ``suspended`` -:Description: True if the user is suspended. -:Type: Boolean -:Parent: ``user`` +:描述: True if the user is suspended. +:类型: Boolean +:父节点: ``user`` ``max_buckets`` -:Description: The maximum number of buckets to be owned by the user. -:Type: Integer -:Parent: ``user`` +:描述: The maximum number of buckets to be owned by the user. +:类型: Integer +:父节点: ``user`` ``subusers`` -:Description: Subusers associated with this user account. -:Type: Container -:Parent: ``user`` +:描述: Subusers associated with this user account. +:类型: Container +:父节点: ``user`` ``keys`` -:Description: S3 keys associated with this user account. -:Type: Container -:Parent: ``user`` +:描述: S3 keys associated with this user account. +:类型: Container +:父节点: ``user`` ``swift_keys`` -:Description: Swift keys associated with this user account. -:Type: Container -:Parent: ``user`` +:描述: Swift keys associated with this user account. +:类型: Container +:父节点: ``user`` ``caps`` -:Description: User capabilities. -:Type: Container -:Parent: ``user`` +:描述: User capabilities. +:类型: Container +:父节点: ``user`` -Special Error Responses -~~~~~~~~~~~~~~~~~~~~~~~ +特殊错误响应 +~~~~~~~~~~~~ ``UserExists`` -:Description: Attempt to create existing user. -:Code: 409 Conflict +:描述: Attempt to create existing user. +:状态码: 409 Conflict ``InvalidAccessKey`` -:Description: Invalid access key specified. -:Code: 400 Bad Request +:描述: Invalid access key specified. +:状态码: 400 Bad Request -``InvalidKeyType`` +``InvalidKey类型`` -:Description: Invalid key type specified. -:Code: 400 Bad Request +:描述: Invalid key type specified. +:状态码: 400 Bad Request ``InvalidSecretKey`` -:Description: Invalid secret key specified. -:Code: 400 Bad Request +:描述: Invalid secret key specified. +:状态码: 400 Bad Request -``InvalidKeyType`` +``InvalidKey类型`` -:Description: Invalid key type specified. -:Code: 400 Bad Request +:描述: Invalid key type specified. +:状态码: 400 Bad Request ``KeyExists`` -:Description: Provided access key exists and belongs to another user. -:Code: 409 Conflict +:描述: Provided access key exists and belongs to another user. +:状态码: 409 Conflict ``EmailExists`` -:Description: Provided email address exists. -:Code: 409 Conflict +:描述: Provided email address exists. +:状态码: 409 Conflict ``InvalidCapability`` -:Description: Attempt to grant invalid admin capability. -:Code: 400 Bad Request +:描述: Attempt to grant invalid admin capability. +:状态码: 400 Bad Request Modify User @@ -510,8 +515,8 @@ Modify a user. :caps: users=write -Syntax -~~~~~~ +语法 +~~~~ :: @@ -524,73 +529,73 @@ Request Parameters ``uid`` -:Description: The user ID to be modified. -:Type: String -:Example: ``foo_user`` -:Required: Yes +:描述: The user ID to be modified. +:类型: String +:实例: ``foo_user`` +:是否必需: Yes ``display-name`` -:Description: The display name of the user to be modified. -:Type: String -:Example: ``foo user`` -:Required: No +:描述: The display name of the user to be modified. +:类型: String +:实例: ``foo user`` +:是否必需: No ``email`` -:Description: The email address to be associated with the user. -:Type: String -:Example: ``foo@bar.com`` -:Required: No +:描述: The email address to be associated with the user. +:类型: String +:实例: ``foo@bar.com`` +:是否必需: No ``generate-key`` -:Description: Generate a new key pair and add to the existing keyring. -:Type: Boolean -:Example: True [False] -:Required: No +:描述: Generate a new key pair and add to the existing keyring. +:类型: Boolean +:实例: True [False] +:是否必需: No ``access-key`` -:Description: Specify access key. -:Type: String -:Example: ``ABCD0EF12GHIJ2K34LMN`` -:Required: No +:描述: Specify access key. +:类型: String +:实例: ``ABCD0EF12GHIJ2K34LMN`` +:是否必需: No ``secret-key`` -:Description: Specify secret key. -:Type: String -:Example: ``0AbCDEFg1h2i34JklM5nop6QrSTUV+WxyzaBC7D8`` -:Required: No +:描述: Specify secret key. +:类型: String +:实例: ``0AbCDEFg1h2i34JklM5nop6QrSTUV+WxyzaBC7D8`` +:是否必需: No ``key-type`` -:Description: Key type to be generated, options are: swift, s3 (default). -:Type: String -:Example: ``s3`` -:Required: No +:描述: Key type to be generated, options are: swift, s3 (default). +:类型: String +:实例: ``s3`` +:是否必需: No ``user-caps`` -:Description: User capabilities. -:Type: String -:Example: ``usage=read, write; users=read`` -:Required: No +:描述: User capabilities. +:类型: String +:实例: ``usage=read, write; users=read`` +:是否必需: No ``max-buckets`` -:Description: Specify the maximum number of buckets the user can own. -:Type: Integer -:Example: 500 [1000] -:Required: No +:描述: Specify the maximum number of buckets the user can own. +:类型: Integer +:实例: 500 [1000] +:是否必需: No ``suspended`` -:Description: Specify whether the user should be suspended. -:Type: Boolean -:Example: False [False] -:Required: No +:描述: Specify whether the user should be suspended. +:类型: Boolean +:实例: False [False] +:是否必需: No Response Entities ~~~~~~~~~~~~~~~~~ @@ -599,96 +604,96 @@ If successful, the response contains the user information. ``user`` -:Description: A container for the user data information. -:Type: Container +:描述: A container for the user data information. +:类型: Container ``user_id`` -:Description: The user id. -:Type: String -:Parent: ``user`` +:描述: The user id. +:类型: String +:父节点: ``user`` ``display_name`` -:Description: Display name for the user. -:Type: String -:Parent: ``user`` +:描述: Display name for the user. +:类型: String +:父节点: ``user`` ``suspended`` -:Description: True if the user is suspended. -:Type: Boolean -:Parent: ``user`` +:描述: True if the user is suspended. +:类型: Boolean +:父节点: ``user`` ``max_buckets`` -:Description: The maximum number of buckets to be owned by the user. -:Type: Integer -:Parent: ``user`` +:描述: The maximum number of buckets to be owned by the user. +:类型: Integer +:父节点: ``user`` ``subusers`` -:Description: Subusers associated with this user account. -:Type: Container -:Parent: ``user`` +:描述: Subusers associated with this user account. +:类型: Container +:父节点: ``user`` ``keys`` -:Description: S3 keys associated with this user account. -:Type: Container -:Parent: ``user`` +:描述: S3 keys associated with this user account. +:类型: Container +:父节点: ``user`` ``swift_keys`` -:Description: Swift keys associated with this user account. -:Type: Container -:Parent: ``user`` +:描述: Swift keys associated with this user account. +:类型: Container +:父节点: ``user`` ``caps`` -:Description: User capabilities. -:Type: Container -:Parent: ``user`` +:描述: User capabilities. +:类型: Container +:父节点: ``user`` -Special Error Responses -~~~~~~~~~~~~~~~~~~~~~~~ +特殊错误响应 +~~~~~~~~~~~~ ``InvalidAccessKey`` -:Description: Invalid access key specified. -:Code: 400 Bad Request +:描述: Invalid access key specified. +:状态码: 400 Bad Request -``InvalidKeyType`` +``InvalidKey类型`` -:Description: Invalid key type specified. -:Code: 400 Bad Request +:描述: Invalid key type specified. +:状态码: 400 Bad Request ``InvalidSecretKey`` -:Description: Invalid secret key specified. -:Code: 400 Bad Request +:描述: Invalid secret key specified. +:状态码: 400 Bad Request ``KeyExists`` -:Description: Provided access key exists and belongs to another user. -:Code: 409 Conflict +:描述: Provided access key exists and belongs to another user. +:状态码: 409 Conflict ``EmailExists`` -:Description: Provided email address exists. -:Code: 409 Conflict +:描述: Provided email address exists. +:状态码: 409 Conflict ``InvalidCapability`` -:Description: Attempt to grant invalid admin capability. -:Code: 400 Bad Request +:描述: Attempt to grant invalid admin capability. +:状态码: 400 Bad Request Remove User =========== @@ -697,8 +702,8 @@ Remove an existing user. :caps: users=write -Syntax -~~~~~~ +语法 +~~~~ :: @@ -711,26 +716,26 @@ Request Parameters ``uid`` -:Description: The user ID to be removed. -:Type: String -:Example: ``foo_user`` -:Required: Yes. +:描述: The user ID to be removed. +:类型: String +:实例: ``foo_user`` +:是否必需: Yes. ``purge-data`` -:Description: When specified the buckets and objects belonging +:描述: When specified the buckets and objects belonging to the user will also be removed. -:Type: Boolean -:Example: True -:Required: No +:类型: Boolean +:实例: True +:是否必需: No Response Entities ~~~~~~~~~~~~~~~~~ None -Special Error Responses -~~~~~~~~~~~~~~~~~~~~~~~ +特殊错误响应 +~~~~~~~~~~~~ None. @@ -746,8 +751,8 @@ be automatically generated. :caps: users=write -Syntax -~~~~~~ +语法 +~~~~ :: @@ -760,47 +765,47 @@ Request Parameters ``uid`` -:Description: The user ID under which a subuser is to be created. -:Type: String -:Example: ``foo_user`` -:Required: Yes +:描述: The user ID under which a subuser is to be created. +:类型: String +:实例: ``foo_user`` +:是否必需: Yes ``subuser`` -:Description: Specify the subuser ID to be created. -:Type: String -:Example: ``sub_foo`` -:Required: No +:描述: Specify the subuser ID to be created. +:类型: String +:实例: ``sub_foo`` +:是否必需: No ``secret-key`` -:Description: Specify secret key. -:Type: String -:Example: ``0AbCDEFg1h2i34JklM5nop6QrSTUV+WxyzaBC7D8`` -:Required: No +:描述: Specify secret key. +:类型: String +:实例: ``0AbCDEFg1h2i34JklM5nop6QrSTUV+WxyzaBC7D8`` +:是否必需: No ``key-type`` -:Description: Key type to be generated, options are: swift (default), s3. -:Type: String -:Example: ``swift`` [``swift``] -:Required: No +:描述: Key type to be generated, options are: swift (default), s3. +:类型: String +:实例: ``swift`` [``swift``] +:是否必需: No ``access`` -:Description: Set access permissions for sub-user, should be one +:描述: Set access permissions for sub-user, should be one of ``read, write, readwrite, full``. -:Type: String -:Example: ``read`` -:Required: No +:类型: String +:实例: ``read`` +:是否必需: No ``generate-secret`` -:Description: Generate the secret key. -:Type: Boolean -:Example: True [False] -:Required: No +:描述: Generate the secret key. +:类型: Boolean +:实例: True [False] +:是否必需: No Response Entities ~~~~~~~~~~~~~~~~~ @@ -810,43 +815,43 @@ If successful, the response contains the subuser information. ``subusers`` -:Description: Subusers associated with the user account. -:Type: Container +:描述: Subusers associated with the user account. +:类型: Container ``id`` -:Description: Subuser id. -:Type: String -:Parent: ``subusers`` +:描述: Subuser id. +:类型: String +:父节点: ``subusers`` ``permissions`` -:Description: Subuser access to user account. -:Type: String -:Parent: ``subusers`` +:描述: Subuser access to user account. +:类型: String +:父节点: ``subusers`` -Special Error Responses -~~~~~~~~~~~~~~~~~~~~~~~ +特殊错误响应 +~~~~~~~~~~~~ ``SubuserExists`` -:Description: Specified subuser exists. -:Code: 409 Conflict +:描述: Specified subuser exists. +:状态码: 409 Conflict -``InvalidKeyType`` +``InvalidKey类型`` -:Description: Invalid key type specified. -:Code: 400 Bad Request +:描述: Invalid key type specified. +:状态码: 400 Bad Request ``InvalidSecretKey`` -:Description: Invalid secret key specified. -:Code: 400 Bad Request +:描述: Invalid secret key specified. +:状态码: 400 Bad Request ``InvalidAccess`` -:Description: Invalid subuser access specified. -:Code: 400 Bad Request +:描述: Invalid subuser access specified. +:状态码: 400 Bad Request Modify Subuser ============== @@ -855,8 +860,8 @@ Modify an existing subuser :caps: users=write -Syntax -~~~~~~ +语法 +~~~~ :: @@ -869,47 +874,47 @@ Request Parameters ``uid`` -:Description: The user ID under which the subuser is to be modified. -:Type: String -:Example: ``foo_user`` -:Required: Yes +:描述: The user ID under which the subuser is to be modified. +:类型: String +:实例: ``foo_user`` +:是否必需: Yes ``subuser`` -:Description: The subuser ID to be modified. -:Type: String -:Example: ``sub_foo`` -:Required: Yes +:描述: The subuser ID to be modified. +:类型: String +:实例: ``sub_foo`` +:是否必需: Yes ``generate-secret`` -:Description: Generate a new secret key for the subuser, +:描述: Generate a new secret key for the subuser, replacing the existing key. -:Type: Boolean -:Example: True [False] -:Required: No +:类型: Boolean +:实例: True [False] +:是否必需: No ``secret`` -:Description: Specify secret key. -:Type: String -:Example: ``0AbCDEFg1h2i34JklM5nop6QrSTUV+WxyzaBC7D8`` -:Required: No +:描述: Specify secret key. +:类型: String +:实例: ``0AbCDEFg1h2i34JklM5nop6QrSTUV+WxyzaBC7D8`` +:是否必需: No ``key-type`` -:Description: Key type to be generated, options are: swift (default), s3 . -:Type: String -:Example: ``swift`` [``swift``] -:Required: No +:描述: Key type to be generated, options are: swift (default), s3 . +:类型: String +:实例: ``swift`` [``swift``] +:是否必需: No ``access`` -:Description: Set access permissions for sub-user, should be one +:描述: Set access permissions for sub-user, should be one of ``read, write, readwrite, full``. -:Type: String -:Example: ``read`` -:Required: No +:类型: String +:实例: ``read`` +:是否必需: No Response Entities @@ -920,38 +925,38 @@ If successful, the response contains the subuser information. ``subusers`` -:Description: Subusers associated with the user account. -:Type: Container +:描述: Subusers associated with the user account. +:类型: Container ``id`` -:Description: Subuser id. -:Type: String -:Parent: ``subusers`` +:描述: Subuser id. +:类型: String +:父节点: ``subusers`` ``permissions`` -:Description: Subuser access to user account. -:Type: String -:Parent: ``subusers`` +:描述: Subuser access to user account. +:类型: String +:父节点: ``subusers`` -Special Error Responses -~~~~~~~~~~~~~~~~~~~~~~~ +特殊错误响应 +~~~~~~~~~~~~ -``InvalidKeyType`` +``InvalidKey类型`` -:Description: Invalid key type specified. -:Code: 400 Bad Request +:描述: Invalid key type specified. +:状态码: 400 Bad Request ``InvalidSecretKey`` -:Description: Invalid secret key specified. -:Code: 400 Bad Request +:描述: Invalid secret key specified. +:状态码: 400 Bad Request ``InvalidAccess`` -:Description: Invalid subuser access specified. -:Code: 400 Bad Request +:描述: Invalid subuser access specified. +:状态码: 400 Bad Request Remove Subuser ============== @@ -960,8 +965,8 @@ Remove an existing subuser :caps: users=write -Syntax -~~~~~~ +语法 +~~~~ :: @@ -974,33 +979,34 @@ Request Parameters ``uid`` -:Description: The user ID under which the subuser is to be removed. -:Type: String -:Example: ``foo_user`` -:Required: Yes +:描述: The user ID under which the subuser is to be removed. +:类型: String +:实例: ``foo_user`` +:是否必需: Yes ``subuser`` -:Description: The subuser ID to be removed. -:Type: String -:Example: ``sub_foo`` -:Required: Yes +:描述: The subuser ID to be removed. +:类型: String +:实例: ``sub_foo`` +:是否必需: Yes ``purge-keys`` -:Description: Remove keys belonging to the subuser. -:Type: Boolean -:Example: True [True] -:Required: No +:描述: Remove keys belonging to the subuser. +:类型: Boolean +:实例: True [True] +:是否必需: No Response Entities ~~~~~~~~~~~~~~~~~ None. -Special Error Responses -~~~~~~~~~~~~~~~~~~~~~~~ +特殊错误响应 +~~~~~~~~~~~~ + None. Create Key @@ -1020,8 +1026,8 @@ each user or subuser. :caps: users=write -Syntax -~~~~~~ +语法 +~~~~ :: @@ -1034,45 +1040,45 @@ Request Parameters ``uid`` -:Description: The user ID to receive the new key. -:Type: String -:Example: ``foo_user`` -:Required: Yes +:描述: The user ID to receive the new key. +:类型: String +:实例: ``foo_user`` +:是否必需: Yes ``subuser`` -:Description: The subuser ID to receive the new key. -:Type: String -:Example: ``sub_foo`` -:Required: No +:描述: The subuser ID to receive the new key. +:类型: String +:实例: ``sub_foo`` +:是否必需: No ``key-type`` -:Description: Key type to be generated, options are: swift, s3 (default). -:Type: String -:Example: ``s3`` [``s3``] -:Required: No +:描述: Key type to be generated, options are: swift, s3 (default). +:类型: String +:实例: ``s3`` [``s3``] +:是否必需: No ``access-key`` -:Description: Specify the access key. -:Type: String -:Example: ``AB01C2D3EF45G6H7IJ8K`` -:Required: No +:描述: Specify the access key. +:类型: String +:实例: ``AB01C2D3EF45G6H7IJ8K`` +:是否必需: No ``secret-key`` -:Description: Specify the secret key. -:Type: String -:Example: ``0ab/CdeFGhij1klmnopqRSTUv1WxyZabcDEFgHij`` -:Required: No +:描述: Specify the secret key. +:类型: String +:实例: ``0ab/CdeFGhij1klmnopqRSTUv1WxyZabcDEFgHij`` +:是否必需: No ``generate-key`` -:Description: Generate a new key pair and add to the existing keyring. -:Type: Boolean -:Example: True [``True``] -:Required: No +:描述: Generate a new key pair and add to the existing keyring. +:类型: Boolean +:实例: True [``True``] +:是否必需: No Response Entities @@ -1080,55 +1086,55 @@ Response Entities ``keys`` -:Description: Keys of type created associated with this user account. -:Type: Container +:描述: Keys of type created associated with this user account. +:类型: Container ``user`` -:Description: The user account associated with the key. -:Type: String -:Parent: ``keys`` +:描述: The user account associated with the key. +:类型: String +:父节点: ``keys`` ``access-key`` -:Description: The access key. -:Type: String -:Parent: ``keys`` +:描述: The access key. +:类型: String +:父节点: ``keys`` ``secret-key`` -:Description: The secret key -:Type: String -:Parent: ``keys`` +:描述: The secret key +:类型: String +:父节点: ``keys`` -Special Error Responses -~~~~~~~~~~~~~~~~~~~~~~~ +特殊错误响应 +~~~~~~~~~~~~ ``InvalidAccessKey`` -:Description: Invalid access key specified. -:Code: 400 Bad Request +:描述: Invalid access key specified. +:状态码: 400 Bad Request -``InvalidKeyType`` +``InvalidKey类型`` -:Description: Invalid key type specified. -:Code: 400 Bad Request +:描述: Invalid key type specified. +:状态码: 400 Bad Request ``InvalidSecretKey`` -:Description: Invalid secret key specified. -:Code: 400 Bad Request +:描述: Invalid secret key specified. +:状态码: 400 Bad Request -``InvalidKeyType`` +``InvalidKey类型`` -:Description: Invalid key type specified. -:Code: 400 Bad Request +:描述: Invalid key type specified. +:状态码: 400 Bad Request ``KeyExists`` -:Description: Provided access key exists and belongs to another user. -:Code: 409 Conflict +:描述: Provided access key exists and belongs to another user. +:状态码: 409 Conflict Remove Key ========== @@ -1137,8 +1143,8 @@ Remove an existing key. :caps: users=write -Syntax -~~~~~~ +语法 +~~~~ :: @@ -1151,35 +1157,35 @@ Request Parameters ``access-key`` -:Description: The S3 access key belonging to the S3 key pair to remove. -:Type: String -:Example: ``AB01C2D3EF45G6H7IJ8K`` -:Required: Yes +:描述: The S3 access key belonging to the S3 key pair to remove. +:类型: String +:实例: ``AB01C2D3EF45G6H7IJ8K`` +:是否必需: Yes ``uid`` -:Description: The user to remove the key from. -:Type: String -:Example: ``foo_user`` -:Required: No +:描述: The user to remove the key from. +:类型: String +:实例: ``foo_user`` +:是否必需: No ``subuser`` -:Description: The subuser to remove the key from. -:Type: String -:Example: ``sub_foo`` -:Required: No +:描述: The subuser to remove the key from. +:类型: String +:实例: ``sub_foo`` +:是否必需: 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 +:描述: Key type to be removed, options are: swift, s3. + NOTE: 是否必需 to remove swift key. +:类型: String +:实例: ``swift`` +:是否必需: No -Special Error Responses -~~~~~~~~~~~~~~~~~~~~~~~ +特殊错误响应 +~~~~~~~~~~~~ None. @@ -1198,8 +1204,8 @@ retrieved. :caps: buckets=read -Syntax -~~~~~~ +语法 +~~~~ :: @@ -1212,24 +1218,24 @@ Request Parameters ``bucket`` -:Description: The bucket to return info on. -:Type: String -:Example: ``foo_bucket`` -:Required: No +:描述: The bucket to return info on. +:类型: String +:实例: ``foo_bucket`` +:是否必需: No ``uid`` -:Description: The user to retrieve bucket information for. -:Type: String -:Example: ``foo_user`` -:Required: No +:描述: The user to retrieve bucket information for. +:类型: String +:实例: ``foo_user`` +:是否必需: No ``stats`` -:Description: Return bucket statistics. -:Type: Boolean -:Example: True [False] -:Required: No +:描述: Return bucket statistics. +:类型: Boolean +:实例: True [False] +:是否必需: No Response Entities ~~~~~~~~~~~~~~~~~ @@ -1239,69 +1245,69 @@ the desired bucket information. ``stats`` -:Description: Per bucket information. -:Type: Container +:描述: Per bucket information. +:类型: Container ``buckets`` -:Description: Contains a list of one or more bucket containers. -:Type: Container +:描述: Contains a list of one or more bucket containers. +:类型: Container ``bucket`` -:Description: Container for single bucket information. -:Type: Container -:Parent: ``buckets`` +:描述: Container for single bucket information. +:类型: Container +:父节点: ``buckets`` ``name`` -:Description: The name of the bucket. -:Type: String -:Parent: ``bucket`` +:描述: The name of the bucket. +:类型: String +:父节点: ``bucket`` ``pool`` -:Description: The pool the bucket is stored in. -:Type: String -:Parent: ``bucket`` +:描述: The pool the bucket is stored in. +:类型: String +:父节点: ``bucket`` ``id`` -:Description: The unique bucket id. -:Type: String -:Parent: ``bucket`` +:描述: The unique bucket id. +:类型: String +:父节点: ``bucket`` ``marker`` -:Description: Internal bucket tag. -:Type: String -:Parent: ``bucket`` +:描述: Internal bucket tag. +:类型: String +:父节点: ``bucket`` ``owner`` -:Description: The user id of the bucket owner. -:Type: String -:Parent: ``bucket`` +:描述: The user id of the bucket owner. +:类型: String +:父节点: ``bucket`` ``usage`` -:Description: Storage usage information. -:Type: Container -:Parent: ``bucket`` +:描述: Storage usage information. +:类型: Container +:父节点: ``bucket`` ``index`` -:Description: Status of bucket index. -:Type: String -:Parent: ``bucket`` +:描述: Status of bucket index. +:类型: String +:父节点: ``bucket`` -Special Error Responses -~~~~~~~~~~~~~~~~~~~~~~~ +特殊错误响应 +~~~~~~~~~~~~ ``IndexRepairFailed`` -:Description: Bucket index repair failed. -:Code: 409 Conflict +:描述: Bucket index repair failed. +:状态码: 409 Conflict Check Bucket Index ================== @@ -1311,8 +1317,8 @@ accounting with ``check-objects``, ``fix`` must be set to True. :caps: buckets=write -Syntax -~~~~~~ +语法 +~~~~ :: @@ -1325,40 +1331,40 @@ Request Parameters ``bucket`` -:Description: The bucket to return info on. -:Type: String -:Example: ``foo_bucket`` -:Required: Yes +:描述: The bucket to return info on. +:类型: String +:实例: ``foo_bucket`` +:是否必需: Yes ``check-objects`` -:Description: Check multipart object accounting. -:Type: Boolean -:Example: True [False] -:Required: No +:描述: Check multipart object accounting. +:类型: Boolean +:实例: True [False] +:是否必需: No ``fix`` -:Description: Also fix the bucket index when checking. -:Type: Boolean -:Example: False [False] -:Required: No +:描述: Also fix the bucket index when checking. +:类型: Boolean +:实例: False [False] +:是否必需: No Response Entities ~~~~~~~~~~~~~~~~~ ``index`` -:Description: Status of bucket index. -:Type: String +:描述: Status of bucket index. +:类型: String -Special Error Responses -~~~~~~~~~~~~~~~~~~~~~~~ +特殊错误响应 +~~~~~~~~~~~~ ``IndexRepairFailed`` -:Description: Bucket index repair failed. -:Code: 409 Conflict +:描述: Bucket index repair failed. +:状态码: 409 Conflict Remove Bucket ============= @@ -1367,8 +1373,8 @@ Delete an existing bucket. :caps: buckets=write -Syntax -~~~~~~ +语法 +~~~~ :: @@ -1382,35 +1388,35 @@ Request Parameters ``bucket`` -:Description: The bucket to remove. -:Type: String -:Example: ``foo_bucket`` -:Required: Yes +:描述: The bucket to remove. +:类型: String +:实例: ``foo_bucket`` +:是否必需: Yes ``purge-objects`` -:Description: Remove a buckets objects before deletion. -:Type: Boolean -:Example: True [False] -:Required: No +:描述: Remove a buckets objects before deletion. +:类型: Boolean +:实例: True [False] +:是否必需: No Response Entities ~~~~~~~~~~~~~~~~~ None. -Special Error Responses -~~~~~~~~~~~~~~~~~~~~~~~ +特殊错误响应 +~~~~~~~~~~~~ ``BucketNotEmpty`` -:Description: Attempted to delete non-empty bucket. -:Code: 409 Conflict +:描述: Attempted to delete non-empty bucket. +:状态码: 409 Conflict ``ObjectRemovalFailed`` -:Description: Unable to remove objects. -:Code: 409 Conflict +:描述: Unable to remove objects. +:状态码: 409 Conflict Unlink Bucket ============= @@ -1420,8 +1426,8 @@ bucket ownership. :caps: buckets=write -Syntax -~~~~~~ +语法 +~~~~ :: @@ -1434,30 +1440,30 @@ Request Parameters ``bucket`` -:Description: The bucket to unlink. -:Type: String -:Example: ``foo_bucket`` -:Required: Yes +:描述: The bucket to unlink. +:类型: String +:实例: ``foo_bucket`` +:是否必需: Yes ``uid`` -:Description: The user ID to unlink the bucket from. -:Type: String -:Example: ``foo_user`` -:Required: Yes +:描述: The user ID to unlink the bucket from. +:类型: String +:实例: ``foo_user`` +:是否必需: Yes Response Entities ~~~~~~~~~~~~~~~~~ None. -Special Error Responses -~~~~~~~~~~~~~~~~~~~~~~~ +特殊错误响应 +~~~~~~~~~~~~ ``BucketUnlinkFailed`` -:Description: Unable to unlink bucket from specified user. -:Code: 409 Conflict +:描述: Unable to unlink bucket from specified user. +:状态码: 409 Conflict Link Bucket =========== @@ -1467,8 +1473,8 @@ any previous user. :caps: buckets=write -Syntax -~~~~~~ +语法 +~~~~ :: @@ -1481,80 +1487,80 @@ Request Parameters ``bucket`` -:Description: The bucket to unlink. -:Type: String -:Example: ``foo_bucket`` -:Required: Yes +:描述: The bucket to unlink. +:类型: String +:实例: ``foo_bucket`` +:是否必需: Yes ``uid`` -:Description: The user ID to link the bucket to. -:Type: String -:Example: ``foo_user`` -:Required: Yes +:描述: The user ID to link the bucket to. +:类型: String +:实例: ``foo_user`` +:是否必需: Yes Response Entities ~~~~~~~~~~~~~~~~~ ``bucket`` -:Description: Container for single bucket information. -:Type: Container +:描述: Container for single bucket information. +:类型: Container ``name`` -:Description: The name of the bucket. -:Type: String -:Parent: ``bucket`` +:描述: The name of the bucket. +:类型: String +:父节点: ``bucket`` ``pool`` -:Description: The pool the bucket is stored in. -:Type: String -:Parent: ``bucket`` +:描述: The pool the bucket is stored in. +:类型: String +:父节点: ``bucket`` ``id`` -:Description: The unique bucket id. -:Type: String -:Parent: ``bucket`` +:描述: The unique bucket id. +:类型: String +:父节点: ``bucket`` ``marker`` -:Description: Internal bucket tag. -:Type: String -:Parent: ``bucket`` +:描述: Internal bucket tag. +:类型: String +:父节点: ``bucket`` ``owner`` -:Description: The user id of the bucket owner. -:Type: String -:Parent: ``bucket`` +:描述: The user id of the bucket owner. +:类型: String +:父节点: ``bucket`` ``usage`` -:Description: Storage usage information. -:Type: Container -:Parent: ``bucket`` +:描述: Storage usage information. +:类型: Container +:父节点: ``bucket`` ``index`` -:Description: Status of bucket index. -:Type: String -:Parent: ``bucket`` +:描述: Status of bucket index. +:类型: String +:父节点: ``bucket`` -Special Error Responses -~~~~~~~~~~~~~~~~~~~~~~~ +特殊错误响应 +~~~~~~~~~~~~ ``BucketUnlinkFailed`` -:Description: Unable to unlink bucket from specified user. -:Code: 409 Conflict +:描述: Unable to unlink bucket from specified user. +:状态码: 409 Conflict ``BucketLinkFailed`` -:Description: Unable to link bucket to specified user. -:Code: 409 Conflict +:描述: Unable to link bucket to specified user. +:状态码: 409 Conflict Remove Object ============= @@ -1563,8 +1569,8 @@ Remove an existing object. NOTE: Does not require owner to be non-suspended. :caps: buckets=write -Syntax -~~~~~~ +语法 +~~~~ :: @@ -1576,35 +1582,35 @@ Request Parameters ``bucket`` -:Description: The bucket containing the object to be removed. -:Type: String -:Example: ``foo_bucket`` -:Required: Yes +:描述: The bucket containing the object to be removed. +:类型: String +:实例: ``foo_bucket`` +:是否必需: Yes ``object`` -:Description: The object to remove. -:Type: String -:Example: ``foo.txt`` -:Required: Yes +:描述: The object to remove. +:类型: String +:实例: ``foo.txt`` +:是否必需: Yes Response Entities ~~~~~~~~~~~~~~~~~ None. -Special Error Responses -~~~~~~~~~~~~~~~~~~~~~~~ +特殊错误响应 +~~~~~~~~~~~~ ``NoSuchObject`` -:Description: Specified object does not exist. -:Code: 404 Not Found +:描述: Specified object does not exist. +:状态码: 404 Not Found ``ObjectRemovalFailed`` -:Description: Unable to remove objects. -:Code: 409 Conflict +:描述: Unable to remove objects. +:状态码: 409 Conflict @@ -1615,8 +1621,8 @@ Read the policy of an object or bucket. :caps: buckets=read -Syntax -~~~~~~ +语法 +~~~~ :: @@ -1629,17 +1635,17 @@ Request Parameters ``bucket`` -:Description: The bucket to read the policy from. -:Type: String -:Example: ``foo_bucket`` -:Required: Yes +:描述: The bucket to read the policy from. +:类型: String +:实例: ``foo_bucket`` +:是否必需: Yes ``object`` -:Description: The object to read the policy from. -:Type: String -:Example: ``foo.txt`` -:Required: No +:描述: The object to read the policy from. +:类型: String +:实例: ``foo.txt`` +:是否必需: No Response Entities ~~~~~~~~~~~~~~~~~ @@ -1648,17 +1654,17 @@ If successful, returns the object or bucket policy ``policy`` -:Description: Access control policy. -:Type: Container +:描述: Access control policy. +:类型: Container -Special Error Responses -~~~~~~~~~~~~~~~~~~~~~~~ +特殊错误响应 +~~~~~~~~~~~~ ``IncompleteBody`` -:Description: Either bucket was not specified for a bucket policy request or bucket +:描述: Either bucket was not specified for a bucket policy request or bucket and object were not specified for an object policy request. -:Code: 400 Bad Request +:状态码: 400 Bad Request Add A User Capability ===================== @@ -1667,8 +1673,8 @@ Add an administrative capability to a specified user. :caps: users=write -Syntax -~~~~~~ +语法 +~~~~ :: @@ -1680,17 +1686,17 @@ Request Parameters ``uid`` -:Description: The user ID to add an administrative capability to. -:Type: String -:Example: ``foo_user`` -:Required: Yes +:描述: The user ID to add an administrative capability to. +:类型: String +:实例: ``foo_user`` +:是否必需: Yes ``user-caps`` -:Description: The administrative capability to add to the user. -:Type: String -:Example: ``usage=read, write`` -:Required: Yes +:描述: The administrative capability to add to the user. +:类型: String +:实例: ``usage=read, write`` +:是否必需: Yes Response Entities ~~~~~~~~~~~~~~~~~ @@ -1699,39 +1705,39 @@ If successful, the response contains the user's capabilities. ``user`` -:Description: A container for the user data information. -:Type: Container -:Parent: ``user`` +:描述: A container for the user data information. +:类型: Container +:父节点: ``user`` ``user_id`` -:Description: The user id. -:Type: String -:Parent: ``user`` +:描述: The user id. +:类型: String +:父节点: ``user`` ``caps`` -:Description: User capabilities. -:Type: Container -:Parent: ``user`` +:描述: User capabilities. +:类型: Container +:父节点: ``user`` -Special Error Responses -~~~~~~~~~~~~~~~~~~~~~~~ +特殊错误响应 +~~~~~~~~~~~~ ``InvalidCapability`` -:Description: Attempt to grant invalid admin capability. -:Code: 400 Bad Request +:描述: Attempt to grant invalid admin capability. +:状态码: 400 Bad Request -Example Request +实例 Request ~~~~~~~~~~~~~~~ :: PUT /{admin}/user?caps&format=json HTTP/1.1 Host: {fqdn} - Content-Type: text/plain + Content-类型: text/plain Authorization: {your-authorization-token} usage=read @@ -1744,8 +1750,8 @@ Remove an administrative capability from a specified user. :caps: users=write -Syntax -~~~~~~ +语法 +~~~~ :: @@ -1757,17 +1763,17 @@ Request Parameters ``uid`` -:Description: The user ID to remove an administrative capability from. -:Type: String -:Example: ``foo_user`` -:Required: Yes +:描述: The user ID to remove an administrative capability from. +:类型: String +:实例: ``foo_user`` +:是否必需: Yes ``user-caps`` -:Description: The administrative capabilities to remove from the user. -:Type: String -:Example: ``usage=read, write`` -:Required: Yes +:描述: The administrative capabilities to remove from the user. +:类型: String +:实例: ``usage=read, write`` +:是否必需: Yes Response Entities ~~~~~~~~~~~~~~~~~ @@ -1776,44 +1782,46 @@ If successful, the response contains the user's capabilities. ``user`` -:Description: A container for the user data information. -:Type: Container -:Parent: ``user`` +:描述: A container for the user data information. +:类型: Container +:父节点: ``user`` ``user_id`` -:Description: The user id. -:Type: String -:Parent: ``user`` +:描述: The user id. +:类型: String +:父节点: ``user`` ``caps`` -:Description: User capabilities. -:Type: Container -:Parent: ``user`` +:描述: User capabilities. +:类型: Container +:父节点: ``user`` -Special Error Responses -~~~~~~~~~~~~~~~~~~~~~~~ +特殊错误响应 +~~~~~~~~~~~~ ``InvalidCapability`` -:Description: Attempt to remove an invalid admin capability. -:Code: 400 Bad Request +:描述: Attempt to remove an invalid admin capability. +:状态码: 400 Bad Request ``NoSuchCap`` -:Description: User does not possess specified capability. -:Code: 404 Not Found +:描述: User does not possess specified capability. +:状态码: 404 Not Found -Special Error Responses -~~~~~~~~~~~~~~~~~~~~~~~ +特殊错误响应 +~~~~~~~~~~~~ None. -Quotas -====== +.. _Quotas: + +配额 +==== The Admin Operations API enables you to set quotas on users and on bucket owned by users. See `Quota Management`_ for additional details. Quotas include the @@ -1838,9 +1846,10 @@ Valid parameters for quotas include: The options are ``bucket`` and ``user``. +.. _Get User Quota: -Get User Quota -~~~~~~~~~~~~~~ +读取用户配额 +~~~~~~~~~~~~ To get a quota, the user must have ``users`` capability set with ``read`` permission. :: @@ -1848,21 +1857,24 @@ permission. :: GET /admin/user?quota&uid=<uid>"a-type=user -Set User Quota -~~~~~~~~~~~~~~ +.. _Set User Quota: + +设置用户配额 +~~~~~~~~~~~~ To set a quota, the user must have ``users`` capability set with ``write`` permission. :: PUT /admin/user?quota&uid=<uid>"a-type=user - The content must include a JSON representation of the quota settings as encoded in the corresponding read operation. -Get Bucket Quota -~~~~~~~~~~~~~~~~ +.. _Get Bucket Quota: + +读取桶配额 +~~~~~~~~~~ To get a quota, the user must have ``users`` capability set with ``read`` permission. :: @@ -1870,8 +1882,10 @@ permission. :: GET /admin/user?quota&uid=<uid>"a-type=bucket -Set Bucket Quota -~~~~~~~~~~~~~~~~ +.. _Set Bucket Quota: + +设置桶配额 +~~~~~~~~~~ To set a quota, the user must have ``users`` capability set with ``write`` permission. :: @@ -1884,34 +1898,35 @@ as encoded in the corresponding read operation. -Standard Error Responses -======================== +.. _Standard Error Responses: + +标准错误响应 +============ ``AccessDenied`` -:Description: Access denied. -:Code: 403 Forbidden +:描述: 访问被拒绝。 +:状态码: 403 Forbidden ``InternalError`` -:Description: Internal server error. -:Code: 500 Internal Server Error +:描述: 服务器内部错误。 +:状态码: 500 Internal Server Error ``NoSuchUser`` -:Description: User does not exist. -:Code: 404 Not Found +:描述: 用户不存在。 +:状态码: 404 Not Found ``NoSuchBucket`` -:Description: Bucket does not exist. -:Code: 404 Not Found +:描述: 桶不存在。 +:状态码: 404 Not Found ``NoSuchKey`` -:Description: No such access key. -:Code: 404 Not Found - +:描述: 此访问密钥不存在。 +:状态码: 404 Not Found .. _Admin Guide: ../admin diff --git a/radosgw/config-ref.rst b/radosgw/config-ref.rst index ff177b86..db518181 100644 --- a/radosgw/config-ref.rst +++ b/radosgw/config-ref.rst @@ -304,19 +304,24 @@ ``rgw content length compat`` -:描述: 允许兼容设置了 CONTENT_LENGTH 和 HTTP_CONTENT_LENGTH 的 FCGI 请求。 +:描述: 允许兼容设置了 CONTENT_LENGTH 和 HTTP_CONTENT_LENGTH 的 + FCGI 请求。 :类型: Boolean :默认值: ``false`` +.. _Regions: + region (域组) =============== -Ceph 从 v0.67 版开始,通过 region 概念支持 Ceph 对象网关联盟部署和统一的命\ -名空间。 region 定义了位于一或多个域内的 Ceph 对象网关例程的地理位置。 +Ceph 从 v0.67 版开始,通过 region 概念支持 Ceph 对象网关联盟\ +部署和统一的命名空间。 region 定义了位于一或多个域内的 Ceph +对象网关例程的地理位置。 -region 的配置不同于一般配置过程,因为不是所有的配置都放在 Ceph 配置文件中。\ -从 Ceph 0.67 版开始,你可以列举 region 、获取 region 配置或设置 region 配置。 +region 的配置不同于一般配置过程,因为不是所有的配置都放在 Ceph +配置文件中。从 Ceph 0.67 版开始,你可以列举 region 、获取 +region 配置或设置 region 配置。 罗列 region @@ -324,7 +329,7 @@ region 的配置不同于一般配置过程,因为不是所有的配置都放 Ceph 集群可包含一系列 region ,可用下列命令列举 region : :: - sudo radosgw-admin regions list + sudo radosgw-admin region list ``radosgw-admin`` 命令会返回 JSON 格式的 region 列表。 @@ -342,9 +347,8 @@ Ceph 集群可包含一系列 region ,可用下列命令列举 region : :: sudo radosgw-admin region-map get - -.. note:: 如果你的到了 ``failed to read region map`` 错误,先试试 \ - ``sudo radosgw-admin region-map update`` 。 +.. note:: 如果你的到了 ``failed to read region map`` 错误,\ + 先试试 ``sudo radosgw-admin region-map update`` 。 获取单个 region diff --git a/rbd/rbd-openstack.rst b/rbd/rbd-openstack.rst index 246818d0..5514793c 100644 --- a/rbd/rbd-openstack.rst +++ b/rbd/rbd-openstack.rst @@ -92,8 +92,9 @@ Create a Pool 配置 OpenStack 的 Ceph 客户端 ============================= -运行着 ``glance-api`` 、 ``cinder-volume`` 、 ``nova-compute`` 或 \ -``cinder-backup`` 的主机被当作 Ceph 客户端,它们都需要 ``ceph.conf`` 文件。 :: +运行着 ``glance-api`` 、 ``cinder-volume`` 、 ``nova-compute`` +或 ``cinder-backup`` 的主机被当作 Ceph 客户端,它们都需要 +``ceph.conf`` 文件。 :: ssh {your-openstack-server} sudo tee /etc/ceph/ceph.conf </etc/ceph/ceph.conf @@ -101,29 +102,33 @@ Create a Pool 安装 Ceph 客户端软件包 ---------------------- -在运行 ``glance-api`` 的节点上你需要 ``librbd`` 的 Python 接口: :: +在运行 ``glance-api`` 的节点上你得安装 ``librbd`` 的 Python 绑定: :: sudo apt-get install python-rbd sudo yum install python-rbd -在 ``nova-compute`` 、 ``cinder-backup`` 和 ``cinder-volume`` 节点上,要安装 \ -Python 绑定和客户端命令行工具: :: +在 ``nova-compute`` 、 ``cinder-backup`` 和 ``cinder-volume`` +节点上,要安装 Python 绑定和客户端命令行工具: :: sudo apt-get install ceph-common - sudo yum install ceph + sudo yum install ceph-common +.. _Setup Ceph Client Authentication: + 配置 Ceph 客户端认证 -------------------- -如果你启用了 `cephx 认证`_\ ,需要分别为 Nova/Cinder 和 Glance 创建新用户。命令如下: :: +如果你启用了 `cephx 认证`_\ ,需要分别为 Nova/Cinder 和 Glance +创建新用户。命令如下: :: ceph auth get-or-create client.cinder mon 'allow r' osd 'allow class-read object_prefix rbd_children, allow rwx pool=volumes, allow rwx pool=vms, allow rx pool=images' ceph auth get-or-create client.glance mon 'allow r' osd 'allow class-read object_prefix rbd_children, allow rwx pool=images' ceph auth get-or-create client.cinder-backup mon 'allow r' osd 'allow class-read object_prefix rbd_children, allow rwx pool=backups' -把这些用户 ``client.cinder`` 、 ``client.glance`` 和 ``client.cinder-backup`` 的\ -密钥环复制到各自所在节点,并修正所有权: :: +把这些用户 ``client.cinder`` 、 ``client.glance`` 和 +``client.cinder-backup`` 的密钥环复制到各自所在节点,并修正\ +所有权: :: ceph auth get-or-create client.glance | ssh {your-glance-api-server} sudo tee /etc/ceph/ceph.client.glance.keyring ssh {your-glance-api-server} sudo chown glance:glance /etc/ceph/ceph.client.glance.keyring diff --git a/update-doc.sh b/update-doc.sh index 5da10be1..0ef2fbe8 100755 --- a/update-doc.sh +++ b/update-doc.sh @@ -2,7 +2,7 @@ # Where we synced with ceph mainline. Note by date is more reliable than # commit ID, because there's too many criss-cross branches which is hard # for us to sync by branch/commit ID. -SYNC_START="2016-04-05" +SYNC_START="2016-04-12" if ! /usr/bin/which tig &>/dev/null; then echo "Need command line tool: tig"