Print this page
3699 zfs hold or release of a non-existent snapshot does not output error

@@ -22,10 +22,11 @@
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2012 by Delphix. All rights reserved.
  * Copyright (c) 2012 DEY Storage Systems, Inc.  All rights reserved.
  * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2013 Martin Matuska. All rights reserved.
  */
 
 #include <ctype.h>
 #include <errno.h>
 #include <libintl.h>

@@ -4114,10 +4115,21 @@
         ha.nvl = fnvlist_alloc();
         ha.snapname = snapname;
         ha.tag = tag;
         ha.recursive = recursive;
         (void) zfs_hold_one(zfs_handle_dup(zhp), &ha);
+
+        if (nvlist_next_nvpair(ha.nvl, NULL) == NULL) {
+                fnvlist_free(ha.nvl);
+                ret = ENOENT;
+                (void) snprintf(errbuf, sizeof (errbuf),
+                    dgettext(TEXT_DOMAIN, "cannot hold snapshot '%s@%s'"),
+                    zhp->zfs_name, snapname);
+                (void) zfs_standard_error(hdl, ret, errbuf);
+                return (ret);
+        }
+
         ret = lzc_hold(ha.nvl, cleanup_fd, &errors);
         fnvlist_free(ha.nvl);
 
         if (ret == 0)
                 return (0);

@@ -4215,26 +4227,37 @@
         int ret;
         struct holdarg ha;
         nvlist_t *errors;
         nvpair_t *elem;
         libzfs_handle_t *hdl = zhp->zfs_hdl;
+        char errbuf[1024];
 
         ha.nvl = fnvlist_alloc();
         ha.snapname = snapname;
         ha.tag = tag;
         ha.recursive = recursive;
         (void) zfs_release_one(zfs_handle_dup(zhp), &ha);
+
+        if (nvlist_next_nvpair(ha.nvl, NULL) == NULL) {
+                fnvlist_free(ha.nvl);
+                ret = ENOENT;
+                (void) snprintf(errbuf, sizeof (errbuf),
+                    dgettext(TEXT_DOMAIN,
+                    "cannot release hold from snapshot '%s@%s'"),
+                    zhp->zfs_name, snapname);
+                (void) zfs_standard_error(hdl, ret, errbuf);
+                return (ret);
+        }
+
         ret = lzc_release(ha.nvl, &errors);
         fnvlist_free(ha.nvl);
 
         if (ret == 0)
                 return (0);
 
         if (nvlist_next_nvpair(errors, NULL) == NULL) {
                 /* no hold-specific errors */
-                char errbuf[1024];
-
                 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
                     "cannot release"));
                 switch (errno) {
                 case ENOTSUP:
                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,

@@ -4247,12 +4270,10 @@
         }
 
         for (elem = nvlist_next_nvpair(errors, NULL);
             elem != NULL;
             elem = nvlist_next_nvpair(errors, elem)) {
-                char errbuf[1024];
-
                 (void) snprintf(errbuf, sizeof (errbuf),
                     dgettext(TEXT_DOMAIN,
                     "cannot release hold from snapshot '%s'"),
                     nvpair_name(elem));
                 switch (fnvpair_value_int32(elem)) {