]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
common: fix for broken rbdmap parameter parsing 24446/head
authorMarc Schoechlin <marc.schoechlin@vico-research.com>
Fri, 5 Oct 2018 11:05:12 +0000 (13:05 +0200)
committerJason Dillaman <dillaman@redhat.com>
Mon, 14 Jan 2019 19:29:59 +0000 (14:29 -0500)
This improves the broken parameter parsing discussed in #36327

Test expression for the parsing function:

PARAMS="options='lock_on_read,queue_depth=1024',id=archiv,keyring=/etc/ceph/ceph.client.archiv.keyring"
echo -e " ORIGINAL PARAM: >>>$PARAMS<<<\nCONVERTED PARAM: >>>$(create_cmd_params "$PARAMS")<<<"

PARAMS="id=archiv,keyring=/etc/ceph/ceph.client.archiv.keyring,options='lock_on_read,queue_depth=1024'"
echo -e " ORIGINAL PARAM: >>>$PARAMS<<<\nCONVERTED PARAM: >>>$(create_cmd_params "$PARAMS")<<<"

PARAMS=""
echo -e " ORIGINAL PARAM: >>>$PARAMS<<<\nCONVERTED PARAM: >>>$(create_cmd_params "$PARAMS")<<<"

PARAMS=",keyring=/etc/ceph/ceph.client.archiv.keyring,options='lock_on_read,queue_depth=1024',id=archiv,"
echo -e " ORIGINAL PARAM: >>>$PARAMS<<<\nCONVERTED PARAM: >>>$(create_cmd_params "$PARAMS")<<<"

PARAMS="'keyring'=/etc/ceph/ceph.client.archiv.keyring,options='lock_on_read,queue_depth=1024',id=archiv,"
echo -e " ORIGINAL PARAM: >>>$PARAMS<<<\nCONVERTED PARAM: >>>$(create_cmd_params "$PARAMS")<<<"

PARAMS="--keyring=/etc/ceph/ceph.client.archiv.keyring,options='lock_on_read,queue_depth=1024',id=archiv, # a comment"
echo -e " ORIGINAL PARAM: >>>$PARAMS<<<\nCONVERTED PARAM: >>>$(create_cmd_params "$PARAMS")<<<"

Fixes: https://tracker.ceph.com/issues/36327
Signed-off-by: Marc Schoechlin <ms@256bit.org]>
doc/man/8/rbdmap.rst
src/rbdmap

index ba8001ff83fb4bad20e49113dd74809ab93c4e36..e6980ab7e326cda5407d9c4b0a4845884a14e409 100644 (file)
@@ -46,6 +46,8 @@ This will cause the script to issue an ``rbd map`` command like the following::
     rbd map POOLNAME/IMAGENAME --PARAM1 VAL1 --PARAM2 VAL2 
 
 (See the ``rbd`` manpage for a full list of possible options.)
+For parameters and values which contain commas or equality signs, a simple
+apostrophe can be used to prevent replacing them.
 
 When run as ``rbdmap map``, the script parses the configuration file, and for
 each RBD image specified attempts to first map the image (using the ``rbd map``
@@ -77,11 +79,12 @@ sequence.)
 Examples
 ========
 
-Example ``/etc/ceph/rbdmap`` for two RBD images called "bar1" and "bar2", both
-in pool "foopool"::
+Example ``/etc/ceph/rbdmap`` for three RBD images called "bar1", "bar2" and "bar3", 
+which are in pool "foopool"::
 
     foopool/bar1    id=admin,keyring=/etc/ceph/ceph.client.admin.keyring
     foopool/bar2    id=admin,keyring=/etc/ceph/ceph.client.admin.keyring
+    foopool/bar3    id=admin,keyring=/etc/ceph/ceph.client.admin.keyring,options='lock_on_read,queue_depth=1024'
 
 Each line in the file contains two strings: the image spec and the options to
 be passed to ``rbd map``. These two lines get transformed into the following
@@ -89,12 +92,14 @@ commands::
 
     rbd map foopool/bar1 --id admin --keyring /etc/ceph/ceph.client.admin.keyring
     rbd map foopool/bar2 --id admin --keyring /etc/ceph/ceph.client.admin.keyring
+    rbd map foopool/bar2 --id admin --keyring /etc/ceph/ceph.client.admin.keyring --options lock_on_read,queue_depth=1024
 
 If the images had XFS filesystems on them, the corresponding ``/etc/fstab``
 entries might look like this::
 
     /dev/rbd/foopool/bar1 /mnt/bar1 xfs noauto 0 0
     /dev/rbd/foopool/bar2 /mnt/bar2 xfs noauto 0 0
+    /dev/rbd/foopool/bar3 /mnt/bar3 xfs noauto 0 0
 
 After creating the images and populating the ``/etc/ceph/rbdmap`` file, making
 the images get automatically mapped and mounted at boot is just a matter of
index 2b13517491f2c54331d8d62ea5e3ad7c096e54e4..fa0cf7b821c62e38486a2eb881246c17e68d96d9 100755 (executable)
@@ -1,5 +1,52 @@
 #!/usr/bin/env bash
 
+create_cmd_params() {
+       local PARAMS="$1"
+       local CMDPARAMS=""
+       local STATE="START"
+       for (( i=0; i<${#PARAMS}; i++ )); do
+               CHAR="${PARAMS:$i:1}"
+               case $CHAR in
+                       "#")
+                               break
+                               ;;
+                       "'")
+                               if [ "$STATE" == "INQUOTE" ];then
+                                       STATE="NORMAL"
+                               else
+                                       STATE="INQUOTE"
+                               fi
+                               ;;
+                       "=")
+                               if [ "$STATE" == "INQUOTE" ]; then
+                                       CMDPARAMS="${CMDPARAMS}${CHAR}"
+                               else
+                                       CMDPARAMS="${CMDPARAMS} "
+                               fi
+                               ;;
+                       ",")
+                               if [ "$STATE" == "INQUOTE" ]; then
+                                       CMDPARAMS="${CMDPARAMS}${CHAR}"
+                               elif [ "$STATE" == "START" ]; then
+                                       STATE="NORMAL"
+                                       CMDPARAMS="${CMDPARAMS} --"
+                               else
+                                       CMDPARAMS="${CMDPARAMS} --"
+                               fi
+                               ;;
+                       *)
+                               if [ "$STATE" == "START" ];then
+                                       STATE="NORMAL"
+                                       CMDPARAMS="${CMDPARAMS}--${CHAR}"
+                               else
+                                       CMDPARAMS="${CMDPARAMS}${CHAR}"
+                               fi
+                               ;;
+               esac
+       done
+       echo -n "$CMDPARAMS"
+}
+
 do_map() {
        # Read /etc/rbdtab to create non-existant mapping
        RET=0
@@ -14,16 +61,12 @@ do_map() {
                        DEV=rbd/$DEV
                        ;;
                esac
+
+               CMDPARAMS="$(create_cmd_params "${PARAMS}")"
                logger -p "daemon.debug" -t rbdmap "Mapping '${DEV}'"
                newrbd=""
                MAP_RV=""
-               OIFS=$IFS
-               IFS=','
-               CMDPARAMS=""
-               for PARAM in ${PARAMS[@]}; do
-                       CMDPARAMS="$CMDPARAMS --$(echo $PARAM | tr '=' ' ')"
-               done
-               IFS=$OIFS
+
                if [ -b /dev/rbd/$DEV ]; then
                        MAP_RV="$(readlink -f /dev/rbd/$DEV)"
                else