Skip to content
This repository was archived by the owner on Oct 7, 2023. It is now read-only.

Commit e4352ce

Browse files
author
Anthony Romano
authored
Merge pull request #77 from heyitsanthony/fix-root-stat
zetcd: fix stat data for root directory
2 parents de71a64 + 393dde8 commit e4352ce

File tree

3 files changed

+39
-20
lines changed

3 files changed

+39
-20
lines changed

integration/integration_test.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,14 +271,20 @@ func TestSync(t *testing.T) {
271271

272272
func TestExists(t *testing.T) {
273273
runTest(t, func(t *testing.T, c *zk.Conn) {
274+
if ok, _, err := c.Exists("/"); err != nil || !ok {
275+
t.Errorf("expected /, got err=%v, ok=%v", err, ok)
276+
}
274277
if _, err := c.Create("/abc", []byte(""), 0, acl); err != nil {
275278
t.Fatal(err)
276279
}
280+
if ok, _, err := c.Exists("/"); err != nil || !ok {
281+
t.Errorf("expected /, got err=%v, ok=%v", err, ok)
282+
}
277283
if ok, _, err := c.Exists("/abc"); err != nil || !ok {
278-
t.Fatalf("expected it to exist %v %v", err, ok)
284+
t.Errorf("expected it to exist %v %v", err, ok)
279285
}
280286
if ok, _, err := c.Exists("/ab"); ok {
281-
t.Fatalf("expected it to not exist %v %v", err, ok)
287+
t.Errorf("expected it to not exist %v %v", err, ok)
282288
}
283289
})
284290
}

stat.go

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func statGetsRev(p string, rev int64) []etcd.Op {
3333

3434
func statGets(p string) []etcd.Op { return statGetsRev(p, 0) }
3535

36-
func statTxn(txnresp *etcd.TxnResponse) (s Stat) {
36+
func statTxn(p string, txnresp *etcd.TxnResponse) (s Stat, err error) {
3737
ctime := txnresp.Responses[0].GetResponseRange()
3838
mtime := txnresp.Responses[1].GetResponseRange()
3939
node := txnresp.Responses[2].GetResponseRange()
@@ -64,5 +64,21 @@ func statTxn(txnresp *etcd.TxnResponse) (s Stat) {
6464
s.DataLength = int32(len(node.Kvs[0].Value))
6565
}
6666
s.NumChildren = int32(len(children.Kvs))
67-
return s
67+
68+
if p != "/" {
69+
if s.Ctime == 0 {
70+
return s, ErrNoNode
71+
}
72+
return s, nil
73+
}
74+
75+
// fix ups for special root node
76+
77+
// lie about having the quota dir so stat on "/" xchks OK
78+
s.NumChildren++
79+
// Cversion for root begins at -1, then 0 on first child
80+
if len(cver.Kvs) == 0 {
81+
s.Cversion = -1
82+
}
83+
return s, nil
6884
}

zketcd.go

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,8 @@ func (z *zkEtcd) GetChildren2(xid Xid, op *GetChildren2Request) ZKResponse {
140140
return mkErr(err)
141141
}
142142

143-
resp.Stat = statTxn(txnresp)
144-
if op.Path != "/" && resp.Stat.Ctime == 0 {
145-
return mkZKErr(xid, ZXid(txnresp.Header.Revision), errNoNode)
143+
if resp.Stat, err = statTxn(op.Path, txnresp); err != nil {
144+
return apiErrToZKErr(xid, ZXid(txnresp.Header.Revision), err)
146145
}
147146

148147
children := txnresp.Responses[5].GetResponseRange()
@@ -258,7 +257,7 @@ func (z *zkEtcd) Exists(xid Xid, op *ExistsRequest) ZKResponse {
258257
}
259258

260259
exResp := &ExistsResponse{}
261-
exResp.Stat = statTxn(txnresp)
260+
exResp.Stat, err = statTxn(op.Path, txnresp)
262261
zxid := ZXid(txnresp.Header.Revision)
263262
z.s.Wait(exResp.Stat.Czxid, p, EventNodeCreated)
264263

@@ -279,8 +278,8 @@ func (z *zkEtcd) Exists(xid Xid, op *ExistsRequest) ZKResponse {
279278
z.s.Watch(zxid, xid, p, ev, f)
280279
}
281280

282-
if exResp.Stat.Mtime == 0 {
283-
return mkZKErr(xid, zxid, errNoNode)
281+
if err != nil {
282+
return apiErrToZKErr(xid, zxid, err)
284283
}
285284

286285
glog.V(7).Infof("Exists(%v) = (zxid=%v, resp=%+v)", xid, zxid, *exResp)
@@ -298,9 +297,8 @@ func (z *zkEtcd) GetData(xid Xid, op *GetDataRequest) ZKResponse {
298297
zxid := ZXid(txnresp.Header.Revision)
299298

300299
datResp := &GetDataResponse{}
301-
datResp.Stat = statTxn(txnresp)
302-
if datResp.Stat.Mtime == 0 {
303-
return mkZKErr(xid, zxid, errNoNode)
300+
if datResp.Stat, err = statTxn(op.Path, txnresp); err != nil {
301+
return apiErrToZKErr(xid, zxid, err)
304302
}
305303

306304
z.s.Wait(datResp.Stat.Mzxid, p, EventNodeDataChanged)
@@ -362,7 +360,8 @@ func (z *zkEtcd) mkSetDataTxnOp(op *SetDataRequest) opBundle {
362360
glog.Warningf("set data failed (%v)", err)
363361
return mkZKErr(xid, zxid, errSystemError)
364362
}
365-
return mkZKResp(xid, zxid, &SetDataResponse{Stat: statTxn(statResp)})
363+
st, _ := statTxn(op.Path, statResp)
364+
return mkZKResp(xid, zxid, &SetDataResponse{Stat: st})
366365
}
367366

368367
return opBundle{apply, reply}
@@ -382,9 +381,8 @@ func (z *zkEtcd) GetAcl(xid Xid, op *GetAclRequest) ZKResponse {
382381
zxid := ZXid(txnresp.Header.Revision)
383382
resps := txnresp.Responses
384383
txnresp.Responses = resps[1:]
385-
resp.Stat = statTxn(txnresp)
386-
if resp.Stat.Ctime == 0 {
387-
return mkZKErr(xid, zxid, errNoNode)
384+
if resp.Stat, err = statTxn(op.Path, txnresp); err != nil {
385+
return apiErrToZKErr(xid, zxid, err)
388386
}
389387
resp.Acl = decodeACLs(resps[0].GetResponseRange().Kvs[0].Value)
390388

@@ -410,9 +408,8 @@ func (z *zkEtcd) GetChildren(xid Xid, op *GetChildrenRequest) ZKResponse {
410408
return mkErr(err)
411409
}
412410

413-
s := statTxn(txnresp)
414-
if op.Path != "/" && s.Ctime == 0 {
415-
return mkZKErr(xid, ZXid(txnresp.Header.Revision), errNoNode)
411+
if _, err := statTxn(op.Path, txnresp); err != nil {
412+
return apiErrToZKErr(xid, ZXid(txnresp.Header.Revision), err)
416413
}
417414

418415
children := txnresp.Responses[5].GetResponseRange()

0 commit comments

Comments
 (0)