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 \
--- /dev/null
+/*
+ * 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 + "]";
+ }
+}
import java.util.Arrays;
import java.lang.String;
+import com.ceph.crush.Bucket;
+
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);
}
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<string> 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;
+}
import org.junit.*;
import static org.junit.Assert.*;
+import com.ceph.crush.Bucket;
+
/*
* Coverage
* - Everything is covered in at least success cases.
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);
+ }
+ }
}