|
|
1. 部署LIBRADOS环境. ^8 f- b3 B- ~; t
客户端应用程序需要librados才能连接到Ceph存储集群。+ B' P/ ^1 l+ g; h% ^
, [8 J# W4 Z1 R# U# J d
1.1 安装jna.jar
1 d& A/ W a) p! V$ }" d) KDebian/Ubuntu环境下执行以下命令 A( w Z4 |9 j" g3 \
, N r" g' q: Y/ Y, |
sudo apt-get install libjna-java
# d |' ?7 J% j& w [6 A8 L0 a! Q: _5 b
% l+ j, G; S+ A# R0 N
CentOS/RHEL环境下执行以下命令
* O. M) | O2 Q
4 ~9 w+ u1 H# S5 Nsudo yum install jna! S) u" z: G5 W t- N4 N
( K* S7 v& y0 y4 e+ i
JAR文件位于/usr/share/java. _7 B& D+ v1 ^9 h. M& g( R
w1 U1 f3 x0 \1 G
1.2 克隆rados-java代码库4 Y) D+ y& O8 w s2 c9 p
git clone --recursive https://github.com/ceph/rados-java.git- w/ E' C) E% P* ~
! p$ }3 b/ t& _+ X/ ^1.3 编译rados-java代码:
7 h5 {3 A5 c J2 b# }$ I( h. ?* Hcd rados-java
; O% y$ t# l- ?: f/ m8 Aant
& ?7 Q: ~7 ]5 }4 e& N3 J# [
1 C5 }2 {9 O8 e
5 R4 v5 f: m, i' }% x! j# h( HJAR文件位于rados-java/target目录下* d7 @( w$ l& O3 d& m' [
; c* g0 L& D5 n7 T1 V \+ F1.4 关联路径
$ D* ^; N s; f/ M( u- Y, b7 A复制该JAR文件到公共目录 (例如 /usr/share/java) ,并且确认该文件和JNA JAR在你的JVM’s classpath目录中. 举个例子,你可以按照以下的方法来关联路径:
- U" e" X! m# M# x1 k& Q, Q% [0 ?, U m2 q. D7 L* h
sudo cp target/rados-0.1.3.jar /usr/share/java/rados-0.1.3.jar. ^& f9 g, h# C7 J5 U
sudo ln -s /usr/share/java/jna-3.2.7.jar /usr/lib/jvm/default-java/jre/lib/ext/jna-3.2.7.jar
: W: p/ G- D* z4 |* `1 A4 Rsudo ln -s /usr/share/java/rados-0.1.3.jar /usr/lib/jvm/default-java/jre/lib/ext/rados-0.1.3.jar
* `% L% i3 b4 O4 b l0 n8 ^ [ |3 P/ h, ]
T' |0 F- }* V- _
编译文档可执行以下的命令:
4 ^, m/ c" h# R" x+ @7 s8 R9 S3 ^3 A P! z) ?# b$ E
ant docs
9 H/ y. |1 c0 C; [( }' H0 C9 [1 r0 y X
2. 配置群集句柄
9 Z T* N: c# l一个Ceph的客户端通过librados,直接与交互的OSD来存储和检索数据。要与OSD交互,客户端应用程序必须调用 librados 并连接到Ceph Monitor。连接后,librados从Ceph Monitor中检索 Cluster Map。当客户端应用程序想要读取或写入数据时,它会创建I/O上下文并绑定到池。该池具有关联的规则集,该规则集定义了如何将数据放入存储群集中。通过I/O上下文,客户端向librados提供对象名称,它获取对象名称和集群映射(即集群的拓扑)并计算用于定位数据的放置组和OSD。然后客户端应用程序可以读取或写入数据。客户端应用程序无需直接了解群集的拓扑。
5 ]) [# |* L& x% X8 A$ u
: H8 f- G; t1 ?7 |Ceph存储集群句柄封装了客户端配置,包括:- n7 q. X9 B1 X6 x
6 m7 E' B e# c/ W
使用用户ID的rados_create() 或使用用户名称的rados_create2() (推荐使用此方法).2 c4 C3 P( d8 Y9 Q. A2 @7 N
cephx认证密钥
; ]+ u( M8 y' k/ s监视器ID和IP地址
* ~% G1 T: h: }记录级别6 y" e8 u0 E; G1 }
调试级别- u" |4 ~0 w4 T0 G
因此,从您的应用程序使用群集的第一步是:1)创建应用程序将用于连接到存储群集的群集句柄,然后2)使用该句柄进行连接。要连接到群集,应用程序必须提供监视器地址,用户名和身份验证密钥(默认情况下启用cephx)。
! j, i4 t, F. d$ b- A- U/ T1 @
8 P( [0 t, o6 [! W注意 与不同的Ceph存储集群 - 或与不同用户的同一集群 - 交互需要不同的集群句柄。
1 \/ f5 V2 U; O" b4 j5 ]2 A* \& i% Z4 Z+ _ B% c5 D
RADOS提供了多种设置所需值的方法。对于监视器和加密密钥设置,一种处理它们的简单方法是确保您的Ceph配置文件包含密钥环文件的密钥环路径和至少一个监视器地址(例如,mon 主机)。例如:
) u5 h' S& E1 {1 y1 c5 S9 d
2 j' J" R3 T& ]5 F3 L! Q+ x[global]
" f) ^2 Y Z( D: s ?mon host = 192.168.11.1 5 e9 a- R1 l) y$ ]8 w
keyring = /etc/ceph/ceph.client.admin.keyring$ V- d2 E/ o$ ?/ w9 ]' S1 Z
! Y) `. l) A5 M5 }4 |" p1 @! [
1 M4 i6 W2 N6 e4 M; C创建句柄后,可以读取Ceph配置文件以配置句柄。还可以将参数传递给您的应用程序,并使用函数解析它们以解析命令行参数(例如,rados_conf_parse_argv()),或解析Ceph环境变量(例如,rados_conf_parse_env())。某些包装器无法实现便捷方法,因此需要实现这些功能。下图提供了初始连接的高级流程。
/ p- G m7 g' l) M* D' K$ ]& }/ o7 W+ o0 U- K* c8 [5 q
连接后,应用程序可以仅使用群集句柄调用影响整个群集的功能。例如,一旦有了集群句柄,您就可以:
% r+ ]% u$ O3 I) \) O6 @
U) [3 e$ A5 z" s获取群集统计信息* E( g* x2 K3 x
使用池操作(存在,创建,列表,删除)
9 s- b2 ]+ L+ Y! F获取并设置配置
8 z0 ?6 e, F X1 }- ]1 ICeph的一个强大功能是能够绑定到不同的池。每个池可能具有不同数量的放置组,对象副本和复制策略。例如,可以将池设置为“热”池,其将SSD用于常用对象或使用擦除编码的“冷”池。
* [! i& a! z* z& W) g# dJava要求你指定用户ID(admin)或用户名(client.admin),并使用默认的ceph cluster name。Java绑定将基于C ++的错误转换为异常。
' X% y2 z0 R3 h6 K8 N
6 \1 s1 ?0 T2 Z- f3 l0 cimport com.ceph.rados.Rados;6 W3 R$ u; Z" n! K
import com.ceph.rados.RadosException;% z; Q, i E! g7 u0 f- C' f/ |
5 O6 B+ {. C, V
import java.io.File;! B& y$ d6 c. ~, M9 G6 Y# a
8 P4 D z0 z) @2 x! N/ S
public class CephClient {
( M! }9 c) z9 _9 v# D* `+ Q5 j public static void main (String args[]){
( x' s6 D9 ^. [
0 p) B& w* y, I* T: z3 D try {
0 Q1 C* |4 y9 ?+ @# V# i' X* S Rados cluster = new Rados("admin");
1 B: w" r1 X7 L" W System.out.println("Created cluster handle.");
3 D- l9 D5 d$ X1 {* n2 I8 a
1 y$ ~8 [4 v( d File f = new File("/etc/ceph/ceph.conf");
$ h4 ^( H: M4 S$ @/ D8 {: h cluster.confReadFile(f);
) E V( i, C8 v! Q System.out.println("Read the configuration file.");' \# g9 y! c6 b, I/ E
( A& g8 L1 | \1 |3 h' H6 l( s
cluster.connect();
. s( j' I- ]3 C$ i! E System.out.println("Connected to the cluster.");
* {6 z* Y2 _/ l. s4 h) K1 D& k9 `3 a3 Q: D2 T/ g" ~) F1 K
} catch (RadosException e) {, b; K# d' m' a9 D( F/ a/ l
System.out.println(e.getMessage() + ": " + e.getReturnValue());) E, g1 }' L' d% R0 H' \/ U) q
}
5 W. C3 x- F9 F3 ^0 x. J }
/ ~8 p, q) _3 k7 q8 H9 t}
' y7 c1 {! h2 {4 ]/ r* q8 @
/ I, o$ I8 B& z; t; @; M4 E9 t4 v* S" }$ Y2 a; }. f& G
编译源代码; 然后,运行。如果你已经把连接Ceph的JAR文件复制到/usr/share/java并软连接到扩展路径, 就无需设置classpath. 如下运行:
8 A& Q) R; f+ f6 z: Z
! i- t3 p2 u) ?) Vjavac CephClient.java
2 G9 Z4 {2 U6 k8 b5 Ljava CephClient5 f1 u' R5 s% R" U, a, F2 X
1 m; L) J0 f+ y. K! a5 o1 h5 i
* x. P3 o" \" o7 i
3. 创建I/O上下文
5 ]" v. l B% A% W一旦应用程序具有集群句柄和与Ceph存储集群的连接,就可以创建I/O上下文并开始读取和写入数据。I/O上下文将连接绑定到特定池。用户必须具有适当的 CAPS权限才能访问指定的池。例如,具有读访问权但不具有写访问权的用户将只能读取数据。I/O上下文功能包括:, W' q) I( V+ Y! a, n W- o4 P
5 w, m+ R0 u# n5 t. Y写/读数据和扩展属性+ n/ S0 P/ d. p/ H% _& Y
列出并迭代对象和扩展属性$ _ A. d0 F( I- H! x- w) \
快照池,列表快照等
5 r8 i2 M# w4 SRADOS使应用程序可以同步和异步交互。一旦应用程序具有I/O上下文,读/写操作只需要知道object / xattr名称。封装在librados中的CRUSH算法使用群集映射来识别适当的OSD。OSD守护程序处理复制,如Smart Daemons启用超大规模中所述。所述librados库也映射对象来展示位置组,如在 计算PG的ID。$ f, v$ E: S* S3 A/ G* m
0 y7 d3 b n& d% Y9 N以下示例使用默认数据池。但是,也可以使用API列出池,确保它们存在,或者创建和删除池。对于写操作,这些示例说明了如何使用同步模式。对于读取操作,这些示例说明了如何使用异步模式。5 L* a8 s9 S* V x1 \
+ ?* s0 O: `& z/ `5 ?# N# M- ~
注意 使用此API删除池时请小心。如果删除池,池中的池和所有数据将丢失。1 U; p6 ? i3 M
1
$ G9 R% U6 M1 q9 z9 m3.1 写入数据代码5 c3 N8 U; v: }
import com.ceph.rados.Rados;
; y7 @ A# u; Y4 }( L5 q# T; \import com.ceph.rados.RadosException;
/ X5 k0 b& X3 Z; O. @6 }' r- W2 V. r7 c+ q
import java.io.File;
3 V, E3 u% W5 Q9 m3 n; Dimport com.ceph.rados.IoCTX;4 I! u Y- P4 F/ j \
4 A" ~7 l0 y% a" b$ bpublic class CephClient {7 V' I7 p4 A5 i# [# _9 g
public static void main (String args[]){
+ a2 @! l# z8 \8 e; V0 j/ H4 b8 x, n, t" b" ~, L
try {8 e' E0 ]9 D- E' M
Rados cluster = new Rados("admin");
4 d5 S m, R4 a, c! o# v System.out.println("Created cluster handle.");
9 |1 i7 ^; V. h: } s9 Z5 ` //利用配置文件连接ceph
' [9 y, G4 e$ }+ u# h1 q; @7 F+ L File f = new File("/etc/ceph/ceph.conf");
& M1 }0 C0 F, \+ r cluster.confReadFile(f);
# {, u$ Z$ ~! K+ W( E8 d System.out.println("Read the configuration file.");
+ @2 e$ K. P5 W' N2 @( ?! d1 I, E' t
cluster.connect();+ ?6 l2 ^& ~! s9 Z# N8 c* K; C
System.out.println("Connected to the cluster.");7 I2 R% V0 o. A. N
8 e2 h* i2 T; P+ X5 m+ Z6 b O IoCTX io = cluster.ioCtxCreate("data");1 _2 h9 {9 Q/ H% w
9 h" A2 m5 `/ U# D) Q- q1 n
String oidone = "hw";
# C# _2 e" h2 x8 t5 Y# h; I String contentone = "Hello World!";. C9 ]6 a! a, w2 y
io.write(oidone, contentone);: ^$ p5 w1 C4 f2 u6 S
( O1 D8 e, K5 m7 E8 \
String oidtwo = "bm";
7 ^) T6 [2 K( ~- q String contenttwo = "Bonjour tout le monde!";! |9 i" ]9 G% W/ Q$ Y& O# E2 t
io.write(oidtwo, contenttwo);
( S2 ~2 T5 W% U5 w! x! [' n% R
9 l+ K- o: r4 O0 J String[] objects = io.listObjects();+ a' G" H/ Y5 X9 r4 W
for (String object: objects)0 z- Q" j8 F% u
System.out.println(object);2 |( r8 B2 E( ]( q% i9 {
, F1 x9 b6 {0 _, f io.remove(oidone);# F) i t' D( [$ v
io.remove(oidtwo);: {0 |+ U' v, y7 g; l# s
2 Q. _0 p% X) _/ h/ Y e% U/ |. { cluster.ioCtxDestroy(io);+ ^3 t5 E" z! G; s1 }: T; r! j
' b8 u) J5 i9 T1 g( X4 C5 H1 y& H
} catch (RadosException e) {
% [7 S2 y( t' A/ r9 S7 b4 } System.out.println(e.getMessage() + ": " + e.getReturnValue());
" r$ C1 |* z0 ?% r }
; w2 \! Z6 w" l2 x: V k' p# b }$ N2 c4 [7 i9 C" u, }4 n
}% R# M; d @" c) N8 u
6 r+ {2 F3 |( D
. g* T, P: f L; H* w; E
3.2 一些基本操作) J" j8 _& r* [* P$ G$ V$ a- U) W
package com.ceph.rbd;
% @9 L, f- `$ L$ Y* Y* Z5 j ^* \- d5 t, I6 w: P& ?- R9 q6 C$ Q" Q
import java.io.File;$ b, q' V3 w7 p% o+ P3 j
import java.util.Arrays;
& I* [5 f% I: t! nimport java.util.List;9 i+ Q! D" _# @) [
0 k. c: K7 ]- m) \- `4 ]import com.ceph.rados.IoCTX;
# R3 x0 f# b3 ~3 nimport com.ceph.rados.Rados;5 H. R0 p$ t: ~, x
import com.ceph.rados.exceptions.RadosException;
: H/ v- V7 K) A* F/ h7 W. `: Jimport com.ceph.rbd.jna.RbdImageInfo;9 P8 p7 t( z F# ~
import com.ceph.rbd.jna.RbdSnapInfo;3 h p& ?* k9 z; H# \2 Y2 V) E
2 s9 \1 ?+ r$ @& Q
public class RbdDao { q0 E& {) @4 ^* B
8 f+ U. ]6 ^1 q' w6 |
private static Rados rados;" f1 n) p( f7 d/ c5 s; J
private static IoCTX ioctx;
" e7 R8 H; V( `4 }/ e. X4 p private static Rbd rbd;0 h. Y* a' b( B9 ~- X1 x
/**
8 e3 r5 L: k/ E/ K * 连接上ceph环境! V1 J7 |, v# c5 n9 q0 R0 p$ Y
*/
9 c2 n8 _" r) k+ g; b' V public static void connectCeph(){
8 }, Z- J, h3 ?" r try {
$ K. Y$ X- `8 {2 \( P //利用参数连接Ceph
" [8 x7 F- g& j; I) o rados = new Rados("admin");
' l; Q4 I4 E( S# g- f& J rados.confSet("mon_host", "172.16.60.41");
. l- z9 }4 J9 j" f# L rados.confSet("key", "AQCdP9pYGI4jBBAAc96J8/OconCkVKWPBNU2vg==");
' b( w1 x- { H0 r/ M P; L rados.connect();
6 J. m6 ]1 V! g, b0 A% \% K ioctx = rados.ioCtxCreate("rbd");! X2 Q& B- J q$ q; }$ J# ^
rbd = new Rbd(ioctx);
+ ^% G3 M) d1 X1 b System.out.println("successs connetc");( c/ c/ E" @" {! A
} catch (Exception e) {+ A) J3 y! D4 z% C S
e.printStackTrace();- X' n- f; m/ z: [$ [
// TODO: handle exception. J4 m- [4 u& Y1 |- N% [
}- x( K; A9 l* l& a0 R, V
}9 B8 [+ A4 j* u# d/ W* X h
0 y" f" }: L+ j4 J/ z% b: x/ S0 L% @( Z
/**& U: Z( u4 @! u" w4 O, N3 e
* 返回所有的image,并展示其详细信息
' ^% R! m& O( x * @return' F" _) T" S- O/ c l& M; P
*/' X( w% `% d6 t: r
public static List<String> imageList(){
' ~& v2 p3 [# P D! Z List<String> imageList=null;) M$ U4 d2 J4 f( o$ E5 A
try {
' J# T$ }% d$ g imageList = Arrays.asList(rbd.list());
{; I2 m1 x+ ^3 o. `: H for(String s:imageList){
4 |, v* A1 b% o. Y) f9 b) X- r/ l showDetailOfImage(s);
# A1 W5 j) f4 J) }/ v0 o) O* h0 |- Q/ T }6 G3 T% A! n0 u. w
} catch (RbdException e) {$ k4 z2 f# s' ^) O
// TODO Auto-generated catch block
% K9 O8 g; K U1 J7 x' z% W$ X e.printStackTrace();) T& Y+ E2 P1 h9 I |* H$ M
}+ C* \: ~/ M9 Z& G$ v1 w e
return imageList;. K# C' D; C8 r6 e
}6 B' ?3 ? |/ d1 f( R' a
3 k# L& o! H1 ]
/**/ F" D% n0 J1 |8 ~% o( ?- Y
* 显示image的详细信息
0 A% l3 ?: g9 F( U4 s9 s * @param imageName
4 z% }$ R, }5 w; }7 e$ m$ T( X */
6 a' v$ | [2 T% |% \3 ~1 R public static void showDetailOfImage(String imageName){
, D, R' n6 _$ E: Z RbdImage image;
- i5 _3 c" I+ O9 `1 \ try {
& g% Y% v U; J; X image = rbd.open(imageName);) Z+ T% h) u ?/ ^
RbdImageInfo info = image.stat();
4 s! _9 G2 o' }0 i4 f2 P% K* s System.out.println("=================================================================");
7 o8 v8 u* @# n; O" k System.out.println("imageName: "+imageName);
5 m' V( s' n2 S2 u. {, W System.out.println("imageSize: "+info.size);2 J3 ^: L* y( p2 e2 E
System.out.println("order: "+info.order);
* I! e0 ]: K5 W( F rbd.close(image);
% L+ M, v9 f1 |3 @3 q% X6 W- t } catch (RbdException e) {9 {( R9 b- S" W4 k5 X& P
// TODO Auto-generated catch block# _$ `& l8 \! Y7 A: P8 \
e.printStackTrace();: ?7 { t/ V% Z% M" g) p
}) i9 C0 f' B- P3 m8 O4 G( X
7 }3 ~ w) [& D9 X9 e8 j2 g }
7 S/ q* N O$ b1 s! _# i, J$ C- U- W8 t8 D) ?
/**, e: G8 z+ A, U$ ^9 f
* 以格式1创建image
. p+ y- b9 c1 ^0 P* G * @param imageName 名称
8 e! F r$ u' m+ ?! C * @param imageSize 大小
3 G2 W" |9 l9 t* ~0 M$ N8 g */9 `0 T3 Z' X# p1 G# x0 Q
public static void createRbd_format1(String imageName, long imageSize){4 t1 R& i6 E% F4 A+ j/ s' H
try {
7 \2 I3 y2 M3 Z8 {& { rbd.create(imageName, imageSize);
1 ^& n5 u" c$ |. @( f+ {" E0 m; w RbdImage image = rbd.open(imageName);! \( r$ S1 f- p/ {
boolean oldFormat = image.isOldFormat();; b/ |* c7 ^8 _5 P* L3 {# ?
System.out.println("imageFormat:==========================="+oldFormat);
; p3 z9 k0 L( L) W" X
* G% |. k, ^ Z1 H5 H7 I rbd.close(image);
$ r: @+ \5 J) N/ @ } catch (RbdException e) {
2 \ q6 w( t7 i/ o7 g System.out.println(e.getMessage() + ": " + e.getReturnValue());- X0 O+ ^$ ^, g7 j
}
* B% F& W' ?& o2 G }7 w; G4 h) J- {) s
0 K9 y5 ?+ R; z. O, s+ V
/**
1 F$ A7 {( u0 ~( f" ?( z * 以格式2创建image,ceph 仅支持克隆 format 2 映像(即用 rbd create –format 2 创建的),而且内核 rbd 模块还不支持。
# q5 B7 c/ h" t5 w 所以现在你 只能用 QEMU/KVM 或 librbd直接访问克隆品2 @' |& a* j+ V# H; b" A/ I" F7 h
* @param imageName 名称5 k' O6 {6 q) O# p) Z9 x4 a
* @param imageSize 大小
! A% V; w2 l: K */
9 l9 g/ Y6 y; \5 p public static void createRbd_format2(String imageName, long imageSize){
7 J) u& x) P) a2 X' N- i" A try {
6 y/ P# }8 _) E8 r6 U. v! w int features = (1<<0);
+ y: ]8 \* k( g System.out.println("features=============="+features);
* X" {0 [- l4 r) }5 J$ z' l. F rbd.create(imageName, imageSize,features, 0);
4 p$ Z+ S" s2 u: y2 Q RbdImage image = rbd.open(imageName);
3 O [4 d D6 [0 v W6 \, s boolean oldFormat = image.isOldFormat();
+ t+ ]0 ]% R3 X. E0 w System.out.println("imageFormat:==========================="+oldFormat); " ]9 W6 g5 _7 B. t/ ~
rbd.close(image);1 Z( T7 j1 M, t' ~* @" T/ W0 C
image.flatten();
1 Q) O2 l' n9 }6 E$ ^; |' @ K } catch (RbdException e) {
3 Z% I% v: V5 `) q System.out.println(e.getMessage() + ": " + e.getReturnValue());
# T; D. ~6 Q5 V3 I, ? }
! A! \% k6 q7 R* E$ |3 s }
' f- y8 p4 b- W9 C; F& x* ^3 ?# C/ B2 c2 k1 B& N0 D. e7 t: v% l9 [9 H4 U
/*** s5 a/ W/ G0 L- G& G
* 方法创建一个image并对重设置大小为初始化大小的2倍
) K5 `; o3 F; j* ?& h! m * @param imageName' h I4 w9 S0 [2 j6 ?) O$ F8 \2 L
*/( x' e5 ?6 e' ?
public static void resizeImage(String imageName){$ r" H8 ^7 u- X
long initialSize = 10485760;+ x( j; o0 a/ A2 v. h- M$ v: D9 o
long newSize = initialSize * 2;
8 Q7 J( J* C/ z/ Q try {7 ~. A; ]" N; |
int features = (1<<0);
$ b+ \8 A3 O- \+ { System.out.println("features=============="+features);
8 g# ^. n: S$ ^4 J% R) s rbd.create(imageName, initialSize,features, 0);( e0 E' E+ B: n4 _
RbdImage image = rbd.open(imageName);! Q' F5 M0 G5 u/ y9 w; x# j
image.resize(newSize);
& E$ ~5 t5 U, N9 B rbd.close(image);
$ Q( b' s5 \, f0 k9 i& @ } catch (RbdException e) {% B1 w5 H0 [% d% Q! Y$ e1 Z( |; X
System.out.println(e.getMessage() + ": " + e.getReturnValue());
' ]. @" ~' I3 { }
6 E& B5 u$ C' P+ \2 J" c5 Q }: I1 Y% o& o& W6 O
. H! M! N, Y9 n8 b9 y0 J5 F: N; D /**
! Z9 }0 `- |9 F2 H1 B- i- p * 创建映像的快照
* @# w% O6 N& |: B4 s * @param imageName 映像名称
! i* X8 j1 {: o0 F5 s * @param snapName 快照名称6 |4 l+ D% |/ [) E; Z
*/
R! r k, P1 h public static void createSnap(String imageName,String snapName){3 z* T ^+ }( l8 C6 Y7 l; [
try {9 M( C: l* o* q9 w: l3 w; b
RbdImage image = rbd.open(imageName);
( P$ U1 j' m+ S9 W //创建快照
3 ^( T" k$ w& p) ~2 j( T$ [ image.snapCreate(snapName);
! N1 f: U4 j9 ?4 o* [1 V //保护快照可以防止快照被删除
4 q2 i+ f. k" L. O image.snapProtect(snapName);
3 J# I5 W( i- `3 }7 i //返回一个image的所有快照
# e+ ?1 c7 X9 J4 B/ ` List<RbdSnapInfo> snaps = image.snapList();
, @3 J1 q. z) q) _: w for(RbdSnapInfo rbds:snaps){% o- G% m' E! U: [
System.out.println("快照名称:"+rbds.name);
/ ~' E3 b" I- J: e1 a! e7 [0 {( _ System.out.println("快照大小:"+rbds.size);9 [$ q, x4 N+ L& S( \( s6 F2 y
}7 l' J% K( {4 f* A$ c3 A2 }2 f* b/ |
} catch (RbdException e) {
0 g) p0 O, _, }* I // TODO Auto-generated catch block
& s6 {* c0 H- ~% w: O& \9 e1 N+ T; R e.printStackTrace();6 u+ G- V( D( [7 G- U6 p
}
3 X' K- A/ H7 ^& @' q" P; W5 u- T" t }" a( Q# ^6 k7 s& W# x2 h3 M
0 p' A4 h4 F( p7 X& d& i, g# R0 m- Q
/**
. a# ~# @5 M5 z( T* B. M8 D * 通过快照克隆出新的image
0 v) D8 U2 G7 V, H& R * @param parentImageName 快照对应的image名称
& ]8 U0 S5 A5 H4 b: d5 M * @param snapName 快照的名称
1 q: Q6 m; J8 Z0 l4 r5 _ * @param newImageName 生成的新的image的名称; ^. }2 n! F& L% r, d X/ \
*/. z7 J; d6 L: R. @
public static void copySnapToNewImage(String parentImageName,String snapName,String newImageName){! j% V0 w( @9 k$ N/ ]* p9 w
int features = (1<<0);& l0 G( q8 I; s2 O4 \
try {
- g# O9 _6 v$ X1 h5 ^ rbd.clone(parentImageName, snapName, ioctx, newImageName, features, 0);1 e" i: m. i6 n8 D: G# I' o2 J
} catch (RbdException e) {3 D! d5 d4 J- p5 K" E
// TODO Auto-generated catch block7 d. [1 q8 A# W: J
e.printStackTrace();3 \, N8 f q1 D7 Y4 N( }# f8 U
}
- }: z6 @/ u+ f0 w8 Q) g }) l2 p: L0 ~* O. T. u! s( V
9 k! D8 R/ }% h
/**
% f+ Z! { A2 O. K/ h; {0 q2 r( L * 删除某个image的名叫 snapName的快照,需要注意的是要删除快照,必须保证快照没有copy的子image,否则会删除失败。; \# C; K) W3 \- v
* @param imageName9 i& u% u2 Z l
* @param snapName
8 y# i8 O% n) } */$ Q* Q1 L: ^6 |
public static void deleteSnap(String imageName,String snapName){
9 q3 C$ i, u8 d/ e( { v try {( ?* y) R. Q9 c! B" J
RbdImage image = rbd.open(imageName);
6 H9 R5 _. y5 k1 Z( x- _( K) n image.snapUnprotect(snapName);: |. D0 L+ n! i& t3 k/ b; v
image.snapRemove(snapName);2 b' p6 i5 }7 x9 {
} catch (RbdException e) {0 _- F7 f5 ~7 w8 P" o! m) S
// TODO Auto-generated catch block
) Z7 A$ z5 T6 K4 N$ T4 m, z e.printStackTrace();
1 R' h8 a' v [& b# Q6 K }
8 {. E) V/ u4 w }
! E6 F1 k( _( O H) X9 G6 Y, k4 S' M4 |' N0 n
/**
3 ^: }8 l( c" x2 F * 删除某一个image
( y$ i2 f* J2 m7 a& { * @param r' B1 i6 f6 r& X9 W i- n. |1 A2 P
* @param io
7 C+ v: k) e! ^. s$ ?/ }" y) _! P * @param imageName- O l( P* P" G' |
* @throws RadosException% ?) g- h' N8 O# u
* @throws RbdException- R/ Q9 _- W! {$ @
*/: S" k$ R/ L! Z& I$ E( {8 y" C9 r
public static void cleanupImage(Rados r, IoCTX io, String imageName) {
6 |- q) n/ @ p try {- z5 k- S: T' ~7 c) v
if (r != null) {
9 H8 K4 G2 V6 L$ ^. A: C# I7 K9 j if (io != null) {
# Y, p( q# ] i4 S Rbd rbd = new Rbd(ioctx);& [0 v ?8 @/ `- D$ N/ B
RbdImage image = rbd.open(imageName);
; V6 B7 [" Q: \ rbd.close(image);1 {6 g/ s! |/ O0 r" e
rbd.remove(imageName);
+ h7 n, F$ K0 D$ q( L% c/ V }% A4 p) _* A7 y7 I5 f/ z+ X9 ^
}
) @) [; q( {- F% W% C2 x8 r } catch (Exception e) {8 a, \! P% S+ O5 n) \2 U- `3 |- W
// TODO: handle exception
9 m- v K; E& ^$ X( ~7 P6 t9 } } 2 ?! j, V, M- M X- U5 L* y$ J, `
}% c( `0 S( m. E% Q: e/ z! P1 R
# C+ {9 l; Q8 N# q0 I& u( C: |9 u, z$ W+ _& T1 y6 r& o; [6 @9 H$ X
public static void main(String[] args){3 T; H' g- m" `
connectCeph();) r% L. o( C0 \- b4 u
//createRbd_format1("mysql-hzb-2",10737418240l);5 M/ ]' _) O* C+ i! @' L+ K D4 \
//createRbd_format2("imageformat2",10485760);( [' d# `8 u W: p; I
//cleanupImage(rados,ioctx,"mysql-hzb");
# n1 l7 p0 d: m7 j3 R! }3 v //resizeImage("mysql-hzb");7 n: [! {! T- @% g7 t$ R5 g
0 F$ N# r+ B9 ~# v' x // createSnap("imageformat3","imageformat3-snap");
' o# {- |( L) g/ Y5 p7 T( r //copySnapToNewImage("imageformat3","imageformat3-snap","imageformat3-copy");( n$ E6 v" B C1 q$ y$ b
//deleteSnap("imageformat3","imageformat3-snap");
% U' p3 L/ s0 k( b" A$ S9 d imageList();
- Z7 U: P( h# @ G5 M q }
8 P: v0 H4 E5 I4 z}* a3 X/ F# {5 Y% i# f; X- h7 \; L
$ A7 H5 f" X' V
) c& z- L- d$ c" K7 v7 Z8 _9 v/ ]3 i
( `/ r2 V/ N: L1 o4 w4 J8 N0 r2 D, M% N
; A* V0 u# n" E" q) B. M
3.3 IoCTX源代码
- e$ L5 I$ d X( s9 {5 k% H/*& m- ]$ c2 v0 H: @) \& s
* RADOS Java - Java bindings for librados9 a' @1 `' d6 [
*+ Z |4 b. Q j4 n
* Copyright (C) 2013 Wido den Hollander <wido@42on.com>4 Z) l5 T4 x8 j: s; q
* Copyright (C) 2014 1&1 - Behar Veliqi <behar.veliqi@1und1.de>
8 Z1 V8 B/ K; P4 y2 j9 y9 h *0 r& L# Z9 b' ^: ^$ [7 G1 C
* Licensed under the Apache License, Version 2.0 (the "License");
: E) i/ T' r% n4 F * you may not use this file except in compliance with
, X! K) R8 E9 I( M# T8 U * the License. You may obtain a copy of the License at& `3 l2 T1 X* h, [
*8 @+ B, ]; ?, @" K
* http://www.apache.org/licenses/LICENSE-2.0. ]. V* ^9 ?: l
*2 R& Y+ Q6 P& d2 v* \
* Unless required by applicable law or agreed to in writing,
1 F) V N I, @! u a * software distributed under the License is distributed on
7 P4 X* ?% ?! E * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,- K, p3 ~ |) J* p9 Z
* either express or implied. See the License for the specific
1 {% T i2 H& A+ V* L& |! { * language governing permissions and limitations under the License.
V2 w1 l5 `: _$ F */
2 w0 K4 z( n3 k2 h! f* p% l1 @$ E" M( H9 }. K/ l
package com.ceph.rados;; p, e5 x& \9 P; f# |; B* X
# O. L. b. b2 w" D( D
import static com.ceph.rados.Library.rados;
# ]. ]& d7 U: [$ {3 b, y' |
5 W! N& |# G. l9 G( k' Y1 vimport java.io.Closeable;
+ R$ x j! P9 T' d0 nimport java.io.IOException;4 N' Z2 w6 {: i& a
import java.util.ArrayList;
$ v8 l" q! L. O2 U0 h$ A6 ?import java.util.HashMap;6 s9 Q! S; ^6 L) z; Q! F4 J; A+ X
import java.util.List;7 M8 b2 X+ L& s6 g* f
import java.util.Map;3 l$ c) E6 c4 K( P( u
import java.util.concurrent.Callable;- `- f9 a4 l7 j+ M2 r( c' }
0 Z0 ?- O, k9 p- c
import com.ceph.rados.exceptions.RadosException;# G" A3 n3 B% J% X
import com.ceph.rados.jna.RadosObjectInfo;0 M9 Z. J$ j1 ?8 y- Z2 }
import com.ceph.rados.jna.RadosPoolInfo;
0 Q4 \% ~* P2 ^import com.sun.jna.Memory; A9 x% u8 Q$ [) ]3 e
import com.sun.jna.Native;" k" j1 K* Q! E1 }! k
import com.sun.jna.Pointer;" }5 V6 r* B/ ?6 R+ c
import com.sun.jna.ptr.IntByReference;
; }/ ]& } A! c0 }. j) t( iimport com.sun.jna.ptr.LongByReference;* o- v: g, g: O7 U& x
import com.sun.jna.ptr.PointerByReference;
# b# T4 f9 m- l+ c
$ l- v) ?- n* q$ E% A3 Cpublic class IoCTX extends RadosBase implements Closeable {& f6 U- l% I1 ], @0 z- X L
. }4 _+ D& l( w7 ]( A; X, t
private static final int EXT_ATTR_MAX_LEN = 4096;2 {9 T6 Q! S r) s6 p! ?) u1 V
9 T" c# v x: W1 L# C' d
private Pointer ioCtxPtr;; I3 O. U* ]) l A
6 g# g9 [+ K2 @1 [8 G
/**
+ s/ E: C9 }; | * Create a new IO Context object% f* Z i- p0 ?# I7 ~/ L
*
+ h/ _: O* W: V * This constructor should never be called, IO Context
, |* C4 y% L( l+ m% b7 W * objects are created by the RADOS class and returned
4 q1 K7 k+ q* Q- V8 @. |+ J * when creating a IO Context there& r+ ~4 i0 q+ |; x7 ~, @- j
*/
/ J7 M+ l) K5 H! t( Q/ | L public IoCTX(Pointer p) {
; i" G& C8 p* g' }! r: [! h this.ioCtxPtr = p;
: ^0 j J. k; ~1 E }
, _3 l; t0 K5 F0 @& \! H0 \# x W3 u+ m. _
/**
5 Y3 v2 l( D' W/ ~( h * Return the pointer to the IO Context' n; J4 H" Q5 s: f2 V( z8 V
*. ?& Q+ Y+ ]" F# ^- J# \7 f3 U/ C
* This method is used internally and by the RADOS class
, G* ~4 {% x9 B4 a8 @6 p1 T * to destroy a IO Context
3 h4 X5 Q: r2 |9 Z5 }9 d *: q+ n. I( P* ?) J; l$ y
* @return Pointer0 j1 f1 Q% X0 x D
*/# @ q6 q$ T. d6 R' v( A
public Pointer getPointer() {3 p$ g0 Q5 o* h; e6 a+ F
return this.ioCtxPtr.getPointer(0);3 w9 ~& @2 }- U( k2 }0 r2 Y, }
}% c" }* d& I; A6 \
3 }( s* V4 @, s! @ /**2 g/ g/ V1 Y) A6 d# _
* Set the namespace for objects within an IO context.; o1 p3 o. }% b: O
*
' m3 W( }' p5 n) L' {$ r2 i * The namespace specification further refines a pool into different domains. The mapping of objects to PGs is also based on this value.
3 u+ ~/ z* h4 ` j *
5 d) q- c/ `+ s" f: P * @param namespace The name to use as the namespace, or NULL use the default namespace.
8 ~! E ]/ H# d- Z" M */
5 r2 i+ w2 \7 F* t% ~8 x/ E public void setNamespace(String namespace) {
3 N. A. g) L: v- P5 C' H rados.rados_ioctx_set_namespace(getPointer(), namespace);; p; i# _5 O4 z, Y$ u
}
4 o) Q. ?' \# d% S; W8 ?
. C, h5 |8 D1 u/ D! g1 R /**
) w# c/ a& _' P8 }) }) }/ e * Get the pool ID of this context+ j: |# Z1 [. ?( P% c7 x
*! Q6 Q! p$ b; X! Z) }; o
* @return long4 e: t; o$ {$ Q0 Z
*/
. F) E3 z) v+ O& k public long getId() {
7 T i. }% _* v. p) C return rados.rados_ioctx_get_id(this.getPointer());
0 f) P& w+ T! E4 E# j) K }
' k5 d/ f! {' ?/ q8 x- i7 [8 K( _( N, l: \1 X1 \
/**
. o( j" O7 d3 z, T * Set the associated auid owner of the current pool
6 b: [! C$ Y9 S+ |9 ]/ E2 A *
0 V& G- Q- o+ X" Q9 v: ] * @param auid3 W* ?5 ~, c7 w4 d4 ?4 m
* The new auid
7 _7 I: L8 _/ }" a: y0 K * @throws RadosException
- L2 m+ j" q" g. r. u* E */: D x" k5 P9 t3 E
public void setAuid(final long auid) throws RadosException {7 D; E- q5 M% y
handleReturnCode(new Callable<Integer>() {
1 P7 o+ n) o% q' Y2 [2 F @Override* J; {3 n/ j+ `7 Y k3 ]2 k6 Y
public Integer call() throws Exception {
" q) M4 d% c. r" G return rados.rados_ioctx_pool_set_auid(getPointer(), auid);
7 u' t6 `$ `9 N$ A }
9 U# f+ Y2 T2 G0 Q }, "Failed to set the auid to %s", auid);9 ^* r$ g/ @8 }7 q) ^2 Q! I$ a. z& g
}" B7 ]7 L6 R% h2 a, o- I4 R
1 Z9 _$ L8 H# r0 q- h$ l /**/ z1 x; |5 A9 t9 D) T/ V) L
* Get the associated auid owner of the current pool# [. X8 Z" K' \+ w3 i/ d u2 y
*7 z0 r% k, H3 t7 u5 \3 [
* @return long# l9 n& E' P, l$ B
* @throws RadosException
7 m- S( g0 B* Q8 l3 P6 }1 F, f */0 I, t7 T' Q( l0 r, ]; Q& D
public long getAuid() throws RadosException {% X% Z' c6 `: X2 y! s
final LongByReference auid = new LongByReference();0 a! S, [6 y/ T. }" q! _* [7 V' ^: r
4 d; @% G* j: b! I; J handleReturnCode(new Callable<Integer>() {5 M! T% j+ S. \9 e P: A
@Override
- i6 [ }; K; @, j public Integer call() throws Exception {" C0 g8 f- Z( h; {. `2 Q2 t" K8 z* o
return rados.rados_ioctx_pool_get_auid(getPointer(), auid);
+ P9 `! i* t8 T' t }; ~- p; R5 N& t$ T9 ^, [
}, "Failed to get the auid");
+ V6 F# D$ x [+ f& ~) Q6 `. K1 M% t q; w
return auid.getValue();
. U4 C6 H% \" Q9 M6 \! z }( g, o. H: x9 o. j
2 c1 o) f, G, a+ } /**# S) P1 K0 R+ j! P; _5 e% L
* Get the pool name of the context
4 e) o8 V+ j" n( X, _ *8 I2 P3 }# U1 i
* @return String6 `8 f* s! S8 j. I4 {# `
* @throws RadosException/ m% {% N1 f6 @, u6 P- Q4 H
*/8 f$ y# e4 Q/ ~ k7 @
public String getPoolName() throws RadosException {- ~, L: ~! a% W
final byte[] buf = new byte[1024];* J' [6 y/ z- D) E; L
handleReturnCode(new Callable<Integer>() {" e+ l g" b# ?, h7 a
@Override
8 q' O9 S! m& f. m public Integer call() throws Exception {9 S p" W3 _. j7 t |! U" p& C
return rados.rados_ioctx_get_pool_name(getPointer(), buf, buf.length);& h. E3 s0 ~2 N5 o$ x! k
}' ~# v. p* F4 @! {, X3 E
}, "Failed to get the pool name");
1 Z& ?! @3 X, i' |% a! {+ z return Native.toString(buf);
7 {: _( X3 _4 M5 p/ `; ~) B }5 k: G8 V3 o* C' L) T
5 S7 a3 Y, A" Q7 Z$ h. m ^2 l /**4 ~' o8 F. w& f0 E( o" L% W
* Set the locator key
/ Z# s% g3 g) y5 G& p3 ~ Y5 h *
' M1 H9 M$ c# Z * @param key( T: ~) s/ b/ W- @- F
* The new locator key or NULL to remove a previous one
B4 t5 f: ~* O' ] */
% E: v: v5 O. N9 p' K6 A public void locatorSetKey(String key) {0 q: f4 Z, P( J4 X: q
rados.rados_ioctx_locator_set_key(this.getPointer(), key);! F6 F7 o- u% V* l7 \
}! s6 E% v+ l$ l
) u+ E8 F, n4 J% g0 R5 m6 N0 H /**
7 j Z3 W8 d3 H! E/ J * List all objects in a pool" G! S, [0 I7 b5 R+ O8 P% p: ]
*
. U4 {6 h+ B8 P( } * @return String[]% Z! z! j# l! q0 w$ Z: {
* @throws RadosException) g+ }9 y+ D7 ~
*/
2 T0 P9 ~6 b, @# c+ Z public String[] listObjects() throws RadosException {+ f0 R9 O0 E" ]! y% G
Pointer entry = new Memory(Pointer.SIZE);
2 a! {1 p" _$ {1 Z) R$ @ List<String> objects = new ArrayList<String>();
* V7 X: B. _, q2 T ^ M final Pointer list = new Memory(Pointer.SIZE);
# I! q6 I+ w5 z( J6 T" h; b' m
" O n4 Z8 Q: R' D& Y# L9 b/ y% t handleReturnCode(new Callable<Integer>() {
3 V4 F( `4 l- V+ g) e @Override
6 m, g. i, C7 Q$ f2 V public Integer call() throws Exception {) U* t* p+ w" x# Q
return rados.rados_nobjects_list_open(getPointer(), list);
8 f) S- J, \2 ]4 N4 j }
3 u+ x3 Z- B1 ^! m# b }, "Failed starting to list all objects");4 L' i1 L" Y! o! ~4 i! p8 ?6 I! _1 s
5 j/ [/ C) T" q1 ~: @+ q$ [# K
while (rados.rados_nobjects_list_next(list.getPointer(0), entry, null, null) == 0) {
- C: D. r' I$ r; y objects.add(entry.getPointer(0).getString(0));
$ {. ?# a7 E n7 j5 p% |5 p1 a# ] }
' w6 U% E ~1 H" }5 o2 e
6 J6 |, A1 |/ O. {; e& F7 m$ o: d rados.rados_nobjects_list_close(list.getPointer(0));" G0 {' |8 Q# v1 F
4 N& S/ X8 p8 k return objects.toArray(new String[objects.size()]);
- V6 M& s) f2 r: W }- r. B" r1 m% n6 k
9 ?2 P& f) N4 m) U! n5 G& z& r /**
1 J2 A( t7 l# r i * List all objects in a pool by piece. Useful if a lot of objects are in the pool and do not
3 r2 Q! c6 T4 f1 W- r * fit in memory through listObjects() method1 F, m5 E. [( y3 o9 h
* @param limit
. [! X1 d% }# m% z) l. A7 u * @return a ListCtx from which nextObjects()/nextObjects(skip) and getObjects() could be called
2 u$ X E j+ Z9 M) { * @throws RadosException
4 W8 s/ k8 t. g6 Q. s/ j */
; w0 \( k3 k2 B- U public ListCtx listObjectsPartial(int limit) throws RadosException {( R. i( }3 s0 {5 O
Pointer list = new Memory(Pointer.SIZE);
2 C$ p7 i+ Y( } S- f1 d2 |$ w5 s9 P$ R \+ Q+ X E
int r = rados.rados_nobjects_list_open(this.getPointer(), list);
1 ^% _% S0 v/ c+ j if (r < 0) {
8 s @' G: ~9 }# Y! i throw new RadosException("Failed listing all objects", r);" M( W& d& E& h, c# d
}/ g) J, _( E. G
return new ListCtx(limit, list);
5 x9 n5 _) u! f Q# x- A }
m8 \0 ]7 c- E' A5 Q9 }3 ^
k' x! t/ [# d/ H /**3 o6 x+ g% s1 D j! L
* Write to an object
/ N6 k& ^4 i9 d: p$ t. A* O6 U *
3 Q* w, v8 m6 z( M * @param oid
, z) e5 w _% o. ]- w1 D * The object to write to7 _! U/ q6 _$ Q8 I
* @param buf
1 `' R6 q1 O- [3 i7 t* m' q * The content to write' h' w& W! t: y
* @param offset
$ s# i& ]7 T7 e% v$ e9 ^2 m" N8 K0 ^ * The offset when writing
6 I% R: K9 I6 P6 v' x * @throws RadosException
% k0 E1 U2 w L* j */
; R7 B% t" z# J1 q C( m4 o$ r public void write(final String oid, final byte[] buf, final long offset) throws RadosException, IllegalArgumentException {1 W! y- z' H7 ^( |" L2 p
if (offset < 0) {$ T2 J& O2 c$ ]! N
throw new IllegalArgumentException("Offset shouldn't be a negative value");
$ h' G4 O" s! ?' j* I- w0 A1 h }/ Q: B$ I6 a0 v, f/ F( ^5 ]" I
handleReturnCode(new Callable<Integer>() {9 b G2 h- c2 s& {2 m! G: b! I
@Override( w* }' D2 f# t% m, o: ]$ L
public Integer call() throws Exception {
+ ]' i) X4 ~* d+ g4 t return rados.rados_write(getPointer(), oid, buf, buf.length, offset);! H, P% x* [. a+ \# T" n7 p. ]8 G$ ~
}
9 I) n, w: f) N5 K. ?7 G }, "Failed writing %s bytes with offset %s to %s", buf.length, offset, oid);
4 d; L# j4 I3 f }( w$ } [* g" s
3 z3 B( t- C" z4 X /**5 L6 j. o6 B: r/ y
* Write to an object without an offset
6 X* d. c7 K; H4 f/ R *6 u9 t! E: s; v2 h5 S+ q
* @param oid
& M: M$ T9 H3 c$ [" X * The object to write to
6 o1 m" @! H8 x. o- N * @param buf: H# O. K4 Y3 [; x1 A
* The content to write W' c2 K, v1 j, h
* @throws RadosException' ?' n4 w8 m7 P# @1 E
*/4 R: S4 s- j$ |) W
public void write(String oid, byte[] buf) throws RadosException {
" `3 I4 z7 H$ I" R# ~5 S8 x: u this.writeFull(oid, buf, buf.length);
" p+ m- d0 a( ^& x: O* w# w7 ^ }
$ D D4 V( G! m) C [3 F+ [6 W8 @+ M& G, Q. N) O
/**
9 B% r$ A7 B% G+ w * Write an entire object
! H0 v9 H6 H; R1 m * The object is filled with the provided data. If the object exists, it is atomically truncated and then written.; r% b/ ?3 u+ G7 `6 ]! [0 K
*& Q. w: y: ~7 ~, \' \
* @param oid
6 K$ m" f) R C N- _' o * The object to write to; d! u: z7 }( v# }" ]9 i* D
* @param buf
* ^& l O4 Z4 x* e5 j* H * The content to write; d) M: S: ~% v4 J+ N
* @param len: t6 [( D* y2 e T* A- ^3 f* c" w
* The length of the data to write
; `( l: N/ A* ] * @throws RadosException
4 H% @: e' c! m0 i2 } S3 E1 n */! d" W$ f7 \5 O6 a' H. P- ~8 A7 ^
public void writeFull(final String oid, final byte[] buf, final int len) throws RadosException {
& m, F* n1 h4 [% O! u& e9 D8 } handleReturnCode(new Callable<Integer>() {$ Q( e5 {" ]4 e
@Override" l: y4 Q. @2 h& k1 v; v
public Integer call() throws Exception {
- y0 y, R- p5 c: S7 A6 k return rados.rados_write_full(getPointer(), oid, buf, len);
. t% f4 \ r! t- a }
% \8 W* \$ o; @3 h$ L3 ` }, "Failed to write %s bytes to %s", len, oid);
+ e& z3 P) _% C1 g7 p* L }' G0 d3 ?( v4 p: v5 f
* K' n) h4 o; C) U
/**6 ~: ~0 D0 D# Z D
* Write to an object without an offset
/ ~# b* K9 H# t! f *
- z6 }) s) R0 [5 C! h% Y * @param oid. E* ^4 z i1 D2 Q* F! s; e% `! K
* The object to write to
2 X# H% A4 P+ A0 ? * @param buf2 I- q$ _ A" P' I) E* P
* The content to write+ z0 v6 z' ~9 ~* J
* @param offset
3 N2 W* Q6 S9 H+ k" q" _8 ]( ^ * The offset when writing1 |' u$ j4 [1 V# p+ |% g+ p
* @throws RadosException
" K' n( E; B$ a w! r ?8 X */" \- Q ]8 a6 d% z8 i
public void write(String oid, String buf, long offset) throws RadosException {
7 v& |. T/ s! h( c: \/ p5 o. Z this.write(oid, buf.getBytes(), offset);
* o2 T" p2 @# u; d+ L }+ q: ?3 u1 a+ ?0 O4 i
s5 ?( e3 ]' e3 E( i- [& E4 m
/**
4 t' |9 K4 T# S4 h% q * Write to an object without an offset
% \ N- P' }! {* v2 u8 x v *3 {6 N5 A5 v1 c Y
* @param oid7 l- x& D# T$ ~/ |+ e6 U! l' h& l
* The object to write to
! x5 e7 J! [/ }/ S/ _2 d * @param buf
9 N- S) q) c( F0 l * The content to write
( p; `0 ^- k# a) T) x * @throws RadosException/ Y/ f; K8 D5 O1 J& y
*/
( a p/ E6 k+ f public void write(String oid, String buf) throws RadosException {
" W8 q) u5 F9 C Y! a4 a+ R* m this.write(oid, buf.getBytes());
1 q8 ?! G! d `9 \' C }1 {1 Q! t: ~# V8 E4 O
) P/ S3 d- E! s/ O9 v" L8 {
/**% s' \0 h" D/ D& T
* Asynchronously write to an object8 ]- H. [( C8 [: j" `
*
7 o3 n" P6 g* q- S0 b * @param oid
9 E# o9 Q$ i6 q+ Q * The object to write to
3 |" r& @. R# A5 H * @param completion0 Q! a) l7 M i, r
* The completion instructions
- K" @- k, x; o( P1 |6 l * @param buf
7 V5 P$ B8 T* _7 A9 G; m9 b0 n * The content to write
& z" ?/ b3 U3 @6 x$ {) J# M" d; V * @param offset
$ Y- J6 X/ k7 u+ y * The offset when writing9 A' m& K' l9 i ?
* @throws RadosException1 w; H0 Q( l% G) o' r4 n: K
*/
; n; y* X4 x* W% f% `6 k8 t- i; M+ T public void aioWrite(final String oid, final Completion completion, final byte[] buf, final long offset) throws RadosException, IllegalArgumentException {
, v/ d R" w0 Z1 a if (offset < 0) {
3 k+ x$ j2 R/ E* W3 E) [ throw new IllegalArgumentException("Offset shouldn't be a negative value");
0 U6 k* p% W% A# ?6 `% B$ E }
* C# o8 F" T0 c* h Z: N handleReturnCode(new Callable<Integer>() {; m' E0 e" c! `9 S+ L# _
@Override
$ U1 f& t) U' M- P8 W W* v public Integer call() throws Exception {
! r2 G+ l T3 r, y; _ return rados.rados_aio_write(getPointer(), oid, completion.getPointer(), buf, buf.length, offset);2 f% F5 K7 U" j7 e) j6 a+ T( E& Q
}2 E$ {4 j5 U& T! h/ R
}, "Failed AIO writing %s bytes with offset %s to %s", buf.length, offset, oid);' d" R6 v- r! m; X% x
}" o) x+ c% f# y
, M- y6 W$ h: L3 f /**
4 r4 U- ~% @' m * Asynchronously write to an object without an offset3 r1 X9 x1 K( _' b8 v; n/ l
*8 l7 g Z% J) l
* @param oid8 M( @% w! o* F3 ?- n3 c0 R) M
* The object to write to5 p( {0 ` }- G$ b1 J
* @param completion T8 D! h! |- ~/ B/ Y' x
* The completion instructions
) R' x! j5 s0 X# @: N6 z- J * @param buf
/ I1 P! x! x: y' `6 o! o7 P * The content to write) `# e) H4 N) s
* @throws RadosException! K! v5 G0 P7 C: ^
*/. }& z5 r% a( ^" u& x
public void aioWrite(String oid, final Completion completion, byte[] buf) throws RadosException {; B; w( s$ s4 n C) c/ E7 b2 h
this.aioWriteFull(oid, completion, buf, buf.length);% B$ ?% r$ v8 a
}
4 ?. E, ?2 e$ Z+ x* I$ Q' C0 D$ i% h2 p% J" U7 \, ?) i8 X: ^6 x) H, f
/**8 R7 v J J+ @ u+ `
* Asynchronously write an entire object
4 N' S4 Z1 d: H0 S6 }% ] * The object is filled with the provided data. If the object exists, it is atomically truncated and then written.
( I, d1 H1 ?7 C' Q, b *
( h# S2 e( a2 X, H/ Q * @param oid9 V0 x( h1 m; A* T% R
* The object to write to
$ w6 [8 I, z7 v# m, E5 ? * @param completion
9 u7 s, H G% Y& l2 n * The completion instructions8 X+ v/ R- g e0 u1 R. @. t+ W
* @param buf) Z- y7 C+ i e( t6 ? \7 a
* The content to write
( M, A9 y/ Y8 X' b. F9 L * @param len7 D4 a: u( S8 s9 j/ V
* The length of the data to write" @) Q$ g( k. e! T q s5 j
* @throws RadosException! u) l+ ~+ j4 E* b) f
*/
I% _. \9 n2 i2 y9 A- @' C public void aioWriteFull(final String oid, final Completion completion, final byte[] buf, final int len) throws RadosException {1 ~! q3 p% {8 J1 z1 \
handleReturnCode(new Callable<Integer>() {# D$ g/ S7 O3 j$ Q" Z; N, M: U, |
@Override
7 K# K. q7 q* z public Integer call() throws Exception {% v7 m2 O6 V9 l; |: ?7 [' h
return rados.rados_aio_write_full(getPointer(), oid, completion.getPointer(), buf, len);
3 ?1 H6 ]2 d4 u& K# B0 | }' f9 u1 x9 v* Y8 C
}, "Failed to AIO write %s bytes to %s", len, oid);
6 _6 i7 a( T# U, K5 S i' t2 } }& Q( D, ?% @8 d8 J! l! T
' d# T" T( ]" ^7 p/ x1 D /**2 _: ?2 p9 t$ B3 t
* Asynchronously write to an object without an offset
( Y& A4 p4 o4 A2 x7 H" d$ J *& ~6 c; v! P# `
* @param oid
4 a- e7 U( [# i _$ @; F * The object to write to
D" X' p4 n1 E * @param completion* |9 f9 [+ A3 k% R4 K+ z
* The completion instructions
! A7 u( r! S' R$ _# X) o * @param buf
; W7 c3 z5 y# Z i/ }0 I * The content to write
: E% `# S7 `! s6 e2 [0 G * @param offset1 D5 F: ^# b8 y* {
* The offset when writing w5 ]/ T9 ~4 y _9 f7 y! ?! `+ B# X) \7 b
* @throws RadosException0 K$ S h& n" r L
*/# f( l6 s1 j4 z# F
public void aioWrite(String oid, final Completion completion, String buf, long offset) throws RadosException {# X, v' G% y2 ~$ _
this.aioWrite(oid, completion, buf.getBytes(), offset);
! G4 Q, Z" `+ Z$ A } b5 }8 }$ `- C- C9 D* F
8 C5 K/ A: i/ T# ]. \
/** W+ X$ |- Y1 P; c
* Asynchronously write to an object without an offset! p$ f7 y+ P0 x% l6 j
*% i, ]9 }3 @( |2 I' t. z6 [
* @param oid8 j S# x; Q" q0 m1 d, t! R! O% E
* The object to write to
" G8 r7 [$ _" G( f& @; ^ * @param completion/ @+ b) c/ R9 v- u! u. `( Z2 }5 S
* The completion instructions; Y, Q. G4 z9 N( `
* @param buf4 I: B# {' h, Q e
* The content to write
- O* V3 }# C3 W8 r. v * @throws RadosException7 j5 W$ L, U5 k, L: k3 E% O3 a
*/) ^& l3 ?* H2 Y. {( I0 c1 W4 y
public void aioWrite(String oid, final Completion completion, String buf) throws RadosException {) V) k1 J( ^0 b( f' |! @' w
this.aioWrite(oid, completion, buf.getBytes());+ M+ ~( i7 `9 E8 b' T/ P9 {
}
# L, o3 E( `8 a
$ ]+ W* M# m n% K8 i% I /**& F8 v g) y f7 O
* Block until all pending writes in an io context are safe.
~0 t$ |# ?# U1 E. z g *7 [1 s' I' c3 q- U6 E) C# Y
* This is not equivalent to calling rados_aio_wait_for_safe() on all write completions, since this waits for the associated callbacks to complete as well.
' e: @# l1 Z3 k: U; m$ } * @throws RadosException5 |8 d9 Q6 a8 O3 `; L& W
*/5 {! J2 o2 T* o. o' n0 u
public void aioFlush() throws RadosException {
5 {% L3 V# I. ]) @# x8 q handleReturnCode(new Callable<Integer>() {8 V+ o; M& C% B" `
@Override2 z2 r/ ~* {' y, P+ Y4 i) {- }
public Integer call() throws Exception {/ C; d, A( m. c5 J. Z9 S9 ~
return rados.rados_aio_flush(getPointer());9 B1 K; _9 k- r, B
}
$ y9 R u5 h( J. \. W }, "Failed to AIO flush");: d9 r, R0 E+ W3 W- L) \2 J8 q
}
( y9 _) e. Z2 \" G' q
' k6 n5 }6 E0 q9 b" H9 q2 C /**
1 r; e( r: C6 b+ d9 t# y d8 k * Remove an object( j; }+ ?3 F# H0 |* x, ^
*
+ L1 v) \+ v+ e; V8 P/ a3 s6 ` * @param oid
0 x1 s' y) H. ]: z * The object to remove; |% p4 ]+ l5 Y+ r4 f
* @throws RadosException$ ^- z* ^9 {& L& ^) U6 m U
*/1 I1 l7 L: Y+ V( v6 |; W2 ? ]
public void remove(final String oid) throws RadosException {
9 [7 T" A% g' u4 r3 c& T. P handleReturnCode(new Callable<Integer>() {
' J- |, T; S7 w+ D& W6 i0 ~ @Override
' u c6 @5 t8 C9 Q. X# i" { public Integer call() throws Exception {) `& N# |6 |, Q/ w' n
return rados.rados_remove(getPointer(), oid);
, W) k5 R0 G/ `3 i2 P" ] }
" F5 j/ A" {3 [5 p& i! Q1 M }, "Failed removing object %s", oid);
& Z6 t( G6 o. @$ e! a }( [9 ?3 {! P3 ^+ W! X
/ p; v1 C, C* N /**+ q$ j3 u( k- T F4 X
* Read data from an object
! O5 T' o5 J- @! l7 G) z1 y+ |, g *
* g4 ]% c3 K+ W * @param oid
8 |, R/ U* B# \& `* ^ * The object's name5 c% P( D: t) N% |* Q, V V) t7 y
* @param length& W2 m( b% U/ T( t9 F& a
* Amount of bytes to read
* \, u$ N! `6 [! S9 p * @param offset
* j6 x5 u0 a. v+ o& a. I * The offset where to start reading0 G8 @& E4 b; }
* @param buf3 Y. R# x9 z" {" y; e
* The buffer to store the result) Q3 h6 V; R4 U0 o
* @return Number of bytes read or negative on error
3 n, }" j+ H: _ * @throws RadosException
( S$ h1 M% h. m w' c% q) F */
2 M% u! ^6 u' ?) u public int read(final String oid, final int length, final long offset, final byte[] buf)
+ G% ]. L; l" F throws RadosException {
& _1 u; I2 a/ x2 p if (length < 0) {% l! a2 d- e$ }* W3 \( d
throw new IllegalArgumentException("Length shouldn't be a negative value");7 N, q6 p- @+ h8 {. ~7 E) v, i
}
; y2 [8 f) z) ]: K: X# n6 j if (offset < 0) {7 w2 ~/ ]+ `4 d' Z
throw new IllegalArgumentException("Offset shouldn't be a negative value");7 @. T, M7 s; K0 B- a( W3 r
}3 Y# I5 G) p* A/ n! [5 ~
3 e$ C- J2 T% J0 [7 v return handleReturnCode(new Callable<Integer>() {
3 N, `) O; I! T6 a% u( F# n" t% W4 r" S @Override
6 y4 @+ f1 y* u# A# H# Z) T public Integer call() throws Exception {; r+ Z2 D& j2 G" _0 N. k- u& N
return rados.rados_read(getPointer(), oid, buf, length, offset);: _# {$ O% ?/ L; g* x6 ?( j
}
+ b$ l5 Q9 z3 `$ y# w }, "Failed to read object %s using offset %s and length %s", oid, offset, length);
. K Q! Q) o% }2 C6 y8 f+ @' u' N+ ]1 F }4 S p, P' S0 z" O% R7 j
7 R1 K/ [; [6 b7 _! U) E" i
/**+ e3 U; \% P0 P# a, u
* Resize an object& B: A( W. J A7 r. Q9 @4 V
*; S! i v0 x6 g# p/ S, P3 d3 o
* @param oid6 X* Y- Z4 p8 h4 X/ P J+ |
* The object to resize
$ v( t3 y% ]! e3 [. s4 W * @param size6 E# P7 F2 u7 y% u( v9 X
* The new length of the object. If this enlarges the object,
5 H k J5 `1 { * the new area is logically filled with3 X8 o J+ }7 D+ J5 \
* zeroes. If this shrinks the object, the excess data is removed.8 `! Y# Q [ X0 e) w( h
* @throws RadosException5 P1 i" f+ P3 |* D, A% E
*/
' \: V7 x* k& E: ?; `( G0 k public void truncate(final String oid, final long size) throws RadosException {0 F& i& _$ G: y( ?
if (size < 0) {# g7 D" s+ E. e/ m& O
throw new IllegalArgumentException("Size shouldn't be a negative value");
8 }# ~( ^/ ^9 z; G+ w3 u" P }
0 v+ T% G5 b+ I/ R# O& y- e1 v handleReturnCode(new Callable<Integer>() {
2 ~8 m, }9 }5 w% _ @Override% e& U) _/ I& S! u" E8 W R2 N% M
public Integer call() throws Exception {% \7 U: B5 x+ m) d6 }2 ], O
return rados.rados_trunc(getPointer(), oid, size);
5 j0 A5 {* J$ c0 E2 q }
2 P7 F5 Z% w' u5 t: a( X e- P9 C }, "Failed resizing objects %s to %s bytes", oid, size);
. ^$ |4 I( z7 ]$ V3 Y% a( v }9 R4 k& h$ S6 u6 I2 G2 [, T- N
% W4 K; p5 _5 e1 Y2 F" O" P h /**& q1 L6 x4 K. a
* Append data to an object
( B+ z; F* W e! K2 ^, J; X *) D( `0 V& R: Y+ Y4 D) Z5 l: L
* @param oid% s1 i# r1 A* X) i" J" a* `
* The name to append to
# ?0 D! ]. M; q( s2 c * @param buf
7 Y( A" Z, D W- Z" e * The data to append8 X: `$ P! Z8 I/ Y% p0 A p/ g' n
* @throws RadosException
. Y4 ^$ ^4 R2 O2 W8 F% `( L */
" q% d3 i: y1 S' X% q public void append(String oid, byte[] buf) throws RadosException {
) U- D5 f% B: O- t3 x1 S+ f v% P this.append(oid, buf, buf.length);( p9 p, D# w' i. f; @7 U( l
}: C: T2 A8 [& V) N: w
/ x3 H# s. h. U! S/ d /**
# B6 s( i: Z% J/ W Z% } *" r. l! S( P8 i# F3 k% }( X
* @param oid
1 g0 B1 ]% m& U2 i6 m * The name to append to
, Z5 B, @5 {$ }# _' b/ _6 g7 \ * @param buf3 C5 n0 S/ }, `3 r
* The data to append
) X9 {4 ]$ H; l * @param len
r$ X2 w+ P( y+ q- z( j * The number of bytes to write from buf0 V; X# l3 x% o( D
* @throws RadosException0 [! ~9 f8 i. v, b
*/9 i$ E( r V9 L9 z/ P E
public void append(final String oid, final byte[] buf, final int len) throws RadosException {0 R; F/ D d0 s2 }9 e
handleReturnCode(new Callable<Integer>() {- B0 w( E$ {. V$ r2 n0 \1 `: a
@Override3 S! K+ i. C6 |$ N
public Integer call() throws Exception {1 j7 ~4 z8 B$ t0 D. K
return rados.rados_append(getPointer(), oid, buf, len);
7 ~; f4 e. T. J4 p. d5 s }/ b& ~$ n6 p. u8 J( T( y
}, "Failed appending %s bytes to object %s", len, oid);6 {+ r- X! Q% S; S' k# C
}7 n$ ^3 g( [6 L
* d0 D) g3 c. f, W6 m `% J- ?! e' ?
/**2 O' i/ O- R# e( b/ ~! \/ J, F
* Append data to an object
! p3 _" a3 {2 e( ]" \% K *. _- o( L: K3 m/ ?8 I
* @param oid# b9 L: j) R! V% N( A# o
* The name to append to7 c. c( n, `5 U, \
* @param buf
5 E& I' T5 e9 `$ c7 t) z" ~; i * The data to append
( C, k/ W2 n! n * @throws RadosException) q, O, |; e% S- M
*/6 O! Z( j' }1 B
public void append(String oid, String buf) throws RadosException {" t3 K j" x! Y
this.append(oid, buf.getBytes());
3 ~% L4 q" }! q, F! d+ Q# b }
5 N1 ]& t5 b( h# s2 A" ]- |* u% \: v. }8 e* p- H/ ]( d* v/ C
/**2 t( G$ o2 d H1 D4 y- u8 A8 \
* Efficiently copy a portion of one object to another
' d# {4 |) ^/ [) k; W2 i. u *) e: z0 a! w0 x ~7 g3 R% O
* If the underlying filesystem on the OSD supports it, this will be a
5 g! i+ ~, J" b0 M( Y * copy-on-write clone. I8 x3 M% f. m' v/ z" z7 v
*
3 g, K) \/ ` u" ?% l$ T * The src and dest objects must be in the same pg. To ensure this,8 u4 u) M7 }1 I0 G2 H8 I1 u
* the io context should have a locator key set (see IoCTX.locatorSetKey()).
+ @3 G8 E; H5 c/ A ** ~" @5 E0 b$ y+ h- W C
* @param dst
" G8 ?1 m$ H9 Y% i( F. g7 w. N * The destination object% j. i: u. j3 @4 g K+ s
* @param dst_off
$ F3 `' ]: o0 p3 [ * The offset at the destination object
8 ?; u6 f$ z" i4 P+ F9 l! A- r * @param src! h7 i4 j& D# Q: C6 {- C
* The source object
# f+ J8 q H7 @$ W+ c' z, _ * @param src_off3 m3 I8 I" O% S: M) D4 U
* The offset at the source object
- r% B/ e. A+ w8 T * @param len$ u( p8 M7 c3 ]: b
* The amount of bytes to copy
: R. F. e/ s' Y. b9 Z3 L * @throws RadosException8 R# C6 K& D6 h! }
*/# }) w. _# A3 E) h+ B2 Z* r
public void clone(final String dst, final long dst_off, final String src, final long src_off, final long len) throws RadosException {
$ f) l2 F0 p% n4 C6 l handleReturnCode(new Callable<Integer>() { X( G* |; S$ i: Z
@Override
' y- W f* a! U public Integer call() throws Exception {( o& _3 W8 G' u6 E& g' B7 j" \ D
return rados.rados_clone_range(getPointer(), dst, dst_off, src, src_off, len);1 L2 ]3 i% D* H9 f0 M0 X2 P
}
" ~, S3 r; G* \: H- U }, "Failed to copy %s bytes from %s to %s", len, src, dst);$ p" d& l/ `8 W& b
}. L; i# q9 B$ [$ z
5 A' a* V8 T5 j1 ?# D ?6 x1 J7 l /**$ o& v% i- ~ N1 t- J
* Stat an object
( a6 n% y; N! L# \2 _- b; ^ *( O; ~8 h- ?- l/ b, W" K7 \
* @param oid3 F! R% w% m( W0 L9 K
* The name of the object
( J1 }/ V, b6 u3 w# H& n& A * @return RadosObjectInfo _& t# i O" m ?* y8 \0 e* R
* The size and mtime of the object
; X; I- h$ p& M/ E% c" V * @throws RadosException
8 X4 \& L) l+ x6 R4 y; V */
( T. I/ ]2 |/ f$ \, k% n3 | public RadosObjectInfo stat(final String oid) throws RadosException {
- O+ W" T, f5 b+ G4 G: { final LongByReference size = new LongByReference();
. e: g- \( d# i: a5 L! {* }$ M( U final LongByReference mtime = new LongByReference();0 h/ b, }9 Z+ x6 c3 O9 Q
handleReturnCode(new Callable<Integer>() {0 q0 }' w6 V S5 g: E
@Override7 k# z: W( U$ Z2 n
public Integer call() throws Exception {
6 L7 J4 c7 U: }, \% U return rados.rados_stat(getPointer(), oid, size, mtime);
& Z0 A! b+ a* r Q }& }3 {* g2 z' }* r4 N' w
}, "Failed performing a stat on object %s", oid); i; X: Z/ P. k: O" s9 P$ @
return new RadosObjectInfo(oid, size.getValue(), mtime.getValue());
$ o, Q! S( ^- L }
# B5 t/ C* p, c/ p3 |$ s# D, G/ \ T
/**4 A$ A/ d8 {, R x; D' ~" \
* Stat the currently open pool- f& L9 E' t" h/ J
*% G8 r7 t: b. n/ ]' N9 z; j2 v
* @return RadosPoolInfo$ w, X, n! p6 X/ g; c# q
* @throws RadosException
7 J+ P' Y- L/ v% B */
. ?, ^. A g) I4 [7 g; t, l$ w public RadosPoolInfo poolStat() throws RadosException {+ \8 w6 \$ s$ e; V; o( Q
final RadosPoolInfo result = new RadosPoolInfo();3 W- |, |' w+ W: P* |1 ~1 w
handleReturnCode(new Callable<Integer>() {! S1 v U- C# O: S0 q0 ~/ U* k
@Override
, a S. C+ d3 X9 N4 g public Integer call() throws Exception {
6 j1 X2 v% Y) [ return rados.rados_ioctx_pool_stat(getPointer(), result);
( C" e0 \7 q$ j9 G, N }
" V" ^1 N+ B: G8 G# ^& t; F, d }, "Failed retrieving the pool stats");, e2 c9 d6 X0 m6 |
return result;7 z" j( R, v* |4 i
}
+ D, X& [0 ]8 p" f& Y* ]
% [8 D6 a) d0 |+ _# ^ /**6 N& e0 J* k$ h2 F) y7 D9 q) K% i- D: I
* Create a snapshot
* O; R7 I0 m4 k2 c *& c: ~8 o' n6 a! B) c
* @param snapname
X5 q# j1 v7 ` * The name of the snapshot! r, E& @( [$ O$ Q5 u2 N
* @throws RadosException4 a+ E: n8 H% a3 ~1 h+ L* S
*/) N2 j4 b( H6 {7 h5 l, }' K+ g
public void snapCreate(final String snapname) throws RadosException {
) a* j6 e& I/ j. ^1 Y$ Z0 Y handleReturnCode(new Callable<Integer>() {
j, ?+ B/ W- d9 U @Override
7 l# U0 n% M: U4 [0 r( Q public Integer call() throws Exception {" _9 F& z- M2 e$ w) h1 i
return rados.rados_ioctx_snap_create(getPointer(), snapname);9 ~2 J0 A& |2 N4 C S
}/ q4 l2 q" _- O# y' w. M: \5 i
}, "Failed to create snapshot %s", snapname);
" F% h, i# y% c7 d3 W, R ~ r }
! w f+ o* e: {2 J' H p; m+ o' A0 ^6 u
/**
6 r* k2 h$ R v" A1 h' f8 a0 d * Remove a snapshot6 u, J7 e9 Q! t, V3 a% N1 O4 p9 s
*; Y; a, d5 L O: ?3 D
* @param snapname
3 n8 f( U9 i6 q, v1 H5 ~ * The name of the snapshot) f2 X r9 p. Y; q' d9 t2 b7 }
* @throws RadosException% E" E0 R1 V3 b5 s
*/6 R- p1 P- k' {* Z/ |- v, Y
public void snapRemove(final String snapname) throws RadosException {
8 H- N2 }' ~6 b9 q handleReturnCode(new Callable<Integer>() {
! d# ]9 C' ?8 f! A) P. R4 h. o( L3 | @Override
7 A4 \" j" Z( G9 w* E public Integer call() throws Exception {: F- G9 Y7 Z$ J: J8 `
return rados.rados_ioctx_snap_remove(getPointer(), snapname);0 I$ z9 a) @" ]: T4 x5 Z# t8 M
}% a4 {- n6 O5 z; Z5 t. Q
}, "Failed to remove snapshot %s", snapname);" M) Z' f* I. X! s
}
* _* k# }& \+ K7 L4 F% M# P7 v& l6 S6 j9 Y$ T
/**0 u& @/ I' \9 a `$ a. q) w
* Get the ID of a snapshot
) H5 u- J: `! }1 W *
, {" P8 {4 y. V3 [ W5 v; J * @param snapname
& w$ Y: e$ ~" {& h9 D * The name of the snapshot
4 l' A+ o0 D) W * @return long
6 H, U3 _$ L, K6 P# @% k * @throws RadosException
# r& D$ `- p Y9 n o( b4 K */
/ Y+ M' {+ R" g public long snapLookup(final String snapname) throws RadosException {1 }- \4 E" W. a& Q* X$ Q3 j) b" [
final LongByReference id = new LongByReference();
+ G9 R: i2 y- i9 t( i handleReturnCode(new Callable<Integer>() {5 ]3 Y2 V) Q0 T; m$ A/ O
@Override
3 X: E% V0 z0 e1 r' q" E! D/ j6 c public Integer call() throws Exception {' }/ J8 f# A1 i
return rados.rados_ioctx_snap_lookup(getPointer(), snapname, id);( n8 Y4 e/ L! J
}
5 x' H' i+ M. A. ?+ ` }, "Failed to lookup the ID of snapshot %s", snapname);6 z; c6 G" z6 u) i) P+ F( _) q! F4 v
return id.getValue(); f$ d$ @" _- E7 W+ Z2 V
}5 o+ [- f- `7 b% m% ?: A1 ]1 _
\2 P) P- S' B0 A% O7 M /*** F9 m0 ?6 B: ]& G
* Get the name of a snapshot by it's ID2 @/ B' Z/ q7 E. V, h o* S
*
1 w7 o6 t2 B; j9 p1 Y+ S" Z * @param id
, ?$ D ~; ?. p+ C! c3 { * The ID of the snapshot7 O* k0 p9 W8 `( h
* @return String5 u; |9 T* J: @5 V2 B) H
* @throws RadosException s }( v% T8 O/ z3 G% } j# o0 u
*/
8 U$ y% |: r. ~/ z' j" t public String snapGetName(final long id) throws RadosException {/ r8 E( F4 m4 g6 N
final byte[] buf = new byte[512];$ n# O, E1 \$ V6 ^/ O D
handleReturnCode(new Callable<Integer>() {1 c; h" S) a2 y
@Override
' G0 N' N! Z Y) H0 ?, w- o public Integer call() throws Exception {( x" h. h- H! F/ a8 U1 t8 I) W
return rados.rados_ioctx_snap_get_name(getPointer(), id, buf, buf.length);% T7 g: E6 w0 P0 ~9 {. m
}
8 ^4 O6 O! Y( j2 c }, "Failed to lookup the name of snapshot %s", id);
" a/ ^' x6 O& s8 @8 Q' H return new String(buf).trim();0 w! k% p' m# x
}
4 }0 f/ T4 g1 R* p, r" P; J+ B; {/ e" s" Q
/**4 d; J! T2 e: X! r9 t5 V
* Get the timestamp of a snapshot: S6 A% d/ ?; i- S
*
( B' k+ B" }$ t, U- Z2 K/ G * @param id' b& h# m3 T+ L( E5 k
* The ID of the snapshot2 A8 y3 N0 }. }: ], _
* @return long* p) Y P3 M( P/ O
* @throws RadosException
" K3 L3 p8 I3 l: _: O0 P) f. d */
7 r9 y$ W! q: B, B! H( A& F# {2 E7 Z public long snapGetStamp(final long id) throws RadosException {- {6 ^: h. i6 u/ \% a& C
final LongByReference time = new LongByReference();
# N* N6 |/ ]( B* t5 s2 O2 A handleReturnCode(new Callable<Integer>() {+ ^$ o2 d$ j4 Q
@Override
2 m1 P0 e9 Y, }0 q public Integer call() throws Exception {
+ k1 A( O8 o/ m# H( L- M! Y3 V return rados.rados_ioctx_snap_get_stamp(getPointer(), id, time);
C3 f1 C# _: o) Y9 F }
4 c6 l: t1 U3 ~% \4 x( W }, "Failed to retrieve the timestamp of snapshot %s", id);
% k/ @, A3 D I- t0 q, i return time.getValue();
6 O; E& ~" A" V/ Z }7 |* D/ ?4 A. s5 E) c0 l _( `
4 l, q3 |5 {/ I0 m+ t /**
5 U8 P) M& c s) {. \( S * List all snapshots
+ \$ n! Q- {9 T$ j) a e3 Q *
2 {2 o2 J1 D4 J" f4 q6 ^0 n9 l * @return Long[]4 ~% h( N: E8 ?# N8 `/ I
* @throws RadosException
7 R6 V9 g3 j* F+ f% n1 | */3 E0 ?/ H ^& v, i: V- h
public Long[] snapList() throws RadosException {3 ]3 _0 t- Z4 U. f
final byte[] buf = new byte[512];5 ^) A, u# _' }7 j$ E4 I- a) L0 X
\0 g4 a/ ?$ `- } final Integer result = handleReturnCode(new Callable<Integer>() {" C1 ]3 u. C$ C$ r( w4 d
@Override7 m+ `2 {& Z' J! F9 {+ N: o
public Integer call() throws Exception {
& g# x- X# H, Y# J return rados.rados_ioctx_snap_list(getPointer(), buf, buf.length);, d e2 H3 t1 `% G) S# S" j( [
}
4 w7 Y, ^6 E! d6 c) C }, "Failed to list all snapshots");5 v) H7 z# Z. w% ?
# @6 H2 O* ^ s2 E4 o
Long[] snaps = new Long[result];3 [% b. G" R2 L( c# G5 A
for (int i = 0; i < result; i++) {
( ?, o7 ]1 R: ^7 D snaps = (long) buf;* |) l1 _5 `* H- _/ z
}
1 O4 J1 u8 Y: @1 w6 a5 ~3 I return snaps;- C# Z, [3 _" E5 g2 i4 p" q# N/ V
}* u6 n m) M5 p( l6 K( ~) c
% x* S' u: d' p# @! ? public ReadOp readOpCreate() {9 I1 M7 q |+ |$ W; X# y, y9 x
return new ReadOp(getPointer(), rados.rados_create_read_op());9 ?' M z1 h- C8 {1 V4 W! a7 @9 Y
}
* b) n/ U7 R, k7 t \) P6 j" w. }1 j# m& w1 ?8 Q: |
/**
: t* {( [+ E! ] * Instead of releasing the read operation directly, better use ReadOp.close2 i _$ x& e+ V a- J
*/
& J6 n! V* t X' |! a4 V7 r* N @Deprecated
1 }2 D8 P. [& F$ X public void readOpRelease(ReadOp read_op) {/ S9 j5 @, m! s- R$ t& R8 @" G% m
rados.rados_release_read_op(read_op.getPointer());1 y. x" E1 f2 ^( T
}" v0 v% g) l5 t$ ~
' z/ c" k+ {3 G" @6 k; C/ A+ |. L. t8 I9 U& ~# V; W
/**
& P% \0 v P* s! E3 U& x9 @" { * Get the value of an extended attribute on an object. j6 O3 P* g6 f& E1 b Z( ?- Q
*
, P* |! x, O/ n b* N * @param oid% p$ i9 c7 S/ j1 u3 _
* The name of the object
( E& U- A6 B% L2 c * @param xattrName
2 c' B$ d! v2 i * The name of the extended attribute
6 h p5 m y& q7 v, k * @return# _9 d! e7 U: k0 L/ g+ Q/ m
* The value of the extended attribute
% u6 r( q( U5 N * @throws RadosException
) F. ~8 v3 v) G$ C * on failure -- common error codes:' s8 \# I. w7 F: V Z$ `
* -34 (ERANGE) : value exceeds buffer; |% Y9 R; S$ t) \# b* l
* -61 (ENODATA) : no such attribute
3 u; ~+ j# a4 p7 Y \ */' E' F* X: E: h" h* K+ C& \, l# i
public String getExtendedAttribute(final String oid, final String xattrName) throws RadosException {0 N" ?) Q' z5 @; v- Q/ T9 ?
final byte[] buf = new byte[EXT_ATTR_MAX_LEN];* R( P0 W0 Q, Q5 c( S
handleReturnCode(new Callable<Integer>() {
3 {' y. f0 f/ J @Override" N) Z0 D4 S0 E! Q0 z
public Integer call() throws Exception {
# ?; B. [! q' R; l1 L8 L6 x return rados.rados_getxattr(getPointer(), oid, xattrName, buf, buf.length);
7 \+ g/ k. J% X1 |9 t }
% I) A- Z R# b9 W/ k; e }, "Failed to get extended attribute %s on %s", xattrName, oid);8 u3 \8 \0 W7 ~' g
// else...
0 ^% g: F& e* P5 o! G" V# } return Native.toString(buf);
- @7 m q- [2 l/ k" m0 R! {. r }
% f* [8 [; Y1 t9 ]7 F0 w1 y
1 a! z9 R1 x5 [0 u+ O /**4 @, j* ^: e8 L, A
* Set an extended attribute on an object.
! k% |; [ Y% i) }# z) Z# a *& o) o5 R+ r0 b/ L- G
* @param oid) V+ P1 U- B1 ~* l0 c6 p
* The name of the object
2 R2 f0 x% {- H: d1 U * @param xattrName
" Z. z! w3 }: t" L( g( n' h; {6 ~ * The name of the extended attribute
U* d3 F. H) i0 d6 _ * @param val
# S1 G1 G) U# E; S, S+ R# `0 ?* n * The value of the extended attribute
8 \ O# P- ]/ c5 I n; E" E/ }$ m * @throws IllegalArgumentException
' o+ \: G3 L- B9 Z' v( e * attribute value is too long# B; s2 X: J7 U6 ]% y6 F0 ]
* @throws RadosException
" R8 l# m* {4 W4 N2 | * on failure
' d" x' y2 D8 } */$ @" {6 X- K ]+ Q/ ~' V/ T3 n, }
public void setExtendedAttribute(final String oid, final String xattrName, String val) throws IllegalArgumentException, RadosException {! _: z" w6 F6 y
final byte[] buf = Native.toByteArray(val);
0 I- V6 U7 r8 k- K7 F N# L if (buf.length > EXT_ATTR_MAX_LEN) {
- N& x" h& }) P throw new IllegalArgumentException( "Length of attribute value must not exceed " + EXT_ATTR_MAX_LEN);
6 s2 E1 G/ u3 }: h; A. |& @ }% D% V$ k" f/ l1 _0 M4 w% r
// else...
6 z; ~% O5 o% l( d' Y4 i$ _7 ? handleReturnCode(new Callable<Integer>() {0 E( a9 x. K5 i" W( k. u
@Override
3 V" L3 b$ v3 t9 ^: r5 n/ x& L public Integer call() throws Exception {, k' w8 W: \6 J9 S- }" J. x4 [
return rados.rados_setxattr(getPointer(), oid, xattrName, buf, buf.length);! J. X- r E- w3 s* D% \" l
}: {0 m9 D0 U; A% O
}, "Failed to set extended attribute %s on %s", xattrName, oid);
" h5 m' M: _- {* K/ Y% E O }
% \0 y4 {' s; [+ W' ~8 ?' k+ ]0 z( v3 g0 G' l
/**
& ~+ \# k4 H, c) {( j$ }; F * Delete an extended attribute from an object.
F2 k$ f% c7 v5 t0 N- S *: X' l/ P7 m. J* L1 i
* @param oid8 j( i3 I3 U! A8 n9 D- ?4 k8 @
* The name of the object
6 v# B% c. [# L * @param xattrName
4 r% }7 d. q, S6 u * The name of the extended attribute
0 I9 F2 Q3 M) R3 k+ h( v' ^6 S- C * @throws RadosException9 P3 C$ }- C, e/ J8 S2 ?- h
* on failure2 {7 u R5 A% O2 J
*/. d. a# g, R; B; k, `! ]8 c, L
public void removeExtendedAttribute(final String oid, final String xattrName) throws RadosException {+ m. J; l+ X6 \3 E2 M( ]
handleReturnCode(new Callable<Integer>() {
& H$ s* U }) L6 p- k4 d- K @Override
$ u# k! A0 q6 h- @: x4 @0 Q) C public Integer call() throws Exception {
+ i4 l8 D' t" P" M- [ return rados.rados_rmxattr(getPointer(), oid, xattrName);
) \6 i4 i9 h# a- ~: E \' e }
1 d8 O& @) j, | X3 N( V }, "Failed to remove extended attribute %s from %s", xattrName, oid);
0 u [. Q! N% o4 \! l+ s8 p }
7 G! w9 a# ?! K% d" N3 Z' _4 ]. P
+ o$ B. v) a5 C* o' Q /**
# F) | H* M7 [- a * Get all extended attributes on an object.
( A8 Z1 G; z7 s8 _6 L3 r */ g6 {# V7 b/ z
* @param oid
+ c5 w; \! W8 C7 c * The name of the object2 L; g* M) g* p5 r `, L
* @return, D! v; d! j& E. b
* The map of the extended attributes; U# z- a: z5 h7 D# ^
* @throws RadosException
3 T+ k) F9 ~& J9 ` * on failure; ?8 H& _2 v) Q7 O- r; [. D+ [
*/" s* U$ I' v. Z/ V9 p, D$ p
public Map<String, String> getExtendedAttributes(final String oid) throws RadosException {$ b3 ~' Y: l5 ~$ ^, ]9 y: P
Map<String, String> attr_map = new HashMap<>();' @' ^: K! D! V3 t
final Pointer iterator = new Memory(Pointer.SIZE);+ d! D- _( Y/ E& L, E! Q& |
final PointerByReference attr_name = new PointerByReference();
7 F& N- {( M4 S3 \9 T/ J! p final PointerByReference attr_value = new PointerByReference();
. \5 S( b' X, F# e# h' K( |. W final IntByReference attr_value_len = new IntByReference();# C' q$ W! F2 g
/ u. s( d9 X9 b* h* G+ }/ C
handleReturnCode(new Callable<Integer>() {
( Y0 T* j) {& U @Override
- S; X2 L) ]; N4 p& [0 r; Y public Integer call() throws Exception {
8 `/ S6 o" |; C2 Y return rados.rados_getxattrs(getPointer(), oid, iterator); ]% e% ~" K M; h3 y
}
6 |! X* y) K( n }, "Failed starting to list all extended attributes");
- P) J$ s D6 \" a1 M+ @- D7 \
# _9 ?# n5 k* d8 q" w3 i" o while (rados.rados_getxattrs_next(iterator.getPointer(0), attr_name, attr_value, attr_value_len) == 0( m/ e" O8 ]7 J9 K" L
&& attr_value_len.getValue() > 0) {1 G) W- \/ N9 T' T5 G; R; R0 B& w/ c
int length = attr_value_len.getValue();
* n( x B+ Y9 V$ P3 d String name = (attr_name.getValue() == null ? null : new String(attr_name.getValue().getString(0)));
+ `" R6 E# w' A* w5 ]% l" e) n String value = (attr_value.getValue() == null ? null : new String(attr_value.getValue().getString(0)));* |/ S. x9 A, m+ s; e
if (length > 0 && name != null && value != null) {4 m( A t3 I: N. K9 A% G: ?
attr_map.put(name, value);
2 m& L6 W7 F- Q, q. Y4 Z: B, k }
$ W0 u( \9 I! N2 ~: Q/ w+ b }
6 s. Q! p) ?$ F3 x2 z1 Y! I8 ]# q- k3 e5 V9 N
rados.rados_getxattrs_end(iterator.getPointer(0));# x P) \" Y1 c& b3 K5 k
/ M7 Z7 N. q5 S5 G5 r$ ^ return attr_map;
. u. j1 ~% \, c3 ^ }
9 D; l, L$ W0 }1 @4 `- f B7 w5 A4 f% `, t) P3 l; i0 S( R4 z/ e
@Override
% M7 Y4 s# g, y% H. G: J% y; N7 D; O- ~ public void close() throws IOException {/ Q# _+ [- B4 g3 N! z
rados.rados_ioctx_destroy(getPointer());; Y3 f( t6 K1 M$ v2 a/ P* G
}
# o+ b6 v6 i: [ s! N}
; h+ k$ B: x# A" H' x' I( v) v" _* c# Z! E# Q1 ^$ J4 N% w0 p' ~7 C
7 e$ `" n+ V8 X- h2 [* ~2 F7 b至此,大家应该对Java访问Ceph有了彻底的认识了' k+ F# e' ?5 L. y( T/ u# I
( X! H% m4 }, _
# {+ B1 X6 H4 ]5 n) {/ o |
|