/* Copyright (c) 2018 Red Hat, Inc. 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 #include #include #include #include #include #include #include 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 glfs_stat stat_src = { 0, }; struct glfs_stat prestat_dst = { 0, }; struct glfs_stat poststat_dst = { 0, }; size_t len; if (argc < 6) { printf("%s ", 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, &stat_src, &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; }