Currently lzc_receive() requires that its 'snapname' argument is a snapshot name
(contains '@').  zfs receive allows to specify just a dataset name and would try
to deduce the snapshot name from the stream.  I propose to allow lzc_receive()
to do the same.  That is quite easy to achieve, it requires only a small amount
of logic, it does not require any additional system calls or any additional data
from the stream.
Below is a proof of concept patch that seems to work.

--- lib/libzfs_core/common/libzfs_core.c
+++ lib/libzfs_core/common/libzfs_core.c
@@ -721,9 +721,8 @@ lzc_receive
        /* zc_name is name of containing filesystem */
        (void) strlcpy(zc.zc_name, snapname, sizeof (zc.zc_name));
        atp = strchr(zc.zc_name, '@');
-       if (atp == NULL)
-               return (EINVAL);
-       *atp = '\0';
+       if (atp != NULL)
+               *atp = '\0';

        /* if the fs does not exist, try its parent. */
        if (!lzc_exists(zc.zc_name)) {
@@ -734,9 +733,6 @@ lzc_receive

        }

-       /* zc_value is full name of the snapshot to create */
-       (void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value));
-
        if (props != NULL) {
                /* zc_nvlist_src is props to set */
                packed = fnvlist_pack(props, &size);
@@ -754,6 +750,20 @@ lzc_receive
                goto out;
        zc.zc_begin_record = drr.drr_u.drr_begin;

+       /* zc_value is full name of the snapshot to create */
+       (void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value));
+
+       /* if snapshot name is not provided try to take it from the stream */
+       atp = strchr(zc.zc_value, '@');
+       if (atp == NULL) {
+               atp = strchr(zc.zc_begin_record.drr_toname, '@');
+               if (atp == NULL)
+                       return (EINVAL);
+               if (strlen(zc.zc_value) + strlen(atp) >= sizeof(zc.zc_value))
+                       return (ENAMETOOLONG);
+               strcat(zc.zc_value, atp);
+       }
+
        /* zc_cookie is fd to read from */
        zc.zc_cookie = fd;


-- 
Andriy Gapon
_______________________________________________
developer mailing list
[email protected]
http://lists.open-zfs.org/mailman/listinfo/developer

Reply via email to