From bc65ace09f3420406357c440accb14bed20a69fe Mon Sep 17 00:00:00 2001 From: Noah Watkins Date: Thu, 21 Mar 2013 15:42:34 -0700 Subject: [PATCH] java: support ceph_get_osd_crush_location Signed-off-by: Noah Watkins --- src/java/Makefile.am | 3 +- src/java/java/com/ceph/crush/Bucket.java | 42 ++++++++++ src/java/java/com/ceph/fs/CephMount.java | 26 +++++++ src/java/native/libcephfs_jni.cc | 82 ++++++++++++++++++++ src/java/test/com/ceph/fs/CephMountTest.java | 12 +++ 5 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 src/java/java/com/ceph/crush/Bucket.java diff --git a/src/java/Makefile.am b/src/java/Makefile.am index d37e700aeb4ba..790ce0d865618 100644 --- a/src/java/Makefile.am +++ b/src/java/Makefile.am @@ -10,7 +10,8 @@ JAVA_SRC = \ java/com/ceph/fs/CephAlreadyMountedException.java \ java/com/ceph/fs/CephNotDirectoryException.java \ java/com/ceph/fs/CephPoolException.java \ - java/com/ceph/fs/CephFileExtent.java + java/com/ceph/fs/CephFileExtent.java \ + java/com/ceph/crush/Bucket.java JAVA_TEST_SRC = \ test/com/ceph/fs/CephDoubleMountTest.java \ diff --git a/src/java/java/com/ceph/crush/Bucket.java b/src/java/java/com/ceph/crush/Bucket.java new file mode 100644 index 0000000000000..989f61982e835 --- /dev/null +++ b/src/java/java/com/ceph/crush/Bucket.java @@ -0,0 +1,42 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +package com.ceph.crush; + +public class Bucket { + private String type; + private String name; + + public Bucket(String type, String name) { + this.type = type; + this.name = name; + } + + public String getType() { + return type; + } + + public String getName() { + return name; + } + + public String toString() { + return "bucket[" + type + "," + name + "]"; + } +} diff --git a/src/java/java/com/ceph/fs/CephMount.java b/src/java/java/com/ceph/fs/CephMount.java index e6a3721ccd631..dcc263063fedc 100644 --- a/src/java/java/com/ceph/fs/CephMount.java +++ b/src/java/java/com/ceph/fs/CephMount.java @@ -26,6 +26,8 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.Arrays; import java.lang.String; +import com.ceph.crush.Bucket; + public class CephMount { /* @@ -1006,4 +1008,28 @@ public class CephMount { } private static native CephFileExtent native_ceph_get_file_extent_osds(long mountp, int fd, long offset); + + /** + * Get the fully qualified CRUSH location of an OSD. + * + * Returns (type, name) string pairs for each device in the CRUSH bucket + * hierarchy starting from the given OSD to the root. + * + * @param osd The OSD device id. + * @return List of pairs. + */ + public Bucket[] get_osd_crush_location(int osd) { + rlock.lock(); + try { + String[] parts = native_ceph_get_osd_crush_location(instance_ptr, osd); + Bucket[] path = new Bucket[parts.length / 2]; + for (int i = 0; i < path.length; i++) + path[i] = new Bucket(parts[i*2], parts[i*2+1]); + return path; + } finally { + rlock.unlock(); + } + } + + private static native String[] native_ceph_get_osd_crush_location(long mountp, int osd); } diff --git a/src/java/native/libcephfs_jni.cc b/src/java/native/libcephfs_jni.cc index 4a205b9037171..8da54989e25a4 100644 --- a/src/java/native/libcephfs_jni.cc +++ b/src/java/native/libcephfs_jni.cc @@ -2713,3 +2713,85 @@ out: return extent; } + +/* + * Class: com_ceph_fs_CephMount + * Method: native_ceph_get_osd_crush_location + * Signature: (JI)[Ljava/lang/String; + */ +JNIEXPORT jobjectArray JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1get_1osd_1crush_1location + (JNIEnv *env, jclass clz, jlong j_mntp, jint osdid) +{ + struct ceph_mount_info *cmount = get_ceph_mount(j_mntp); + CephContext *cct = ceph_get_mount_context(cmount); + jobjectArray path = NULL; + vector str_path; + int ret, bufpos, buflen = 0; + char *buf = NULL; + + CHECK_MOUNTED(cmount, NULL); + + ldout(cct, 10) << "jni: osd loc: osd " << osdid << dendl; + + for (;;) { + /* get length of the location path */ + ret = ceph_get_osd_crush_location(cmount, osdid, NULL, 0); + if (ret < 0) + break; + + /* alloc path buffer */ + if (buf) + delete [] buf; + buflen = ret; + buf = new char[buflen+1]; + memset(buf, 0, buflen*sizeof(*buf)); + + /* empty path */ + if (buflen == 0) + break; + + /* get the path */ + ret = ceph_get_osd_crush_location(cmount, osdid, buf, buflen); + if (ret == -ERANGE) + continue; + else + break; + } + + ldout(cct, 10) << "jni: osd loc: osd " << osdid << " ret " << ret << dendl; + + if (ret < 0) { + handle_error(env, ret); + goto out; + } + + bufpos = 0; + while (bufpos < ret) { + string type(buf + bufpos); + bufpos += type.size() + 1; + string name(buf + bufpos); + bufpos += name.size() + 1; + str_path.push_back(type); + str_path.push_back(name); + } + + path = env->NewObjectArray(str_path.size(), env->FindClass("java/lang/String"), NULL); + if (!path) + goto out; + + for (unsigned i = 0; i < str_path.size(); i++) { + jstring ent = env->NewStringUTF(str_path[i].c_str()); + if (!ent) + goto out; + env->SetObjectArrayElement(path, i, ent); + if (env->ExceptionOccurred()) + goto out; + env->DeleteLocalRef(ent); + } + +out: + if (buf) + delete [] buf; + + return path; +} diff --git a/src/java/test/com/ceph/fs/CephMountTest.java b/src/java/test/com/ceph/fs/CephMountTest.java index 22274d1905c5d..2922f589eba92 100644 --- a/src/java/test/com/ceph/fs/CephMountTest.java +++ b/src/java/test/com/ceph/fs/CephMountTest.java @@ -26,6 +26,8 @@ import java.util.UUID; import org.junit.*; import static org.junit.Assert.*; +import com.ceph.crush.Bucket; + /* * Coverage * - Everything is covered in at least success cases. @@ -981,4 +983,14 @@ public class CephMountTest { mount.close(fd); mount.unlink(path); } + + @Test + public void test_get_osd_crush_location() throws Exception { + Bucket[] path = mount.get_osd_crush_location(0); + assertTrue(path.length > 0); + for (Bucket b : path) { + assertTrue(b.getType().length() > 0); + assertTrue(b.getName().length() > 0); + } + } } -- 2.39.5