diff options
| author | Pranith Kumar K <pkarampu@redhat.com> | 2019-05-06 15:27:44 +0530 | 
|---|---|---|
| committer | Pranith Kumar Karampuri <pkarampu@redhat.com> | 2019-05-24 03:45:39 +0000 | 
| commit | 0b83b8af60916dcdb850f15da7e7b406809dd1d5 (patch) | |
| tree | 7907f1ebb43884e7b2b7720837c4cca9b8876b40 /tests | |
| parent | 2a31a7130dd866eed5848caaf9588e6461aca836 (diff) | |
tests: Test openfd heal doesn't truncate files
fixes bz#1706603
Change-Id: I0bfd30f787f157b7a54f71088f767ccfd7621208
Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/basic/ec/gfapi-ec-open-truncate.c | 170 | ||||
| -rw-r--r-- | tests/basic/ec/gfapi-ec-open-truncate.t | 48 | 
2 files changed, 218 insertions, 0 deletions
diff --git a/tests/basic/ec/gfapi-ec-open-truncate.c b/tests/basic/ec/gfapi-ec-open-truncate.c new file mode 100644 index 00000000000..22f17f436b6 --- /dev/null +++ b/tests/basic/ec/gfapi-ec-open-truncate.c @@ -0,0 +1,170 @@ +#include <fcntl.h> +#include <unistd.h> +#include <time.h> +#include <limits.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <glusterfs/api/glfs.h> +#include <glusterfs/api/glfs-handles.h> + +#define LOG_ERR(msg)                                                           \ +    do {                                                                       \ +        fprintf(stderr, "%s : Error (%s)\n", msg, strerror(errno));            \ +    } while (0) + +int +fill_iov(struct iovec *iov, char fillchar, int count) +{ +    int ret = -1; + +    iov->iov_base = calloc(count + 1, sizeof(fillchar)); +    if (iov->iov_base == NULL) { +        return ret; +    } else { +        iov->iov_len = count; +        ret = 0; +    } +    memset(iov->iov_base, fillchar, count); +    memset(iov->iov_base + count, '\0', 1); + +    return ret; +} + +glfs_t * +init_glfs(const char *hostname, const char *volname, const char *logfile) +{ +    int ret = -1; +    glfs_t *fs = NULL; + +    fs = glfs_new(volname); +    if (!fs) { +        LOG_ERR("glfs_new failed"); +        return NULL; +    } + +    ret = glfs_set_volfile_server(fs, "tcp", hostname, 24007); +    if (ret < 0) { +        LOG_ERR("glfs_set_volfile_server failed"); +        goto out; +    } + +    ret = glfs_set_logging(fs, logfile, 7); +    if (ret < 0) { +        LOG_ERR("glfs_set_logging failed"); +        goto out; +    } + +    ret = glfs_init(fs); +    if (ret < 0) { +        LOG_ERR("glfs_init failed"); +        goto out; +    } + +    ret = 0; +out: +    if (ret) { +        glfs_fini(fs); +        fs = NULL; +    } + +    return fs; +} + +int +main(int argc, char *argv[]) +{ +    char *hostname = NULL; +    char *volname = NULL; +    char *logfile = NULL; +    glfs_t *fs = NULL; +    glfs_fd_t *glfd = NULL; +    int ret = 0; +    int i = 0; +    int count = 200; +    struct iovec iov = {0}; +    int flags = O_RDWR; +    int bricksup = 0; +    int fdopen = 0; + +    if (argc != 4) { +        fprintf(stderr, "Invalid argument\n"); +        exit(1); +    } + +    hostname = argv[1]; +    volname = argv[2]; +    logfile = argv[3]; + +    fs = init_glfs(hostname, volname, logfile); +    if (fs == NULL) { +        LOG_ERR("init_glfs failed"); +        return -1; +    } + +    /* Brick is down and we are opening a file to trigger fd heal. */ +    /* Bypass Write-behind */ +    glfd = glfs_open(fs, "a", O_WRONLY | O_TRUNC | O_SYNC); +    if (glfd == NULL) { +        LOG_ERR("glfs_open_truncate failed"); +        exit(1); +    } +    system("gluster --mode=script volume start patchy force"); +    /*CHILD_UP_TIMEOUT is 20 seconds*/ +    for (i = 0; i < 20; i++) { +        ret = system( +            "[ $(gluster --mode=script volume status patchy | " +            "grep \" Y \" | awk '{print $(NF-1)}' | wc -l) == 3 ]"); +        if (WIFEXITED(ret) && WEXITSTATUS(ret)) { +            printf("Ret value of system: %d\n, ifexited: %d, exitstatus: %d", +                   ret, WIFEXITED(ret), WEXITSTATUS(ret)); +            sleep(1); +            continue; +        } +        printf("Number of loops: %d\n", i); +        bricksup = 1; +        break; +    } +    if (!bricksup) { +        system("gluster --mode=script volume status patchy"); +        LOG_ERR("Bricks didn't come up\n"); +        exit(1); +    } + +    /*Not sure how to check that the child-up reached EC, so sleep 3 for now*/ +    sleep(3); +    ret = fill_iov(&iov, 'a', 200); +    if (ret) { +        LOG_ERR("failed to create iov"); +        exit(1); +    } + +    /*write will trigger re-open*/ +    ret = glfs_pwritev(glfd, &iov, 1, 0, flags); +    if (ret < 0) { +        LOG_ERR("glfs_test_function failed"); +        exit(1); +    } +    /*Check reopen happened by checking for open-fds on the brick*/ +    for (i = 0; i < 20; i++) { +        ret = system( +            "[ $(for i in $(pgrep glusterfsd); do ls -l /proc/$i/fd | grep " +            "\"[.]glusterfs\" | grep -v health_check; done | wc -l) == 3 ]"); +        if (WIFEXITED(ret) && WEXITSTATUS(ret)) { +            printf("Ret value of system: %d\n, ifexited: %d, exitstatus: %d", +                   ret, WIFEXITED(ret), WEXITSTATUS(ret)); +            sleep(1); +            continue; +        } +        fdopen = 1; +        break; +    } + +    if (!fdopen) { +        LOG_ERR("fd reopen didn't succeed"); +        exit(1); +    } + +    return 0; +} diff --git a/tests/basic/ec/gfapi-ec-open-truncate.t b/tests/basic/ec/gfapi-ec-open-truncate.t new file mode 100644 index 00000000000..e22562c6ea3 --- /dev/null +++ b/tests/basic/ec/gfapi-ec-open-truncate.t @@ -0,0 +1,48 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + +#This .t tests the functionality of open-fd-heal when opened with O_TRUNC. +#If re-open is not done with O_TRUNC then the test will pass. + +cleanup + +TEST glusterd + +TEST $CLI volume create $V0 disperse 3 ${H0}:$B0/brick{1,2,3} +EXPECT 'Created' volinfo_field $V0 'Status' +#Disable heals to prevent any chance of heals masking the problem +TEST $CLI volume set $V0 disperse.background-heals 0 +TEST $CLI volume set $V0 disperse.heal-wait-qlength 0 +TEST $CLI volume set $V0 performance.write-behind off + +#We need truncate fop to go through before pre-op completes for the write-fop +#which triggers open-fd heal. Otherwise truncate won't be allowed on 'bad' brick +TEST $CLI volume set $V0 delay-gen posix +TEST $CLI volume set $V0 delay-gen.enable fxattrop +TEST $CLI volume set $V0 delay-gen.delay-percentage 100 +TEST $CLI volume set $V0 delay-gen.delay-duration 1000000 + +TEST $CLI volume heal $V0 disable + +TEST $CLI volume start $V0 +TEST $CLI volume profile $V0 start +EXPECT 'Started' volinfo_field $V0 'Status' +TEST glusterfs --entry-timeout=0 --attribute-timeout=0 -s $H0 --volfile-id $V0 $M0 +EXPECT_WITHIN $CHILD_UP_TIMEOUT "3" ec_child_up_count $V0 0 +TEST touch $M0/a +EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M0 + +TEST kill_brick $V0 $H0 $B0/brick1 +logdir=`gluster --print-logdir` + +TEST build_tester $(dirname $0)/gfapi-ec-open-truncate.c -lgfapi + +TEST $CLI volume profile $V0 info clear +TEST ./$(dirname $0)/gfapi-ec-open-truncate ${H0} $V0 $logdir/gfapi-ec-open-truncate.log + +EXPECT "^2$" echo $($CLI volume profile $V0 info incremental | grep -i truncate | wc -l) +cleanup_tester $(dirname $0)/gfapi-ec-open-truncate + +cleanup  | 
