Swift源碼分析----swift-container-auditor

感謝朋友支持本博客,歡迎共同探討交流,由於能力和時間有限,錯誤之處在所難免,歡迎指正!

如果轉載,請保留作者信息。
博客地址:http://blog.csdn.net/gaoxingnengjisuan
郵箱地址:[email protected]

PS:最近沒有登錄博客,很多朋友的留言沒有看見,這裏道歉!還有就是本人較少上QQ,可以郵件交流。


概述部分:

容器審計守護進程;  
審計的主要的職責就是檢查容器數據是否被刪除(通過解析賬戶目錄下的.db文件);
這裏定義的once=True,說明系統默認調用守護進程類Daemon中的run_once方法,有人說run_once主要應用於測試,這個沒有驗證
從而最終實現調用ContainerAuditor類中的run_once方法;
如果調用的是ContainerAuditor類中的run_forever方法,則會實現循環實現檢查指定容器數據是否被刪除;


源碼解析部分:

from swift.container.auditor import ContainerAuditor
from swift.common.utils import parse_options
from swift.common.daemon import run_daemon

if __name__ == '__main__':
    conf_file, options = parse_options(once=True)
    run_daemon(ContainerAuditor, conf_file, **options)

def run_daemon(klass, conf_file, section_name='', once=False, **kwargs):
    """
    從配置文件加載設置,然後實例化守護進程“klass”並運行這個守護進程通過指定的參數kwarg;
    """
    ......

   try:
       klass(conf).run(once=once, **kwargs)
   except KeyboardInterrupt:
       logger.info('User quit')
   logger.info('Exited')

def run(self, once=False, **kwargs):
    """
   Run the daemon
    運行守護進程程序;
    即運行方法run_once,或者方法run_forever;
    """
    # 配置參數相關;
   utils.validate_configuration()
   utils.drop_privileges(self.conf.get('user', 'swift'))
    # 日誌相關處理;
   utils.capture_stdio(self.logger, **kwargs)

   def kill_children(*args):
       signal.signal(signal.SIGTERM, signal.SIG_IGN)
       os.killpg(0, signal.SIGTERM)
       sys.exit()

   signal.signal(signal.SIGTERM, kill_children)
   if once:
       self.run_once(**kwargs)
   else:
       self.run_forever(**kwargs)

def run_once(self, *args, **kwargs):
    """
   Override this to run the script once
    子類中的方法需要被重寫;
    """
   raise NotImplementedError('run_once not implemented')

def run_once(self, *args, **kwargs):
    """
    執行一次container審計操作;
    """
   self.logger.info(_('Begin container audit "once" mode'))
   begin = reported = time.time()    
    # 進行一次審計操作;
   self._one_audit_pass(reported)
   elapsed = time.time() - begin
   self.logger.info(
        ('Container audit "once" mode completed: %.02fs'), elapsed)
        dump_recon_cache({'container_auditor_pass_completed': elapsed},
                    self.rcache, self.logger)

def _one_audit_pass(self, reported):
    """
    對container進行審計操作;
    """
    # 基於給定的設備路徑和文件後綴,爲在這個數據目錄中的所有以.db爲後綴的文件生成元組(path, device, partition);
    # 通過方法audit_location_generator方法計算獲得path,device,partition;
   all_locs = audit_location_generator(self.devices, DATADIR, '.db',
                                       mount_check=self.mount_check,
                                       logger=self.logger)
   for path, device, partition in all_locs:
       # container_audit:對給定的container路徑的db文件進行檢查;
          # 審計給定的容器,看看是否已經被刪除,如果沒有刪除,則爲容器獲取全局數據;
       self.container_audit(path)
       if time.time() - reported >= 3600:  # once an hour
           self.logger.info(_('Since %(time)s: Container audits: %(pass)s passed '
                              'audit, %(fail)s failed audit'),
                            {'time': time.ctime(reported),
                             'pass': self.container_passes,
                             'fail': self.container_failures})
           dump_recon_cache(
                            {'container_audits_since': reported,
                             'container_audits_passed': self.container_passes,
                             'container_audits_failed': self.container_failures},
                             self.rcache, self.logger)
           reported = time.time()
           self.container_passes = 0
           self.container_failures = 0
       self.containers_running_time = ratelimit_sleep(self.containers_running_time, self.max_containers_per_second)
    return reported
1.調用方法audit_location_generator,實現基於給定的設備路徑(self.devices,DATADIR=containers)和文件後綴(.db),爲在這個數據目錄中的所有以.db爲後綴的文件生成元組(path, device, partition);
生成路徑示例如下:
path = /devices/device/containers/partition/asuffix/hsh/****.db
device:self.devices下具體的一個設備名稱;
partition:/devices/device/containers/下具體的一個分區名稱;
2.遍歷元組(path, device, partition)中的每一個匹配對,調用方法container_audit實現審計給定的容器,看看是否已經被刪除,如果沒有刪除,則爲賬戶獲取全局數據;


轉到2,來看方法container_audit:

def container_audit(self, path):
    """
    對給定的container路徑的db文件進行檢查;
    審計給定的容器,看看是否被視爲刪除,如果沒有刪除,則爲容器獲取全局數據;
    """
   start_time = time.time()
   try:
       # ContainerBroker:container數據庫的封裝工作;
       broker = ContainerBroker(path)
       # is_deleted:檢測指定容器的數據庫是否被視爲刪除;
       if not broker.is_deleted():
           # get_info:獲取container的全局數據;
           broker.get_info()
           self.logger.increment('passes')
           self.container_passes += 1
           self.logger.debug(_('Audit passed for %s'), broker)
       except (Exception, Timeout):
           self.logger.increment('failures')
           self.container_failures += 1
           self.logger.exception(_('ERROR Could not get container info %s'), path)
       self.logger.timing_since('timing', start_time)
這個方法的實現比較簡單,這裏就不再進一步進行解析。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章