diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/basic/gfapi/gfapi-copy-file-range.t | 80 | ||||
| -rw-r--r-- | tests/basic/gfapi/glfs-copy-file-range.c | 177 | 
2 files changed, 257 insertions, 0 deletions
diff --git a/tests/basic/gfapi/gfapi-copy-file-range.t b/tests/basic/gfapi/gfapi-copy-file-range.t new file mode 100644 index 00000000000..c24c1433edf --- /dev/null +++ b/tests/basic/gfapi/gfapi-copy-file-range.t @@ -0,0 +1,80 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + +cleanup; + +TEST glusterd + +# for now, a xfs filesystem with reflink support is created. +# In future, better to make changes in MKFS_LOOP so that, +# once can create a xfs filesystem with reflink enabled in +# generic and simple way, instead of doing below steps each +# time. +TEST truncate -s 2G $B0/xfs_image +mkfs.xfs 2>&1 | grep reflink +if [ $? -eq 0 ]; then +    mkfs.xfs -f -i size=512 -m reflink=1 $B0/xfs_image; +else +    mkfs.xfs -f -i size=512 $B0/xfs_image; +fi + +TEST mkdir $B0/bricks +TEST mount -t xfs -o loop $B0/xfs_image $B0/bricks + +# Just a single brick volume. More test cases need to be +# added in future for distribute, replicate, +# distributed replicate and distributed replicated sharded +# volumes. +TEST $CLI volume create $V0 $H0:$B0/bricks/brick1; +EXPECT 'Created' volinfo_field $V0 'Status'; + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 + +TEST dd if=/dev/urandom of=$M0/file bs=1M count=555; + +# check for the existence of the created file +TEST stat  $M0/file; + +# grab the size of the file +SRC_SIZE=$(stat -c %s $M0/file); + +logdir=`gluster --print-logdir` + +# TODO: +# For now, do not call copy-file-range utility. This is because, +# the regression machines are centos-7 based which does not have +# copy_file_range API available. So, instead of this testcase +# causing regression failures, for now, this is just a dummy test +# case. Uncomment the below tests (until volume stop) when there +# is support for copy_file_range in the regression machines. +# + +TEST build_tester $(dirname $0)/glfs-copy-file-range.c -lgfapi + +TEST ./$(dirname $0)/glfs-copy-file-range $H0 $V0 $logdir/gfapi-copy-file-range.log /file /new + +# check whether the destination file is created or not +TEST stat $M0/new + +# check the size of the destination file +DST_SIZE=$(stat -c %s $M0/new); + +# The sizes of the source and destination should be same. +# Atleast it ensures that, copy_file_range API is working +# as expected. Whether the actual cloning happened via reflink +# or a read/write happened is different matter. +TEST [ $SRC_SIZE == $DST_SIZE ]; + +cleanup_tester $(dirname $0)/glfs-copy-file-range + +TEST $CLI volume stop $V0 +TEST $CLI volume delete $V0 + +UMOUNT_LOOP $B0/bricks; + +cleanup; diff --git a/tests/basic/gfapi/glfs-copy-file-range.c b/tests/basic/gfapi/glfs-copy-file-range.c new file mode 100644 index 00000000000..756c38d21ec --- /dev/null +++ b/tests/basic/gfapi/glfs-copy-file-range.c @@ -0,0 +1,177 @@ +/* + Copyright (c) 2018 Red Hat, Inc. <http://www.redhat.com> + This file is part of GlusterFS. + + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <glusterfs/api/glfs.h> +#include <glusterfs/api/glfs-handles.h> +#include <string.h> +#include <time.h> +#include <libgen.h> + +static void +cleanup(glfs_t *fs) +{ +    if (!fs) +        return; +#if 0 +        /* glfs fini path is still racy and crashing the program. Since +         * this program any way has to die, we are not going to call fini +         * in the released versions. i.e. final builds. For all +         * internal testing lets enable this so that glfs_fini code +         * path becomes stable. */ +        glfs_fini (fs); +#endif +} + +int +main(int argc, char **argv) +{ +    glfs_t *fs = NULL; +    int ret = -1; +    char *volname = NULL; +    char *logfilepath = NULL; +    char *path_src = NULL; +    char *path_dst = NULL; +    glfs_fd_t *glfd_in = NULL; +    glfs_fd_t *glfd_out = NULL; +    char *volfile_server = NULL; + +    struct stat stbuf = { +        0, +    }; +    struct stat prestat_dst = { +        0, +    }; +    struct stat poststat_dst = { +        0, +    }; +    size_t len; + +    if (argc < 6) { +        printf("%s <volume> <log file path> <source> <destination>", argv[0]); +        ret = -1; +        goto out; +    } + +    volfile_server = argv[1]; +    volname = argv[2]; +    logfilepath = argv[3]; +    path_src = argv[4]; +    path_dst = argv[5]; + +    if (path_src[0] != '/') { +        fprintf(stderr, "source path %s is not absolute", path_src); +        errno = EINVAL; +        goto out; +    } + +    if (path_dst[0] != '/') { +        fprintf(stderr, "destination path %s is not absolute", path_dst); +        errno = EINVAL; +        goto out; +    } + +    fs = glfs_new(volname); +    if (!fs) { +        ret = -errno; +        fprintf(stderr, "Not able to initialize volume '%s'", volname); +        goto out; +    } + +    ret = glfs_set_volfile_server(fs, "tcp", volfile_server, 24007); +    if (ret < 0) { +        ret = -errno; +        fprintf(stderr, +                "Failed to set the volfile server, " +                "%s", +                strerror(errno)); +        goto out; +    } + +    ret = glfs_set_logging(fs, logfilepath, 7); +    if (ret < 0) { +        ret = -errno; +        fprintf(stderr, +                "Failed to set the log file path, " +                "%s", +                strerror(errno)); +        goto out; +    } + +    ret = glfs_init(fs); +    if (ret < 0) { +        ret = -errno; +        if (errno == ENOENT) { +            fprintf(stderr, "Volume %s does not exist", volname); +        } else { +            fprintf(stderr, +                    "%s: Not able to fetch " +                    "volfile from glusterd", +                    volname); +        } +        goto out; +    } + +    glfd_in = glfs_open(fs, path_src, O_RDONLY | O_NONBLOCK); +    if (!glfd_in) { +        ret = -errno; +        goto out; +    } else { +        printf("OPEN_SRC: opening %s is success\n", path_src); +    } + +    glfd_out = glfs_creat(fs, path_dst, O_RDWR, 0644); +    if (!glfd_out) { +        fprintf(stderr, +                "FAILED_DST_OPEN: failed to " +                "open (create) %s (%s)\n", +                path_dst, strerror(errno)); +        ret = -errno; +        goto out; +    } else { +        printf("OPEN_DST: opening %s is success\n", path_dst); +    } + +    ret = glfs_fstat(glfd_in, &stbuf); +    if (ret < 0) { +        ret = -errno; +        goto out; +    } else { +        printf("FSTAT_SRC: fstat on %s is success\n", path_dst); +    } + +    len = stbuf.st_size; + +    do { +        ret = glfs_copy_file_range(glfd_in, NULL, glfd_out, NULL, len, 0, +                                   &stbuf, &prestat_dst, &poststat_dst); +        if (ret == -1) { +            fprintf(stderr, "copy_file_range failed with %s\n", +                    strerror(errno)); +            ret = -errno; +            break; +        } else { +            printf("copy_file_range successful\n"); +            len -= ret; +        } +    } while (len > 0); + +out: +    if (glfd_in) +        glfs_close(glfd_in); +    if (glfd_out) +        glfs_close(glfd_out); + +    cleanup(fs); + +    return ret; +}  | 
