Illumos #1949, #1953
[zfs.git] / lib / libzfs / libzfs_sendrecv.c
index 87ffd12..bc62373 100644 (file)
@@ -21,6 +21,8 @@
 
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
+ * All rights reserved
  */
 
 #include <assert.h>
 #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>
 
@@ -45,6 +52,7 @@
 #include "libzfs_impl.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 *);
@@ -711,7 +719,7 @@ send_iterate_fs(zfs_handle_t *zhp, void *arg)
        sd->parent_fromsnap_guid = 0;
        VERIFY(0 == nvlist_alloc(&sd->parent_snaps, NV_UNIQUE_NAME, 0));
        VERIFY(0 == nvlist_alloc(&sd->snapprops, NV_UNIQUE_NAME, 0));
-       (void) zfs_iter_snapshots(zhp, send_iterate_snap, sd);
+       (void) zfs_iter_snapshots(zhp, B_FALSE, send_iterate_snap, sd);
        VERIFY(0 == nvlist_add_nvlist(nvfs, "snaps", sd->parent_snaps));
        VERIFY(0 == nvlist_add_nvlist(nvfs, "snapprops", sd->snapprops));
        nvlist_free(sd->parent_snaps);
@@ -837,7 +845,7 @@ zfs_iter_snapshots_sorted(zfs_handle_t *zhp, zfs_iter_f callback, void *data)
        avl_create(&avl, zfs_snapshot_compare,
            sizeof (zfs_node_t), offsetof(zfs_node_t, zn_avlnode));
 
-       ret = zfs_iter_snapshots(zhp, zfs_sort_snaps, &avl);
+       ret = zfs_iter_snapshots(zhp, B_FALSE, zfs_sort_snaps, &avl);
 
        for (node = avl_first(&avl); node != NULL; node = AVL_NEXT(&avl, node))
                ret |= callback(node->zn_handle, data);
@@ -1295,7 +1303,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));
@@ -2608,6 +2616,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 {
                /*
@@ -2813,6 +2827,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,