1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
  14  */
  15 #ifndef _SYS_AUTOSNAP_H
  16 #define _SYS_AUTOSNAP_H
  17 
  18 #include <sys/dsl_pool.h>
  19 #include <sys/dmu_tx.h>
  20 #include <sys/dsl_dataset.h>
  21 #include <sys/spa.h>
  22 #include <sys/nvpair.h>
  23 #include <sys/list.h>
  24 #include <sys/avl.h>
  25 
  26 #ifdef  __cplusplus
  27 extern "C" {
  28 #endif
  29 
  30 typedef boolean_t (*autosnap_confirm_cb)(const char *name, boolean_t recursive,
  31     uint64_t txg, void *arg);
  32 typedef boolean_t (*autosnap_notify_created_cb)(const char *name,
  33     boolean_t recursive, boolean_t autosnap, uint64_t txg, uint64_t etxg,
  34     void *arg);
  35 typedef void (*autosnap_error_cb)(const char *name, int err,
  36     uint64_t txg, void *arg);
  37 
  38 typedef enum autosnap_flags {
  39         AUTOSNAP_RECURSIVE      = 1 << 0,
  40         AUTOSNAP_CREATOR        = 1 << 1,
  41         AUTOSNAP_DESTROYER      = 1 << 2,
  42         AUTOSNAP_KRRP           = 1 << 3,
  43         AUTOSNAP_OWNER          = 1 << 4,
  44         AUTOSNAP_WBC            = 1 << 5
  45 } autosnap_flags_t;
  46 
  47 
  48 typedef struct autosnap_snapshot {
  49         avl_node_t node; /* for release */
  50         list_node_t dnode; /* for destroyer */
  51         char name[ZFS_MAX_DATASET_NAME_LEN];
  52         boolean_t recursive;
  53         boolean_t orphaned;
  54         uint64_t txg;
  55         uint64_t etxg;
  56 
  57         list_t ref_cnt;
  58 } autosnap_snapshot_t;
  59 
  60 typedef struct zfs_autosnap zfs_autosnap_t;
  61 
  62 /* The zone lock protects the list of the listeners */
  63 /* Pools are distinguished by dataset and prefix */
  64 typedef struct autosnap_zone {
  65         list_node_t node;
  66         /* The name of top-level dataset */
  67         char dataset[ZFS_MAX_DATASET_NAME_LEN];
  68         autosnap_flags_t flags;
  69         list_t listeners;
  70         avl_tree_t snapshots;
  71         kmutex_t avl_lock;
  72         zfs_autosnap_t *autosnap;
  73         boolean_t created; /* Snap already created */
  74         boolean_t delayed; /* Snap delayed for some reasons */
  75 
  76         /*
  77          * B_TRUE if this zone is related to dirty
  78          * DS in the given sync-round
  79          */
  80         boolean_t dirty;
  81 } autosnap_zone_t;
  82 
  83 struct zfs_autosnap {
  84         kmutex_t autosnap_lock;
  85         kcondvar_t autosnap_cv;
  86         krwlock_t autosnap_rwlock;
  87         list_t autosnap_zones;
  88         list_t autosnap_destroy_queue;
  89         kthread_t *destroyer;
  90         boolean_t need_stop;
  91         boolean_t initialized;
  92         boolean_t register_busy;
  93 };
  94 
  95 /*
  96  * confirm_cb - should snapshot be created
  97  * nc_cb - snapshot is created
  98  * err_cb - can't create snapshot
  99  * Client must not rely on confirm_cb to store
 100  * information about existing snapshots. This
 101  * callback's call can be ommited for any client
 102  * if autosnap decides that it has enough data or
 103  * in no_creation case. The only reliable way to
 104  * know about snapshots that are created by autosnap
 105  * is nc_cb. Also, releasing snapshot doesn't destroy
 106  * a snapshot. After all references to a snapshot are
 107  * dropped, it is moved to destroyer's queue and
 108  * destroyed asynchronously.
 109  */
 110 typedef struct autosnap_handler {
 111         list_node_t node;
 112         autosnap_confirm_cb confirm_cb;
 113         autosnap_notify_created_cb nc_cb;
 114         autosnap_error_cb err_cb;
 115         void *cb_arg;
 116         uint64_t flags;
 117         autosnap_zone_t *zone;
 118 } autosnap_handler_t;
 119 
 120 void * autosnap_register_handler_impl(spa_t *spa,
 121     const char *name, uint64_t flags,
 122     autosnap_confirm_cb confirm_cb,
 123     autosnap_notify_created_cb nc_cb,
 124     autosnap_error_cb err_cb, void *cb_arg);
 125 void *autosnap_register_handler(const char *name, uint64_t flags,
 126     autosnap_confirm_cb confirm_cb,
 127     autosnap_notify_created_cb nc_cb,
 128     autosnap_error_cb, void *cb_arg);
 129 void autosnap_unregister_handler(void *opaque);
 130 autosnap_zone_t *autosnap_find_zone(zfs_autosnap_t *autosnap,
 131     const char *name, boolean_t recursive);
 132 boolean_t autosnap_has_children_zone(zfs_autosnap_t *autosnap,
 133     const char *name, boolean_t krrp_only);
 134 void autosnap_exempt_snapshot(spa_t *spa, const char *name);
 135 void autosnap_force_snap_by_name(const char *dsname,
 136     autosnap_zone_t *zone, boolean_t sync);
 137 void autosnap_force_snap(void *opaque, boolean_t sync);
 138 void autosnap_force_snap_fast(void *opaque);
 139 boolean_t autosnap_confirm_snap(autosnap_zone_t *zone, uint64_t txg);
 140 void autosnap_error_snap(autosnap_zone_t *zone, uint64_t txg, int err);
 141 
 142 void autosnap_create_cb(zfs_autosnap_t *autosnap,
 143     dsl_dataset_t *ds, const char *snapname, uint64_t txg);
 144 int autosnap_check_for_destroy(zfs_autosnap_t *autosnap,
 145     const char *name);
 146 
 147 #define AUTOSNAP_PREFIX ".autosnap_"
 148 #define AUTOSNAP_PREFIX_LEN (sizeof (AUTOSNAP_PREFIX) - 1)
 149 #define AUTOSNAP_NO_SNAP UINT64_MAX
 150 #define AUTOSNAP_LAST_SNAP (UINT64_MAX-1)
 151 #define AUTOSNAP_FIRST_SNAP 0x0
 152 
 153 /*
 154  * No lock version should be called if and only if a
 155  * snapshot should be released in nc_cb context
 156  */
 157 void autosnap_release_snapshots_by_txg(void *opaque,
 158     uint64_t from_txg, uint64_t to_txg);
 159 void autosnap_release_snapshots_by_txg_no_lock(void *opaque,
 160     uint64_t from_txg, uint64_t to_txg);
 161 
 162 nvlist_t *autosnap_get_owned_snapshots(void *opaque);
 163 
 164 int autosnap_lock(spa_t *spa, krw_t rw);
 165 void autosnap_unlock(spa_t *spa);
 166 
 167 boolean_t autosnap_is_autosnap(dsl_dataset_t *ds);
 168 boolean_t autosnap_check_name(const char *snap_name);
 169 
 170 void autosnap_destroyer_thread_start(spa_t *spa);
 171 void autosnap_destroyer_thread_stop(spa_t *spa);
 172 void autosnap_init(spa_t *spa);
 173 void autosnap_fini(spa_t *spa);
 174 
 175 void autosnap_create_snapshot(autosnap_zone_t *azone, char *snap,
 176     dsl_pool_t *dp, uint64_t txg, dmu_tx_t *tx);
 177 void autosnap_invalidate_list(dsl_pool_t *dp, nvlist_t *snapshots);
 178 
 179 #ifdef  __cplusplus
 180 }
 181 #endif
 182 
 183 #endif /* _SYS_AUTOSNAP_H */