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 */