xen塊裝置體繫結構 – tapdisk2 (2)

來源:互聯網
上載者:User
tapdisk2 logtapdisk2 的log 分為兩部分 /var/log/messages , /tmp/tapdisk.log.${PID} tapdisk syslog 以 tapdisk[1231] 開頭,這裡1231是進程號tapdisk log 一般以 count.time.timeseconds 開頭tapdisk error log內容以 TAPDISK ERROR 開頭,或者以 tap-err 開頭struct error {
int            cnt;
int            err;
char          *func;
char           msg[MAX_ENTRY_LEN];
};

struct ehandle {
int            cnt;
int            dropped;
struct error   errors[MAX_ERROR_MESSAGES];
};

struct tlog {
char          *p;
int            size;
uint64_t       cnt;
char          *buf;
int            level;
char          *file;
int            append;
};具體的代碼請參考 tapdisk-log.h / tapdisk-log.ctapdisk2 imagetapdisk2 提供了 td_image_t 結構,用於儲存 tapdisk2 讀寫的image盤資訊td_image_t - > driver 是不同類型的 disk_type 所提供的,儲存為 td_driver_handle 類型,其中 td_driver_handle -> ops 為 struct tap_disk * 結構。 td_image_t -> flags ,其值可以為:#define TD_OPEN_QUIET                0x00001
#define TD_OPEN_QUERY                0x00002
#define TD_OPEN_RDONLY               0x00004
#define TD_OPEN_STRICT               0x00008
#define TD_OPEN_SHAREABLE            0x00010
#define TD_OPEN_ADD_CACHE            0x00020
#define TD_OPEN_VHD_INDEX            0x00040
#define TD_OPEN_LOG_DIRTY            0x00080tapdisk_image_check_td_request 用於從 td_image_t 中檢查 td_request_t 請求的合法性,e.g. td_request_t -> op 至少為TD_OP_READ或者TD_OP_WRITE,request 的sectors 不能越界。tapdisk_image_check_ring_request 用於檢查 blkif_request, blkif_response 的合法性。這兩個函數唯一需要的是 image是否有TD_OPEN_RDONLY的flagtapdisk2 queuetlist 是 tiocb 的 list,其中 tiocb 是 tapdisk2 對 struct iocb 的結構的封裝。 對於 struct iocb 的 IO 請求,有相應的 callback 函數 td_queue_callback_t cbstruct tqueue {
int                   size;

const struct tio     *tio;
void                 *tio_data;

struct opioctx        opioctx;

int                   queued;
struct iocb         **iocbs;

/* number of iocbs pending in the aio layer */
int                   iocbs_pending;

/* number of tiocbs pending in the queue -- 
* this is likely to be larger than iocbs_pending 
* due to request coalescing */
int                   tiocbs_pending;

/* iocbs may be deferred if the aio ring is full.
* tapdisk_queue_complete will ensure deferred
* iocbs are queued as slots become available. */
struct tlist          deferred;
int                   tiocbs_deferred;

/* optional tapdisk filter */
struct tfilter       *filter;

uint64_t              deferrals;
};tapdisk 除了要通過各種 driver 來區分各種鏡像的類型之外,還要區分不同的 IO類型,即 tapdisk 通過何種方式來讀寫鏡像。目前支援的有兩種: aio, rwio 

Hide tapdisk support for different raw I/O interfaces behind a newstruct tio. Libaio remains to dominate the interface, requiringeveryone to dispatch iocb/ioevent structs.Backends: - lio:  Kernel AIO via libaio. - rwio: Canonical read/write() mode.
struct tio {const char           *name;
size_t                data_size;

int  (*tio_setup)    (struct tqueue *queue, int qlen);
void (*tio_destroy)  (struct tqueue *queue);
int  (*tio_submit)   (struct tqueue *queue);
};

enum {
TIO_DRV_LIO     = 1,
TIO_DRV_RWIO    = 2,
};tqueue -> tio 指向這個 struct tio 結構,通過 tio_submit 函數真正發出 IO 請求。queue_tiocb :把 struct  tiocb* 指向的結構體加入到隊列中。注意 tiocb 是一個封裝了 libaio 的 struct iocb 結構的一個結構體。同時 struct iocb -> data 所指向的 void 指標指向這個 struct tiocb。defer_tiocb :把 struct tiocb* 指向的結構插入到 deferred list ( tqueue -> deferred ) 的末尾。queue_deferred_tiocb : 取出 tqueue -> deferred 隊列頭的 struct tiocb 結構,調用 queue_tiocb 加入到 tqueue -> iocbs 隊列中complete_tiocb : 每一個 struct tiocb 結構體都會事先註冊好一個回呼函數 cb,對於libaio 返回的 struct iocb 結構,判斷 libaio 的返回狀態,之後調用 tiocb->cb(tiocb->arg, tiocb, err)cancel_tiocbs : 對於 tqueue未完成的 tqueue->iocbs 隊列裡的所有 IO 請求,調用 complete_tiocb 取消這些請求。對於兩種IO模式,我們跳過 rwio, 直接去看 lio,下面是lio 對應的 struct tio 結構:static const struct tio td_tio_lio = {
.name        = "lio",
.data_size   = sizeof(struct lio),
.tio_setup   = tapdisk_lio_setup,
.tio_destroy = tapdisk_lio_destroy,
.tio_submit  = tapdisk_lio_submit,
};tapdisk_init_queue : 用於初始化 struct tqueue 結構,其中又調用了 tapdisk_queue_init_io , 該方法 會調用 tio->tio_setup 初始化 IO queue tapdisk_free_queue : 用於釋放 tqueue 佔用的資源tapdisk_debug_queue : 列印出當前 tqueue 的狀態,對於 deferred queue 裡的所有 IO 請求,同時列印詳細資料tapdisk_lio_setup_aio : 首先檢查核心版本,從而調用 __lio_setup_aio_poll 或者 __lio_setup_aio_eventfdtapdisk_lio_destroy_aio :  關閉 lio -> event_fd, 釋放 lio -> aio_ctxtapdisk_lio_setup : 調用 tapdisk_lio_setup_aio 擷取一個 aio 的 event_fd,接著調用 tapdisk_server_register_event,把這個 event_fd 註冊到事件 SCHEDULER_POLL_READ_FD 上面,對應的 callback 函數為 tapdisk_lio_eventtapdisk_lio_event : tapdisk_lio_event 是回呼函數,首先調用 tapdisk_lio_ack_event 來讀一個 uint64_t 大小的內容,之後調用 io_getevents, io_split, 得到對應的 event 個數, 影響的 tiocbs 的個數。最後對於所有的 tiocbs, 調用 complete_tiocb 完成IOtapdisk_lio_submit : 調用 io_merge 對IO請求做合并最佳化,之後調用 io_submit 把請求通過 aio 提交上去。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.