diff options
| -rwxr-xr-x | tests/bugs/bug-921408.t | 89 | ||||
| -rw-r--r-- | tests/dht.rc | 8 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/dht-layout.c | 40 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/dht-selfheal.c | 68 | 
4 files changed, 178 insertions, 27 deletions
diff --git a/tests/bugs/bug-921408.t b/tests/bugs/bug-921408.t new file mode 100755 index 00000000000..ef2b4fb21cd --- /dev/null +++ b/tests/bugs/bug-921408.t @@ -0,0 +1,89 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../fileio.rc +. $(dirname $0)/../dht.rc + +cleanup; +wait_check_status () +{ +        n=0 +        while [ $n -lt $1 ] +        do +                ret=$(rebalance_completed) +                if [ $ret == "0" ] +                then +                        return 0; +                else +                        sleep 1 +                        n=`expr $n + 1`; +                fi +       done +       return 1; +} + +addbr_rebal_till_layout_change() +{ +        val=1 +        l=$1 +        i=1 +        while [ $i -lt 5 ] +        do +                $CLI volume add-brick $V0 $H0:$B0/${V0}$l &>/dev/null +                $CLI volume rebalance $V0 fix-layout start &>/dev/null +                wait_check_status 15 +                if [ $? -eq 1 ] +                then +                        break +                fi +                NEW_LAYOUT=`get_layout $B0/${V0}0` +                if [ $OLD_LAYOUT == $NEW_LAYOUT ] +                then +                        i=`expr $i + 1`; +                        l=`expr $l + 1`; +                else +                        val=0 +                        break +                fi +        done +        return $val +} +TEST glusterd +TEST pidof glusterd + +TEST $CLI volume create $V0 $H0:$B0/${V0}0 +TEST $CLI volume set $V0 subvols-per-directory 1 +TEST $CLI volume start $V0 + +TEST glusterfs -s $H0 --volfile-id $V0 $M0; + +TEST mkdir $M0/test +TEST touch $M0/test/test + +fd=`fd_available` +TEST fd_open $fd "rw" $M0/test/test + +OLD_LAYOUT=`get_layout $B0/${V0}0` + +addbr_rebal_till_layout_change 1 + +TEST [ $? -eq 0 ] + +for i in $(seq 1 1000) +do +	ls -l $M0/ >/dev/null +	ret=$? +	if [ $ret != 0 ] +	then +		break +	fi +done + +TEST [ $ret == 0 ]; +TEST fd_close $fd; + +TEST umount $M0 +TEST $CLI volume stop $V0 +TEST $CLI volume delete $V0 + +cleanup diff --git a/tests/dht.rc b/tests/dht.rc index ee92a47bd62..663ea543173 100644 --- a/tests/dht.rc +++ b/tests/dht.rc @@ -2,13 +2,7 @@  function get_layout()  { -        layout=`getfattr -n trusted.glusterfs.dht -e hex $1 2>&1|grep dht |cut -d = -f2` -        if [ $? -eq 1] -        then -                return -1 -        else -                return $layout -        fi +        getfattr -n trusted.glusterfs.dht -e hex $1 2>&1|grep dht |cut -d = -f2  } diff --git a/xlators/cluster/dht/src/dht-layout.c b/xlators/cluster/dht/src/dht-layout.c index 34a7475bdc3..3331db5c518 100644 --- a/xlators/cluster/dht/src/dht-layout.c +++ b/xlators/cluster/dht/src/dht-layout.c @@ -365,7 +365,7 @@ dht_layout_merge (xlator_t *this, dht_layout_t *layout, xlator_t *subvol,          }          if (ret != 0) { -                layout->list[i].err = -1; +                layout->list[i].err = 0;                  gf_log (this->name, GF_LOG_TRACE,                          "missing disk layout on %s. err = %d",                          subvol->name, err); @@ -529,23 +529,29 @@ dht_layout_anomalies (xlator_t *this, loc_t *loc, dht_layout_t *layout,          prev_stop = last_stop;          for (i = 0; i < layout->cnt; i++) { -                if (layout->list[i].err) { -                        switch (layout->list[i].err) { -                        case -1: -                        case ENOENT: -                                missing++; -                                break; -                        case ENOTCONN: -                                down++; -                                break; -                        case ENOSPC: -                                no_space++; -                                break; -                        default: -                                misc++; +                switch (layout->list[i].err) { +                case -1: +                case ENOENT: +                        missing++; +                        break; +                case ENOTCONN: +                        down++; +                        break; +                case ENOSPC: +                        no_space++; +                        break; +                case 0: +                        /* if err == 0 and start == stop, then it is a non misc++; +                         * participating subvolume(spread-cnt). Then, do not +                         * check for anomalies. If start != stop, then treat it +                         * as misc err */ +                        if (layout->list[i].start == layout->list[i].stop) { +                                continue;                          } -                        continue; -                } +                        break; +                default: +                        misc++; +                 }                  is_virgin = 0; diff --git a/xlators/cluster/dht/src/dht-selfheal.c b/xlators/cluster/dht/src/dht-selfheal.c index df7a475e035..2d0b37e6974 100644 --- a/xlators/cluster/dht/src/dht-selfheal.c +++ b/xlators/cluster/dht/src/dht-selfheal.c @@ -35,6 +35,7 @@                          layout->list[cnt].stop  = 0;                    \                  }                                                       \          } while (0) +  static uint32_t  dht_overlap_calc (dht_layout_t *old, int o, dht_layout_t *new, int n)  { @@ -237,6 +238,67 @@ out:  }  int +dht_selfheal_dir_xattr (call_frame_t *frame, loc_t *loc, dht_layout_t *layout) +{ +        dht_local_t *local = NULL; +        int          missing_xattr = 0; +        int          i = 0; +        xlator_t    *this = NULL; +        dht_conf_t   *conf = NULL; +        dht_layout_t *dummy = NULL; + +        local = frame->local; +        this = frame->this; +        conf = this->private; + +        for (i = 0; i < layout->cnt; i++) { +                if (layout->list[i].err != -1 || !layout->list[i].stop) { +                        /* err != -1 would mean xattr present on the directory +                         * or the directory is non existent. +                         * !layout->list[i].stop would mean layout absent +                         */ + +                        continue; +                } +                missing_xattr++; +        } + +        gf_log (this->name, GF_LOG_TRACE, +                "%d subvolumes missing xattr for %s", +                missing_xattr, loc->path); + +        if (missing_xattr == 0) { +                dht_selfheal_dir_finish (frame, this, 0); +                return 0; +        } + +        local->call_cnt = missing_xattr; + +        for (i = 0; i < layout->cnt; i++) { +                if (layout->list[i].err != -1 || !layout->list[i].stop) +                        continue; + +                dht_selfheal_dir_xattr_persubvol (frame, loc, layout, i, NULL); + +                if (--missing_xattr == 0) +                        break; +        } +        dummy = dht_layout_new (this, 1); +        if (!dummy) +                goto out; +        for (i = 0; i < conf->subvolume_cnt; i++) { +                if (_gf_false == +                    dht_is_subvol_in_layout (layout, conf->subvolumes[i])) { +                        dht_selfheal_dir_xattr_persubvol (frame, loc, dummy, 0, +                                                          conf->subvolumes[i]); +                } +        } +        dht_layout_unref (this, dummy); +out: +        return 0; +} + +int  dht_selfheal_dir_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                                int op_ret, int op_errno, struct iatt *statpre,                                struct iatt *statpost, dict_t *xdata) @@ -251,7 +313,7 @@ dht_selfheal_dir_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          this_call_cnt = dht_frame_return (frame);          if (is_last_call (this_call_cnt)) { -                dht_fix_dir_xattr (frame, &local->loc, layout); +                dht_selfheal_dir_xattr (frame, &local->loc, layout);          }          return 0; @@ -276,7 +338,7 @@ dht_selfheal_dir_setattr (call_frame_t *frame, loc_t *loc, struct iatt *stbuf,          }          if (missing_attr == 0) { -                dht_fix_dir_xattr (frame, loc, layout); +                dht_selfheal_dir_xattr (frame, loc, layout);                  return 0;          } @@ -780,7 +842,7 @@ dht_selfheal_new_directory (call_frame_t *frame,          dht_layout_sort_volname (layout);          dht_selfheal_layout_new_directory (frame, &local->loc, layout); -        dht_fix_dir_xattr (frame, &local->loc, layout); +        dht_selfheal_dir_xattr (frame, &local->loc, layout);          return 0;  }  | 
