diff options
author | Sage Weil <sage@inktank.com> | 2013-01-26 13:45:12 -0800 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-01-26 13:45:12 -0800 |
commit | bbb86ec79409bc906c08c896e855d2a7b556fb9f (patch) | |
tree | ed7dc6c1c7b3ae0f9c98f1b7dc61484ce87bddf2 | |
parent | 700bcede4d07b0565adcb081414cf840bbf17d66 (diff) | |
download | ceph-bbb86ec79409bc906c08c896e855d2a7b556fb9f.tar.gz |
mon: safety interlock for pool deletion
Require that the pool name be passed twice along with an force option
before we irreversibly delete an entire pool of objects.
Signed-off-by: Sage Weil <sage@inktank.com>
-rwxr-xr-x | qa/workunits/mon/pool_ops.sh | 10 | ||||
-rwxr-xr-x | qa/workunits/rbd/copy.sh | 17 | ||||
-rwxr-xr-x | qa/workunits/rbd/permissions.sh | 4 | ||||
-rw-r--r-- | src/mon/OSDMonitor.cc | 25 |
4 files changed, 36 insertions, 20 deletions
diff --git a/qa/workunits/mon/pool_ops.sh b/qa/workunits/mon/pool_ops.sh index 0fed24d7474..a9e9f422c40 100755 --- a/qa/workunits/mon/pool_ops.sh +++ b/qa/workunits/mon/pool_ops.sh @@ -7,9 +7,13 @@ ceph osd pool create fooo 123 ceph osd pool create foo 123 # idempotent -ceph osd pool delete foo -ceph osd pool delete foo -ceph osd pool delete fuggg +ceph osd pool delete foo && exit 1 || true # should fail due to safety interlock +ceph osd pool delete foo foo && exit 1 || true # should fail due to safety interlock +ceph osd pool delete foo foo --force && exit 1 || true # should fail due to safety interlock + +ceph osd pool delete foo foo --yes-i-really-really-mean-it +ceph osd pool delete foo foo --yes-i-really-really-mean-it +ceph osd pool delete fuggg fugg --yes-i-really-really-mean-it ceph osd pool delete fooo diff --git a/qa/workunits/rbd/copy.sh b/qa/workunits/rbd/copy.sh index cd0bea79c2c..e2465fa3c45 100755 --- a/qa/workunits/rbd/copy.sh +++ b/qa/workunits/rbd/copy.sh @@ -1,5 +1,8 @@ #!/bin/sh -ex +# make sure rbd pool is EMPTY.. this is a test script!! +rbd ls | wc -l | grep -v '^0$' && echo "nonempty rbd pool, aborting! run this script on an empty test cluster only." && exit 1 + IMGS="testimg1 testimg2 testimg3 foo foo2 bar bar2 test1 test2 test3" remove_images() { @@ -90,7 +93,7 @@ test_rename() { ! rbd rename rbd2/bar --dest-pool rbd foo rbd rename --pool rbd2 bar --dest-pool rbd2 foo rbd -p rbd2 ls | grep foo - rados rmpool rbd2 + rados rmpool rbd2 rbd2 --yes-i-really-really-mean-it remove_images } @@ -234,7 +237,7 @@ test_pool_image_args() { echo "testing pool and image args..." remove_images - ceph osd pool delete test || true + ceph osd pool delete test test --yes-i-really-really-mean-it || true ceph osd pool create test 100 truncate -s 1 /tmp/empty @@ -283,8 +286,8 @@ test_pool_image_args() { rbd ls test | grep -qv test12 rm -f /tmp/empty - ceph osd pool delete test - ceph osd pool delete rbd + ceph osd pool delete test test --yes-i-really-really-mean-it + ceph osd pool delete rbd rbd --yes-i-really-really-mean-it ceph osd pool create rbd 100 } @@ -307,9 +310,9 @@ test_clone() { rbd ls -l | grep clone2 | grep rbd2/clone@s1 rbd -p rbd2 ls | grep -v clone2 - rados rmpool rbd2 - rados rmpool rbd - rados mkpool rbd + rados rmpool rbd2 rbd2 --yes-i-really-really-mean-it + rados rmpool rbd rbd --yes-i-really-really-mean-it + rados mkpool rbd rbd --yes-i-really-really-mean-it } test_pool_image_args diff --git a/qa/workunits/rbd/permissions.sh b/qa/workunits/rbd/permissions.sh index 40428df38e3..74c24c03c2b 100755 --- a/qa/workunits/rbd/permissions.sh +++ b/qa/workunits/rbd/permissions.sh @@ -6,8 +6,8 @@ create_pools() { } delete_pools() { - (ceph osd pool delete images || true) >/dev/null 2>&1 - (ceph osd pool delete volumes || true) >/dev/null 2>&1 + (ceph osd pool delete images images --yes-i-really-really-mean-it || true) >/dev/null 2>&1 + (ceph osd pool delete volumes volumes --yes-i-really-really-mean-it || true) >/dev/null 2>&1 } diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc index 226229591d3..5786713e043 100644 --- a/src/mon/OSDMonitor.cc +++ b/src/mon/OSDMonitor.cc @@ -2779,19 +2779,28 @@ bool OSDMonitor::prepare_command(MMonCommand *m) paxos->wait_for_commit(new Monitor::C_Command(mon, m, 0, rs, paxos->get_version())); return true; } else if (m->cmd[2] == "delete" && m->cmd.size() >= 4) { - //hey, let's delete a pool! + // osd pool delete <poolname> <poolname again> --yes-i-really-really-mean-it int64_t pool = osdmap.lookup_pg_pool_name(m->cmd[3].c_str()); if (pool < 0) { ss << "pool '" << m->cmd[3] << "' does not exist"; err = 0; - } else { - int ret = _prepare_remove_pool(pool); - if (ret == 0) - ss << "pool '" << m->cmd[3] << "' deleted"; - getline(ss, rs); - paxos->wait_for_commit(new Monitor::C_Command(mon, m, ret, rs, paxos->get_version())); - return true; + goto out; } + if (m->cmd.size() != 6 || + m->cmd[3] != m->cmd[4] || + m->cmd[5] != "--yes-i-really-really-mean-it") { + ss << "WARNING: this will *PERMANENTLY DESTROY* all data stored in pool " << m->cmd[3] + << ". If you are *ABSOLUTELY CERTAIN* that is what you want, pass the pool name *twice*, " + << "followed by --yes-i-really-really-mean-it."; + err = -EPERM; + goto out; + } + int ret = _prepare_remove_pool(pool); + if (ret == 0) + ss << "pool '" << m->cmd[3] << "' deleted"; + getline(ss, rs); + paxos->wait_for_commit(new Monitor::C_Command(mon, m, ret, rs, paxos->get_version())); + return true; } else if (m->cmd[2] == "rename" && m->cmd.size() == 5) { int64_t pool = osdmap.lookup_pg_pool_name(m->cmd[3].c_str()); if (pool < 0) { |