Path: blob/main/sys/contrib/openzfs/tests/zfs-tests/cmd/badsend.c
48529 views
// SPDX-License-Identifier: CDDL-1.01/*2* CDDL HEADER START3*4* The contents of this file are subject to the terms of the5* Common Development and Distribution License (the "License").6* You may not use this file except in compliance with the License.7*8* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE9* or https://opensource.org/licenses/CDDL-1.0.10* See the License for the specific language governing permissions11* and limitations under the License.12*13* When distributing Covered Code, include this CDDL HEADER in each14* file and include the License file at usr/src/OPENSOLARIS.LICENSE.15* If applicable, add the following below this CDDL HEADER, with the16* fields enclosed by brackets "[]" replaced with your own identifying17* information: Portions Copyright [yyyy] [name of copyright owner]18*19* CDDL HEADER END20*/2122/*23* Portions Copyright 2020 iXsystems, Inc.24*/2526/*27* Test some invalid send operations with libzfs/libzfs_core.28*29* Specifying the to and from snaps in the wrong order should return EXDEV.30* We are checking that the early return doesn't accidentally leave any31* references held, so this test is designed to trigger a panic when asserts32* are verified with the bug present.33*/3435#include <libzfs.h>36#include <libzfs_core.h>3738#include <fcntl.h>39#include <stdlib.h>40#include <string.h>41#include <unistd.h>42#include <sysexits.h>43#include <err.h>4445static void46usage(const char *name)47{48fprintf(stderr, "usage: %s snap0 snap1\n", name);49exit(EX_USAGE);50}5152int53main(int argc, char const * const argv[])54{55sendflags_t flags = { 0 };56libzfs_handle_t *zhdl;57zfs_handle_t *zhp;58const char *fromfull, *tofull, *fsname, *fromsnap, *tosnap, *p;59uint64_t size;60int fd, error;6162if (argc != 3)63usage(argv[0]);6465fromfull = argv[1];66tofull = argv[2];6768p = strchr(fromfull, '@');69if (p == NULL)70usage(argv[0]);71fromsnap = p + 1;7273p = strchr(tofull, '@');74if (p == NULL)75usage(argv[0]);76tosnap = p + 1;7778fsname = strndup(tofull, p - tofull);79if (fsname == NULL) {80perror("strndup");81exit(EXIT_FAILURE);82}83if (strncmp(fsname, fromfull, p - tofull) != 0)84usage(argv[0]);8586fd = open("/dev/null", O_WRONLY);87if (fd == -1)88err(EX_OSERR, "open(\"/dev/null\", O_WRONLY)");8990zhdl = libzfs_init();91if (zhdl == NULL)92errx(EX_OSERR, "libzfs_init(): %s", libzfs_error_init(errno));9394zhp = zfs_open(zhdl, fsname, ZFS_TYPE_FILESYSTEM);95if (zhp == NULL)96err(EX_OSERR, "zfs_open(\"%s\")", fsname);9798/*99* Exercise EXDEV in dmu_send_obj. The error gets translated to100* EZFS_CROSSTARGET in libzfs.101*/102error = zfs_send(zhp, tosnap, fromsnap, &flags, fd, NULL, NULL, NULL);103if (error == 0 || libzfs_errno(zhdl) != EZFS_CROSSTARGET)104errx(EX_OSERR, "zfs_send(\"%s\", \"%s\") should have failed "105"with EZFS_CROSSTARGET, not %d",106tofull, fromfull, libzfs_errno(zhdl));107printf("zfs_send(\"%s\", \"%s\"): %s\n",108tofull, fromfull, libzfs_error_description(zhdl));109110zfs_close(zhp);111112/*113* Exercise EXDEV in dmu_send.114*/115error = lzc_send_resume_redacted(fromfull, tofull, fd, 0, 0, 0, NULL);116if (error != EXDEV)117errx(EX_OSERR, "lzc_send_resume_redacted(\"%s\", \"%s\")"118" should have failed with EXDEV, not %d",119fromfull, tofull, error);120printf("lzc_send_resume_redacted(\"%s\", \"%s\"): %s\n",121fromfull, tofull, strerror(error));122123/*124* Exercise EXDEV in dmu_send_estimate_fast.125*/126error = lzc_send_space_resume_redacted(fromfull, tofull, 0, 0, 0, 0,127NULL, fd, &size);128if (error != EXDEV)129errx(EX_OSERR, "lzc_send_space_resume_redacted(\"%s\", \"%s\")"130" should have failed with EXDEV, not %d",131fromfull, tofull, error);132printf("lzc_send_space_resume_redacted(\"%s\", \"%s\"): %s\n",133fromfull, tofull, strerror(error));134135close(fd);136libzfs_fini(zhdl);137free((void *)fsname);138139return (EXIT_SUCCESS);140}141142143