cubefs

Форк
0
/
api_handler.go 
877 строк · 21.3 Кб
1
// Copyright 2018 The CubeFS Authors.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12
// implied. See the License for the specific language governing
13
// permissions and limitations under the License.
14

15
package metanode
16

17
import (
18
	"bytes"
19
	"encoding/json"
20
	"fmt"
21
	"io"
22
	"math"
23
	"net/http"
24
	"os"
25
	"path"
26
	"strconv"
27

28
	"github.com/cubefs/cubefs/proto"
29
	"github.com/cubefs/cubefs/util/config"
30
	"github.com/cubefs/cubefs/util/errors"
31
	"github.com/cubefs/cubefs/util/log"
32
)
33

34
// APIResponse defines the structure of the response to an HTTP request
35
type APIResponse struct {
36
	Code int         `json:"code"`
37
	Msg  string      `json:"msg"`
38
	Data interface{} `json:"data,omitempty"`
39
}
40

41
// NewAPIResponse returns a new API response.
42
func NewAPIResponse(code int, msg string) *APIResponse {
43
	return &APIResponse{
44
		Code: code,
45
		Msg:  msg,
46
	}
47
}
48

49
// Marshal is a wrapper function of json.Marshal
50
func (api *APIResponse) Marshal() ([]byte, error) {
51
	return json.Marshal(api)
52
}
53

54
// register the APIs
55
func (m *MetaNode) registerAPIHandler() (err error) {
56
	http.HandleFunc("/getPartitions", m.getPartitionsHandler)
57
	http.HandleFunc("/getPartitionById", m.getPartitionByIDHandler)
58
	http.HandleFunc("/getLeaderPartitions", m.getLeaderPartitionsHandler)
59
	http.HandleFunc("/getInode", m.getInodeHandler)
60
	http.HandleFunc("/getSplitKey", m.getSplitKeyHandler)
61
	http.HandleFunc("/getExtentsByInode", m.getExtentsByInodeHandler)
62
	http.HandleFunc("/getEbsExtentsByInode", m.getEbsExtentsByInodeHandler)
63
	// get all inodes of the partitionID
64
	http.HandleFunc("/getAllInodes", m.getAllInodesHandler)
65
	// get dentry information
66
	http.HandleFunc("/getDentry", m.getDentryHandler)
67
	http.HandleFunc("/getDirectory", m.getDirectoryHandler)
68
	http.HandleFunc("/getAllDentry", m.getAllDentriesHandler)
69
	http.HandleFunc("/getAllTxInfo", m.getAllTxHandler)
70
	http.HandleFunc("/getParams", m.getParamsHandler)
71
	http.HandleFunc("/getSmuxStat", m.getSmuxStatHandler)
72
	http.HandleFunc("/getRaftStatus", m.getRaftStatusHandler)
73
	http.HandleFunc("/genClusterVersionFile", m.genClusterVersionFileHandler)
74
	http.HandleFunc("/getInodeSnapshot", m.getInodeSnapshotHandler)
75
	http.HandleFunc("/getDentrySnapshot", m.getDentrySnapshotHandler)
76
	// get tx information
77
	http.HandleFunc("/getTx", m.getTxHandler)
78
	return
79
}
80

81
func (m *MetaNode) getParamsHandler(w http.ResponseWriter,
82
	r *http.Request) {
83
	resp := NewAPIResponse(http.StatusOK, http.StatusText(http.StatusOK))
84
	params := make(map[string]interface{})
85
	params[metaNodeDeleteBatchCountKey] = DeleteBatchCount()
86
	resp.Data = params
87
	data, _ := resp.Marshal()
88
	if _, err := w.Write(data); err != nil {
89
		log.LogErrorf("[getPartitionsHandler] response %s", err)
90
	}
91
}
92

93
func (m *MetaNode) getSmuxStatHandler(w http.ResponseWriter,
94
	r *http.Request) {
95
	resp := NewAPIResponse(http.StatusOK, http.StatusText(http.StatusOK))
96
	resp.Data = smuxPool.GetStat()
97
	data, _ := resp.Marshal()
98
	if _, err := w.Write(data); err != nil {
99
		log.LogErrorf("[getSmuxStatHandler] response %s", err)
100
	}
101
}
102

103
func (m *MetaNode) getPartitionsHandler(w http.ResponseWriter,
104
	r *http.Request) {
105
	resp := NewAPIResponse(http.StatusOK, http.StatusText(http.StatusOK))
106
	resp.Data = m.metadataManager
107
	data, _ := resp.Marshal()
108
	if _, err := w.Write(data); err != nil {
109
		log.LogErrorf("[getPartitionsHandler] response %s", err)
110
	}
111
}
112

113
func (m *MetaNode) getPartitionByIDHandler(w http.ResponseWriter, r *http.Request) {
114
	r.ParseForm()
115
	resp := NewAPIResponse(http.StatusBadRequest, "")
116
	defer func() {
117
		data, _ := resp.Marshal()
118
		if _, err := w.Write(data); err != nil {
119
			log.LogErrorf("[getPartitionByIDHandler] response %s", err)
120
		}
121
	}()
122
	pid, err := strconv.ParseUint(r.FormValue("pid"), 10, 64)
123
	if err != nil {
124
		resp.Msg = err.Error()
125
		return
126
	}
127
	mp, err := m.metadataManager.GetPartition(pid)
128
	if err != nil {
129
		resp.Code = http.StatusNotFound
130
		resp.Msg = err.Error()
131
		return
132
	}
133
	msg := make(map[string]interface{})
134
	leader, _ := mp.IsLeader()
135
	_, leaderTerm := mp.LeaderTerm()
136
	msg["leaderAddr"] = leader
137
	msg["leader_term"] = leaderTerm
138
	conf := mp.GetBaseConfig()
139
	msg["partition_id"] = conf.PartitionId
140
	msg["partition_type"] = conf.PartitionType
141
	msg["vol_name"] = conf.VolName
142
	msg["start"] = conf.Start
143
	msg["end"] = conf.End
144
	msg["peers"] = conf.Peers
145
	msg["nodeId"] = conf.NodeId
146
	msg["cursor"] = conf.Cursor
147
	resp.Data = msg
148
	resp.Code = http.StatusOK
149
	resp.Msg = http.StatusText(http.StatusOK)
150
}
151

152
func (m *MetaNode) getLeaderPartitionsHandler(w http.ResponseWriter, r *http.Request) {
153
	resp := NewAPIResponse(http.StatusOK, http.StatusText(http.StatusOK))
154
	mps := m.metadataManager.GetLeaderPartitions()
155
	resp.Data = mps
156
	data, err := resp.Marshal()
157
	if err != nil {
158
		log.LogErrorf("json marshal error:%v", err)
159
		resp.Code = http.StatusInternalServerError
160
		resp.Msg = err.Error()
161
		return
162
	}
163
	if _, err := w.Write(data); err != nil {
164
		log.LogErrorf("[getPartitionsHandler] response %s", err)
165
		resp.Code = http.StatusInternalServerError
166
		resp.Msg = err.Error()
167
	}
168
}
169

170
func (m *MetaNode) getAllInodesHandler(w http.ResponseWriter, r *http.Request) {
171
	var err error
172

173
	defer func() {
174
		if err != nil {
175
			msg := fmt.Sprintf("[getAllInodesHandler] err(%v)", err)
176
			if _, e := w.Write([]byte(msg)); e != nil {
177
				log.LogErrorf("[getAllInodesHandler] failed to write response: err(%v) msg(%v)", e, msg)
178
			}
179
		}
180
	}()
181

182
	if err = r.ParseForm(); err != nil {
183
		return
184
	}
185
	id, err := strconv.ParseUint(r.FormValue("pid"), 10, 64)
186
	if err != nil {
187
		return
188
	}
189
	mp, err := m.metadataManager.GetPartition(id)
190
	if err != nil {
191
		return
192
	}
193
	verSeq, err := m.getRealVerSeq(w, r)
194
	if err != nil {
195
		return
196
	}
197
	var inode *Inode
198

199
	f := func(i BtreeItem) bool {
200
		var (
201
			data []byte
202
			e    error
203
		)
204

205
		if inode != nil {
206
			if _, e = w.Write([]byte("\n")); e != nil {
207
				log.LogErrorf("[getAllInodesHandler] failed to write response: %v", e)
208
				return false
209
			}
210
		}
211

212
		inode, _ = i.(*Inode).getInoByVer(verSeq, false)
213
		if inode == nil {
214
			return true
215
		}
216
		if data, e = inode.MarshalToJSON(); e != nil {
217
			log.LogErrorf("[getAllInodesHandler] failed to marshal to json: %v", e)
218
			return false
219
		}
220

221
		if _, e = w.Write(data); e != nil {
222
			log.LogErrorf("[getAllInodesHandler] failed to write response: %v", e)
223
			return false
224
		}
225

226
		return true
227
	}
228

229
	mp.GetInodeTree().Ascend(f)
230
}
231

232
func (m *MetaNode) getSplitKeyHandler(w http.ResponseWriter, r *http.Request) {
233
	r.ParseForm()
234
	log.LogDebugf("getSplitKeyHandler")
235
	resp := NewAPIResponse(http.StatusBadRequest, "")
236
	defer func() {
237
		data, _ := resp.Marshal()
238
		if _, err := w.Write(data); err != nil {
239
			log.LogErrorf("[getSplitKeyHandler] response %s", err)
240
		}
241
	}()
242
	pid, err := strconv.ParseUint(r.FormValue("pid"), 10, 64)
243
	if err != nil {
244
		resp.Msg = err.Error()
245
		return
246
	}
247
	log.LogDebugf("getSplitKeyHandler")
248
	id, err := strconv.ParseUint(r.FormValue("ino"), 10, 64)
249
	if err != nil {
250
		resp.Msg = err.Error()
251
		return
252
	}
253
	log.LogDebugf("getSplitKeyHandler")
254
	verSeq, err := m.getRealVerSeq(w, r)
255
	if err != nil {
256
		resp.Msg = err.Error()
257
		return
258
	}
259
	log.LogDebugf("getSplitKeyHandler")
260
	verAll, _ := strconv.ParseBool(r.FormValue("verAll"))
261
	mp, err := m.metadataManager.GetPartition(pid)
262
	if err != nil {
263
		resp.Code = http.StatusNotFound
264
		resp.Msg = err.Error()
265
		return
266
	}
267
	log.LogDebugf("getSplitKeyHandler")
268
	req := &InodeGetSplitReq{
269
		PartitionID: pid,
270
		Inode:       id,
271
		VerSeq:      verSeq,
272
		VerAll:      verAll,
273
	}
274
	log.LogDebugf("getSplitKeyHandler")
275
	p := &Packet{}
276
	err = mp.InodeGetSplitEk(req, p)
277
	if err != nil {
278
		resp.Code = http.StatusInternalServerError
279
		resp.Msg = err.Error()
280
		return
281
	}
282
	log.LogDebugf("getSplitKeyHandler")
283
	resp.Code = http.StatusSeeOther
284
	resp.Msg = p.GetResultMsg()
285
	if len(p.Data) > 0 {
286
		resp.Data = json.RawMessage(p.Data)
287
		log.LogDebugf("getSplitKeyHandler data %v", resp.Data)
288
	} else {
289
		log.LogDebugf("getSplitKeyHandler")
290
	}
291
	return
292
}
293

294
func (m *MetaNode) getInodeHandler(w http.ResponseWriter, r *http.Request) {
295
	r.ParseForm()
296
	resp := NewAPIResponse(http.StatusBadRequest, "")
297
	defer func() {
298
		data, _ := resp.Marshal()
299
		if _, err := w.Write(data); err != nil {
300
			log.LogErrorf("[getInodeHandler] response %s", err)
301
		}
302
	}()
303
	pid, err := strconv.ParseUint(r.FormValue("pid"), 10, 64)
304
	if err != nil {
305
		resp.Msg = err.Error()
306
		return
307
	}
308
	id, err := strconv.ParseUint(r.FormValue("ino"), 10, 64)
309
	if err != nil {
310
		resp.Msg = err.Error()
311
		return
312
	}
313

314
	verSeq, err := m.getRealVerSeq(w, r)
315
	if err != nil {
316
		resp.Msg = err.Error()
317
		return
318
	}
319

320
	verAll, _ := strconv.ParseBool(r.FormValue("verAll"))
321

322
	mp, err := m.metadataManager.GetPartition(pid)
323
	if err != nil {
324
		resp.Code = http.StatusNotFound
325
		resp.Msg = err.Error()
326
		return
327
	}
328
	req := &InodeGetReq{
329
		PartitionID: pid,
330
		Inode:       id,
331
		VerSeq:      verSeq,
332
		VerAll:      verAll,
333
	}
334
	p := &Packet{}
335
	err = mp.InodeGet(req, p)
336
	if err != nil {
337
		resp.Code = http.StatusInternalServerError
338
		resp.Msg = err.Error()
339
		return
340
	}
341
	resp.Code = http.StatusSeeOther
342
	resp.Msg = p.GetResultMsg()
343
	if len(p.Data) > 0 {
344
		resp.Data = json.RawMessage(p.Data)
345
	}
346
	return
347
}
348

349
func (m *MetaNode) getRaftStatusHandler(w http.ResponseWriter, r *http.Request) {
350
	const (
351
		paramRaftID = "id"
352
	)
353

354
	resp := NewAPIResponse(http.StatusOK, http.StatusText(http.StatusOK))
355
	defer func() {
356
		data, _ := resp.Marshal()
357
		if _, err := w.Write(data); err != nil {
358
			log.LogErrorf("[getRaftStatusHandler] response %s", err)
359
		}
360
	}()
361

362
	raftID, err := strconv.ParseUint(r.FormValue(paramRaftID), 10, 64)
363
	if err != nil {
364
		err = fmt.Errorf("parse param %v fail: %v", paramRaftID, err)
365
		resp.Msg = err.Error()
366
		resp.Code = http.StatusBadRequest
367
		return
368
	}
369

370
	raftStatus := m.raftStore.RaftStatus(raftID)
371
	resp.Data = raftStatus
372
}
373

374
func (m *MetaNode) getEbsExtentsByInodeHandler(w http.ResponseWriter,
375
	r *http.Request) {
376
	r.ParseForm()
377
	resp := NewAPIResponse(http.StatusBadRequest, "")
378
	defer func() {
379
		data, _ := resp.Marshal()
380
		if _, err := w.Write(data); err != nil {
381
			log.LogErrorf("[getEbsExtentsByInodeHandler] response %s", err)
382
		}
383
	}()
384
	pid, err := strconv.ParseUint(r.FormValue("pid"), 10, 64)
385
	if err != nil {
386
		resp.Msg = err.Error()
387
		return
388
	}
389
	id, err := strconv.ParseUint(r.FormValue("ino"), 10, 64)
390
	if err != nil {
391
		resp.Msg = err.Error()
392
		return
393
	}
394
	mp, err := m.metadataManager.GetPartition(pid)
395
	if err != nil {
396
		resp.Code = http.StatusNotFound
397
		resp.Msg = err.Error()
398
		return
399
	}
400
	req := &proto.GetExtentsRequest{
401
		PartitionID: pid,
402
		Inode:       id,
403
	}
404
	p := &Packet{}
405
	if err = mp.ObjExtentsList(req, p); err != nil {
406
		resp.Code = http.StatusInternalServerError
407
		resp.Msg = err.Error()
408
		return
409
	}
410
	resp.Code = http.StatusSeeOther
411
	resp.Msg = p.GetResultMsg()
412
	if len(p.Data) > 0 {
413
		resp.Data = json.RawMessage(p.Data)
414
	}
415
	return
416
}
417

418
func (m *MetaNode) getExtentsByInodeHandler(w http.ResponseWriter,
419
	r *http.Request) {
420
	r.ParseForm()
421
	resp := NewAPIResponse(http.StatusBadRequest, "")
422
	defer func() {
423
		data, _ := resp.Marshal()
424
		if _, err := w.Write(data); err != nil {
425
			log.LogErrorf("[getExtentsByInodeHandler] response %s", err)
426
		}
427
	}()
428
	pid, err := strconv.ParseUint(r.FormValue("pid"), 10, 64)
429
	if err != nil {
430
		resp.Msg = err.Error()
431
		return
432
	}
433
	id, err := strconv.ParseUint(r.FormValue("ino"), 10, 64)
434
	if err != nil {
435
		resp.Msg = err.Error()
436
		return
437
	}
438

439
	verSeq, err := m.getRealVerSeq(w, r)
440
	if err != nil {
441
		resp.Msg = err.Error()
442
		return
443
	}
444
	verAll, _ := strconv.ParseBool(r.FormValue("verAll"))
445
	mp, err := m.metadataManager.GetPartition(pid)
446
	if err != nil {
447
		resp.Code = http.StatusNotFound
448
		resp.Msg = err.Error()
449
		return
450
	}
451

452
	req := &proto.GetExtentsRequest{
453
		PartitionID: pid,
454
		Inode:       id,
455
		VerSeq:      uint64(verSeq),
456
		VerAll:      verAll,
457
	}
458
	p := &Packet{}
459
	if err = mp.ExtentsList(req, p); err != nil {
460
		resp.Code = http.StatusInternalServerError
461
		resp.Msg = err.Error()
462
		return
463
	}
464
	resp.Code = http.StatusSeeOther
465
	resp.Msg = p.GetResultMsg()
466
	if len(p.Data) > 0 {
467
		resp.Data = json.RawMessage(p.Data)
468
	}
469
	return
470
}
471

472
func (m *MetaNode) getDentryHandler(w http.ResponseWriter, r *http.Request) {
473
	r.ParseForm()
474
	name := r.FormValue("name")
475
	resp := NewAPIResponse(http.StatusBadRequest, "")
476
	defer func() {
477
		data, _ := resp.Marshal()
478
		if _, err := w.Write(data); err != nil {
479
			log.LogErrorf("[getDentryHandler] response %s", err)
480
		}
481
	}()
482
	var (
483
		pid  uint64
484
		pIno uint64
485
		err  error
486
	)
487
	if pid, err = strconv.ParseUint(r.FormValue("pid"), 10, 64); err == nil {
488
		pIno, err = strconv.ParseUint(r.FormValue("parentIno"), 10, 64)
489
	}
490
	if err != nil {
491
		resp.Msg = err.Error()
492
		return
493
	}
494

495
	verSeq, err := m.getRealVerSeq(w, r)
496
	if err != nil {
497
		resp.Msg = err.Error()
498
		return
499
	}
500
	verAll, _ := strconv.ParseBool(r.FormValue("verAll"))
501

502
	mp, err := m.metadataManager.GetPartition(pid)
503
	if err != nil {
504
		resp.Code = http.StatusNotFound
505
		resp.Msg = err.Error()
506
		return
507
	}
508
	req := &LookupReq{
509
		PartitionID: pid,
510
		ParentID:    pIno,
511
		Name:        name,
512
		VerSeq:      verSeq,
513
		VerAll:      verAll,
514
	}
515
	p := &Packet{}
516
	if err = mp.Lookup(req, p); err != nil {
517
		resp.Code = http.StatusSeeOther
518
		resp.Msg = err.Error()
519
		return
520
	}
521

522
	resp.Code = http.StatusSeeOther
523
	resp.Msg = p.GetResultMsg()
524
	if len(p.Data) > 0 {
525
		resp.Data = json.RawMessage(p.Data)
526
	}
527
	return
528
}
529

530
func (m *MetaNode) getTxHandler(w http.ResponseWriter, r *http.Request) {
531
	r.ParseForm()
532
	resp := NewAPIResponse(http.StatusBadRequest, "")
533
	defer func() {
534
		data, _ := resp.Marshal()
535
		if _, err := w.Write(data); err != nil {
536
			log.LogErrorf("[getTxHandler] response %s", err)
537
		}
538
	}()
539
	var (
540
		pid  uint64
541
		txId string
542
		err  error
543
	)
544
	if pid, err = strconv.ParseUint(r.FormValue("pid"), 10, 64); err == nil {
545
		if txId = r.FormValue("txId"); txId == "" {
546
			err = fmt.Errorf("no txId")
547
		}
548
	}
549
	if err != nil {
550
		resp.Msg = err.Error()
551
		return
552
	}
553

554
	mp, err := m.metadataManager.GetPartition(pid)
555
	if err != nil {
556
		resp.Code = http.StatusNotFound
557
		resp.Msg = err.Error()
558
		return
559
	}
560
	req := &proto.TxGetInfoRequest{
561
		Pid:  pid,
562
		TxID: txId,
563
	}
564
	p := &Packet{}
565
	if err = mp.TxGetInfo(req, p); err != nil {
566
		resp.Code = http.StatusSeeOther
567
		resp.Msg = err.Error()
568
		return
569
	}
570

571
	resp.Code = http.StatusSeeOther
572
	resp.Msg = p.GetResultMsg()
573
	if len(p.Data) > 0 {
574
		resp.Data = json.RawMessage(p.Data)
575
	}
576
	return
577
}
578

579
func (m *MetaNode) getRealVerSeq(w http.ResponseWriter, r *http.Request) (verSeq uint64, err error) {
580
	if r.FormValue("verSeq") != "" {
581
		var ver int64
582
		if ver, err = strconv.ParseInt(r.FormValue("verSeq"), 10, 64); err != nil {
583
			return
584
		}
585
		verSeq = uint64(ver)
586
		if verSeq == 0 {
587
			verSeq = math.MaxUint64
588
		}
589
	}
590
	return
591
}
592

593
func (m *MetaNode) getAllDentriesHandler(w http.ResponseWriter, r *http.Request) {
594
	r.ParseForm()
595
	resp := NewAPIResponse(http.StatusSeeOther, "")
596
	shouldSkip := false
597
	defer func() {
598
		if !shouldSkip {
599
			data, _ := resp.Marshal()
600
			if _, err := w.Write(data); err != nil {
601
				log.LogErrorf("[getAllDentriesHandler] response %s", err)
602
			}
603
		}
604
	}()
605
	pid, err := strconv.ParseUint(r.FormValue("pid"), 10, 64)
606
	if err != nil {
607
		resp.Code = http.StatusBadRequest
608
		resp.Msg = err.Error()
609
		return
610
	}
611
	mp, err := m.metadataManager.GetPartition(pid)
612
	if err != nil {
613
		resp.Code = http.StatusNotFound
614
		resp.Msg = err.Error()
615
		return
616
	}
617

618
	verSeq, err := m.getRealVerSeq(w, r)
619
	if err != nil {
620
		resp.Msg = err.Error()
621
		return
622
	}
623

624
	buff := bytes.NewBufferString(`{"code": 200, "msg": "OK", "data":[`)
625
	if _, err := w.Write(buff.Bytes()); err != nil {
626
		return
627
	}
628
	buff.Reset()
629
	var (
630
		val       []byte
631
		delimiter = []byte{',', '\n'}
632
		isFirst   = true
633
	)
634

635
	mp.GetDentryTree().Ascend(func(i BtreeItem) bool {
636
		den, _ := i.(*Dentry).getDentryFromVerList(verSeq, false)
637
		if den == nil || den.isDeleted() {
638
			return true
639
		}
640

641
		if !isFirst {
642
			if _, err = w.Write(delimiter); err != nil {
643
				return false
644
			}
645
		} else {
646
			isFirst = false
647
		}
648
		val, err = json.Marshal(den)
649
		if err != nil {
650
			w.WriteHeader(http.StatusInternalServerError)
651
			w.Write([]byte(err.Error()))
652
			return false
653
		}
654
		if _, err = w.Write(val); err != nil {
655
			return false
656
		}
657
		return true
658
	})
659
	shouldSkip = true
660
	buff.WriteString(`]}`)
661
	if _, err = w.Write(buff.Bytes()); err != nil {
662
		log.LogErrorf("[getAllDentriesHandler] response %s", err)
663
	}
664
	return
665
}
666

667
func (m *MetaNode) getAllTxHandler(w http.ResponseWriter, r *http.Request) {
668
	r.ParseForm()
669
	resp := NewAPIResponse(http.StatusOK, "")
670
	shouldSkip := false
671
	defer func() {
672
		if !shouldSkip {
673
			data, _ := resp.Marshal()
674
			if _, err := w.Write(data); err != nil {
675
				log.LogErrorf("[getAllTxHandler] response %s", err)
676
			}
677
		}
678
	}()
679
	pid, err := strconv.ParseUint(r.FormValue("pid"), 10, 64)
680
	if err != nil {
681
		resp.Code = http.StatusBadRequest
682
		resp.Msg = err.Error()
683
		return
684
	}
685
	mp, err := m.metadataManager.GetPartition(pid)
686
	if err != nil {
687
		resp.Code = http.StatusNotFound
688
		resp.Msg = err.Error()
689
		return
690
	}
691
	buff := bytes.NewBufferString(`{"code": 200, "msg": "OK", "data":[`)
692
	if _, err := w.Write(buff.Bytes()); err != nil {
693
		return
694
	}
695
	buff.Reset()
696
	var (
697
		val       []byte
698
		delimiter = []byte{',', '\n'}
699
		isFirst   = true
700
	)
701

702
	f := func(i BtreeItem) bool {
703
		if !isFirst {
704
			if _, err = w.Write(delimiter); err != nil {
705
				return false
706
			}
707
		} else {
708
			isFirst = false
709
		}
710

711
		if ino, ok := i.(*TxRollbackInode); ok {
712
			_, err = w.Write([]byte(ino.ToString()))
713
			if err != nil {
714
				return false
715
			}
716
			return true
717
		}
718
		if den, ok := i.(*TxRollbackDentry); ok {
719
			_, err = w.Write([]byte(den.ToString()))
720
			if err != nil {
721
				return false
722
			}
723
			return true
724
		}
725

726
		val, err = json.Marshal(i)
727
		if err != nil {
728
			w.WriteHeader(http.StatusInternalServerError)
729
			w.Write([]byte(err.Error()))
730
			return false
731
		}
732
		if _, err = w.Write(val); err != nil {
733
			return false
734
		}
735
		return true
736
	}
737

738
	txTree, rbInoTree, rbDenTree := mp.TxGetTree()
739
	txTree.Ascend(f)
740
	rbInoTree.Ascend(f)
741
	rbDenTree.Ascend(f)
742

743
	shouldSkip = true
744
	buff.WriteString(`]}`)
745
	if _, err = w.Write(buff.Bytes()); err != nil {
746
		log.LogErrorf("[getAllTxHandler] response %s", err)
747
	}
748
	return
749
}
750

751
func (m *MetaNode) getDirectoryHandler(w http.ResponseWriter, r *http.Request) {
752
	resp := NewAPIResponse(http.StatusBadRequest, "")
753
	defer func() {
754
		data, _ := resp.Marshal()
755
		if _, err := w.Write(data); err != nil {
756
			log.LogErrorf("[getDirectoryHandler] response %s", err)
757
		}
758
	}()
759
	pid, err := strconv.ParseUint(r.FormValue("pid"), 10, 64)
760
	if err != nil {
761
		resp.Msg = err.Error()
762
		return
763
	}
764

765
	pIno, err := strconv.ParseUint(r.FormValue("parentIno"), 10, 64)
766
	if err != nil {
767
		resp.Msg = err.Error()
768
		return
769
	}
770

771
	verSeq, err := m.getRealVerSeq(w, r)
772
	if err != nil {
773
		resp.Msg = err.Error()
774
		return
775
	}
776

777
	mp, err := m.metadataManager.GetPartition(pid)
778
	if err != nil {
779
		resp.Code = http.StatusNotFound
780
		resp.Msg = err.Error()
781
		return
782
	}
783
	req := ReadDirReq{
784
		ParentID: pIno,
785
		VerSeq:   verSeq,
786
	}
787
	p := &Packet{}
788
	if err = mp.ReadDir(&req, p); err != nil {
789
		resp.Code = http.StatusInternalServerError
790
		resp.Msg = err.Error()
791
		return
792
	}
793
	resp.Code = http.StatusSeeOther
794
	resp.Msg = p.GetResultMsg()
795
	if len(p.Data) > 0 {
796
		resp.Data = json.RawMessage(p.Data)
797
	}
798
	return
799
}
800

801
func (m *MetaNode) genClusterVersionFileHandler(w http.ResponseWriter, r *http.Request) {
802
	r.ParseForm()
803
	resp := NewAPIResponse(http.StatusOK, "Generate cluster version file success")
804
	defer func() {
805
		data, _ := resp.Marshal()
806
		if _, err := w.Write(data); err != nil {
807
			log.LogErrorf("[genClusterVersionFileHandler] response %s", err)
808
		}
809
	}()
810
	paths := make([]string, 0)
811
	paths = append(paths, m.metadataDir, m.raftDir)
812
	for _, p := range paths {
813
		if _, err := os.Stat(path.Join(p, config.ClusterVersionFile)); err == nil || os.IsExist(err) {
814
			resp.Code = http.StatusCreated
815
			resp.Msg = "Cluster version file already exists in " + p
816
			return
817
		}
818
	}
819
	for _, p := range paths {
820
		if err := config.CheckOrStoreClusterUuid(p, m.clusterUuid, true); err != nil {
821
			resp.Code = http.StatusInternalServerError
822
			resp.Msg = "Failed to create cluster version file in " + p
823
			return
824
		}
825
	}
826
	return
827
}
828

829
func (m *MetaNode) getInodeSnapshotHandler(w http.ResponseWriter, r *http.Request) {
830
	m.getSnapshotHandler(w, r, inodeFile)
831
}
832

833
func (m *MetaNode) getDentrySnapshotHandler(w http.ResponseWriter, r *http.Request) {
834
	m.getSnapshotHandler(w, r, dentryFile)
835
}
836

837
func (m *MetaNode) getSnapshotHandler(w http.ResponseWriter, r *http.Request, file string) {
838
	var err error
839
	defer func() {
840
		if err != nil {
841
			msg := fmt.Sprintf("[getInodeSnapshotHandler] err(%v)", err)
842
			log.LogErrorf("%s", msg)
843
			if _, e := w.Write([]byte(msg)); e != nil {
844
				log.LogErrorf("[getInodeSnapshotHandler] failed to write response: err(%v) msg(%v)", e, msg)
845
			}
846
		}
847
	}()
848
	if err = r.ParseForm(); err != nil {
849
		return
850
	}
851
	id, err := strconv.ParseUint(r.FormValue("pid"), 10, 64)
852
	if err != nil {
853
		return
854
	}
855
	mp, err := m.metadataManager.GetPartition(id)
856
	if err != nil {
857
		return
858
	}
859

860
	filename := path.Join(mp.GetBaseConfig().RootDir, snapshotDir, file)
861
	if _, err = os.Stat(filename); err != nil {
862
		err = errors.NewErrorf("[getInodeSnapshotHandler] Stat: %s", err.Error())
863
		return
864
	}
865
	fp, err := os.OpenFile(filename, os.O_RDONLY, 0o644)
866
	if err != nil {
867
		err = errors.NewErrorf("[getInodeSnapshotHandler] OpenFile: %s", err.Error())
868
		return
869
	}
870
	defer fp.Close()
871

872
	_, err = io.Copy(w, fp)
873
	if err != nil {
874
		err = errors.NewErrorf("[getInodeSnapshotHandler] copy: %s", err.Error())
875
		return
876
	}
877
}
878

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.