zfs send -R segfault, anyone else?

James R. Van Artsdalen james-freebsd-current at jrv.org
Thu May 14 22:48:29 UTC 2009


Thomas Backman wrote:
> [root at chaos ~]# zfs send -R -I $OLD tank@$NOW > diff-snap
> [root at chaos ~]# cat diff-snap | zfs recv -Fvd slave
> Segmentation fault: 11 (core dumped)
>
> Same kinda backtrace, but what's up with strcmp()?
> I suppose the issue stems from libzfs, and is not within libc:

Different problem  The SIGSEGV is happening in strcmp because it is
called with strcmp(0,0)
and tries to dereference address -4 (probably another bug itself).

This hack gets around the issue but someone familiar with this needs to
decide the correct action.

The first change is actually unrelated (a sorry attempt at fixing the
previous zfs send bug).

The last change may be unnecessary as that case may never happen unless
the pool can be renamed?

Index: cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
===================================================================
--- cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c       
(revision 190917)
+++ cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c       
(working copy)
@@ -240,6 +240,8 @@
                zfs_prop_t prop = zfs_name_to_prop(propname);
                nvlist_t *propnv;
 
+               if (prop == ZPROP_INVAL)
+                 continue;
                if (!zfs_prop_user(propname) && zfs_prop_readonly(prop))
                        continue;
 
@@ -1126,7 +1128,7 @@
                uint64_t originguid = 0;
                uint64_t stream_originguid = 0;
                uint64_t parent_fromsnap_guid, stream_parent_fromsnap_guid;
-               char *fsname, *stream_fsname;
+               char *fsname, *stream_fsname, *p1, *p2;
 
                nextfselem = nvlist_next_nvpair(local_nv, fselem);
 
@@ -1295,10 +1297,12 @@
                    "parentfromsnap", &stream_parent_fromsnap_guid));
 
                /* check for rename */
+               p1 = strrchr(fsname, '/');
+               p2 = strrchr(stream_fsname, '/');
                if ((stream_parent_fromsnap_guid != 0 &&
                    stream_parent_fromsnap_guid != parent_fromsnap_guid) ||
-                   strcmp(strrchr(fsname, '/'),
-                   strrchr(stream_fsname, '/')) != 0) {
+                   (p1 != NULL && p2 != NULL && strcmp (p1, p2) != 0) ||
+                   ((p1 == NULL) ^ (p2 == NULL))) {
                        nvlist_t *parent;
                        char tryname[ZFS_MAXNAMELEN];
 
@@ -1317,7 +1321,7 @@
                                VERIFY(0 == nvlist_lookup_string(parent,
"name",
                                    &pname));
                                (void) snprintf(tryname, sizeof (tryname),
-                                   "%s%s", pname,
strrchr(stream_fsname, '/'));
+                                               "%s%s", pname, p2 ? p2 :
"");
                        } else {
                                tryname[0] = '\0';
                                if (flags.verbose) {



More information about the freebsd-current mailing list