diff options
-rw-r--r-- | doc/man/8/rbd.rst | 2 | ||||
-rw-r--r-- | man/rbd.8 | 4 | ||||
-rw-r--r-- | src/common/ceph_argparse.cc | 2 | ||||
-rw-r--r-- | src/common/config_opts.h | 4 | ||||
-rw-r--r-- | src/mon/OSDMonitor.cc | 19 | ||||
-rw-r--r-- | src/osdc/Objecter.cc | 21 | ||||
-rw-r--r-- | src/pybind/rbd.py | 25 | ||||
-rw-r--r-- | src/test/pybind/test_rbd.py | 7 |
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') |