12
#if defined(GF_LINUX_HOST_OS)
15
#include "mntent_compat.h"
19
#include <glusterfs/dict.h>
20
#include <glusterfs/syscall.h>
21
#include "glusterd-op-sm.h"
22
#include "glusterd-utils.h"
23
#include "glusterd-messages.h"
24
#include "glusterd-store.h"
25
#include "glusterd-volgen.h"
26
#include "glusterd-snapd-svc.h"
27
#include "glusterd-svc-helper.h"
28
#include "glusterd-snapd-svc-helper.h"
29
#include "glusterd-snapshot-utils.h"
30
#include "glusterd-server-quorum.h"
31
#include "glusterd-messages.h"
32
#include "glusterd-errno.h"
34
#define GANESHA_EXPORT_DIRECTORY CONFDIR "/exports"
36
extern char snap_mount_dir[VALID_GLUSTERD_PATHMAX];
45
glusterd_snapobject_delete(glusterd_snap_t *snap)
48
gf_msg(THIS->name, GF_LOG_WARNING, 0, GD_MSG_PARAM_NULL,
53
cds_list_del_init(&snap->snap_list);
54
cds_list_del_init(&snap->volumes);
55
if (LOCK_DESTROY(&snap->lock))
56
gf_msg(THIS->name, GF_LOG_WARNING, 0, GD_MSG_LOCK_DESTROY_FAILED,
57
"Failed destroying lock"
61
GF_FREE(snap->description);
73
glusterd_cleanup_snaps_for_volume(glusterd_volinfo_t *volinfo)
77
xlator_t *this = THIS;
78
glusterd_volinfo_t *snap_vol = NULL;
79
glusterd_volinfo_t *dummy_snap_vol = NULL;
80
glusterd_snap_t *snap = NULL;
82
cds_list_for_each_entry_safe(snap_vol, dummy_snap_vol,
83
&volinfo->snap_volumes, snapvol_list)
85
snap = snap_vol->snapshot;
86
ret = glusterd_store_delete_snap(snap);
88
gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_VOL_DELETE_FAIL,
96
ret = glusterd_snapobject_delete(snap);
98
gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_VOL_DELETE_FAIL,
106
ret = glusterd_store_delete_volume(snap_vol);
108
gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_VOL_DELETE_FAIL,
110
"volume %s from store",
116
if (glusterd_volinfo_unref(snap_vol)) {
117
gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_VOL_DELETE_FAIL,
130
glusterd_snap_geo_rep_restore(glusterd_volinfo_t *snap_volinfo,
131
glusterd_volinfo_t *new_volinfo)
133
char vol_tstamp_file[PATH_MAX] = {
136
char snap_tstamp_file[PATH_MAX] = {
139
glusterd_conf_t *priv = NULL;
140
xlator_t *this = THIS;
141
int geo_rep_indexing_on = 0;
144
GF_ASSERT(snap_volinfo);
145
GF_ASSERT(new_volinfo);
147
priv = this->private;
153
geo_rep_indexing_on = glusterd_volinfo_get_boolean(new_volinfo,
155
if (geo_rep_indexing_on == -1) {
156
gf_msg_debug(this->name, 0,
158
" to check whether geo-rep-indexing enabled or not");
163
if (geo_rep_indexing_on == 1) {
164
GLUSTERD_GET_VOLUME_DIR(vol_tstamp_file, new_volinfo, priv);
165
strncat(vol_tstamp_file, "/marker.tstamp",
166
PATH_MAX - strlen(vol_tstamp_file) - 1);
167
GLUSTERD_GET_VOLUME_DIR(snap_tstamp_file, snap_volinfo, priv);
168
strncat(snap_tstamp_file, "/marker.tstamp",
169
PATH_MAX - strlen(snap_tstamp_file) - 1);
170
ret = gf_set_timestamp(snap_tstamp_file, vol_tstamp_file);
172
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_TSTAMP_SET_FAIL,
173
"Unable to set atime and mtime of %s as of %s",
174
vol_tstamp_file, snap_tstamp_file);
191
glusterd_brickinfo_dup(glusterd_brickinfo_t *brickinfo,
192
glusterd_brickinfo_t *dup_brickinfo)
195
xlator_t *this = THIS;
197
GF_VALIDATE_OR_GOTO(this->name, brickinfo, out);
198
GF_VALIDATE_OR_GOTO(this->name, dup_brickinfo, out);
200
strcpy(dup_brickinfo->hostname, brickinfo->hostname);
201
strcpy(dup_brickinfo->path, brickinfo->path);
202
strcpy(dup_brickinfo->origin_path, brickinfo->origin_path);
203
strcpy(dup_brickinfo->real_path, brickinfo->real_path);
204
strcpy(dup_brickinfo->device_path, brickinfo->device_path);
205
strcpy(dup_brickinfo->fstype, brickinfo->fstype);
206
strcpy(dup_brickinfo->mnt_opts, brickinfo->mnt_opts);
207
ret = gf_canonicalize_path(dup_brickinfo->path);
209
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_CANONICALIZE_FAIL,
210
"Failed to canonicalize "
214
gf_uuid_copy(dup_brickinfo->uuid, brickinfo->uuid);
216
dup_brickinfo->port = brickinfo->port;
217
dup_brickinfo->rdma_port = brickinfo->rdma_port;
218
if (NULL != brickinfo->logfile) {
219
dup_brickinfo->logfile = gf_strdup(brickinfo->logfile);
220
if (NULL == dup_brickinfo->logfile) {
225
strcpy(dup_brickinfo->brick_id, brickinfo->brick_id);
226
strcpy(dup_brickinfo->mount_dir, brickinfo->mount_dir);
227
dup_brickinfo->status = brickinfo->status;
228
dup_brickinfo->snap_status = brickinfo->snap_status;
229
dup_brickinfo->snap = brickinfo->snap;
246
glusterd_snap_volinfo_restore(dict_t *dict, dict_t *rsp_dict,
247
glusterd_volinfo_t *new_volinfo,
248
glusterd_volinfo_t *snap_volinfo,
249
int32_t volcount, gf_boolean_t retain_origin_path,
250
char *snap_mount_dir)
254
int32_t brick_count = -1;
256
xlator_t *this = THIS;
257
glusterd_brickinfo_t *brickinfo = NULL;
258
glusterd_brickinfo_t *new_brickinfo = NULL;
259
struct glusterd_snap_ops *snap_ops = NULL;
264
GF_VALIDATE_OR_GOTO(this->name, new_volinfo, out);
265
GF_VALIDATE_OR_GOTO(this->name, snap_volinfo, out);
268
cds_list_for_each_entry(brickinfo, &snap_volinfo->bricks, brick_list)
271
ret = glusterd_brickinfo_new(&new_brickinfo);
273
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_BRICK_NEW_INFO_FAIL,
280
ret = glusterd_brickinfo_dup(brickinfo, new_brickinfo);
282
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_BRICK_SET_INFO_FAIL,
292
if (retain_origin_path) {
293
snprintf(key, sizeof(key), "snap%d.brick%d.origin_path", volcount,
295
ret = dict_get_str(dict, key, &value);
297
gf_strncpy(new_brickinfo->path, value,
298
sizeof(new_brickinfo->path));
301
glusterd_snapshot_plugin_by_name(snap_volinfo->snap_plugin,
304
snap_ops->brick_path(snap_mount_dir, brickinfo->origin_path, 0,
305
snap_volinfo->snapshot->snapname,
306
snap_volinfo->volname, brickinfo->mount_dir,
307
brick_count - 1, new_brickinfo, 1);
310
snprintf(key, sizeof(key), "snap%d.brick%d.snap_status", volcount,
312
ret = dict_get_int32(dict, key, &new_brickinfo->snap_status);
314
snprintf(key, sizeof(key), "snap%d.brick%d.device_path", volcount,
316
ret = dict_get_str(dict, key, &value);
318
gf_strncpy(new_brickinfo->device_path, value,
319
sizeof(new_brickinfo->device_path));
321
snprintf(key, sizeof(key), "snap%d.brick%d.fs_type", volcount,
323
ret = dict_get_str(dict, key, &value);
325
gf_strncpy(new_brickinfo->fstype, value,
326
sizeof(new_brickinfo->fstype));
328
snprintf(key, sizeof(key), "snap%d.brick%d.snap_type", volcount,
330
ret = dict_get_str(dict, key, &value);
332
gf_strncpy(new_brickinfo->snap_type, value,
333
sizeof(new_brickinfo->snap_type));
335
snprintf(key, sizeof(key), "snap%d.brick%d.mnt_opts", volcount,
337
ret = dict_get_str(dict, key, &value);
339
gf_strncpy(new_brickinfo->mnt_opts, value,
340
sizeof(new_brickinfo->mnt_opts));
344
if ((!gf_uuid_compare(brickinfo->uuid, MY_UUID)) &&
345
(brickinfo->snap_status != -1)) {
349
ret = sys_lsetxattr(new_brickinfo->path, GF_XATTR_VOL_ID_KEY,
350
new_volinfo->volume_id,
351
sizeof(new_volinfo->volume_id), XATTR_REPLACE);
353
gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_SET_XATTR_FAIL,
354
"Attribute=%s, Path=%s, Reason=%s, Snap=%s",
355
GF_XATTR_VOL_ID_KEY, new_brickinfo->path,
356
strerror(errno), new_volinfo->volname, NULL);
364
if (brickinfo->snap_status == -1) {
366
ret = glusterd_add_missed_snaps_to_dict(
367
rsp_dict, snap_volinfo, brickinfo, brick_count,
368
GF_SNAP_OPTION_TYPE_RESTORE);
370
gf_msg(this->name, GF_LOG_ERROR, 0,
371
GD_MSG_MISSEDSNAP_INFO_SET_FAIL,
372
"Failed to add missed snapshot info "
373
"for %s:%s in the rsp_dict",
374
brickinfo->hostname, brickinfo->path);
379
cds_list_add_tail(&new_brickinfo->brick_list, &new_volinfo->bricks);
381
new_brickinfo = NULL;
385
ret = glusterd_create_volfiles_and_notify_services(new_volinfo);
387
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLFILE_CREATE_FAIL,
388
"Failed to regenerate volfiles");
393
ret = glusterd_snap_geo_rep_restore(snap_volinfo, new_volinfo);
395
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_TSTAMP_SET_FAIL,
396
"Geo-rep: marker.tstamp's timestamp restoration failed");
401
if (ret && (NULL != new_brickinfo)) {
402
(void)glusterd_brickinfo_delete(new_brickinfo);
409
glusterd_snap_volinfo_find_by_volume_id(uuid_t volume_id,
410
glusterd_volinfo_t **volinfo)
413
xlator_t *this = THIS;
414
glusterd_volinfo_t *voliter = NULL;
415
glusterd_snap_t *snap = NULL;
416
glusterd_conf_t *priv = NULL;
418
priv = this->private;
422
if (gf_uuid_is_null(volume_id)) {
423
gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_UUID_NULL,
424
"Volume UUID is NULL");
428
cds_list_for_each_entry(snap, &priv->snapshots, snap_list)
430
cds_list_for_each_entry(voliter, &snap->volumes, vol_list)
432
if (gf_uuid_compare(volume_id, voliter->volume_id))
440
gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_SNAP_NOT_FOUND,
441
"Snap volume not found");
443
gf_msg_trace(this->name, 0, "Returning %d", ret);
448
glusterd_snap_volinfo_find(char *snap_volname, glusterd_snap_t *snap,
449
glusterd_volinfo_t **volinfo)
452
xlator_t *this = THIS;
453
glusterd_volinfo_t *snap_vol = NULL;
454
glusterd_conf_t *priv = NULL;
456
priv = this->private;
459
GF_ASSERT(snap_volname);
461
cds_list_for_each_entry(snap_vol, &snap->volumes, vol_list)
463
if (!strcmp(snap_vol->volname, snap_volname)) {
470
gf_msg(this->name, GF_LOG_WARNING, EINVAL, GD_MSG_SNAP_NOT_FOUND,
471
"Snap volume %s not found", snap_volname);
473
gf_msg_trace(this->name, 0, "Returning %d", ret);
478
glusterd_snap_volinfo_find_from_parent_volname(char *origin_volname,
479
glusterd_snap_t *snap,
480
glusterd_volinfo_t **volinfo)
483
xlator_t *this = THIS;
484
glusterd_volinfo_t *snap_vol = NULL;
485
glusterd_conf_t *priv = NULL;
487
priv = this->private;
490
GF_ASSERT(origin_volname);
492
cds_list_for_each_entry(snap_vol, &snap->volumes, vol_list)
494
if (!strcmp(snap_vol->parent_volname, origin_volname)) {
501
gf_msg_debug(this->name, 0,
502
"Snap volume not found(snap: %s, "
504
snap->snapname, origin_volname);
507
gf_msg_trace(this->name, 0, "Returning %d", ret);
517
gd_add_brick_snap_details_to_dict(dict_t *dict, char *prefix,
518
glusterd_brickinfo_t *brickinfo)
521
xlator_t *this = THIS;
526
GF_VALIDATE_OR_GOTO(this->name, (dict != NULL), out);
527
GF_VALIDATE_OR_GOTO(this->name, (prefix != NULL), out);
528
GF_VALIDATE_OR_GOTO(this->name, (brickinfo != NULL), out);
530
snprintf(key, sizeof(key), "%s.snap_status", prefix);
531
ret = dict_set_int32(dict, key, brickinfo->snap_status);
533
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAP_STATUS_FAIL,
534
"Failed to set snap_status for %s:%s", brickinfo->hostname,
539
snprintf(key, sizeof(key), "%s.device_path", prefix);
540
ret = dict_set_str(dict, key, brickinfo->device_path);
542
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
543
"Failed to set snap_device for %s:%s", brickinfo->hostname,
548
if (brickinfo->origin_path[0] != '\0') {
549
snprintf(key, sizeof(key), "%s.origin_path", prefix);
550
ret = dict_set_str(dict, key, brickinfo->origin_path);
552
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
553
"Failed to set origin_path for %s:%s", brickinfo->hostname,
559
snprintf(key, sizeof(key), "%s.fs_type", prefix);
560
ret = dict_set_str(dict, key, brickinfo->fstype);
562
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
563
"Failed to set fstype for %s:%s", brickinfo->hostname,
568
snprintf(key, sizeof(key), "%s.snap_type", prefix);
569
ret = dict_set_str(dict, key, brickinfo->snap_type);
571
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
572
"Failed to set snap_type for %s:%s", brickinfo->hostname,
577
snprintf(key, sizeof(key), "%s.mnt_opts", prefix);
578
ret = dict_set_str(dict, key, brickinfo->mnt_opts);
580
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_BRK_MOUNTOPTS_FAIL,
581
"Failed to set mnt_opts for %s:%s", brickinfo->hostname,
586
snprintf(key, sizeof(key), "%s.mount_dir", prefix);
587
ret = dict_set_str(dict, key, brickinfo->mount_dir);
589
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
590
"Failed to set mount_dir for %s:%s", brickinfo->hostname,
603
gd_add_vol_snap_details_to_dict(dict_t *dict, char *prefix,
604
glusterd_volinfo_t *volinfo)
607
xlator_t *this = THIS;
612
GF_VALIDATE_OR_GOTO(this->name, (dict != NULL), out);
613
GF_VALIDATE_OR_GOTO(this->name, (volinfo != NULL), out);
614
GF_VALIDATE_OR_GOTO(this->name, (prefix != NULL), out);
616
snprintf(key, sizeof(key), "%s.restored_from_snap", prefix);
617
ret = dict_set_dynstr_with_alloc(dict, key,
618
uuid_utoa(volinfo->restored_from_snap));
620
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
621
"Unable to set %s for volume"
623
key, volinfo->volname);
627
if (strlen(volinfo->restored_from_snapname_id) > 0) {
628
snprintf(key, sizeof(key), "%s.restored_from_snapname_id", prefix);
629
ret = dict_set_dynstr_with_alloc(dict, key,
630
volinfo->restored_from_snapname_id);
632
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
633
"Unable to set %s for volume"
635
key, volinfo->volname);
640
if (strlen(volinfo->restored_from_snapname) > 0) {
641
snprintf(key, sizeof(key), "%s.restored_from_snapname", prefix);
642
ret = dict_set_dynstr_with_alloc(dict, key,
643
volinfo->restored_from_snapname);
645
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
646
"Unable to set %s for volume"
648
key, volinfo->volname);
653
if (strlen(volinfo->parent_volname) > 0) {
654
snprintf(key, sizeof(key), "%s.parent_volname", prefix);
655
ret = dict_set_dynstr_with_alloc(dict, key, volinfo->parent_volname);
657
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
660
key, volinfo->volname);
665
snprintf(key, sizeof(key), "%s.is_snap_volume", prefix);
666
ret = dict_set_uint32(dict, key, volinfo->is_snap_volume);
668
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
669
"Unable to set %s for volume"
671
key, volinfo->volname);
675
snprintf(key, sizeof(key), "%s.snap-max-hard-limit", prefix);
676
ret = dict_set_uint64(dict, key, volinfo->snap_max_hard_limit);
678
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
679
"Unable to set %s for volume"
681
key, volinfo->volname);
684
if (strlen(volinfo->snap_plugin) > 0) {
685
snprintf(key, sizeof(key), "%s.snap_plugin", prefix);
686
ret = dict_set_dynstr_with_alloc(dict, key, volinfo->snap_plugin);
688
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
691
key, volinfo->volname);
701
glusterd_add_missed_snaps_to_export_dict(dict_t *peer_data)
703
char name_buf[PATH_MAX] = "";
704
char value[PATH_MAX] = "";
705
int32_t missed_snap_count = 0;
707
glusterd_conf_t *priv = NULL;
708
glusterd_missed_snap_info *missed_snapinfo = NULL;
709
glusterd_snap_op_t *snap_opinfo = NULL;
710
xlator_t *this = THIS;
712
GF_ASSERT(peer_data);
714
priv = this->private;
718
cds_list_for_each_entry(missed_snapinfo, &priv->missed_snaps_list,
721
cds_list_for_each_entry(snap_opinfo, &missed_snapinfo->snap_ops,
724
snprintf(name_buf, sizeof(name_buf), "missed_snaps_%d",
726
snprintf(value, sizeof(value), "%s:%s=%s:%d:%s:%d:%d",
727
missed_snapinfo->node_uuid, missed_snapinfo->snap_uuid,
728
snap_opinfo->snap_vol_id, snap_opinfo->brick_num,
729
snap_opinfo->brick_path, snap_opinfo->op,
730
snap_opinfo->status);
732
ret = dict_set_dynstr_with_alloc(peer_data, name_buf, value);
734
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
735
"Unable to set %s", name_buf);
742
ret = dict_set_int32(peer_data, "missed_snap_count", missed_snap_count);
744
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
745
"Unable to set missed_snap_count");
750
gf_msg_trace(this->name, 0, "Returning %d", ret);
755
glusterd_add_snap_to_dict(glusterd_snap_t *snap, dict_t *peer_data,
759
char prefix[32] = "";
761
int32_t volcount = 0;
762
glusterd_volinfo_t *volinfo = NULL;
763
glusterd_brickinfo_t *brickinfo = NULL;
764
gf_boolean_t host_bricks = _gf_false;
765
xlator_t *this = THIS;
768
GF_ASSERT(peer_data);
770
snprintf(prefix, sizeof(prefix), "snap%d", snap_count);
772
cds_list_for_each_entry(volinfo, &snap->volumes, vol_list)
775
ret = glusterd_add_volume_to_dict(volinfo, peer_data, volcount, prefix);
777
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
778
"Failed to add snap:%s volume:%s "
779
"to peer_data dict for handshake",
780
snap->snapname, volinfo->volname);
784
if (glusterd_is_volume_quota_enabled(volinfo)) {
785
ret = glusterd_vol_add_quota_conf_to_dict(volinfo, peer_data,
788
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
789
"Failed to add quota conf for "
790
"snap:%s volume:%s to peer_data "
791
"dict for handshake",
792
snap->snapname, volinfo->volname);
797
cds_list_for_each_entry(brickinfo, &volinfo->bricks, brick_list)
799
if (!gf_uuid_compare(brickinfo->uuid, MY_UUID)) {
800
host_bricks = _gf_true;
806
snprintf(buf, sizeof(buf), "%s.host_bricks", prefix);
807
ret = dict_set_int8(peer_data, buf, (int8_t)host_bricks);
809
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
810
"Unable to set host_bricks for snap %s", snap->snapname);
814
snprintf(buf, sizeof(buf), "%s.volcount", prefix);
815
ret = dict_set_int32(peer_data, buf, volcount);
817
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
818
"Unable to set volcount for snap %s", snap->snapname);
822
snprintf(buf, sizeof(buf), "%s.snapname", prefix);
823
ret = dict_set_dynstr_with_alloc(peer_data, buf, snap->snapname);
825
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
826
"Unable to set snapname for snap %s", snap->snapname);
830
snprintf(buf, sizeof(buf), "%s.snap_id", prefix);
831
ret = dict_set_dynstr_with_alloc(peer_data, buf, uuid_utoa(snap->snap_id));
833
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
834
"Unable to set snap_id for snap %s", snap->snapname);
838
if (snap->description) {
839
snprintf(buf, sizeof(buf), "%s.description", prefix);
840
ret = dict_set_dynstr_with_alloc(peer_data, buf, snap->description);
842
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
843
"Unable to set description for snap %s", snap->snapname);
848
snprintf(buf, sizeof(buf), "%s.time_stamp", prefix);
849
ret = dict_set_int64(peer_data, buf, (int64_t)snap->time_stamp);
851
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
852
"Unable to set time_stamp for snap %s", snap->snapname);
856
snprintf(buf, sizeof(buf), "%s.snap_restored", prefix);
857
ret = dict_set_int8(peer_data, buf, snap->snap_restored);
859
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
860
"Unable to set snap_restored for snap %s", snap->snapname);
864
snprintf(buf, sizeof(buf), "%s.snap_status", prefix);
865
ret = dict_set_int32(peer_data, buf, snap->snap_status);
867
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
868
"Unable to set snap_status for snap %s", snap->snapname);
872
gf_msg_trace(this->name, 0, "Returning %d", ret);
877
glusterd_add_snapshots_to_export_dict(dict_t *peer_data)
879
int32_t snap_count = 0;
881
glusterd_conf_t *priv = NULL;
882
glusterd_snap_t *snap = NULL;
883
xlator_t *this = THIS;
885
priv = this->private;
887
GF_ASSERT(peer_data);
889
cds_list_for_each_entry(snap, &priv->snapshots, snap_list)
892
ret = glusterd_add_snap_to_dict(snap, peer_data, snap_count);
894
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
895
"Failed to add snap(%s) to the "
896
" peer_data dict for handshake",
902
ret = dict_set_int32(peer_data, "snap_count", snap_count);
904
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
905
"Failed to set snap_count");
910
gf_msg_trace(this->name, 0, "Returning %d", ret);
919
gd_import_new_brick_snap_details(dict_t *dict, char *prefix,
920
glusterd_brickinfo_t *brickinfo)
923
xlator_t *this = THIS;
927
char *snap_device = NULL;
928
char *origin_path = NULL;
929
char *snap_type = NULL;
930
char *fs_type = NULL;
931
char *mnt_opts = NULL;
932
char *mount_dir = NULL;
934
GF_VALIDATE_OR_GOTO(this->name, (dict != NULL), out);
935
GF_VALIDATE_OR_GOTO(this->name, (prefix != NULL), out);
936
GF_VALIDATE_OR_GOTO(this->name, (brickinfo != NULL), out);
938
snprintf(key, sizeof(key), "%s.snap_status", prefix);
939
ret = dict_get_int32(dict, key, &brickinfo->snap_status);
941
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
942
"%s missing in payload", key);
946
snprintf(key, sizeof(key), "%s.device_path", prefix);
947
ret = dict_get_str(dict, key, &snap_device);
949
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
950
"%s missing in payload", key);
953
gf_strncpy(brickinfo->device_path, snap_device,
954
sizeof(brickinfo->device_path));
956
snprintf(key, sizeof(key), "%s.origin_path", prefix);
957
ret = dict_get_str(dict, key, &origin_path);
959
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
960
"%s missing in payload", key);
962
gf_strncpy(brickinfo->origin_path, origin_path,
963
sizeof(brickinfo->origin_path));
965
snprintf(key, sizeof(key), "%s.fs_type", prefix);
966
ret = dict_get_str(dict, key, &fs_type);
968
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
969
"%s missing in payload", key);
972
gf_strncpy(brickinfo->fstype, fs_type, sizeof(brickinfo->fstype));
974
snprintf(key, sizeof(key), "%s.snap_type", prefix);
975
ret = dict_get_str(dict, key, &snap_type);
977
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
978
"%s missing in payload", key);
981
gf_strncpy(brickinfo->snap_type, snap_type, sizeof(brickinfo->snap_type));
983
snprintf(key, sizeof(key), "%s.mnt_opts", prefix);
984
ret = dict_get_str(dict, key, &mnt_opts);
986
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
987
"%s missing in payload", key);
990
gf_strncpy(brickinfo->mnt_opts, mnt_opts, sizeof(brickinfo->mnt_opts));
992
snprintf(key, sizeof(key), "%s.mount_dir", prefix);
993
ret = dict_get_str(dict, key, &mount_dir);
995
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
996
"%s missing in payload", key);
999
gf_strncpy(brickinfo->mount_dir, mount_dir, sizeof(brickinfo->mount_dir));
1009
gd_import_volume_snap_details(dict_t *dict, glusterd_volinfo_t *volinfo,
1010
char *prefix, char *volname)
1013
xlator_t *this = THIS;
1017
char *restored_snap = NULL;
1018
char *restored_snapname_id = NULL;
1019
char *restored_snapname = NULL;
1020
char *snap_plugin = NULL;
1022
GF_VALIDATE_OR_GOTO(this->name, (dict != NULL), out);
1023
GF_VALIDATE_OR_GOTO(this->name, (volinfo != NULL), out);
1024
GF_VALIDATE_OR_GOTO(this->name, (prefix != NULL), out);
1025
GF_VALIDATE_OR_GOTO(this->name, (volname != NULL), out);
1027
snprintf(key, sizeof(key), "%s.is_snap_volume", prefix);
1028
uint32_t is_snap_int;
1029
ret = dict_get_uint32(dict, key, &is_snap_int);
1031
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
1032
"%s missing in payload "
1037
volinfo->is_snap_volume = (is_snap_int != 0);
1039
snprintf(key, sizeof(key), "%s.restored_from_snap", prefix);
1040
ret = dict_get_str(dict, key, &restored_snap);
1042
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
1043
"%s missing in payload "
1048
gf_uuid_parse(restored_snap, volinfo->restored_from_snap);
1050
snprintf(key, sizeof(key), "%s.restored_from_snapname_id", prefix);
1051
ret = dict_get_str(dict, key, &restored_snapname_id);
1053
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
1054
"%s missing in payload "
1058
gf_strncpy(volinfo->restored_from_snapname_id, restored_snapname_id,
1059
sizeof(volinfo->restored_from_snapname_id));
1061
snprintf(key, sizeof(key), "%s.restored_from_snapname", prefix);
1062
ret = dict_get_str(dict, key, &restored_snapname);
1064
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
1065
"%s missing in payload "
1069
gf_strncpy(volinfo->restored_from_snapname, restored_snapname,
1070
sizeof(volinfo->restored_from_snapname));
1072
snprintf(key, sizeof(key), "%s.snap_plugin", prefix);
1073
ret = dict_get_str(dict, key, &snap_plugin);
1075
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
1076
"%s missing in payload "
1080
gf_strncpy(volinfo->snap_plugin, snap_plugin,
1081
sizeof(volinfo->snap_plugin));
1083
snprintf(key, sizeof(key), "%s.snap-max-hard-limit", prefix);
1084
ret = dict_get_uint64(dict, key, &volinfo->snap_max_hard_limit);
1086
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
1087
"%s missing in payload "
1095
glusterd_perform_missed_op(glusterd_snap_t *snap, int32_t op)
1097
dict_t *dict = NULL;
1099
glusterd_conf_t *priv = NULL;
1100
glusterd_volinfo_t *snap_volinfo = NULL;
1101
glusterd_volinfo_t *volinfo = NULL;
1102
glusterd_volinfo_t *tmp = NULL;
1103
xlator_t *this = THIS;
1104
uuid_t null_uuid = {0};
1105
char *parent_volname = NULL;
1106
gf_boolean_t retain_origin_path = _gf_false;
1107
glusterd_brickinfo_t *brickinfo = NULL;
1108
int32_t brick_count = -1;
1110
priv = this->private;
1116
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_CREATE_FAIL,
1117
"Unable to create dict");
1123
case GF_SNAP_OPTION_TYPE_DELETE:
1124
ret = glusterd_snap_remove(dict, snap, _gf_true, _gf_false,
1127
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAP_REMOVE_FAIL,
1128
"Failed to remove snap");
1133
case GF_SNAP_OPTION_TYPE_RESTORE:
1134
cds_list_for_each_entry_safe(snap_volinfo, tmp, &snap->volumes,
1137
parent_volname = gf_strdup(snap_volinfo->parent_volname);
1138
if (!parent_volname)
1141
ret = glusterd_volinfo_find(parent_volname, &volinfo);
1143
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLINFO_GET_FAIL,
1144
"Could not get volinfo of %s", parent_volname);
1149
ret = glusterd_bricks_snapshot_restore(dict, snap_volinfo,
1150
&retain_origin_path);
1152
gf_msg(this->name, GF_LOG_ERROR, 0,
1153
GD_MSG_SNAP_RESTORE_FAIL, "Failed to restore snap");
1158
gf_uuid_copy(volinfo->restored_from_snap, null_uuid);
1159
strcpy(volinfo->restored_from_snapname_id, "");
1160
strcpy(volinfo->restored_from_snapname, "");
1169
ret = gd_restore_snap_volume(dict, dict, volinfo, snap_volinfo,
1170
0, retain_origin_path);
1172
gf_msg(this->name, GF_LOG_ERROR, 0,
1173
GD_MSG_SNAP_RESTORE_FAIL,
1174
"Failed to restore snap for %s", snap->snapname);
1182
if (!gf_uuid_is_null(volinfo->restored_from_snap)) {
1183
cds_list_for_each_entry(brickinfo, &volinfo->bricks,
1187
if (gf_uuid_compare(brickinfo->uuid, MY_UUID))
1190
ret = glusterd_snapshot_remove(dict, volinfo, brickinfo,
1193
gf_msg(this->name, GF_LOG_ERROR, 0,
1194
GD_MSG_SNAP_REMOVE_FAIL,
1195
"Failed to remove LVM backend");
1204
cds_list_del_init(&volinfo->vol_list);
1205
glusterd_volinfo_unref(volinfo);
1207
ret = glusterd_snapshot_restore_cleanup(dict, parent_volname,
1210
gf_msg(this->name, GF_LOG_ERROR, 0,
1211
GD_MSG_SNAP_CLEANUP_FAIL,
1212
"Failed to perform snapshot restore "
1213
"cleanup for %s volume",
1218
GF_FREE(parent_volname);
1219
parent_volname = NULL;
1227
gf_msg(this->name, GF_LOG_ERROR, EINVAL, GD_MSG_INVALID_ENTRY,
1228
"Invalid missed snap entry");
1235
if (parent_volname) {
1236
GF_FREE(parent_volname);
1237
parent_volname = NULL;
1240
gf_msg_trace(this->name, 0, "Returning %d", ret);
1246
glusterd_perform_missed_snap_ops(void)
1249
int32_t op_status = -1;
1250
glusterd_conf_t *priv = NULL;
1251
glusterd_missed_snap_info *missed_snapinfo = NULL;
1252
glusterd_snap_op_t *snap_opinfo = NULL;
1253
glusterd_snap_t *snap = NULL;
1254
uuid_t snap_uuid = {
1257
xlator_t *this = THIS;
1259
priv = this->private;
1262
cds_list_for_each_entry(missed_snapinfo, &priv->missed_snaps_list,
1266
if (strcmp(missed_snapinfo->node_uuid, uuid_utoa(MY_UUID)))
1270
gf_uuid_parse(missed_snapinfo->snap_uuid, snap_uuid);
1272
snap = glusterd_find_snap_by_id(snap_uuid);
1277
gf_msg_debug(this->name, 0, "Not a pending delete or restore op");
1281
op_status = GD_MISSED_SNAP_PENDING;
1282
cds_list_for_each_entry(snap_opinfo, &missed_snapinfo->snap_ops,
1288
if ((snap_opinfo->status == GD_MISSED_SNAP_DONE) ||
1289
(snap_opinfo->op == GF_SNAP_OPTION_TYPE_CREATE))
1297
if (op_status == GD_MISSED_SNAP_PENDING) {
1298
ret = glusterd_perform_missed_op(snap, snap_opinfo->op);
1300
gf_msg(this->name, GF_LOG_ERROR, 0,
1301
GD_MSG_SNAPSHOT_OP_FAILED,
1302
"Failed to perform missed snap op");
1305
op_status = GD_MISSED_SNAP_DONE;
1308
snap_opinfo->status = GD_MISSED_SNAP_DONE;
1314
gf_msg_trace(this->name, 0, "Returning %d", ret);
1321
glusterd_import_friend_missed_snap_list(dict_t *peer_data)
1323
int32_t missed_snap_count = -1;
1325
glusterd_conf_t *priv = NULL;
1326
xlator_t *this = THIS;
1328
GF_ASSERT(peer_data);
1330
priv = this->private;
1334
ret = dict_get_int32(peer_data, "missed_snap_count", &missed_snap_count);
1336
gf_msg(this->name, GF_LOG_INFO, 0, GD_MSG_MISSED_SNAP_GET_FAIL,
1342
ret = glusterd_add_missed_snaps_to_list(peer_data, missed_snap_count);
1344
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MISSED_SNAP_LIST_STORE_FAIL,
1345
"Failed to add missed snaps to list");
1349
ret = glusterd_perform_missed_snap_ops();
1351
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAPSHOT_OP_FAILED,
1352
"Failed to perform snap operations");
1359
ret = glusterd_store_update_missed_snaps();
1361
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MISSED_SNAP_LIST_STORE_FAIL,
1362
"Failed to update missed_snaps_list");
1367
gf_msg_trace(this->name, 0, "Returning %d", ret);
1377
glusterd_check_peer_has_higher_snap_version(dict_t *peer_data,
1378
char *peer_snap_name, int volcount,
1379
gf_boolean_t *conflict,
1380
char *prefix, glusterd_snap_t *snap,
1383
glusterd_volinfo_t *snap_volinfo = NULL;
1384
char key[256] = {0};
1385
int version = 0, i = 0;
1387
xlator_t *this = THIS;
1390
GF_ASSERT(peer_data);
1392
for (i = 1; i <= volcount; i++) {
1393
snprintf(key, sizeof(key), "%s%d.version", prefix, i);
1394
ret = dict_get_int32(peer_data, key, &version);
1396
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
1398
"version of snap volume = %s",
1406
snap_volinfo = cds_list_entry(snap->volumes.next, glusterd_volinfo_t,
1408
if (!snap_volinfo) {
1409
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLINFO_GET_FAIL,
1410
"Failed to get snap "
1416
if (version > snap_volinfo->version) {
1418
gf_msg(this->name, GF_LOG_INFO, 0, GD_MSG_VOL_VERS_MISMATCH,
1419
"Version of volume %s differ. "
1420
"local version = %d, remote version = %d "
1422
snap_volinfo->volname, snap_volinfo->version, version,
1424
*conflict = _gf_true;
1427
*conflict = _gf_false;
1443
glusterd_is_peer_snap_conflicting(char *peer_snap_name, char *peer_snap_id,
1444
gf_boolean_t *conflict,
1445
glusterd_snap_t **snap, char *hostname)
1447
uuid_t peer_snap_uuid = {
1450
xlator_t *this = THIS;
1452
GF_ASSERT(peer_snap_name);
1453
GF_ASSERT(peer_snap_id);
1454
GF_ASSERT(conflict);
1456
GF_ASSERT(hostname);
1458
*snap = glusterd_find_snap_by_name(peer_snap_name);
1460
gf_uuid_parse(peer_snap_id, peer_snap_uuid);
1461
if (!gf_uuid_compare(peer_snap_uuid, (*snap)->snap_id)) {
1465
gf_msg_debug(this->name, 0,
1466
"Snapshot %s from peer %s present in "
1468
peer_snap_name, hostname);
1469
*conflict = _gf_false;
1474
gf_msg_debug(this->name, 0,
1475
"Snapshot %s from peer %s conflicts with "
1476
"snapshot in localhost",
1477
peer_snap_name, hostname);
1478
*conflict = _gf_true;
1482
gf_msg(this->name, GF_LOG_INFO, 0, GD_MSG_MISSED_SNAP_PRESENT,
1483
"Snapshot %s from peer %s missing on localhost", peer_snap_name,
1485
*conflict = _gf_false;
1491
glusterd_are_snap_bricks_local(glusterd_snap_t *snap)
1493
gf_boolean_t is_local = _gf_false;
1494
glusterd_volinfo_t *volinfo = NULL;
1495
glusterd_brickinfo_t *brickinfo = NULL;
1499
cds_list_for_each_entry(volinfo, &snap->volumes, vol_list)
1501
cds_list_for_each_entry(brickinfo, &volinfo->bricks, brick_list)
1503
if (!gf_uuid_compare(brickinfo->uuid, MY_UUID)) {
1504
is_local = _gf_true;
1511
gf_msg_trace(THIS->name, 0, "Returning %d", is_local);
1519
glusterd_peer_has_missed_snap_delete(uuid_t peerid, char *peer_snap_id)
1521
char *peer_uuid = NULL;
1522
gf_boolean_t missed_delete = _gf_false;
1523
glusterd_conf_t *priv = NULL;
1524
glusterd_missed_snap_info *missed_snapinfo = NULL;
1525
glusterd_snap_op_t *snap_opinfo = NULL;
1526
xlator_t *this = THIS;
1528
priv = this->private;
1530
GF_ASSERT(peer_snap_id);
1532
peer_uuid = uuid_utoa(peerid);
1534
cds_list_for_each_entry(missed_snapinfo, &priv->missed_snaps_list,
1540
if ((!strcmp(peer_uuid, missed_snapinfo->node_uuid)) &&
1541
(!strcmp(peer_snap_id, missed_snapinfo->snap_uuid))) {
1545
cds_list_for_each_entry(snap_opinfo, &missed_snapinfo->snap_ops,
1548
if (((snap_opinfo->op == GF_SNAP_OPTION_TYPE_DELETE) ||
1549
(snap_opinfo->op == GF_SNAP_OPTION_TYPE_RESTORE)) &&
1550
(snap_opinfo->status == GD_MISSED_SNAP_PENDING)) {
1551
missed_delete = _gf_true;
1559
gf_msg_trace(this->name, 0, "Returning %d", missed_delete);
1560
return missed_delete;
1565
glusterd_gen_snap_volfiles(glusterd_volinfo_t *snap_vol, char *peer_snap_name)
1568
xlator_t *this = THIS;
1569
glusterd_volinfo_t *parent_volinfo = NULL;
1571
GF_ASSERT(snap_vol);
1572
GF_ASSERT(peer_snap_name);
1574
ret = glusterd_store_volinfo(snap_vol, GLUSTERD_VOLINFO_VER_AC_NONE);
1576
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLINFO_SET_FAIL,
1577
"Failed to store snapshot "
1578
"volinfo (%s) for snap %s",
1579
snap_vol->volname, peer_snap_name);
1583
ret = generate_brick_volfiles(snap_vol);
1585
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLFILE_CREATE_FAIL,
1586
"generating the brick volfiles for the "
1592
ret = generate_client_volfiles(snap_vol, GF_CLIENT_TRUSTED);
1594
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLFILE_CREATE_FAIL,
1595
"generating the trusted client volfiles for "
1596
"the snap %s failed",
1601
ret = generate_client_volfiles(snap_vol, GF_CLIENT_OTHER);
1603
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLFILE_CREATE_FAIL,
1604
"generating the client volfiles for the "
1610
ret = glusterd_volinfo_find(snap_vol->parent_volname, &parent_volinfo);
1612
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLINFO_GET_FAIL,
1614
"not found for %s volume of snap %s",
1615
snap_vol->volname, peer_snap_name);
1619
glusterd_list_add_snapvol(parent_volinfo, snap_vol);
1621
ret = glusterd_store_volinfo(snap_vol, GLUSTERD_VOLINFO_VER_AC_NONE);
1623
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLINFO_SET_FAIL,
1624
"Failed to store snap volinfo");
1628
gf_msg_trace(this->name, 0, "Returning %d", ret);
1634
glusterd_import_friend_snap(dict_t *peer_data, int32_t snap_count,
1635
char *peer_snap_name, char *peer_snap_id)
1638
char prefix[32] = "";
1639
char *description = NULL;
1640
dict_t *dict = NULL;
1641
glusterd_snap_t *snap = NULL;
1642
glusterd_volinfo_t *snap_vol = NULL;
1643
glusterd_conf_t *priv = NULL;
1645
int32_t volcount = -1;
1647
xlator_t *this = THIS;
1650
priv = this->private;
1652
GF_ASSERT(peer_data);
1653
GF_ASSERT(peer_snap_name);
1654
GF_ASSERT(peer_snap_id);
1656
snprintf(prefix, sizeof(prefix), "snap%d", snap_count);
1658
snap = glusterd_new_snap_object();
1660
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAP_CREATION_FAIL,
1662
"the snap object for snap %s",
1669
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_CREATE_FAIL,
1670
"Failed to create dict");
1675
gf_strncpy(snap->snapname, peer_snap_name, sizeof(snap->snapname));
1676
gf_uuid_parse(peer_snap_id, snap->snap_id);
1678
snprintf(buf, sizeof(buf), "%s.description", prefix);
1679
ret = dict_get_str(peer_data, buf, &description);
1680
if (ret == 0 && description) {
1681
snap->description = gf_strdup(description);
1682
if (snap->description == NULL) {
1683
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAP_CREATION_FAIL,
1684
"Saving the Snapshot Description Failed");
1690
snprintf(buf, sizeof(buf), "%s.time_stamp", prefix);
1691
ret = dict_get_int64(peer_data, buf, &time_stamp);
1693
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
1694
"Unable to get time_stamp for snap %s", peer_snap_name);
1697
snap->time_stamp = (time_t)time_stamp;
1699
snprintf(buf, sizeof(buf), "%s.snap_restored", prefix);
1700
ret = dict_get_int8(peer_data, buf, (int8_t *)&snap->snap_restored);
1702
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
1703
"Unable to get snap_restored for snap %s", peer_snap_name);
1707
snprintf(buf, sizeof(buf), "%s.snap_status", prefix);
1708
ret = dict_get_int32(peer_data, buf, (int32_t *)&snap->snap_status);
1710
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
1711
"Unable to get snap_status for snap %s", peer_snap_name);
1717
if (snap->snap_status == GD_SNAP_STATUS_DECOMMISSION) {
1718
gf_msg_debug(this->name, 0,
1719
"The snap(%s) is scheduled to be decommissioned "
1720
"Not accepting the snap.",
1722
glusterd_snap_remove(dict, snap, _gf_true, _gf_true, _gf_false);
1727
snprintf(buf, sizeof(buf), "%s.volcount", prefix);
1728
ret = dict_get_int32(peer_data, buf, &volcount);
1730
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
1731
"Unable to get volcount for snap %s", peer_snap_name);
1735
ret = glusterd_store_create_snap_dir(snap);
1737
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAPDIR_CREATE_FAIL,
1738
"Failed to create snap dir");
1742
glusterd_list_add_order(&snap->snap_list, &priv->snapshots,
1743
glusterd_compare_snap_time);
1745
for (i = 1; i <= volcount; i++) {
1746
ret = glusterd_import_volinfo(peer_data, i, &snap_vol, prefix);
1748
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLINFO_SET_FAIL,
1749
"Failed to import snap volinfo for "
1755
snap_vol->snapshot = snap;
1757
ret = glusterd_gen_snap_volfiles(snap_vol, peer_snap_name);
1759
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLFILE_CREATE_FAIL,
1760
"Failed to generate snap vol files "
1769
if (glusterd_is_volume_started(snap_vol)) {
1770
ret = glusterd_recreate_vol_brick_mounts(this, snap_vol);
1772
gf_msg(this->name, GF_LOG_ERROR, 0,
1773
GD_MSG_BRK_MNT_RECREATE_FAIL,
1774
"Failed to recreate brick mounts"
1780
(void)glusterd_start_bricks(snap_vol);
1781
ret = glusterd_store_volinfo(snap_vol,
1782
GLUSTERD_VOLINFO_VER_AC_NONE);
1784
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLINFO_STORE_FAIL,
1786
"write volinfo for volume %s",
1791
(void)glusterd_stop_bricks(snap_vol);
1792
ret = glusterd_snap_unmount(this, snap_vol);
1794
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_GLUSTERD_UMOUNT_FAIL,
1795
"Failed to unmounts for %s", snap->snapname);
1799
ret = glusterd_import_quota_conf(peer_data, i, snap_vol, prefix);
1801
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_QUOTA_CONFIG_IMPORT_FAIL,
1802
"Failed to import quota conf "
1811
ret = glusterd_store_snap(snap);
1813
gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_SNAP_CREATION_FAIL,
1814
"Could not store snap"
1819
glusterd_fetchsnap_notify(this);
1823
glusterd_snap_remove(dict, snap, _gf_true, _gf_true, _gf_false);
1828
gf_msg_trace(this->name, 0, "Returning %d", ret);
1870
glusterd_compare_snap(dict_t *peer_data, int32_t snap_count, char *peername,
1874
char prefix[32] = "";
1875
char *peer_snap_name = NULL;
1876
char *peer_snap_id = NULL;
1877
glusterd_snap_t *snap = NULL;
1878
gf_boolean_t conflict = _gf_false;
1879
gf_boolean_t is_local = _gf_false;
1880
gf_boolean_t is_hosted = _gf_false;
1881
gf_boolean_t missed_delete = _gf_false;
1883
int32_t volcount = 0;
1884
xlator_t *this = THIS;
1886
GF_ASSERT(peer_data);
1887
GF_ASSERT(peername);
1889
snprintf(prefix, sizeof(prefix), "snap%d", snap_count);
1891
ret = dict_set_uint32(peer_data, buf, 0);
1892
snprintf(buf, sizeof(buf), "%s.accept_peer_data", prefix);
1893
ret = dict_set_uint32(peer_data, buf, 0);
1894
snprintf(buf, sizeof(buf), "%s.remove_lvm", prefix);
1895
ret = dict_set_uint32(peer_data, buf, 0);
1896
snprintf(buf, sizeof(buf), "%s.remove_my_data", prefix);
1897
ret = dict_set_uint32(peer_data, buf, 0);
1900
snprintf(buf, sizeof(buf), "%s.snapname", prefix);
1901
ret = dict_get_str(peer_data, buf, &peer_snap_name);
1903
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
1904
"Unable to fetch snapname from peer: %s", peername);
1909
snprintf(buf, sizeof(buf), "%s.snap_id", prefix);
1910
ret = dict_get_str(peer_data, buf, &peer_snap_id);
1912
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
1913
"Unable to fetch snap_id from peer: %s", peername);
1917
snprintf(buf, sizeof(buf), "%s.volcount", prefix);
1918
ret = dict_get_int32(peer_data, buf, &volcount);
1920
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
1921
"Unable to get volcount for snap %s", peer_snap_name);
1928
missed_delete = glusterd_peer_has_missed_snap_delete(peerid, peer_snap_id);
1929
if (missed_delete == _gf_true) {
1931
gf_msg(this->name, GF_LOG_INFO, 0, GD_MSG_MISSED_SNAP_DELETE,
1932
"Peer %s has missed a delete "
1934
peername, peer_snap_name);
1942
glusterd_is_peer_snap_conflicting(peer_snap_name, peer_snap_id, &conflict,
1944
if (conflict == _gf_false) {
1949
snprintf(buf, sizeof(buf), "%s.accept_peer_data", prefix);
1950
ret = dict_set_uint32(peer_data, buf, 1);
1958
ret = glusterd_check_peer_has_higher_snap_version(
1959
peer_data, peer_snap_name, volcount, &conflict, prefix, snap,
1962
gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_VOL_VERS_MISMATCH,
1964
"to check version of snap volume");
1967
if (conflict == _gf_true) {
1977
snprintf(buf, sizeof(buf), "%s.remove_lvm", prefix);
1978
ret = dict_set_uint32(peer_data, buf, 0);
1979
snprintf(buf, sizeof(buf), "%s.remove_my_data", prefix);
1980
ret = dict_set_uint32(peer_data, buf, 1);
1981
snprintf(buf, sizeof(buf), "%s.accept_peer_data", prefix);
1982
ret = dict_set_uint32(peer_data, buf, 1);
1993
is_local = glusterd_are_snap_bricks_local(snap);
1998
snprintf(buf, sizeof(buf), "%s.host_bricks", prefix);
1999
ret = dict_get_int8(peer_data, buf, (int8_t *)&is_hosted);
2001
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
2002
"Unable to fetch host_bricks from peer: %s "
2004
peername, peer_snap_name);
2014
if (is_hosted == is_local) {
2015
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAP_CONFLICT,
2016
"Conflict in snapshot %s with peer %s", peer_snap_name,
2022
if (is_hosted == _gf_false) {
2026
gf_msg_debug(this->name, 0,
2027
"Peer doesn't hosts bricks for conflicting "
2028
"snap(%s). Not accepting peer data.",
2038
gf_msg_debug(this->name, 0,
2039
"Peer hosts bricks for conflicting "
2040
"snap(%s). Removing local data. Accepting peer data.",
2042
snprintf(buf, sizeof(buf), "%s.remove_lvm", prefix);
2043
ret = dict_set_uint32(peer_data, buf, 1);
2044
snprintf(buf, sizeof(buf), "%s.remove_my_data", prefix);
2045
ret = dict_set_uint32(peer_data, buf, 1);
2046
snprintf(buf, sizeof(buf), "%s.accept_peer_data", prefix);
2047
ret = dict_set_uint32(peer_data, buf, 1);
2050
gf_msg_trace(this->name, 0, "Returning %d", ret);
2055
glusterd_update_snaps_synctask(void *opaque)
2058
int32_t snap_count = 0;
2060
xlator_t *this = THIS;
2061
dict_t *peer_data = NULL;
2063
char prefix[32] = "";
2064
char *peer_snap_name = NULL;
2065
char *peer_snap_id = NULL;
2066
char *peername = NULL;
2067
gf_boolean_t remove_lvm = _gf_false;
2068
gf_boolean_t remove_my_data = _gf_false;
2069
gf_boolean_t accept_peer_data = _gf_false;
2071
glusterd_snap_t *snap = NULL;
2072
dict_t *dict = NULL;
2073
glusterd_conf_t *conf = NULL;
2075
conf = this->private;
2078
peer_data = (dict_t *)opaque;
2079
GF_ASSERT(peer_data);
2081
synclock_lock(&conf->big_lock);
2083
while (conf->restart_bricks) {
2084
synccond_wait(&conf->cond_restart_bricks, &conf->big_lock);
2086
conf->restart_bricks = _gf_true;
2088
ret = dict_get_int32(peer_data, "snap_count", &snap_count);
2090
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
2091
"Failed to fetch snap_count");
2094
ret = dict_get_str(peer_data, "peername", &peername);
2096
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
2097
"Failed to fetch peername");
2101
for (i = 1; i <= snap_count; i++) {
2102
snprintf(prefix, sizeof(prefix), "snap%d", i);
2105
snprintf(buf, sizeof(buf), "%s.snapname", prefix);
2106
ret = dict_get_str(peer_data, buf, &peer_snap_name);
2108
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
2109
"Unable to fetch snapname from peer: %s", peername);
2114
snprintf(buf, sizeof(buf), "%s.snap_id", prefix);
2115
ret = dict_get_str(peer_data, buf, &peer_snap_id);
2117
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
2118
"Unable to fetch snap_id from peer: %s", peername);
2123
snprintf(buf, sizeof(buf), "%s.remove_my_data", prefix);
2124
ret = dict_get_int32(peer_data, buf, &val);
2126
remove_my_data = _gf_true;
2128
remove_my_data = _gf_false;
2130
if (remove_my_data) {
2131
snprintf(buf, sizeof(buf), "%s.remove_lvm", prefix);
2132
ret = dict_get_int32(peer_data, buf, &val);
2134
remove_lvm = _gf_true;
2136
remove_lvm = _gf_false;
2140
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_CREATE_FAIL,
2141
"Unable to create dict");
2145
snap = glusterd_find_snap_by_name(peer_snap_name);
2147
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_MISSED_SNAP_PRESENT,
2148
"Snapshot %s from peer %s missing on "
2150
peer_snap_name, peername);
2155
ret = glusterd_snap_remove(dict, snap, remove_lvm, _gf_false,
2158
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAP_REMOVE_FAIL,
2159
"Failed to remove snap %s", snap->snapname);
2166
snprintf(buf, sizeof(buf), "%s.accept_peer_data", prefix);
2167
ret = dict_get_int32(peer_data, buf, &val);
2169
accept_peer_data = _gf_true;
2171
accept_peer_data = _gf_false;
2173
if (accept_peer_data) {
2175
ret = glusterd_import_friend_snap(peer_data, i, peer_snap_name,
2178
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAP_IMPORT_FAIL,
2179
"Failed to import snap %s from peer %s", peer_snap_name,
2188
dict_unref(peer_data);
2191
conf->restart_bricks = _gf_false;
2192
synccond_broadcast(&conf->cond_restart_bricks);
2201
glusterd_compare_friend_snapshots(dict_t *peer_data, char *peername,
2205
int32_t snap_count = 0;
2207
xlator_t *this = THIS;
2208
dict_t *peer_data_copy = NULL;
2210
GF_ASSERT(peer_data);
2211
GF_ASSERT(peername);
2213
ret = dict_get_int32(peer_data, "snap_count", &snap_count);
2215
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
2216
"Failed to fetch snap_count");
2223
for (i = 1; i <= snap_count; i++) {
2225
ret = glusterd_compare_snap(peer_data, i, peername, peerid);
2227
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAPSHOT_OP_FAILED,
2228
"Failed to compare snapshots with peer %s", peername);
2233
peer_data_copy = dict_copy_with_ref(peer_data, NULL);
2234
ret = dict_set_str(peer_data_copy, "peername", peername);
2236
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
2237
"Failed to set peername into the dict");
2239
dict_unref(peer_data_copy);
2242
glusterd_launch_synctask(glusterd_update_snaps_synctask, peer_data_copy);
2245
gf_msg_trace(this->name, 0, "Returning %d", ret);
2250
glusterd_add_snapd_to_dict(glusterd_volinfo_t *volinfo, dict_t *dict,
2255
int32_t brick_online = -1;
2257
char base_key[32] = {0};
2258
char pidfile[PATH_MAX] = {0};
2259
xlator_t *this = THIS;
2264
snprintf(base_key, sizeof(base_key), "brick%d", count);
2265
snprintf(key, sizeof(key), "%s.hostname", base_key);
2266
ret = dict_set_str(dict, key, "Snapshot Daemon");
2268
gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Key=%s",
2273
snprintf(key, sizeof(key), "%s.path", base_key);
2274
ret = dict_set_dynstr(dict, key, gf_strdup(uuid_utoa(MY_UUID)));
2276
gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Key=%s",
2281
snprintf(key, sizeof(key), "%s.port", base_key);
2282
ret = dict_set_int32(dict, key, volinfo->snapd.port);
2284
gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Key=%s",
2289
glusterd_svc_build_snapd_pidfile(volinfo, pidfile, sizeof(pidfile));
2291
brick_online = gf_is_service_running(pidfile, &pid);
2292
if (brick_online == _gf_false)
2295
snprintf(key, sizeof(key), "%s.pid", base_key);
2296
ret = dict_set_int32(dict, key, pid);
2298
gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED, "Key=%s",
2303
snprintf(key, sizeof(key), "%s.status", base_key);
2304
ret = dict_set_int32(dict, key, brick_online);
2308
gf_msg_debug(this->name, 0, "Returning %d", ret);
2314
glusterd_snap_config_use_rsp_dict(dict_t *dst, dict_t *src)
2316
char buf[PATH_MAX] = "";
2317
char *volname = NULL;
2319
int config_command = 0;
2321
uint64_t hard_limit = GLUSTERD_SNAPS_MAX_HARD_LIMIT;
2322
uint64_t soft_limit = GLUSTERD_SNAPS_DEF_SOFT_LIMIT_PERCENT;
2324
uint64_t voldisplaycount = 0;
2327
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_EMPTY,
2328
"Source or Destination "
2333
ret = dict_get_int32(dst, "config-command", &config_command);
2335
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
2336
"failed to get config-command type");
2340
switch (config_command) {
2341
case GF_SNAP_CONFIG_DISPLAY:
2342
ret = dict_get_uint64(src, GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT,
2345
ret = dict_set_uint64(
2346
dst, GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT, hard_limit);
2348
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
2349
"Unable to set snap_max_hard_limit");
2358
ret = dict_get_uint64(src, GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT,
2361
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
2362
"Unable to get snap_max_soft_limit");
2366
ret = dict_set_uint64(dst, GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT,
2369
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
2370
"Unable to set snap_max_soft_limit");
2374
ret = dict_get_uint64(src, "voldisplaycount", &voldisplaycount);
2376
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
2377
"Unable to get voldisplaycount");
2381
ret = dict_set_uint64(dst, "voldisplaycount", voldisplaycount);
2383
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
2384
"Unable to set voldisplaycount");
2388
for (i = 0; i < voldisplaycount; i++) {
2389
snprintf(buf, sizeof(buf), "volume%" PRIu64 "-volname", i);
2390
ret = dict_get_str(src, buf, &volname);
2392
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
2393
"Unable to get %s", buf);
2396
ret = dict_set_str(dst, buf, volname);
2398
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
2399
"Unable to set %s", buf);
2403
snprintf(buf, sizeof(buf),
2404
"volume%" PRIu64 "-snap-max-hard-limit", i);
2405
ret = dict_get_uint64(src, buf, &value);
2407
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
2408
"Unable to get %s", buf);
2411
ret = dict_set_uint64(dst, buf, value);
2413
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
2414
"Unable to set %s", buf);
2418
snprintf(buf, sizeof(buf),
2419
"volume%" PRIu64 "-active-hard-limit", i);
2420
ret = dict_get_uint64(src, buf, &value);
2422
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
2423
"Unable to get %s", buf);
2426
ret = dict_set_uint64(dst, buf, value);
2428
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
2429
"Unable to set %s", buf);
2433
snprintf(buf, sizeof(buf),
2434
"volume%" PRIu64 "-snap-max-soft-limit", i);
2435
ret = dict_get_uint64(src, buf, &value);
2437
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
2438
"Unable to get %s", buf);
2441
ret = dict_set_uint64(dst, buf, value);
2443
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
2444
"Unable to set %s", buf);
2456
gf_msg_debug("glusterd", 0, "Returning %d", ret);
2461
glusterd_merge_brick_status(dict_t *dst, dict_t *src)
2463
int64_t volume_count = 0;
2466
int64_t brick_count = 0;
2467
int64_t brick_order = 0;
2471
char key_prefix[16] = {
2474
char snapbrckcnt[PATH_MAX] = {
2477
char snapbrckord[PATH_MAX] = {
2480
char *clonename = NULL;
2482
int32_t brick_online = 0;
2483
xlator_t *this = THIS;
2484
int32_t snap_command = 0;
2487
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_EMPTY,
2488
"Source or Destination "
2493
ret = dict_get_int32(dst, "type", &snap_command);
2495
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
2496
"unable to get the type of "
2497
"the snapshot command");
2501
if (snap_command == GF_SNAP_OPTION_TYPE_DELETE) {
2502
gf_msg_debug(this->name, 0,
2503
"snapshot delete command."
2504
" Need not merge the status of the bricks");
2511
ret = dict_get_str(dst, "clonename", &clonename);
2513
snprintf(key_prefix, sizeof(key_prefix), "snap-vol");
2515
snprintf(key_prefix, sizeof(key_prefix), "clone");
2517
ret = dict_get_int64(src, "volcount", &volume_count);
2519
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
2521
"get the volume count");
2525
for (index = 0; index < volume_count; index++) {
2526
ret = snprintf(snapbrckcnt, sizeof(snapbrckcnt) - 1,
2527
"snap-vol%" PRId64 "_brickcount", index + 1);
2528
ret = dict_get_int64(src, snapbrckcnt, &brick_count);
2530
gf_msg_trace(this->name, 0,
2531
"No bricks for this volume in this dict (%s)",
2536
for (j = 0; j < brick_count; j++) {
2538
snprintf(snapbrckord, sizeof(snapbrckord) - 1,
2539
"snap-vol%" PRId64 ".brick%" PRId64 ".order", index + 1,
2542
ret = dict_get_int64(src, snapbrckord, &brick_order);
2544
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
2545
"Failed to get brick order (%s)", snapbrckord);
2549
snprintf(key, sizeof(key), "%s%" PRId64 ".brick%" PRId64 ".status",
2550
key_prefix, index + 1, brick_order);
2551
ret = dict_get_int32(src, key, &brick_online);
2553
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
2555
"get the brick status (%s)",
2560
ret = dict_set_int32(dst, key, brick_online);
2562
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
2564
"set the brick status (%s)",
2581
glusterd_snap_create_use_rsp_dict(dict_t *dst, dict_t *src)
2584
char *tmp_str = NULL;
2585
char name_buf[PATH_MAX] = "";
2588
int32_t src_missed_snap_count = -1;
2589
int32_t dst_missed_snap_count = -1;
2590
xlator_t *this = THIS;
2591
int8_t soft_limit_flag = -1;
2594
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_EMPTY,
2595
"Source or Destination "
2600
ret = glusterd_merge_brick_status(dst, src);
2602
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_BRICK_SET_INFO_FAIL,
2603
"failed to merge brick "
2608
ret = dict_get_str(src, "snapuuid", &buf);
2610
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
2611
"failed to get snap UUID");
2615
ret = dict_set_dynstr_with_alloc(dst, "snapuuid", buf);
2617
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
2618
"Failed to set snap uuid in dict");
2624
ret = dict_get_int8(src, "soft-limit-reach", &soft_limit_flag);
2626
ret = dict_set_int8(dst, "soft-limit-reach", soft_limit_flag);
2628
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
2635
ret = dict_get_int32(src, "missed_snap_count", &src_missed_snap_count);
2637
gf_msg_debug(this->name, 0, "No missed snaps");
2642
ret = dict_get_int32(dst, "missed_snap_count", &dst_missed_snap_count);
2645
dst_missed_snap_count = 0;
2648
for (i = 0; i < src_missed_snap_count; i++) {
2649
snprintf(name_buf, sizeof(name_buf), "missed_snaps_%d", i);
2650
ret = dict_get_str(src, name_buf, &buf);
2652
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
2653
"Unable to fetch %s", name_buf);
2657
snprintf(name_buf, sizeof(name_buf), "missed_snaps_%d",
2658
dst_missed_snap_count);
2660
tmp_str = gf_strdup(buf);
2666
ret = dict_set_dynstr(dst, name_buf, tmp_str);
2668
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
2669
"Unable to set %s", name_buf);
2674
dst_missed_snap_count++;
2677
ret = dict_set_int32(dst, "missed_snap_count", dst_missed_snap_count);
2679
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
2680
"Unable to set dst_missed_snap_count");
2688
gf_msg_trace(this->name, 0, "Returning %d", ret);
2693
glusterd_snap_use_rsp_dict(dict_t *dst, dict_t *src)
2696
int32_t snap_command = 0;
2699
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_EMPTY,
2700
"Source or Destination "
2705
ret = dict_get_int32(dst, "type", &snap_command);
2707
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
2708
"unable to get the type of "
2709
"the snapshot command");
2713
switch (snap_command) {
2714
case GF_SNAP_OPTION_TYPE_CREATE:
2715
case GF_SNAP_OPTION_TYPE_DELETE:
2716
case GF_SNAP_OPTION_TYPE_CLONE:
2717
ret = glusterd_snap_create_use_rsp_dict(dst, src);
2719
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_RSP_DICT_USE_FAIL,
2720
"Unable to use rsp dict");
2724
case GF_SNAP_OPTION_TYPE_CONFIG:
2725
ret = glusterd_snap_config_use_rsp_dict(dst, src);
2727
gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_RSP_DICT_USE_FAIL,
2728
"Unable to use rsp dict");
2735
dict_copy(src, dst);
2741
gf_msg_debug("glusterd", 0, "Returning %d", ret);
2746
glusterd_compare_snap_time(struct cds_list_head *list1,
2747
struct cds_list_head *list2)
2749
glusterd_snap_t *snap1 = NULL;
2750
glusterd_snap_t *snap2 = NULL;
2751
double diff_time = 0;
2756
snap1 = cds_list_entry(list1, glusterd_snap_t, snap_list);
2757
snap2 = cds_list_entry(list2, glusterd_snap_t, snap_list);
2758
diff_time = difftime(snap1->time_stamp, snap2->time_stamp);
2760
return (int)diff_time;
2764
glusterd_compare_snap_vol_time(struct cds_list_head *list1,
2765
struct cds_list_head *list2)
2767
glusterd_volinfo_t *snapvol1 = NULL;
2768
glusterd_volinfo_t *snapvol2 = NULL;
2769
double diff_time = 0;
2774
snapvol1 = cds_list_entry(list1, glusterd_volinfo_t, snapvol_list);
2775
snapvol2 = cds_list_entry(list2, glusterd_volinfo_t, snapvol_list);
2776
diff_time = difftime(snapvol1->snapshot->time_stamp,
2777
snapvol2->snapshot->time_stamp);
2779
return (int)diff_time;
2783
glusterd_missed_snapinfo_new(glusterd_missed_snap_info **missed_snapinfo)
2785
glusterd_missed_snap_info *new_missed_snapinfo = NULL;
2787
xlator_t *this = THIS;
2789
GF_ASSERT(missed_snapinfo);
2791
new_missed_snapinfo = GF_CALLOC(1, sizeof(*new_missed_snapinfo),
2792
gf_gld_mt_missed_snapinfo_t);
2794
if (!new_missed_snapinfo) {
2795
gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_NO_MEMORY, NULL);
2799
CDS_INIT_LIST_HEAD(&new_missed_snapinfo->missed_snaps);
2800
CDS_INIT_LIST_HEAD(&new_missed_snapinfo->snap_ops);
2802
*missed_snapinfo = new_missed_snapinfo;
2807
gf_msg_trace(this->name, 0, "Returning %d", ret);
2812
glusterd_missed_snap_op_new(glusterd_snap_op_t **snap_op)
2814
glusterd_snap_op_t *new_snap_op = NULL;
2816
xlator_t *this = THIS;
2820
new_snap_op = GF_CALLOC(1, sizeof(*new_snap_op),
2821
gf_gld_mt_missed_snapinfo_t);
2824
gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_NO_MEMORY, NULL);
2828
new_snap_op->brick_num = -1;
2829
new_snap_op->op = -1;
2830
new_snap_op->status = -1;
2831
CDS_INIT_LIST_HEAD(&new_snap_op->snap_ops_list);
2833
*snap_op = new_snap_op;
2837
gf_msg_trace(this->name, 0, "Returning %d", ret);
2842
glusterd_mntopts_exists(const char *str, const char *opts)
2844
char *dup_val = NULL;
2845
char *savetok = NULL;
2847
gf_boolean_t exists = _gf_false;
2851
if (!str || !strlen(str))
2854
dup_val = gf_strdup(str);
2858
token = strtok_r(dup_val, ",", &savetok);
2860
if (!strcmp(token, opts)) {
2864
token = strtok_r(NULL, ",", &savetok);
2873
glusterd_volume_quorum_check(glusterd_volinfo_t *volinfo, int64_t index,
2874
dict_t *dict, const char *key_prefix,
2875
char **op_errstr, uint32_t *op_errno)
2878
xlator_t *this = THIS;
2885
glusterd_conf_t *priv = NULL;
2886
gf_boolean_t quorum_met = _gf_false;
2887
int distribute_subvols = 0;
2888
int32_t brick_online = 0;
2889
const char err_str[] = "One or more bricks may be down.";
2891
priv = this->private;
2893
GF_VALIDATE_OR_GOTO(this->name, op_errno, out);
2895
if (!volinfo || !dict) {
2896
gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_INVALID_ENTRY,
2897
"input parameters NULL");
2901
if ((!glusterd_is_volume_replicate(volinfo) ||
2902
volinfo->replica_count < 3) &&
2903
(GF_CLUSTER_TYPE_DISPERSE != volinfo->type)) {
2904
for (i = 0; i < volinfo->brick_count; i++) {
2909
keylen = snprintf(key, sizeof(key),
2910
"%s%" PRId64 ".brick%" PRId64 ".status",
2911
key_prefix, index, i);
2912
ret = dict_get_int32n(dict, key, keylen, &brick_online);
2913
if (ret || !brick_online) {
2915
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_BRICK_DISCONNECTED,
2917
*op_errstr = gf_strdup(err_str);
2918
*op_errno = EG_BRCKDWN;
2923
distribute_subvols = volinfo->brick_count / volinfo->dist_leaf_count;
2924
for (j = 0; j < distribute_subvols; j++) {
2930
for (i = 0; i < volinfo->dist_leaf_count; i++) {
2932
key, sizeof(key), "%s%" PRId64 ".brick%" PRId64 ".status",
2933
key_prefix, index, (j * volinfo->dist_leaf_count) + i);
2934
ret = dict_get_int32n(dict, key, keylen, &brick_online);
2935
if (ret || !brick_online) {
2937
gf_msg(this->name, GF_LOG_ERROR, 0,
2938
GD_MSG_BRICK_DISCONNECTED, "%s", err_str);
2939
*op_errstr = gf_strdup(err_str);
2940
*op_errno = EG_BRCKDWN;
2947
quorum_met = _gf_true;
2949
gf_msg_debug(this->name, 0, "All bricks in volume %s are online.",
2959
glusterd_snap_common_quorum_calculate(glusterd_volinfo_t *volinfo, dict_t *dict,
2960
int64_t index, const char *key_prefix,
2961
char **op_errstr, uint32_t *op_errno)
2964
xlator_t *this = THIS;
2966
GF_VALIDATE_OR_GOTO(this->name, op_errno, out);
2967
GF_VALIDATE_OR_GOTO(this->name, volinfo, out);
2969
ret = glusterd_volume_quorum_check(volinfo, index, dict, key_prefix,
2970
op_errstr, op_errno);
2972
gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_VOL_NOT_FOUND,
2984
glusterd_snap_quorum_check_for_clone(dict_t *dict, gf_boolean_t snap_volume,
2985
char **op_errstr, uint32_t *op_errno)
2987
const char err_str[] = "glusterds are not in quorum";
2988
char key_prefix[16] = {
2991
char *snapname = NULL;
2992
glusterd_snap_t *snap = NULL;
2993
glusterd_volinfo_t *volinfo = NULL;
2994
glusterd_volinfo_t *tmp_volinfo = NULL;
2995
char *volname = NULL;
2996
int64_t volcount = 0;
2999
xlator_t *this = THIS;
3001
GF_VALIDATE_OR_GOTO(this->name, op_errno, out);
3004
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_EMPTY, "dict is NULL");
3009
ret = dict_get_str(dict, "snapname", &snapname);
3011
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
3017
snap = glusterd_find_snap_by_name(snapname);
3019
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAP_NOT_FOUND,
3021
"get the snapshot %s",
3032
if (!does_gd_meet_server_quorum(this)) {
3033
gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_SERVER_QUORUM_NOT_MET,
3035
*op_errstr = gf_strdup(err_str);
3036
*op_errno = EG_NODEDWN;
3040
gf_msg_debug(this->name, 0, "glusterds are in quorum");
3042
ret = dict_get_int64(dict, "volcount", &volcount);
3044
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
3050
for (i = 1; i <= volcount; i++) {
3051
ret = dict_get_str(dict, "clonename", &volname);
3053
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
3059
if (snap_volume && snap) {
3060
cds_list_for_each_entry(tmp_volinfo, &snap->volumes, vol_list)
3063
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAP_NOT_FOUND,
3064
"failed to get snap volume "
3070
volinfo = tmp_volinfo;
3073
ret = glusterd_volinfo_find(volname, &volinfo);
3075
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOL_NOT_FOUND,
3076
"failed to find the volume %s", volname);
3081
snprintf(key_prefix, sizeof(key_prefix), "%s",
3082
snap_volume ? "vol" : "clone");
3084
ret = glusterd_snap_common_quorum_calculate(
3085
volinfo, dict, i, key_prefix, op_errstr, op_errno);
3087
gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_VOL_NOT_FOUND,
3099
glusterd_snap_quorum_check_for_create(dict_t *dict, gf_boolean_t snap_volume,
3100
char **op_errstr, uint32_t *op_errno)
3102
const char err_str[] = "glusterds are not in quorum";
3103
char key_prefix[16] = {
3106
char *snapname = NULL;
3107
glusterd_snap_t *snap = NULL;
3108
glusterd_volinfo_t *volinfo = NULL;
3109
char *volname = NULL;
3110
int64_t volcount = 0;
3116
xlator_t *this = THIS;
3118
GF_VALIDATE_OR_GOTO(this->name, op_errno, out);
3121
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_EMPTY, "dict is NULL");
3126
ret = dict_get_str(dict, "snapname", &snapname);
3128
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
3134
snap = glusterd_find_snap_by_name(snapname);
3136
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAP_NOT_FOUND,
3138
"get the snapshot %s",
3149
if (!does_gd_meet_server_quorum(this)) {
3150
gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_SERVER_QUORUM_NOT_MET,
3152
*op_errstr = gf_strdup(err_str);
3153
*op_errno = EG_NODEDWN;
3157
gf_msg_debug(this->name, 0, "glusterds are in quorum");
3159
ret = dict_get_int64(dict, "volcount", &volcount);
3161
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
3167
for (i = 1; i <= volcount; i++) {
3168
snprintf(key, sizeof(key), "%s%" PRId64,
3169
snap_volume ? "snap-volname" : "volname", i);
3170
ret = dict_get_str(dict, key, &volname);
3172
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
3179
ret = glusterd_snap_volinfo_find(volname, snap, &volinfo);
3181
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SNAP_NOT_FOUND,
3182
"failed to get snap volume %s "
3188
ret = glusterd_volinfo_find(volname, &volinfo);
3190
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOL_NOT_FOUND,
3191
"failed to find the volume %s", volname);
3196
snprintf(key_prefix, sizeof(key_prefix), "%s",
3197
snap_volume ? "snap-vol" : "vol");
3199
ret = glusterd_snap_common_quorum_calculate(
3200
volinfo, dict, i, key_prefix, op_errstr, op_errno);
3202
gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_VOL_NOT_FOUND,
3214
glusterd_snap_quorum_check(dict_t *dict, gf_boolean_t snap_volume,
3215
char **op_errstr, uint32_t *op_errno)
3218
xlator_t *this = THIS;
3219
int32_t snap_command = 0;
3220
const char err_str[] = "glusterds are not in quorum";
3222
GF_VALIDATE_OR_GOTO(this->name, op_errno, out);
3225
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_EMPTY, "dict is NULL");
3229
ret = dict_get_int32(dict, "type", &snap_command);
3231
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
3232
"unable to get the type of "
3233
"the snapshot command");
3237
switch (snap_command) {
3238
case GF_SNAP_OPTION_TYPE_CREATE:
3239
ret = glusterd_snap_quorum_check_for_create(dict, snap_volume,
3240
op_errstr, op_errno);
3242
gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_QUORUM_CHECK_FAIL,
3244
"failed during snapshot create command");
3248
case GF_SNAP_OPTION_TYPE_CLONE:
3249
ret = glusterd_snap_quorum_check_for_clone(dict, !snap_volume,
3250
op_errstr, op_errno);
3252
gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_QUORUM_CHECK_FAIL,
3254
"failed during snapshot clone command");
3258
case GF_SNAP_OPTION_TYPE_DELETE:
3259
case GF_SNAP_OPTION_TYPE_RESTORE:
3260
if (!does_gd_meet_server_quorum(this)) {
3262
gf_msg(this->name, GF_LOG_WARNING, 0,
3263
GD_MSG_SERVER_QUORUM_NOT_MET, "%s", err_str);
3264
*op_errstr = gf_strdup(err_str);
3265
*op_errno = EG_NODEDWN;
3269
gf_msg_debug(this->name, 0,
3284
glusterd_is_path_mounted(const char *path)
3287
struct mntent *part = NULL;
3290
if ((mtab = setmntent("/etc/mtab", "r")) != NULL) {
3291
while ((part = getmntent(mtab)) != NULL) {
3292
if ((part->mnt_fsname != NULL) &&
3293
(strcmp(part->mnt_dir, path)) == 0) {
3305
glusterd_snap_unmount(xlator_t *this, glusterd_volinfo_t *volinfo)
3307
char *brick_mount_path = NULL;
3308
glusterd_brickinfo_t *brickinfo = NULL;
3310
int retry_count = 0;
3311
int brick_count = -1;
3312
struct glusterd_snap_ops *snap_ops = NULL;
3316
glusterd_snapshot_plugin_by_name(volinfo->snap_plugin, &snap_ops);
3318
cds_list_for_each_entry(brickinfo, &volinfo->bricks, brick_list)
3323
if (gf_uuid_compare(brickinfo->uuid, MY_UUID)) {
3327
if (brickinfo->snap_status == -1) {
3331
ret = glusterd_find_brick_mount_path(brickinfo->path,
3334
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_BRK_MNTPATH_GET_FAIL,
3335
"Failed to find brick_mount_path for %s", brickinfo->path);
3343
while (retry_count <= 2) {
3345
ret = snap_ops->deactivate(brickinfo, volinfo->snapshot->snapname,
3346
volinfo->volname, brick_count);
3349
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_GLUSTERD_UMOUNT_FAIL,
3351
"for path %s (brick: %s): %s. Retry(%d)",
3352
brick_mount_path, brickinfo->path, strerror(errno),
3359
if (brick_mount_path)
3360
GF_FREE(brick_mount_path);
3366
glusterd_copy_file(const char *source, const char *destination)
3369
xlator_t *this = THIS;
3370
char buffer[1024] = "";
3374
struct stat stbuf = {
3377
mode_t dest_mode = 0;
3380
GF_ASSERT(destination);
3383
ret = sys_lstat(source, &stbuf);
3385
gf_msg(this->name, GF_LOG_ERROR, errno, GD_MSG_FILE_OP_FAILED,
3386
"%s not found", source);
3390
dest_mode = stbuf.st_mode & 0777;
3392
src_fd = open(source, O_RDONLY);
3395
gf_msg(this->name, GF_LOG_ERROR, errno, GD_MSG_FILE_OP_FAILED,
3396
"Unable to open file %s", source);
3400
dest_fd = sys_creat(destination, dest_mode);
3403
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_FILE_OP_FAILED,
3404
"Unble to open a file %s", destination);
3409
ret = sys_read(src_fd, buffer, sizeof(buffer));
3411
gf_msg(this->name, GF_LOG_ERROR, errno, GD_MSG_FILE_OP_FAILED,
3412
"Error reading file "
3421
ret = sys_write(dest_fd, buffer, read_len);
3422
if (ret != read_len) {
3423
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_FILE_OP_FAILED,
3425
"file %s failed with error %s",
3426
destination, strerror(errno));
3440
glusterd_copy_folder(const char *source, const char *destination)
3443
xlator_t *this = THIS;
3444
DIR *dir_ptr = NULL;
3445
struct dirent *entry = NULL;
3446
struct dirent scratch[2] = {
3451
char src_path[PATH_MAX] = {
3454
char dest_path[PATH_MAX] = {
3459
GF_ASSERT(destination);
3461
dir_ptr = sys_opendir(source);
3463
gf_msg(this->name, GF_LOG_ERROR, errno, GD_MSG_DIR_OP_FAILED,
3464
"Unable to open %s", source);
3470
entry = sys_readdir(dir_ptr, scratch);
3471
if (!entry || errno != 0)
3474
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
3476
ret = snprintf(src_path, sizeof(src_path), "%s/%s", source,
3479
gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_COPY_FAIL, NULL);
3483
ret = snprintf(dest_path, sizeof(dest_path), "%s/%s", destination,
3486
gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_COPY_FAIL, NULL);
3490
ret = glusterd_copy_file(src_path, dest_path);
3492
gf_msg(this->name, GF_LOG_ERROR, ENOMEM, GD_MSG_NO_MEMORY,
3495
src_path, dest_path);
3501
(void)sys_closedir(dir_ptr);
3507
glusterd_get_geo_rep_session(char *secondary_key, char *origin_volname,
3508
dict_t *gsync_secondaries_dict, char *session,
3518
char *ip_temp = NULL;
3519
char *buffer = NULL;
3520
char *secondary_temp = NULL;
3521
char *save_ptr = NULL;
3523
GF_ASSERT(secondary_key);
3524
GF_ASSERT(origin_volname);
3525
GF_ASSERT(gsync_secondaries_dict);
3527
ret = dict_get_str(gsync_secondaries_dict, secondary_key, &buffer);
3529
gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
3531
"get value for key %s",
3536
temp = gf_strdup(buffer);
3545
token = strtok_r(temp, "/", &save_ptr);
3547
token = strtok_r(NULL, ":", &save_ptr);
3554
ip = gf_strdup(token);
3561
token = strtok_r(NULL, ":", &save_ptr);
3567
secondary_temp = gf_strdup(token);
3576
ip_temp = gf_strdup(ip);
3577
tok = strtok_r(ip_temp, "@", &save_ptr);
3579
tok = strtok_r(NULL, "@", &save_ptr);
3581
ip_i = ip + len + 1;
3583
ret = snprintf(session, PATH_MAX, "%s_%s_%s", origin_volname, ip_i,
3588
ret = snprintf(secondary, PATH_MAX, "%s::%s", ip, secondary_temp);
3606
GF_FREE(secondary_temp);
3612
glusterd_copy_quota_files(glusterd_volinfo_t *src_vol,
3613
glusterd_volinfo_t *dest_vol,
3614
gf_boolean_t *conf_present)
3617
char src_dir[PATH_MAX] = "";
3618
char dest_dir[PATH_MAX] = "";
3619
char src_path[PATH_MAX] = "";
3620
char dest_path[PATH_MAX] = "";
3621
xlator_t *this = THIS;
3622
glusterd_conf_t *priv = NULL;
3623
struct stat stbuf = {
3627
priv = this->private;
3631
GF_ASSERT(dest_vol);
3633
GLUSTERD_GET_VOLUME_DIR(src_dir, src_vol, priv);
3635
GLUSTERD_GET_VOLUME_DIR(dest_dir, dest_vol, priv);
3637
ret = snprintf(src_path, sizeof(src_path), "%s/quota.conf", src_dir);
3639
gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_COPY_FAIL, NULL);
3646
ret = sys_lstat(src_path, &stbuf);
3649
gf_msg_debug(this->name, 0, "%s not found", src_path);
3653
ret = snprintf(dest_path, sizeof(dest_path), "%s/quota.conf", dest_dir);
3655
gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_COPY_FAIL, NULL);
3659
ret = glusterd_copy_file(src_path, dest_path);
3661
gf_msg(this->name, GF_LOG_ERROR, ENOMEM, GD_MSG_NO_MEMORY,
3662
"Failed to copy %s in %s", src_path, dest_path);
3666
ret = snprintf(src_path, sizeof(src_path), "%s/quota.cksum", src_dir);
3673
ret = sys_lstat(src_path, &stbuf);
3675
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_FILE_NOT_FOUND,
3676
"%s not found", src_path);
3680
ret = snprintf(dest_path, sizeof(dest_path), "%s/quota.cksum", dest_dir);
3682
gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_COPY_FAIL, NULL);
3686
ret = glusterd_copy_file(src_path, dest_path);
3688
gf_msg(this->name, GF_LOG_ERROR, ENOMEM, GD_MSG_NO_MEMORY,
3689
"Failed to copy %s in %s", src_path, dest_path);
3693
*conf_present = _gf_true;
3706
glusterd_copy_nfs_ganesha_file(glusterd_volinfo_t *src_vol,
3707
glusterd_volinfo_t *dest_vol)
3710
char snap_dir[PATH_MAX] = {
3713
char src_path[PATH_MAX] = {
3716
char dest_path[PATH_MAX] = {
3719
char buffer[BUFSIZ] = {
3722
char *find_ptr = NULL;
3723
char *buff_ptr = NULL;
3724
char *tmp_ptr = NULL;
3725
xlator_t *this = THIS;
3726
glusterd_conf_t *priv = NULL;
3727
struct stat stbuf = {
3733
priv = this->private;
3734
GF_VALIDATE_OR_GOTO(this->name, priv, out);
3736
GF_VALIDATE_OR_GOTO(this->name, src_vol, out);
3737
GF_VALIDATE_OR_GOTO(this->name, dest_vol, out);
3739
if (glusterd_check_ganesha_export(src_vol) == _gf_false) {
3740
gf_msg_debug(this->name, 0,
3741
"%s is not exported via "
3742
"NFS-Ganesha. Skipping copy of export conf.",
3748
if (src_vol->is_snap_volume) {
3749
GLUSTERD_GET_SNAP_DIR(snap_dir, src_vol->snapshot, priv);
3750
ret = snprintf(src_path, PATH_MAX, "%s/export.%s.conf", snap_dir,
3751
src_vol->snapshot->snapname);
3753
ret = snprintf(src_path, PATH_MAX, "%s/export.%s.conf",
3754
GANESHA_EXPORT_DIRECTORY, src_vol->volname);
3756
if (ret < 0 || ret >= PATH_MAX)
3759
ret = sys_lstat(src_path, &stbuf);
3766
gf_msg(this->name, GF_LOG_ERROR, errno, GD_MSG_FILE_OP_FAILED,
3767
"Stat on %s failed with %s", src_path, strerror(errno));
3771
if (dest_vol->is_snap_volume) {
3772
memset(snap_dir, 0, PATH_MAX);
3773
GLUSTERD_GET_SNAP_DIR(snap_dir, dest_vol->snapshot, priv);
3774
ret = snprintf(dest_path, sizeof(dest_path), "%s/export.%s.conf",
3775
snap_dir, dest_vol->snapshot->snapname);
3779
ret = glusterd_copy_file(src_path, dest_path);
3781
gf_msg(this->name, GF_LOG_ERROR, ENOMEM, GD_MSG_NO_MEMORY,
3782
"Failed to copy %s in %s", src_path, dest_path);
3787
ret = snprintf(dest_path, sizeof(dest_path), "%s/export.%s.conf",
3788
GANESHA_EXPORT_DIRECTORY, dest_vol->volname);
3792
src = fopen(src_path, "r");
3793
dest = fopen(dest_path, "w");
3795
if (!src || !dest) {
3796
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_FILE_OP_FAILED,
3797
"Failed to open %s", dest ? src_path : dest_path);
3806
if (src_vol->is_snap_volume)
3807
find_ptr = gf_strdup(src_vol->parent_volname);
3809
find_ptr = gf_strdup(src_vol->volname);
3815
while (fgets(buffer, BUFSIZ, src)) {
3817
while ((tmp_ptr = strstr(buff_ptr, find_ptr))) {
3818
while (buff_ptr < tmp_ptr)
3819
fputc((int)*buff_ptr++, dest);
3820
fputs(dest_vol->volname, dest);
3821
buff_ptr += strlen(find_ptr);
3823
fputs(buff_ptr, dest);
3824
memset(buffer, 0, BUFSIZ);
3839
glusterd_restore_geo_rep_files(glusterd_volinfo_t *snap_vol)
3842
char src_path[PATH_MAX] = "";
3843
char dest_path[PATH_MAX] = "";
3844
xlator_t *this = THIS;
3845
char *origin_volname = NULL;
3846
glusterd_volinfo_t *origin_vol = NULL;
3849
char session[PATH_MAX] = "";
3850
char secondary[PATH_MAX] = "";
3851
char snapgeo_dir[PATH_MAX] = "";
3852
glusterd_conf_t *priv = NULL;
3854
priv = this->private;
3857
GF_ASSERT(snap_vol);
3859
origin_volname = gf_strdup(snap_vol->parent_volname);
3860
if (!origin_volname) {
3865
ret = glusterd_volinfo_find(origin_volname, &origin_vol);
3867
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOL_NOT_FOUND,
3869
"volinfo for volname %s",
3874
for (i = 1; i <= snap_vol->gsync_secondaries->count; i++) {
3875
ret = snprintf(key, sizeof(key), "secondary%d", i);
3889
ret = glusterd_get_geo_rep_session(key, origin_vol->volname,
3890
snap_vol->gsync_secondaries, session,
3893
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_GEOREP_GET_FAILED,
3894
"Failed to get geo-rep session");
3898
GLUSTERD_GET_SNAP_GEO_REP_DIR(snapgeo_dir, snap_vol->snapshot, priv);
3899
ret = snprintf(src_path, sizeof(src_path), "%s/%s", snapgeo_dir,
3904
ret = snprintf(dest_path, sizeof(dest_path), "%s/%s/%s", priv->workdir,
3909
ret = glusterd_copy_folder(src_path, dest_path);
3911
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DIR_OP_FAILED,
3914
src_path, dest_path);
3920
GF_FREE(origin_volname);
3926
glusterd_restore_nfs_ganesha_file(glusterd_volinfo_t *src_vol,
3927
glusterd_snap_t *snap)
3930
char snap_dir[PATH_MAX] = "";
3931
char src_path[PATH_MAX] = "";
3932
char dest_path[PATH_MAX] = "";
3933
xlator_t *this = THIS;
3934
glusterd_conf_t *priv = NULL;
3935
struct stat stbuf = {
3939
priv = this->private;
3940
GF_VALIDATE_OR_GOTO(this->name, priv, out);
3942
GF_VALIDATE_OR_GOTO(this->name, src_vol, out);
3943
GF_VALIDATE_OR_GOTO(this->name, snap, out);
3945
GLUSTERD_GET_SNAP_DIR(snap_dir, snap, priv);
3947
ret = snprintf(src_path, sizeof(src_path), "%s/export.%s.conf", snap_dir,
3950
gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_COPY_FAIL, NULL);
3954
ret = sys_lstat(src_path, &stbuf);
3956
if (errno == ENOENT) {
3958
gf_msg_debug(this->name, errno, "%s not found", src_path);
3960
gf_msg(this->name, GF_LOG_WARNING, errno, GD_MSG_FILE_OP_FAILED,
3961
"Stat on %s failed with %s", src_path, strerror(errno));
3965
ret = snprintf(dest_path, sizeof(dest_path), "%s/export.%s.conf",
3966
GANESHA_EXPORT_DIRECTORY, src_vol->volname);
3968
gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_COPY_FAIL, NULL);
3972
ret = glusterd_copy_file(src_path, dest_path);
3974
gf_msg(this->name, GF_LOG_ERROR, ENOMEM, GD_MSG_NO_MEMORY,
3975
"Failed to copy %s in %s", src_path, dest_path);
3983
glusterd_is_snapd_enabled(glusterd_volinfo_t *volinfo)
3987
ret = dict_get_str_boolean(volinfo->dict, "features.uss", -2);
3989
gf_msg_debug(THIS->name, 0,
3990
"Key features.uss not "
3991
"present in the dict for volume %s",
3995
} else if (ret == -1) {
3996
gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
3997
"Failed to get 'features.uss'"
3998
" from dict for volume %s",
4006
glusterd_is_snap_soft_limit_reached(glusterd_volinfo_t *volinfo, dict_t *dict)
4009
uint64_t opt_max_hard = GLUSTERD_SNAPS_MAX_HARD_LIMIT;
4010
uint64_t opt_max_soft = GLUSTERD_SNAPS_DEF_SOFT_LIMIT_PERCENT;
4012
int auto_delete = 0;
4013
uint64_t effective_max_limit = 0;
4014
xlator_t *this = THIS;
4015
glusterd_conf_t *priv = NULL;
4020
priv = this->private;
4027
gd_get_snap_conf_values_if_present(priv->opts, &opt_max_hard,
4034
auto_delete = dict_get_str_boolean(
4035
priv->opts, GLUSTERD_STORE_KEY_SNAP_AUTO_DELETE, _gf_false);
4037
if (volinfo->snap_max_hard_limit < opt_max_hard)
4038
effective_max_limit = volinfo->snap_max_hard_limit;
4040
effective_max_limit = opt_max_hard;
4042
limit = (opt_max_soft * effective_max_limit) / 100;
4044
if (volinfo->snap_count >= limit && auto_delete != _gf_true) {
4045
gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_SOFT_LIMIT_REACHED,
4048
") of volume %s is reached. "
4049
"Snapshot creation is not possible once effective "
4050
"hard-limit (value = %" PRIu64 ") is reached.",
4051
limit, volinfo->volname, effective_max_limit);
4053
ret = dict_set_int8(dict, "soft-limit-reach", _gf_true);
4055
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
4057
"set soft limit exceed flag in "
4058
"response dictionary");
4075
gd_get_snap_conf_values_if_present(dict_t *dict, uint64_t *sys_hard_limit,
4076
uint64_t *sys_soft_limit)
4078
xlator_t *this = THIS;
4086
if (dict_get_uint64(dict, GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT,
4088
gf_msg_debug(this->name, 0,
4089
"%s is not present in"
4091
GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT);
4098
if (dict_get_uint64(dict, GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT,
4100
gf_msg_debug(this->name, 0,
4101
"%s is not present in"
4103
GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT);
4108
glusterd_get_snap_status_str(glusterd_snap_t *snapinfo, char *snap_status_str)
4112
GF_VALIDATE_OR_GOTO(THIS->name, snapinfo, out);
4113
GF_VALIDATE_OR_GOTO(THIS->name, snap_status_str, out);
4115
switch (snapinfo->snap_status) {
4116
case GD_SNAP_STATUS_NONE:
4117
sprintf(snap_status_str, "%s", "none");
4119
case GD_SNAP_STATUS_INIT:
4120
sprintf(snap_status_str, "%s", "init");
4122
case GD_SNAP_STATUS_IN_USE:
4123
sprintf(snap_status_str, "%s", "in_use");
4125
case GD_SNAP_STATUS_DECOMMISSION:
4126
sprintf(snap_status_str, "%s", "decommissioned");
4128
case GD_SNAP_STATUS_UNDER_RESTORE:
4129
sprintf(snap_status_str, "%s", "under_restore");
4131
case GD_SNAP_STATUS_RESTORED:
4132
sprintf(snap_status_str, "%s", "restored");
4143
glusterd_snapshot_plugin_by_name(char *name,
4144
struct glusterd_snap_ops **snap_ops)
4146
xlator_t *this = NULL;
4150
if (strcmp(name, "LVM") == 0)
4151
*snap_ops = &lvm_snap_ops;
4152
else if (strcmp(name, "ZFS") == 0)
4153
*snap_ops = &zfs_snap_ops;
4155
gf_msg_debug(this->name, 0, "Loaded Snapshot plugin %s", name);
4159
glusterd_snapshot_probe(char *brick_path, glusterd_brickinfo_t *brickinfo)
4161
struct glusterd_snap_ops *glusterd_snap_backend[] = {
4166
xlator_t *this = NULL;
4171
if (brickinfo->snap)
4174
gf_log(this->name, GF_LOG_INFO, "Probing brick %s for snapshot support",
4176
for (i = 0; glusterd_snap_backend[i]; i++) {
4177
if (glusterd_snap_backend[i]->probe(brick_path)) {
4178
gf_log(this->name, GF_LOG_INFO, "%s backend detected",
4179
glusterd_snap_backend[i]->name);
4180
brickinfo->snap = glusterd_snap_backend[i];
4183
gf_log(this->name, GF_LOG_DEBUG, "not a %s backend",
4184
glusterd_snap_backend[i]->name);
4195
glusterd_is_cmd_available(char *cmd)
4205
ret = sys_stat(cmd, &buf);
4207
gf_msg(THIS->name, GF_LOG_ERROR, errno, GD_MSG_FILE_OP_FAILED,
4208
"stat fails on %s, exiting. (errno = %d (%s))", cmd, errno,
4213
if ((!ret) && (!S_ISREG(buf.st_mode))) {
4214
gf_msg(THIS->name, GF_LOG_CRITICAL, EINVAL, GD_MSG_COMMAND_NOT_FOUND,
4215
"Provided command %s is not a regular file,"
4221
if ((!ret) && (!(buf.st_mode & S_IXUSR))) {
4222
gf_msg(THIS->name, GF_LOG_CRITICAL, 0, GD_MSG_NO_EXEC_PERMS,
4223
"Provided command %s has no exec permissions,"