]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd: match against whole disks on unmap
authorIlya Dryomov <ilya.dryomov@inktank.com>
Fri, 13 Dec 2013 15:40:52 +0000 (17:40 +0200)
committerIlya Dryomov <ilya.dryomov@inktank.com>
Fri, 13 Dec 2013 15:40:52 +0000 (17:40 +0200)
Currently the way 'rbd unmap' translates a user-provided block device
into an rbd id is it matches the major number of the specified device
against /sys/bus/rbd/devices/<id>/major for each rbd mapping and
declares success on the first match.  This works for both entire disks
and partitions, because under the current device number allocation
scheme, each mapping means a new major number.

In preparation for support for single-major device number allocation
scheme, which would require matching both major and minor numbers, make
sure to always match against entire disk device numbers, by converting
the specified device major:minor pair into wholdedisk major:minor pair.
To achive that, use the libblkid library, which accomplishes this goal
by walking stable sysfs structures.

Signed-off-by: Ilya Dryomov <ilya.dryomov@inktank.com>
README
ceph.spec.in
configure.ac
debian/control
src/Makefile.am
src/rbd.cc

diff --git a/README b/README
index 16e2cde24e4690c846e2ac73e3113646b4d75680..197a7bfaadead70b29b64d3a425df150fb0dddc9 100644 (file)
--- a/README
+++ b/README
@@ -122,6 +122,7 @@ To build the source code, you must install the following:
 - libgoogle-perftools-dev
 - libkeyutils-dev
 - uuid-dev
+- libblkid-dev
 - libatomic-ops-dev
 - libboost-program-options-dev
 - libboost-thread-dev
@@ -134,7 +135,7 @@ To build the source code, you must install the following:
 
 For example:
 
-       $ apt-get install automake autoconf pkg-config gcc g++ make libboost-dev libedit-dev libssl-dev libtool libfcgi libfcgi-dev libfuse-dev linux-kernel-headers libcrypto++-dev libaio-dev libgoogle-perftools-dev libkeyutils-dev uuid-dev libatomic-ops-dev libboost-program-options-dev libboost-thread-dev libexpat1-dev libleveldb-dev libsnappy-dev libcurl4-gnutls-dev python-argparse python-flask
+       $ apt-get install automake autoconf pkg-config gcc g++ make libboost-dev libedit-dev libssl-dev libtool libfcgi libfcgi-dev libfuse-dev linux-kernel-headers libcrypto++-dev libaio-dev libgoogle-perftools-dev libkeyutils-dev uuid-dev libblkid-dev libatomic-ops-dev libboost-program-options-dev libboost-thread-dev libexpat1-dev libleveldb-dev libsnappy-dev libcurl4-gnutls-dev python-argparse python-flask
 
 rpm-based
 ---------
@@ -149,6 +150,7 @@ These are the rpm packages needed to install in an rpm-based OS:
     python-argparse
     python-flask
     libuuid-devel
+    libblkid-devel
     keyutils-libs-devel
     cryptopp-devel
     nss-devel
@@ -166,5 +168,5 @@ These are the rpm packages needed to install in an rpm-based OS:
 
 For example:
 
-       $ yum install autoconf automake gcc gcc-c++ make libtool python-argparse python-flask libuuid-devel keyutils-libs-devel cryptopp-devel nss-devel fcgi-devel expat-devel libcurl-devel fuse-devel gperftools-devel libedit-devel libatomic_ops-devel snappy-devel leveldb-devel libaio-devel boost-devel
+       $ yum install autoconf automake gcc gcc-c++ make libtool python-argparse python-flask libuuid-devel libblkid-devel keyutils-libs-devel cryptopp-devel nss-devel fcgi-devel expat-devel libcurl-devel fuse-devel gperftools-devel libedit-devel libatomic_ops-devel snappy-devel leveldb-devel libaio-devel boost-devel
 
index b2c9d839904fbb6dae48d861aebb1efa54d8c115..a746461551b179703a4f1b53c8be98f676360b9b 100644 (file)
@@ -43,6 +43,7 @@ BuildRequires:  libaio-devel
 BuildRequires:  libcurl-devel
 BuildRequires:  libxml2-devel
 BuildRequires:  libuuid-devel
+BuildRequires:  libblkid-devel >= 2.17
 BuildRequires:  leveldb-devel > 1.2
 BuildRequires:  yasm
 %if 0%{?rhel_version} || 0%{?centos_version} || 0%{?fedora}
index ab2e49dd707a32f74acba6ed5c923a93f9e970de..5fdd8066fefcde9b9af21f4ea91e7244c99975de 100644 (file)
@@ -128,8 +128,13 @@ AX_C_PRETTY_FUNC
 
 # Checks for libraries.
 ACX_PTHREAD
+
 AC_CHECK_LIB([uuid], [uuid_parse], [true], AC_MSG_FAILURE([libuuid not found]))
 
+if test x"$linux" = x"yes"; then
+  AC_CHECK_LIB([blkid], [blkid_devno_to_wholedisk], [true], AC_MSG_FAILURE([libblkid not found]))
+fi
+
 #
 # Check for res_nquery in libresolv. There are several variations. On OSX
 # res_nquery is a macro defined in resolv.h, so the typical AC_CHECK_LIB
index 1aec592c9f891f4643862031940090a09c258632..fcbadc48ddffe0241cadbca56ce8518591798182 100644 (file)
@@ -36,6 +36,7 @@ Build-Depends: autoconf,
                python (>= 2.6.6-3~),
                python-nose,
                uuid-dev,
+               libblkid-dev (>= 2.17),
                yasm
 Standards-Version: 3.9.3
 
index 9481b981fc81e631ae34f619d2b48689d5aa66e4..7ee5e6a11207b777e67b5c944ef477c5eb571502 100644 (file)
@@ -75,8 +75,8 @@ ceph_syn_SOURCES += client/SyntheticClient.cc # uses g_conf.. needs cleanup
 ceph_syn_LDADD = $(LIBCLIENT) $(CEPH_GLOBAL)
 bin_PROGRAMS += ceph-syn
 
-rbd_SOURCES = rbd.cc 
-rbd_LDADD = $(LIBRBD) $(LIBRADOS) $(CEPH_GLOBAL)
+rbd_SOURCES = rbd.cc
+rbd_LDADD = $(LIBRBD) $(LIBRADOS) $(CEPH_GLOBAL) -lblkid
 if LINUX
 bin_PROGRAMS += rbd
 endif #LINUX
index a5806b9b4c6930d5448320df8c4e5c4a6bb81160..69f550e48290178b2a5343d98ec898bd78dc91fa 100644 (file)
@@ -57,6 +57,8 @@
 #include <sys/param.h>
 #endif
 
+#include <blkid/blkid.h>
+
 #define MAX_SECRET_LEN 1000
 #define MAX_POOL_NAME_SIZE 128
 
@@ -1859,9 +1861,19 @@ static int do_kernel_showmapped(Formatter *f)
   return 0;
 }
 
-static int get_rbd_seq(int major_num, string &seq)
+static int get_rbd_seq(dev_t devno, string &seq)
 {
-  int r;
+  // convert devno, which might be a partition major:minor pair, into
+  // a whole disk major:minor pair
+  dev_t wholediskno;
+  int r = blkid_devno_to_wholedisk(devno, NULL, 0, &wholediskno);
+  if (r) {
+    cerr << "rbd: could not compute wholediskno: " << r << std::endl;
+    // ignore the error: devno == wholediskno most of the time, and if
+    // it turns out it's not we will fail with -ENOENT later anyway
+    wholediskno = devno;
+  }
+
   const char *devices_path = "/sys/bus/rbd/devices";
   DIR *device_dir = opendir(devices_path);
   if (!device_dir) {
@@ -1904,7 +1916,7 @@ static int get_rbd_seq(int major_num, string &seq)
       continue;
     }
 
-    if (cur_major == major_num) {
+    if (cur_major == (int)major(wholediskno)) {
       seq = string(dent->d_name);
       closedir(device_dir);
       return 0;
@@ -1918,16 +1930,14 @@ static int get_rbd_seq(int major_num, string &seq)
 
 static int do_kernel_rm(const char *dev)
 {
-  struct stat dev_stat;
-  int r = stat(dev, &dev_stat);
-  if (!S_ISBLK(dev_stat.st_mode)) {
+  struct stat sbuf;
+  if (stat(dev, &sbuf) || !S_ISBLK(sbuf.st_mode)) {
     cerr << "rbd: " << dev << " is not a block device" << std::endl;
     return -EINVAL;
   }
 
-  int major = major(dev_stat.st_rdev);
   string seq_num;
-  r = get_rbd_seq(major, seq_num);
+  int r = get_rbd_seq(sbuf.st_rdev, seq_num);
   if (r == -ENOENT) {
     cerr << "rbd: " << dev << " is not an rbd device" << std::endl;
     return -EINVAL;