Add linux idmap support
[zfs.git] / lib / libzfs / libzfs_pool.c
index eac5a4c..42f3038 100644 (file)
@@ -178,6 +178,8 @@ char *
 zpool_state_to_name(vdev_state_t state, vdev_aux_t aux)
 {
        switch (state) {
+       default:
+               break;
        case VDEV_STATE_CLOSED:
        case VDEV_STATE_OFFLINE:
                return (gettext("OFFLINE"));
@@ -421,6 +423,8 @@ zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname,
                 * Perform additional checking for specific properties.
                 */
                switch (prop) {
+               default:
+                       break;
                case ZPOOL_PROP_VERSION:
                        if (intval < version || intval > SPA_VERSION) {
                                zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
@@ -730,7 +734,10 @@ zpool_name_valid(libzfs_handle_t *hdl, boolean_t isopen, const char *pool)
                                zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
                                    "multiple '@' delimiters in name"));
                                break;
-
+                       case NAME_ERR_NO_AT:
+                               zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+                                   "permission set is missing '@'"));
+                               break;
                        }
                }
                return (B_FALSE);
@@ -3467,6 +3474,94 @@ zpool_get_history(zpool_handle_t *zhp, nvlist_t **nvhisp)
        return (err);
 }
 
+/*
+ * Retrieve the next event.  If there is a new event available 'nvp' will
+ * contain a newly allocated nvlist and 'dropped' will be set to the number
+ * of missed events since the last call to this function.  When 'nvp' is
+ * set to NULL it indicates no new events are available.  In either case
+ * the function returns 0 and it is up to the caller to free 'nvp'.  In
+ * the case of a fatal error the function will return a non-zero value.
+ * When the function is called in blocking mode it will not return until
+ * a new event is available.
+ */
+int
+zpool_events_next(libzfs_handle_t *hdl, nvlist_t **nvp,
+    int *dropped, int block, int cleanup_fd)
+{
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
+       int error = 0;
+
+       *nvp = NULL;
+       *dropped = 0;
+       zc.zc_cleanup_fd = cleanup_fd;
+
+       if (!block)
+               zc.zc_guid = ZEVENT_NONBLOCK;
+
+       if (zcmd_alloc_dst_nvlist(hdl, &zc, ZEVENT_SIZE) != 0)
+               return (-1);
+
+retry:
+       if (zfs_ioctl(hdl, ZFS_IOC_EVENTS_NEXT, &zc) != 0) {
+               switch (errno) {
+               case ESHUTDOWN:
+                       error = zfs_error_fmt(hdl, EZFS_POOLUNAVAIL,
+                           dgettext(TEXT_DOMAIN, "zfs shutdown"));
+                       goto out;
+               case ENOENT:
+                       /* Blocking error case should not occur */
+                       if (block)
+                               error = zpool_standard_error_fmt(hdl, errno,
+                                   dgettext(TEXT_DOMAIN, "cannot get event"));
+
+                       goto out;
+               case ENOMEM:
+                       if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
+                               error = zfs_error_fmt(hdl, EZFS_NOMEM,
+                                   dgettext(TEXT_DOMAIN, "cannot get event"));
+                               goto out;
+                       } else {
+                               goto retry;
+                       }
+               default:
+                       error = zpool_standard_error_fmt(hdl, errno,
+                           dgettext(TEXT_DOMAIN, "cannot get event"));
+                       goto out;
+               }
+       }
+
+       error = zcmd_read_dst_nvlist(hdl, &zc, nvp);
+       if (error != 0)
+               goto out;
+
+       *dropped = (int)zc.zc_cookie;
+out:
+       zcmd_free_nvlists(&zc);
+
+       return (error);
+}
+
+/*
+ * Clear all events.
+ */
+int
+zpool_events_clear(libzfs_handle_t *hdl, int *count)
+{
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
+       char msg[1024];
+
+       (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
+           "cannot clear events"));
+
+       if (zfs_ioctl(hdl, ZFS_IOC_EVENTS_CLEAR, &zc) != 0)
+               return (zpool_standard_error_fmt(hdl, errno, msg));
+
+       if (count != NULL)
+               *count = (int)zc.zc_cookie; /* # of events cleared */
+
+       return (0);
+}
+
 void
 zpool_obj_to_path(zpool_handle_t *zhp, uint64_t dsobj, uint64_t obj,
     char *pathname, size_t len)