summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/man/8/rbd.rst2
-rw-r--r--man/rbd.84
-rw-r--r--src/common/ceph_argparse.cc2
-rw-r--r--src/common/config_opts.h4
-rw-r--r--src/mon/OSDMonitor.cc19
-rw-r--r--src/osdc/Objecter.cc21
-rw-r--r--src/pybind/rbd.py25
-rw-r--r--src/test/pybind/test_rbd.py7
8 files changed, 66 insertions, 18 deletions
diff --git a/doc/man/8/rbd.rst b/doc/man/8/rbd.rst
index 7069e301d96..4b7d57ed97d 100644
--- a/doc/man/8/rbd.rst
+++ b/doc/man/8/rbd.rst
@@ -94,7 +94,7 @@ Commands
Copies the content of a src-image into the newly created dest-image.
:command:`mv` [*src-image*] [*dest-image*]
- Renames an image.
+ Renames an image. Note: rename across pools is not supported.
:command:`snap` ls [*image-name*]
Dumps the list of snapshots inside a specific image.
diff --git a/man/rbd.8 b/man/rbd.8
index 82171a9e599..7599896596a 100644
--- a/man/rbd.8
+++ b/man/rbd.8
@@ -1,4 +1,4 @@
-.TH "RBD" "8" "February 17, 2012" "dev" "Ceph"
+.TH "RBD" "8" "May 02, 2012" "dev" "Ceph"
.SH NAME
rbd \- manage rados block device (RBD) images
.
@@ -116,7 +116,7 @@ Creates a new image and imports its data from path.
Copies the content of a src\-image into the newly created dest\-image.
.TP
.B \fBmv\fP [\fIsrc\-image\fP] [\fIdest\-image\fP]
-Renames an image. Note: rename across pools is unsupported.
+Renames an image. Note: rename across pools is not supported.
.TP
.B \fBsnap\fP ls [\fIimage\-name\fP]
Dumps the list of snapshots inside a specific image.
diff --git a/src/common/ceph_argparse.cc b/src/common/ceph_argparse.cc
index 3b142b40b0b..75b413d60ed 100644
--- a/src/common/ceph_argparse.cc
+++ b/src/common/ceph_argparse.cc
@@ -357,7 +357,7 @@ CephInitParameters ceph_argparse_early_args
else if (ceph_argparse_witharg(args, i, &val, "--conf", "-c", (char*)NULL)) {
*conf_file_list = val;
}
- else if (ceph_argparse_witharg(args, i, &val, "--cluster", "-C", (char*)NULL)) {
+ else if (ceph_argparse_witharg(args, i, &val, "--cluster", (char*)NULL)) {
*cluster = val;
}
else if ((module_type != CEPH_ENTITY_TYPE_CLIENT) &&
diff --git a/src/common/config_opts.h b/src/common/config_opts.h
index e33c54b405d..1d5ba22057d 100644
--- a/src/common/config_opts.h
+++ b/src/common/config_opts.h
@@ -23,14 +23,14 @@ OPTION(num_client, OPT_INT, 1)
OPTION(monmap, OPT_STR, "")
OPTION(mon_host, OPT_STR, "")
OPTION(lockdep, OPT_BOOL, false)
-OPTION(admin_socket, OPT_STR, "/var/run/ceph/$cluster.name.asok")
+OPTION(admin_socket, OPT_STR, "/var/run/ceph/$cluster-$name.asok")
OPTION(daemonize, OPT_BOOL, false)
OPTION(pid_file, OPT_STR, "")
OPTION(chdir, OPT_STR, "/")
OPTION(max_open_files, OPT_LONGLONG, 0)
-OPTION(log_file, OPT_STR, "/var/log/ceph/$cluster.$name.log")
+OPTION(log_file, OPT_STR, "/var/log/ceph/$cluster-$name.log")
OPTION(log_max_new, OPT_INT, 1000)
OPTION(log_max_recent, OPT_INT, 1000000)
OPTION(log_to_stderr, OPT_BOOL, true)
diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc
index c7f1564d98d..14878c4821e 100644
--- a/src/mon/OSDMonitor.cc
+++ b/src/mon/OSDMonitor.cc
@@ -1544,6 +1544,25 @@ bool OSDMonitor::preprocess_command(MMonCommand *m)
} else ss << "specify osd number or *";
}
}
+ else if (m->cmd[1] == "map" && m->cmd.size() == 4) {
+ int64_t pool = osdmap.lookup_pg_pool_name(m->cmd[2].c_str());
+ if (pool < 0) {
+ ss << "pool " << m->cmd[2] << " dne";
+ r = -ENOENT;
+ } else {
+ object_locator_t oloc(pool);
+ object_t oid(m->cmd[3]);
+ pg_t pgid = osdmap.object_locator_to_pg(oid, oloc);
+ pg_t mpgid = osdmap.raw_pg_to_pg(pgid);
+ vector<int> up, acting;
+ osdmap.pg_to_up_acting_osds(mpgid, up, acting);
+ ss << "osdmap e" << osdmap.get_epoch()
+ << " pool '" << m->cmd[2] << "' (" << pool << ") object '" << oid << "' ->"
+ << " pg " << pgid << " (" << mpgid << ")"
+ << " -> up " << up << " acting " << acting;
+ r = 0;
+ }
+ }
else if ((m->cmd[1] == "scrub" || m->cmd[1] == "repair")) {
if (m->cmd.size() <= 2) {
r = -EINVAL;
diff --git a/src/osdc/Objecter.cc b/src/osdc/Objecter.cc
index 11e86d8bf28..e81bfff43fb 100644
--- a/src/osdc/Objecter.cc
+++ b/src/osdc/Objecter.cc
@@ -265,6 +265,13 @@ void Objecter::send_linger(LingerOp *info)
}
}
op_submit(o, info->session);
+ OSDSession *s = o->session;
+ if (info->session != s) {
+ info->session_item.remove_myself();
+ info->session = s;
+ if (info->session)
+ s->linger_ops.push_back(&info->session_item);
+ }
info->registering = true;
logger->inc(l_osdc_linger_send);
@@ -780,6 +787,17 @@ void Objecter::tick()
++laggy_ops;
}
}
+ for (map<uint64_t,LingerOp*>::iterator p = linger_ops.begin();
+ p != linger_ops.end();
+ p++) {
+ LingerOp *op = p->second;
+ if (op->session) {
+ ldout(cct, 0) << " pinging osd that serves lingering tid " << p->first << " (osd." << op->session->osd << ")" << dendl;
+ toping.insert(op->session);
+ } else {
+ ldout(cct, 0) << " lingering tid " << p->first << " does not have session" << dendl;
+ }
+ }
logger->set(l_osdc_op_laggy, laggy_ops);
logger->set(l_osdc_osd_laggy, toping.size());
@@ -791,8 +809,9 @@ void Objecter::tick()
// (osd reply message policy is lossy)
for (set<OSDSession*>::iterator i = toping.begin();
i != toping.end();
- i++)
+ i++) {
messenger->send_message(new MPing, (*i)->con);
+ }
}
// reschedule
diff --git a/src/pybind/rbd.py b/src/pybind/rbd.py
index d9c554b575b..7cb5d228dba 100644
--- a/src/pybind/rbd.py
+++ b/src/pybind/rbd.py
@@ -56,6 +56,9 @@ class ReadOnlyImage(Error):
class ImageBusy(Error):
pass
+class ImageHasSnapshots(Error):
+ pass
+
def make_ex(ret, msg):
"""
Translate a librbd return code into an exception.
@@ -67,14 +70,15 @@ def make_ex(ret, msg):
:returns: a subclass of :class:`Error`
"""
errors = {
- errno.EPERM : PermissionError,
- errno.ENOENT : ImageNotFound,
- errno.EIO : IOError,
- errno.ENOSPC : NoSpace,
- errno.EEXIST : ImageExists,
- errno.EINVAL : InvalidArgument,
- errno.EROFS : ReadOnlyImage,
- errno.EBUSY : ImageBusy,
+ errno.EPERM : PermissionError,
+ errno.ENOENT : ImageNotFound,
+ errno.EIO : IOError,
+ errno.ENOSPC : NoSpace,
+ errno.EEXIST : ImageExists,
+ errno.EINVAL : InvalidArgument,
+ errno.EROFS : ReadOnlyImage,
+ errno.EBUSY : ImageBusy,
+ errno.ENOTEMPTY : ImageHasSnapshots,
}
ret = abs(ret)
if ret in errors:
@@ -163,13 +167,16 @@ class RBD(object):
not return until every object that comprises the image has
been deleted. Note that all snapshots must be deleted before
the image can be removed. If there are snapshots left,
+ :class:`ImageHasSnapshots` is raised. If the image is still
+ open, or the watch from a crashed client has not expired,
:class:`ImageBusy` is raised.
:param ioctx: determines which RADOS pool the image is in
:type ioctx: :class:`rados.Ioctx`
:param name: the name of the image to remove
:type name: str
- :raises: :class:`ImageNotFound`, :class:`ImageBusy`
+ :raises: :class:`ImageNotFound`, :class:`ImageBusy`,
+ :class:`ImageHasSnapshots`
"""
if not isinstance(name, str):
raise TypeError('name must be a string')
diff --git a/src/test/pybind/test_rbd.py b/src/test/pybind/test_rbd.py
index 7edf8e97a26..94176dff612 100644
--- a/src/test/pybind/test_rbd.py
+++ b/src/test/pybind/test_rbd.py
@@ -5,7 +5,7 @@ from nose import with_setup
from nose.tools import eq_ as eq, assert_raises
from rados import Rados
from rbd import (RBD, Image, ImageNotFound, InvalidArgument, ImageExists,
- ImageBusy)
+ ImageBusy, ImageHasSnapshots)
rados = None
@@ -195,9 +195,12 @@ class TestImage(object):
def test_remove_with_snap(self):
self.image.create_snap('snap1')
- assert_raises(ImageBusy, remove_image)
+ assert_raises(ImageHasSnapshots, remove_image)
self.image.remove_snap('snap1')
+ def test_remove_with_watcher(self):
+ assert_raises(ImageBusy, remove_image)
+
def test_rollback_to_snap(self):
self.image.write('\0' * 256, 0)
self.image.create_snap('snap1')