Illumos #734: Use taskq_dispatch_ent() interface
[zfs.git] / lib / libzfs / libzfs_sendrecv.c
index 3093ab9..7a95de0 100644 (file)
 #include <stddef.h>
 #include <fcntl.h>
 #include <sys/mount.h>
+#include <sys/mntent.h>
+#include <sys/mnttab.h>
+#include <sys/avl.h>
+#include <sys/debug.h>
+#include <stddef.h>
 #include <pthread.h>
 #include <umem.h>
 
@@ -43,9 +48,9 @@
 #include "zfs_prop.h"
 #include "zfs_fletcher.h"
 #include "libzfs_impl.h"
-#include <sha2.h>
 #include <sys/zio_checksum.h>
 #include <sys/ddt.h>
+#include <sys/socket.h>
 
 /* in libzfs_dataset.c */
 extern void zfs_setprop_error(libzfs_handle_t *, zfs_prop_t, int, char *);
@@ -53,7 +58,7 @@ extern void zfs_setprop_error(libzfs_handle_t *, zfs_prop_t, int, char *);
 static int zfs_receive_impl(libzfs_handle_t *, const char *, recvflags_t,
     int, const char *, nvlist_t *, avl_tree_t *, char **, int, uint64_t *);
 
-static const zio_cksum_t zero_cksum = { 0 };
+static const zio_cksum_t zero_cksum = { { 0 } };
 
 typedef struct dedup_arg {
        int     inputfd;
@@ -336,12 +341,11 @@ cksummer(void *arg)
                        if (ZIO_CHECKSUM_EQUAL(drrw->drr_key.ddk_cksum,
                            zero_cksum) ||
                            !DRR_IS_DEDUP_CAPABLE(drrw->drr_checksumflags)) {
-                               SHA256_CTX      ctx;
-                               zio_cksum_t     tmpsha256;
+                               zio_cksum_t tmpsha256;
+
+                               zio_checksum_SHA256(buf,
+                                   drrw->drr_length, &tmpsha256);
 
-                               SHA256Init(&ctx);
-                               SHA256Update(&ctx, buf, drrw->drr_length);
-                               SHA256Final(&tmpsha256, &ctx);
                                drrw->drr_key.ddk_cksum.zc_word[0] =
                                    BE_64(tmpsha256.zc_word[0]);
                                drrw->drr_key.ddk_cksum.zc_word[1] =
@@ -882,7 +886,7 @@ static int
 dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, uint64_t fromsnap_obj,
     boolean_t fromorigin, int outfd, nvlist_t *debugnv)
 {
-       zfs_cmd_t zc = { 0 };
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
        libzfs_handle_t *hdl = zhp->zfs_hdl;
        nvlist_t *thisdbg;
 
@@ -1096,7 +1100,7 @@ dump_filesystem(zfs_handle_t *zhp, void *arg)
        int rv = 0;
        send_dump_data_t *sdd = arg;
        boolean_t missingfrom = B_FALSE;
-       zfs_cmd_t zc = { 0 };
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
 
        (void) snprintf(zc.zc_name, sizeof (zc.zc_name), "%s@%s",
            zhp->zfs_name, sdd->tosnap);
@@ -1297,7 +1301,7 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
        if (flags.dedup) {
                featureflags |= (DMU_BACKUP_FEATURE_DEDUP |
                    DMU_BACKUP_FEATURE_DEDUPPROPS);
-               if (err = pipe(pipefd)) {
+               if ((err = socketpair(AF_UNIX, SOCK_STREAM, 0, pipefd))) {
                        zfs_error_aux(zhp->zfs_hdl, strerror(errno));
                        return (zfs_error(zhp->zfs_hdl, EZFS_PIPEFAILED,
                            errbuf));
@@ -1305,7 +1309,7 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
                dda.outputfd = outfd;
                dda.inputfd = pipefd[1];
                dda.dedup_hdl = zhp->zfs_hdl;
-               if (err = pthread_create(&tid, NULL, cksummer, &dda)) {
+               if ((err = pthread_create(&tid, NULL, cksummer, &dda))) {
                        (void) close(pipefd[0]);
                        (void) close(pipefd[1]);
                        zfs_error_aux(zhp->zfs_hdl, strerror(errno));
@@ -1318,7 +1322,7 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
                dmu_replay_record_t drr = { 0 };
                char *packbuf = NULL;
                size_t buflen = 0;
-               zio_cksum_t zc = { 0 };
+               zio_cksum_t zc = { { 0 } };
 
                if (flags.replicate || flags.props) {
                        nvlist_t *hdrnv;
@@ -1413,7 +1417,7 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
                ++holdseq;
                (void) snprintf(sdd.holdtag, sizeof (sdd.holdtag),
                    ".send-%d-%llu", getpid(), (u_longlong_t)holdseq);
-               sdd.cleanup_fd = open(ZFS_DEV, O_RDWR|O_EXCL);
+               sdd.cleanup_fd = open(ZFS_DEV, O_RDWR);
                if (sdd.cleanup_fd < 0) {
                        err = errno;
                        goto stderr_out;
@@ -1530,7 +1534,7 @@ recv_rename(libzfs_handle_t *hdl, const char *name, const char *tryname,
     int baselen, char *newname, recvflags_t flags)
 {
        static int seq;
-       zfs_cmd_t zc = { 0 };
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
        int err;
        prop_changelist_t *clp;
        zfs_handle_t *zhp;
@@ -1571,7 +1575,7 @@ recv_rename(libzfs_handle_t *hdl, const char *name, const char *tryname,
 
                (void) strncpy(newname, name, baselen);
                (void) snprintf(newname+baselen, ZFS_MAXNAMELEN-baselen,
-                   "recv-%u-%u", getpid(), seq);
+                   "recv-%ld-%u", (long) getpid(), seq);
                (void) strlcpy(zc.zc_value, newname, sizeof (zc.zc_value));
 
                if (flags.verbose) {
@@ -1603,7 +1607,7 @@ static int
 recv_destroy(libzfs_handle_t *hdl, const char *name, int baselen,
     char *newname, recvflags_t flags)
 {
-       zfs_cmd_t zc = { 0 };
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
        int err = 0;
        prop_changelist_t *clp;
        zfs_handle_t *zhp;
@@ -1831,7 +1835,7 @@ again:
                            stream_originguid, originguid)) {
                        case 1: {
                                /* promote it! */
-                               zfs_cmd_t zc = { 0 };
+                               zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
                                nvlist_t *origin_nvfs;
                                char *origin_fsname;
 
@@ -1903,7 +1907,7 @@ again:
                        if (0 == nvlist_lookup_nvlist(stream_nvfs, "snapprops",
                            &props) && 0 == nvlist_lookup_nvlist(props,
                            stream_snapname, &props)) {
-                               zfs_cmd_t zc = { 0 };
+                               zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
 
                                zc.zc_cookie = B_TRUE; /* received */
                                (void) snprintf(zc.zc_name, sizeof (zc.zc_name),
@@ -2334,7 +2338,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
     nvlist_t *stream_nv, avl_tree_t *stream_avl, char **top_zfs, int cleanup_fd,
     uint64_t *action_handlep)
 {
-       zfs_cmd_t zc = { 0 };
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
        time_t begin_time;
        int ioctl_err, ioctl_errno, err;
        char *cp;
@@ -2467,7 +2471,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
         */
        (void) strcpy(zc.zc_top_ds, tosnap);
        (void) strcpy(zc.zc_value, tosnap);
-       (void) strncat(zc.zc_value, chopprefix, sizeof (zc.zc_value));
+       (void) strlcat(zc.zc_value, chopprefix, sizeof (zc.zc_value));
        free(cp);
        if (!zfs_name_valid(zc.zc_value, ZFS_TYPE_SNAPSHOT)) {
                zcmd_free_nvlists(&zc);
@@ -2490,7 +2494,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
                        (void) printf("found clone origin %s\n", zc.zc_string);
        }
 
-       stream_wantsnewfs = (drrb->drr_fromguid == NULL ||
+       stream_wantsnewfs = (drrb->drr_fromguid == 0 ||
            (drrb->drr_flags & DRR_FLAG_CLONE));
 
        if (stream_wantsnewfs) {
@@ -2610,6 +2614,12 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
                                return (-1);
                        }
                }
+               if (!flags.dryrun && zhp->zfs_type == ZFS_TYPE_VOLUME &&
+                   zvol_remove_link(hdl, zhp->zfs_name) != 0) {
+                       zfs_close(zhp);
+                       zcmd_free_nvlists(&zc);
+                       return (-1);
+               }
                zfs_close(zhp);
        } else {
                /*
@@ -2702,7 +2712,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
        zcmd_free_nvlists(&zc);
 
        if (err == 0 && snapprops_nvlist) {
-               zfs_cmd_t zc2 = { 0 };
+               zfs_cmd_t zc2 = { "\0", "\0", "\0", "\0", 0 };
 
                (void) strcpy(zc2.zc_name, zc.zc_value);
                zc2.zc_cookie = B_TRUE; /* received */
@@ -2815,6 +2825,10 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
                if (h != NULL) {
                        if (h->zfs_type == ZFS_TYPE_VOLUME) {
                                *cp = '@';
+                               err = zvol_create_link(hdl, h->zfs_name);
+                               if (err == 0 && ioctl_err == 0)
+                                       err = zvol_create_link(hdl,
+                                           zc.zc_value);
                        } else if (newfs || stream_avl) {
                                /*
                                 * Track the first/top of hierarchy fs,
@@ -2877,7 +2891,7 @@ zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap, recvflags_t flags,
        dmu_replay_record_t drr, drr_noswap;
        struct drr_begin *drrb = &drr.drr_u.drr_begin;
        char errbuf[1024];
-       zio_cksum_t zcksum = { 0 };
+       zio_cksum_t zcksum = { { 0 } };
        uint64_t featureflags;
        int hdrtype;
 
@@ -2988,7 +3002,7 @@ zfs_receive(libzfs_handle_t *hdl, const char *tosnap, recvflags_t flags,
        int cleanup_fd;
        uint64_t action_handle = 0;
 
-       cleanup_fd = open(ZFS_DEV, O_RDWR|O_EXCL);
+       cleanup_fd = open(ZFS_DEV, O_RDWR);
        VERIFY(cleanup_fd >= 0);
 
        err = zfs_receive_impl(hdl, tosnap, flags, infd, NULL, NULL,