summaryrefslogtreecommitdiff
path: root/0311-geo-rep-Fix-Permission-denied-traceback-on-non-root-.patch
blob: af0206a7a8570f971e898f3fbdc644d53eea061b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
From 4a2441e76f4240568093080769ede07bb7fb2016 Mon Sep 17 00:00:00 2001
From: Kotresh HR <khiremat@redhat.com>
Date: Sun, 20 Oct 2019 01:01:39 +0530
Subject: [PATCH 311/313] geo-rep: Fix Permission denied traceback on non root
 setup

Problem:
While syncing rename of directory in hybrid crawl, geo-rep
crashes as below.

Traceback (most recent call last):
  File "/usr/local/libexec/glusterfs/python/syncdaemon/repce.py", line 118, in worker
    res = getattr(self.obj, rmeth)(*in_data[2:])
  File "/usr/local/libexec/glusterfs/python/syncdaemon/resource.py", line 588, in entry_ops
    src_entry = get_slv_dir_path(slv_host, slv_volume, gfid)
  File "/usr/local/libexec/glusterfs/python/syncdaemon/syncdutils.py", line 687, in get_slv_dir_path
    [ENOENT], [ESTALE])
  File "/usr/local/libexec/glusterfs/python/syncdaemon/syncdutils.py", line 546, in errno_wrap
    return call(*arg)
PermissionError: [Errno 13] Permission denied: '/bricks/brick1/b1/.glusterfs/8e/c0/8ec0fcd4-d50f-4a6e-b473-a7943ab66640'

Cause:
Conversion of gfid to path for a directory uses readlink on backend
.glusterfs gfid path. But this fails for non root user with
permission denied.

Fix:
Use gfid2path interface to get the path from gfid

Backport of:
 > Patch: https://review.gluster.org/23570
 > Change-Id: I9d40c713a1b32cea95144cbc0f384ada82972222
 > fixes: bz#1763439
 > Signed-off-by: Kotresh HR <khiremat@redhat.com>

Change-Id: I9d40c713a1b32cea95144cbc0f384ada82972222
BUG: 1763412
Signed-off-by: Kotresh HR <khiremat@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/183665
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
---
 geo-replication/syncdaemon/gsyncd.py               |  3 +-
 geo-replication/syncdaemon/syncdutils.py           | 35 ++++++++++++++++------
 tests/00-geo-rep/00-georep-verify-non-root-setup.t | 30 +++++++++++++++----
 3 files changed, 52 insertions(+), 16 deletions(-)

diff --git a/geo-replication/syncdaemon/gsyncd.py b/geo-replication/syncdaemon/gsyncd.py
index 7b48d82..8940384 100644
--- a/geo-replication/syncdaemon/gsyncd.py
+++ b/geo-replication/syncdaemon/gsyncd.py
@@ -231,7 +231,8 @@ def main():
     # Set default path for config file in that case
     # If an subcmd accepts config file then it also accepts
     # master and Slave arguments.
-    if config_file is None and hasattr(args, "config_file"):
+    if config_file is None and hasattr(args, "config_file") \
+        and args.subcmd != "slave":
         config_file = "%s/geo-replication/%s_%s_%s/gsyncd.conf" % (
             GLUSTERD_WORKDIR,
             args.master,
diff --git a/geo-replication/syncdaemon/syncdutils.py b/geo-replication/syncdaemon/syncdutils.py
index aadaebd..b08098e 100644
--- a/geo-replication/syncdaemon/syncdutils.py
+++ b/geo-replication/syncdaemon/syncdutils.py
@@ -57,6 +57,7 @@ from hashlib import sha256 as sha256
 
 # auxiliary gfid based access prefix
 _CL_AUX_GFID_PFX = ".gfid/"
+ROOT_GFID = "00000000-0000-0000-0000-000000000001"
 GF_OP_RETRIES = 10
 
 GX_GFID_CANONICAL_LEN = 37  # canonical gfid len + '\0'
@@ -670,6 +671,7 @@ def get_slv_dir_path(slv_host, slv_volume, gfid):
     global slv_bricks
 
     dir_path = ENOENT
+    pfx = gauxpfx()
 
     if not slv_bricks:
         slv_info = Volinfo(slv_volume, slv_host, master=False)
@@ -683,15 +685,30 @@ def get_slv_dir_path(slv_host, slv_volume, gfid):
                                gfid[2:4],
                                gfid], [ENOENT], [ESTALE])
         if dir_path != ENOENT:
-            realpath = errno_wrap(os.readlink, [dir_path],
-                                  [ENOENT], [ESTALE])
-            if not isinstance(realpath, int):
-                realpath_parts = realpath.split('/')
-                pargfid = realpath_parts[-2]
-                basename = realpath_parts[-1]
-                pfx = gauxpfx()
-                dir_entry = os.path.join(pfx, pargfid, basename)
-                return dir_entry
+            try:
+                realpath = errno_wrap(os.readlink, [dir_path],
+                                      [ENOENT], [ESTALE])
+                if not isinstance(realpath, int):
+                    realpath_parts = realpath.split('/')
+                    pargfid = realpath_parts[-2]
+                    basename = realpath_parts[-1]
+                    dir_entry = os.path.join(pfx, pargfid, basename)
+                    return dir_entry
+            except OSError:
+                # .gfid/GFID
+                gfidpath = unescape_space_newline(os.path.join(pfx, gfid))
+                realpath = errno_wrap(Xattr.lgetxattr_buf,
+                      [gfidpath, 'glusterfs.gfid2path'], [ENOENT], [ESTALE])
+                if not isinstance(realpath, int):
+                    basename = os.path.basename(realpath).rstrip('\x00')
+                    dirpath = os.path.dirname(realpath)
+                    if dirpath is "/":
+                        pargfid = ROOT_GFID
+                    else:
+                        dirpath = dirpath.strip("/")
+                        pargfid = get_gfid_from_mnt(dirpath)
+                    dir_entry = os.path.join(pfx, pargfid, basename)
+                    return dir_entry
 
     return None
 
diff --git a/tests/00-geo-rep/00-georep-verify-non-root-setup.t b/tests/00-geo-rep/00-georep-verify-non-root-setup.t
index e753c1f..c9fd8b2 100644
--- a/tests/00-geo-rep/00-georep-verify-non-root-setup.t
+++ b/tests/00-geo-rep/00-georep-verify-non-root-setup.t
@@ -118,8 +118,8 @@ clean_lock_files
 TEST /usr/sbin/groupadd $grp
 
 clean_lock_files
-##Create non-root user and assign it to newly created group
-
+##Del if exists and create non-root user and assign it to newly created group
+userdel -r -f $usr
 TEST /usr/sbin/useradd -G $grp $usr
 
 ##Modify password for non-root user to have control over distributing ssh-key
@@ -140,8 +140,6 @@ TEST killall_gluster;
 TEST glusterd;
 TEST pidof glusterd;
 
-
-
 ##Create, start and mount meta_volume
 TEST $CLI volume create $META_VOL replica 3 $H0:$B0/${META_VOL}{1,2,3};
 TEST $CLI volume start $META_VOL
@@ -225,6 +223,26 @@ TEST $GEOREP_CLI  $master $slave_url resume
 #Validate failure of volume stop when geo-rep is running
 TEST ! $CLI volume stop $GMV0
 
+#Hybrid directory rename test BZ#1763439
+TEST $GEOREP_CLI $master $slave_url config change_detector xsync
+mkdir ${master_mnt}/dir1
+mkdir ${master_mnt}/dir1/dir2
+mkdir ${master_mnt}/dir1/dir3
+mkdir ${master_mnt}/hybrid_d1
+
+EXPECT_WITHIN $GEO_REP_TIMEOUT 0 directory_ok ${slave_mnt}/hybrid_d1
+EXPECT_WITHIN $GEO_REP_TIMEOUT 0 directory_ok ${slave_mnt}/dir1
+EXPECT_WITHIN $GEO_REP_TIMEOUT 0 directory_ok ${slave_mnt}/dir1/dir2
+EXPECT_WITHIN $GEO_REP_TIMEOUT 0 directory_ok ${slave_mnt}/dir1/dir3
+
+mv ${master_mnt}/hybrid_d1 ${master_mnt}/hybrid_rn_d1
+mv ${master_mnt}/dir1/dir2 ${master_mnt}/rn_dir2
+mv ${master_mnt}/dir1/dir3 ${master_mnt}/dir1/rn_dir3
+
+EXPECT_WITHIN $GEO_REP_TIMEOUT 0 directory_ok ${slave_mnt}/hybrid_rn_d1
+EXPECT_WITHIN $GEO_REP_TIMEOUT 0 directory_ok ${slave_mnt}/rn_dir2
+EXPECT_WITHIN $GEO_REP_TIMEOUT 0 directory_ok ${slave_mnt}/dir1/rn_dir3
+
 #Stop Geo-rep
 TEST $GEOREP_CLI $master $slave_url stop
 
@@ -232,8 +250,8 @@ TEST $GEOREP_CLI $master $slave_url stop
 TEST $GEOREP_CLI $master $slave_url delete
 
 #Cleanup authorized_keys
-sed -i '/^command=.*SSH_ORIGINAL_COMMAND#.*/d' ~/.ssh/authorized_keys
-sed -i '/^command=.*gsyncd.*/d' ~/.ssh/authorized_keys
+sed -i '/^command=.*SSH_ORIGINAL_COMMAND#.*/d' /home/$usr/.ssh/authorized_keys
+sed -i '/^command=.*gsyncd.*/d' /home/$usr/.ssh/authorized_keys
 
 #clear mountbroker
 gluster-mountbroker remove --user $usr
-- 
1.8.3.1