Skip to content

Commit 6a062b8

Browse files
authored
fix(delete_internal_snap): deletes internally created snap (#148)
Signed-off-by: Vishnu Itta <[email protected]>
1 parent 8000a32 commit 6a062b8

File tree

10 files changed

+161
-122
lines changed

10 files changed

+161
-122
lines changed

cmd/Makefile.am

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
SUBDIRS = zfs zpool zdb zhack zinject zstreamdump ztest uzfs_test zpios
1+
SUBDIRS = zfs zpool zdb zhack zinject zstreamdump ztest zpios
22
SUBDIRS += mount_zfs fsck_zfs zvol_id vdev_id arcstat dbufstat zed
33
SUBDIRS += arc_summary raidz_test zgenhostid
44

55
if ENABLE_UZFS
6-
SUBDIRS += zrepl
6+
SUBDIRS += zrepl uzfs_test
77
endif
88

cmd/uzfs_test/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ uzfs_test_LDADD = \
2222
$(top_builddir)/lib/libnvpair/libnvpair.la \
2323
$(top_builddir)/lib/libuutil/libuutil.la \
2424
$(top_builddir)/lib/libzpool/libzpool.la \
25+
$(top_builddir)/lib/libzrepl/libzrepl.la \
2526
$(top_builddir)/lib/libzfs/libzfs.la \
2627
$(top_builddir)/lib/libzfs_core/libzfs_core.la
2728

cmd/uzfs_test/uzfs_test_rebuilding.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@
2121

2222
#include <sys/zfs_context.h>
2323
#include <sys/spa.h>
24+
#include <sys/dsl_destroy.h>
2425
#include <sys/uzfs_zvol.h>
2526
#include <uzfs_mgmt.h>
27+
#include <data_conn.h>
2628
#include <uzfs_io.h>
2729
#include <zrepl_mgmt.h>
2830
#include <uzfs_zap.h>
@@ -217,18 +219,24 @@ fetch_modified_data(void *arg)
217219
off_t offset, end;
218220
size_t len;
219221
int max_count = 4;
222+
zvol_state_t *snap_zv = NULL;
223+
char *snap_name;
224+
int rc;
220225

221226
printf("fetching modified data\n");
222227
md.io_num = repl_data->base_io;
223228

224229
len = r_data->zvol->zv_volsize / max_count;
225230

231+
uzfs_zvol_create_internal_snapshot(repl_data->zvol, &snap_zv,
232+
md.io_num);
233+
226234
for (offset = 0; offset < r_data->zvol->zv_volsize; ) {
227235
end = offset + len;
228236
if (end > r_data->zvol->zv_volsize)
229237
len = r_data->zvol->zv_volsize - offset;
230238

231-
err = uzfs_get_io_diff(repl_data->zvol, &md,
239+
err = uzfs_get_io_diff(repl_data->zvol, &md, snap_zv,
232240
uzfs_test_meta_diff_traverse_cb, offset, len,
233241
r_data);
234242
if (err)
@@ -239,6 +247,16 @@ fetch_modified_data(void *arg)
239247
break;
240248
}
241249

250+
if (snap_zv != NULL) {
251+
snap_name = kmem_asprintf("%s", snap_zv->zv_name);
252+
uzfs_close_dataset(snap_zv);
253+
rc = dsl_destroy_snapshot(snap_name, B_FALSE);
254+
if (rc != 0)
255+
LOG_ERR("snap destroy failed %s %d", snap_name, rc);
256+
strfree(snap_name);
257+
snap_zv = NULL;
258+
}
259+
242260
if (err) {
243261
printf("error(%d)... while fetching modified data\n", err);
244262
exit(1);

include/data_conn.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ void uzfs_update_ionum_interval(zvol_info_t *zinfo, uint32_t timeout);
7373
void uzfs_zvol_timer_thread(void);
7474

7575
void signal_fds_related_to_zinfo(zvol_info_t *zinfo);
76-
76+
int
77+
uzfs_zvol_create_internal_snapshot(zvol_state_t *zv, zvol_state_t **snap_zv,
78+
uint64_t io_num);
7779
#ifdef __cplusplus
7880
}
7981
#endif

include/uzfs_mgmt.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ extern int uzfs_hold_dataset(zvol_state_t *zv);
4848
extern void uzfs_rele_dataset(zvol_state_t *zv);
4949

5050
int uzfs_pool_create(const char *name, char *path, spa_t **spa);
51+
int
52+
get_snapshot_zv(zvol_state_t *zv, char *snap_name, zvol_state_t **snap_zv,
53+
boolean_t fail_exists, boolean_t fail_notexists);
54+
5155
#ifdef __cplusplus
5256
}
5357
#endif

include/uzfs_rebuilding.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ int compare_blk_metadata(blk_metadata_t *first_md, blk_metadata_t *second_md);
4242
* API to access data whose metadata is higer than base_metadata
4343
*/
4444
int uzfs_get_io_diff(zvol_state_t *zv, blk_metadata_t *base_metadata,
45-
uzfs_get_io_diff_cb_t *cb_func, off_t offset, size_t len, void *arg);
45+
zvol_state_t *snap_zv, uzfs_get_io_diff_cb_t *cb_func, off_t offset,
46+
size_t len, void *arg);
4647

4748
/*
4849
* uzfs_get_nonoverlapping_ondisk_blks will check on_disk metadata with
@@ -60,10 +61,6 @@ uzfs_zvol_create_snaprebuild_clone(zvol_state_t *zv,
6061
int
6162
uzfs_zvol_destroy_snaprebuild_clone(zvol_state_t *zv,
6263
zvol_state_t *snap_zv);
63-
int
64-
uzfs_zvol_create_internal_snapshot(zvol_state_t *zv, zvol_state_t **snap_zv,
65-
uint64_t io_num, char **snap);
66-
6764
#ifdef __cplusplus
6865
}
6966
#endif

lib/libzpool/uzfs_mgmt.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,71 @@ uzfs_zvol_create_minors(spa_t *spa, const char *name)
526526
kmem_free(pool_name, MAXNAMELEN);
527527
}
528528

529+
int
530+
get_snapshot_zv(zvol_state_t *zv, char *snap_name, zvol_state_t **snap_zv,
531+
boolean_t fail_exists, boolean_t fail_notexists)
532+
{
533+
char *dataset;
534+
int ret = 0;
535+
536+
dataset = kmem_asprintf("%s@%s", strchr(zv->zv_name, '/') + 1,
537+
snap_name);
538+
539+
ret = uzfs_open_dataset(zv->zv_spa, dataset, snap_zv);
540+
if (ret == ENOENT) {
541+
if (fail_notexists) {
542+
LOG_ERR("fail on unavailable snapshot %s",
543+
dataset);
544+
strfree(dataset);
545+
ret = SET_ERROR(ENOENT);
546+
return (ret);
547+
}
548+
ret = dmu_objset_snapshot_one(zv->zv_name, snap_name);
549+
if (ret) {
550+
LOG_ERR("Failed to create snapshot %s: %d",
551+
dataset, ret);
552+
strfree(dataset);
553+
return (ret);
554+
}
555+
556+
ret = uzfs_open_dataset(zv->zv_spa, dataset, snap_zv);
557+
if (ret == 0) {
558+
ret = uzfs_hold_dataset(*snap_zv);
559+
if (ret != 0) {
560+
LOG_ERR("Failed to hold snapshot: %s %d",
561+
dataset, ret);
562+
uzfs_close_dataset(*snap_zv);
563+
*snap_zv = NULL;
564+
}
565+
}
566+
else
567+
LOG_ERR("Failed to open snapshot: %d", ret);
568+
} else if (ret == 0) {
569+
if (fail_exists) {
570+
LOG_ERR("fail on already available snapshot %s",
571+
dataset);
572+
uzfs_close_dataset(*snap_zv);
573+
*snap_zv = NULL;
574+
ret = SET_ERROR(EEXIST);
575+
} else {
576+
LOG_INFO("holding already available snapshot %s",
577+
dataset);
578+
ret = uzfs_hold_dataset(*snap_zv);
579+
if (ret != 0) {
580+
LOG_ERR("Failed to hold already existing "
581+
"snapshot %s: %d", dataset, ret);
582+
uzfs_close_dataset(*snap_zv);
583+
*snap_zv = NULL;
584+
}
585+
}
586+
} else {
587+
LOG_ERR("Failed to open snapshot: %d", ret);
588+
}
589+
590+
strfree(dataset);
591+
return (ret);
592+
}
593+
529594
/* uZFS Zvol destroy call back function */
530595
int
531596
uzfs_zvol_destroy_cb(const char *ds_name, void *arg)

lib/libzpool/uzfs_rebuilding.c

Lines changed: 4 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -70,104 +70,6 @@ iszero(blk_metadata_t *md)
7070
last_md = NULL; \
7171
} while (0)
7272

73-
int
74-
get_snapshot_zv(zvol_state_t *zv, char *snap_name, zvol_state_t **snap_zv,
75-
boolean_t fail_exists, boolean_t fail_notexists)
76-
{
77-
char *dataset;
78-
int ret = 0;
79-
80-
dataset = kmem_asprintf("%s@%s", strchr(zv->zv_name, '/') + 1,
81-
snap_name);
82-
83-
ret = uzfs_open_dataset(zv->zv_spa, dataset, snap_zv);
84-
if (ret == ENOENT) {
85-
if (fail_notexists) {
86-
LOG_ERR("fail on unavailable snapshot %s",
87-
dataset);
88-
strfree(dataset);
89-
ret = SET_ERROR(ENOENT);
90-
return (ret);
91-
}
92-
ret = dmu_objset_snapshot_one(zv->zv_name, snap_name);
93-
if (ret) {
94-
LOG_ERR("Failed to create snapshot %s: %d",
95-
dataset, ret);
96-
strfree(dataset);
97-
return (ret);
98-
}
99-
100-
ret = uzfs_open_dataset(zv->zv_spa, dataset, snap_zv);
101-
if (ret == 0) {
102-
ret = uzfs_hold_dataset(*snap_zv);
103-
if (ret != 0) {
104-
LOG_ERR("Failed to hold snapshot: %s %d",
105-
dataset, ret);
106-
uzfs_close_dataset(*snap_zv);
107-
*snap_zv = NULL;
108-
}
109-
}
110-
else
111-
LOG_ERR("Failed to open snapshot: %d", ret);
112-
} else if (ret == 0) {
113-
if (fail_exists) {
114-
LOG_ERR("fail on already available snapshot %s",
115-
dataset);
116-
uzfs_close_dataset(*snap_zv);
117-
*snap_zv = NULL;
118-
ret = SET_ERROR(EEXIST);
119-
} else {
120-
LOG_INFO("holding already available snapshot %s",
121-
dataset);
122-
ret = uzfs_hold_dataset(*snap_zv);
123-
if (ret != 0) {
124-
LOG_ERR("Failed to hold already existing "
125-
"snapshot %s: %d", dataset, ret);
126-
uzfs_close_dataset(*snap_zv);
127-
*snap_zv = NULL;
128-
}
129-
}
130-
} else {
131-
LOG_ERR("Failed to open snapshot: %d", ret);
132-
}
133-
134-
strfree(dataset);
135-
return (ret);
136-
}
137-
138-
/*
139-
* Creates internal snapshot on given zv using current time as part of snapname.
140-
* If snap already exists, waits and attempts to create again.
141-
* Returns zv of snapshot in snap_zv.
142-
*/
143-
int
144-
uzfs_zvol_create_internal_snapshot(zvol_state_t *zv, zvol_state_t **snap_zv,
145-
uint64_t io_num, char **snap)
146-
{
147-
int ret = 0;
148-
char *snap_name;
149-
time_t now;
150-
again:
151-
now = time(NULL);
152-
snap_name = kmem_asprintf("%s%llu.%llu", IO_DIFF_SNAPNAME, io_num, now);
153-
ret = get_snapshot_zv(zv, snap_name, snap_zv, B_TRUE, B_FALSE);
154-
if (ret == EEXIST) {
155-
strfree(snap_name);
156-
sleep(1);
157-
LOG_INFO("Waiting to create internal snapshot");
158-
goto again;
159-
}
160-
if (ret != 0) {
161-
LOG_ERR("Failed to get info about %s@%s",
162-
zv->zv_name, snap_name);
163-
strfree(snap_name);
164-
} else {
165-
*snap = snap_name;
166-
}
167-
return (ret);
168-
}
169-
170-
17173
void
17274
destroy_snapshot_zv(zvol_state_t *zv, char *snap_name)
17375
{
@@ -179,15 +81,15 @@ destroy_snapshot_zv(zvol_state_t *zv, char *snap_name)
17981
}
18082

18183
int
182-
uzfs_get_io_diff(zvol_state_t *zv, blk_metadata_t *low,
84+
uzfs_get_io_diff(zvol_state_t *zv, blk_metadata_t *low, zvol_state_t *snap,
18385
uzfs_get_io_diff_cb_t *func, off_t lun_offset, size_t lun_len, void *arg)
18486
{
18587
uint64_t blocksize = zv->zv_volmetablocksize;
18688
uint64_t metadata_read_chunk_size = 10 * blocksize;
18789
uint64_t metaobjectsize = (zv->zv_volsize / zv->zv_metavolblocksize) *
18890
zv->zv_volmetadatasize;
18991
uint64_t metadatasize = zv->zv_volmetadatasize;
190-
char *buf, *snap_name = NULL;
92+
char *buf;
19193
uint64_t i, read;
19294
uint64_t offset, len, end;
19395
int ret = 0;
@@ -197,7 +99,7 @@ uzfs_get_io_diff(zvol_state_t *zv, blk_metadata_t *low,
19799
zvol_state_t *snap_zv;
198100
metaobj_blk_offset_t snap_metablk;
199101

200-
if (!func || (lun_offset + lun_len) > zv->zv_volsize)
102+
if (!func || (lun_offset + lun_len) > zv->zv_volsize || snap == NULL)
201103
return (EINVAL);
202104

203105
get_zv_metaobj_block_details(&snap_metablk, zv, lun_offset, lun_len);
@@ -207,8 +109,7 @@ uzfs_get_io_diff(zvol_state_t *zv, blk_metadata_t *low,
207109
if (end > metaobjectsize)
208110
end = metaobjectsize;
209111

210-
ret = uzfs_zvol_create_internal_snapshot(zv, &snap_zv,
211-
low->io_num, &snap_name);
112+
snap_zv = snap;
212113

213114
if (ret != 0) {
214115
LOG_ERR("Failed to create snapshot for vol %s io_num %lu",
@@ -292,17 +193,8 @@ uzfs_get_io_diff(zvol_state_t *zv, blk_metadata_t *low,
292193
}
293194
}
294195

295-
uzfs_close_dataset(snap_zv);
296-
297-
/*
298-
* TODO: if we failed to destroy snapshot here then
299-
* this should be handled separately from application.
300-
*/
301-
if (end == metaobjectsize)
302-
destroy_snapshot_zv(zv, snap_name);
303196

304197
umem_free(buf, metadata_read_chunk_size);
305-
strfree(snap_name);
306198
return (ret);
307199
}
308200

0 commit comments

Comments
 (0)