ceph 읽 기 쓰기 경로 소스 코드 분석 (2)

11988 단어
Ceph 읽 기와 쓰기 경로 의 소스 코드 를 계속 분석 하고 본 고 는 주로 Object Contex 라 는 비교적 중요 한 데이터 구 조 를 분석한다.
데이터 구조
MOSDOp
OSDOp
struct OSDOp {
  ceph_osd_op op; 
   //         
  sobject_t soid;
   //src oid,    op     ,       
   //  rados_clone_range    dest obj   src obj
  bufferlist indata, outdata;
  //        data 
  int32_t rval;
  //     
  OSDOp() : rval(0) {
    memset(&op, 0, sizeof(ceph_osd_op));
  }
class MOSDOp : public Message {
  object_t oid;
  //     
  object_locator_t oloc;
  pg_t pgid; //pg
public:
  vector<OSDOp> ops;
  //  oid       
private:
  //    
  snapid_t snapid;
  //snapid,   CEPH_NOSNAP,  head  ,      snap_seq
  snapid_t snap_seq;
  //   head  ,          
  //   snap  ,  snap   seq
  vector<snapid_t> snaps;
  //   snap  
  uint64_t features;

  osd_reqid_t reqid; // reqid explicitly set by sender

}

MOSDOp 은 기본 적 인 요청 을 봉인 했다.ops 에 여러 개의 OSDOp 작업 을 나 누 었 습 니 다.모든 OSDOp 작업 에 또 하나의 soid 가 있 습 니 다. 이 soid 와 MOSDOp 의 oid 는 어떤 관계 입 니까?
여기 서 MOSDOp 패 키 징 작업 은 모두 oid 와 관련 된 작업 입 니 다. 즉, 하나의 MOSDOp 은 같은 oid 에 대한 작업 만 패 키 징 합 니 다.하지만 radosclone_range 와 같은 동작 은 dest oid 가 있 고 src oid 가 있 으 면 src oid 는 OSDOp 의 soid 에 저 장 됩 니 다.
object_info_t
struct object_info_t {
  hobject_t soid;
  eversion_t version, prior_version;
  version_t user_version;
  osd_reqid_t last_reqid;

  uint64_t size;
  utime_t mtime;
  utime_t local_mtime; // local mtime

  // note: these are currently encoded into a total 16 bits; see
  // encode()/decode() for the weirdness.
  typedef enum {
    FLAG_LOST     = 1<<0,
    FLAG_WHITEOUT = 1<<1,  // object logically does not exist
    FLAG_DIRTY    = 1<<2,  
    // object has been modified since last flushed or undirtied
    FLAG_OMAP     = 1 << 3,  // has (or may have) some/any omap data
    FLAG_DATA_DIGEST = 1 << 4,  // has data crc
    FLAG_OMAP_DIGEST = 1 << 5,  // has omap crc
    FLAG_CACHE_PIN = 1 << 6,    // pin the object in cache tier
    // ...
    FLAG_USES_TMAP = 1<<8,  // deprecated; no longer used.
  } flag_t;

  flag_t flags;

  ......

  vector<snapid_t> snaps;  // [clone]

  uint64_t truncate_seq, truncate_size;

  map<pair<uint64_t, entity_name_t>, watch_info_t> watchers;

  // opportunistic checksums; may or may not be present
  __u32 data_digest;  ///< data crc32c
  __u32 omap_digest;  ///< omap crc32c
}

object_info_t 를 대상 으로 하 는 속성, xattr 에 저장, key 는 OIATTR (""), value 는 objectinfo_t 의 decode 뒤의 값
ObjectState
struct ObjectState {
  object_info_t oi;
  bool exists;         
  //the stored object exists (i.e., we will remember the object_info_t)

  ObjectState() : exists(false) {}
  ObjectState(const object_info_t &oi_, bool exists_)
    : oi(oi_), exists(exists_) {}
};

SnapSetContext 는 SnapSet 의 컨 텍스트 정 보 를 저장 합 니 다.스냅 셋 에 대한 내용 은 관련 글 소 개 를 참고 하면 된다.
struct SnapSetContext {
  hobject_t oid;  //  
  int ref;   //        
  bool registered; //   SnapSet Cache   
  SnapSet snapset; //SnapSet          
  bool exists;  //snapset    

  SnapSetContext(const hobject_t& o) :
    oid(o), ref(0), registered(false), exists(true) { }
};

대상 Object Context 는 대상 의 컨 텍스트 정 보 를 저장 합 니 다.
struct ObjectContext {
  ObjectState obs;
  //obs,    object_infot_t,           
  SnapSetContext *ssc;  // may be null
  //       
  Context *destructor_callback;

private:
  Mutex lock;
public:
  Cond cond;
  int unstable_writes, readers, writers_waiting, readers_waiting;
  //        ,        
  //        ,        


  // set if writes for this object are blocked 
  //on another objects recovery
  ObjectContextRef blocked_by;      // object blocking our writes
  set<ObjectContextRef> blocking;   // objects whose writes we block

  // any entity in obs.oi.watchers 
  //MUST be in either watchers or unconnected_watchers.
  map<pair<uint64_t, entity_name_t>, WatchRef> watchers;

  // attr cache
  map<string, bufferlist> attr_cache;

  list<OpRequestRef> waiters;  ///< ops waiting on state change
  int count;              ///< number of readers or writers

  State state:4;               ///< rw state
  /// if set, restart backfill when we can get a read lock
  bool recovery_read_marker:1;
  /// if set, requeue snaptrim on lock release
  bool snaptrimmer_write_marker:1;
  ......
  }

ReplicatedPG::get_object_context
함수 getobject_context 대상 의 object 가 져 오기context 정보.입력 매개 변 수 는:
ObjectContextRef 
ReplicatedPG::get_object_context(const hobject_t& soid,
                      bool can_create,
                      map<string, bufferlist> *attrs)

soid 가 져 올 대상 bool cancreate 를 만 들 필요 가 있 는 지, 쓰기 동작 이 라면 * attrs 대상 의 속성 을 설정 합 니 다.
  • 우선 objectcontexts 의 lru cache 에서 가 져 옵 니 다. 성공 하면 되 돌려 줍 니 다
  • lru cache 에서 찾 지 못 하면:
  • attrs 입력 매개 변수 에 표시 되 지 않 으 면 pgbackend - > objects 를 호출 합 니 다.get_attr(soid, OI_ATTR, &bv)
  • decode 후 object 획득info_t
  • get 호출snapset_context 에서 SnapSetContext 가 져 오기
  • obc 와 관련 된 인 자 를 설정 하고 obc
  • 를 되 돌려 줍 니 다.
    ReplicatedPG::get_snapset_context
    snapset 가 져 오기context 이 함수 와 getobject_context 유사
  • snapsetcontexts snapset 가 져 오기context, 성공 하면 결 과 를 되 돌려 줍 니 다
  • 존재 하지 않 는 다 면, 그리고 cancreate, pgbackend - > objects 호출get_attr (oid. get head (), SS ATTR, & bv) 획득 SSATTR 속성.head 대상 만 ATTR 속성 이 있 습 니 다. head 대상 이 존재 하지 않 으 면 snapdir
  • 를 가 져 옵 니 다.
    ReplicatedPG::find_object_context
    이 함수 찾기 대상 의 objectcontext, 이것 은 snapshot 에 관 한 지식 을 이해 해 야 합 니 다.snapseq 는 해당 하 는 clone 대상 을 정확하게 얻 은 후 해당 하 는 object 를 가 져 옵 니 다.context
    int ReplicatedPG::find_object_context(
    const hobject_t& oid,          
     ObjectContextRef *pobc,       ObjectContext 
      bool can_create,           
      bool map_snapid_to_clone,    snapid clone  
      hobject_t *pmissing          ,       
      }

    매개 변수 mapsnapid_to_clone, 이 snap 가 clone 대상, 즉 snap 대상 의 snap 에 직접 대응 할 수 있 는 지 를 말 합 니 다.id 는 SnapSet 의 clones 목록 에 있 습 니 다.
  • 우선 헤드 대상 이 라면 함수 get 호출object_context 에서 ObjectContext 대상 을 가 져 옵 니 다. 실패 하면 pmissing 대상 설정
  • 그 다음 에 snapdir 대상 이 라면 head 대상 의 object 를 먼저 가 져 옵 니 다.context, 실패 하면 snapdir 의 object 를 가 져 옵 니 다.context
  • 만약!map_snapid_to_clone 및 이 snap 표 시 는 삭제 되 었 습 니 다. 바로 돌아 갑 니 다
  • 함수 호출 getsnapset_context
  • map 라면snapid_to_clone
  • oid. snap > ssc - > snapset. seq 는 이 snap 이 최신 스냅 샷 임 을 설명 합 니 다. 첫 번 째 작업 은 osd 엔 드 에 관련 된 정보 가 업데이트 되 지 않 았 습 니 다.헤드 개체 로 바로 돌아 가기 objectcontext
  • 그렇지 않 으 면 SnapSet 의 clones 목록 을 직접 검사 하고 없 으 면 사이 에 - ENENT
  • 로 돌아 갑 니 다.
  • 대상 이 누락 되 었 는 지 확인 하고 없 으 면 해당 clone 대상 의 object 를 가 져 옵 니 다.context

  • map 가 아니라면snapid_to_clone, snapid. clone 대상 을 직접 가 져 오 려 면 snaps 와 clones 목록 이 필요 합 니 다. snap 를 계산 해 야 합 니 다.id 대응 하 는 clone 대상
  • oid. snap > ssc - > snapset. seq 를 사용 하면 헤드 대상 가 져 오기
  • oid. snap 계산 은 처음으로 ssc - > snapset. clones 목록 의 clone 대상 보다 크 고 oid 에 대응 하 는 clone 대상
  • 입 니 다.
  • soid 대상 구축
  • 이 soid 대상 이 missing 인지 확인
  • 호출 함수 getobject_context 획득 objectcontext
  • 마지막 으로 snapid 호출t first = obc->obs.oi.snaps[obc->obs.oi.snaps.size()-1]; snapid_t last = obc->obs.oi.snaps[0]; first < = oid. snap
  • 검증

    좋은 웹페이지 즐겨찾기