Ejemplo n.º 1
0
def recovery_by_haystack(pid, gid):

    hpath = get_haystack_path(pid, gid)
    h = haystack.Haystack(hpath)
    old_num = h.get_latest_version_num()

    ver_num, haystack_fpaths = download_haystack(pid, gid)

    renamed_paths = []

    try:

        attr_sha1 = haystack_version.get_file_sha1( haystack_fpaths['attribute'] )

        for fn_key, src_path in haystack_fpaths.items():

            dst_path = get_haystack_file_path(pid, gid, ver_num, fn_key)
            rename_force(src_path, dst_path)

            renamed_paths.append(dst_path)

        h.reset_version_num( ver_num, attr_sha1 )

    except Exception as e:
        delete_files( renamed_paths )
        delete_files( haystack_fpaths.values() )
        raise

    switch_port = partition.pid_port(pid)
    switch_url = SWITCH_VERSION_PREFIX + pid + '/' + str(gid)
    h._switch_version(switch_port, switch_url)

    if old_num != ver_num:
        h.delete_version(old_num, switch_port, switch_url)
Ejemplo n.º 2
0
def create_haystack(pid, gid, files):

    for fn, fpath in files.items():

        checksum = fn.split('-', 1)[0]
		#一致性 检查
        try:
            s2recovery_util.check_file_consistent(fpath, checksum)
        except s2recovery_util.FileDamaged as e:
            logger.info( repr(e) + ' ' + fpath )
            raise group.FileDamaged ( ('pid', pid), ('gid', gid), ('fn', fn) )

    needle_list = create_needle_list(files)
	#创建needle-list  格式如下 
	#[{'file_names': ['069e6fabca59e1ba3db034950b88aa074708cf30-99532'], 'data_parts': [{'path': #'/data6/064247da00014006a370842b2b0c0467/g553698/040/069e6fabca59e1ba3db034950b88aa074708cf30-99532'#, 'size': 229, 'offset': 0}], 'key': #'\x06\x9eo\xab\xcaY\xe1\xba=\xb04\x95\x0b\x88\xaa\x07G\x08\xcf0'},

    hpath = get_haystack_path(pid, gid)
    _mkdir(hpath) #创建 haystack目录

    port = partition.pid_port(pid)

    h = haystack.Haystack(hpath)

    try:

        h.create( needle_list, chunk_num = CHUNK_NUM,
                  switch_version_port = port,
                  switch_version_url = SWITCH_VERSION_PREFIX + pid + '/' + str(gid) )

    except haystack_version.VersionExisted as e:
        logger.info( 'haystack %s %s current version is existed ' % (pid, gid) )
Ejemplo n.º 3
0
def download_haystack_from_part(local_pid, remote_pid, gid):

    hpath = get_haystack_path(local_pid, gid)
    spath = os.path.join( hpath, SYNC_HAYSTACK_FOLDER )
    _mkdir(spath)

    files_path = {}

    hfs = get_haystack_files_list(remote_pid, gid)

    try:
        for fn_key, sha1 in hfs['files_sha1'].items():

            fpath = os.path.join( spath, 'haystack_%s_%s_'%(hfs['version'], fn_key) + str( time.time() ) )

            ips = _get_prt_ips(remote_pid)
            port = partition.pid_port( remote_pid, mine = False )

            uri = stoclient.get_haystack_file_uri( remote_pid,
                                {'group_id': gid, 'version': hfs['version'], 'fn_key': fn_key}, timeout=36000 )

            s2recovery_util.download(fpath, ips, port, uri, sha1)

            files_path[fn_key] = fpath

    except Exception as e:
        delete_files( files_path.values() )
        raise

    return hfs['version'], files_path
Ejemplo n.º 4
0
def download_haystack_file(pid, gid, ver_num, fn_key, sha1):

    hpath = get_haystack_path(pid, gid)
    spath = os.path.join( hpath, SYNC_HAYSTACK_FOLDER )
    _mkdir(spath)

    prts = partition_util.get_sorted_prts(gid)

    for remote_prt in prts:

        remote_pid = remote_prt['partition_id']

        if _prt_dead( remote_pid ) or remote_pid == pid or remote_prt['is_del']:
            continue

        ips = _get_prt_ips(remote_pid)
        port = partition.pid_port( remote_pid, mine = False )
        uri = stoclient.get_haystack_file_uri( remote_pid,
                        {'group_id': gid, 'version': ver_num, 'fn_key': fn_key}, timeout=36000 )

        fpath = os.path.join( spath, 'haystack_%s_%s_'%(ver_num, fn_key) + str( time.time() ) )

        try:
            s2recovery_util.download(fpath, ips, port, uri, sha1)
            break
        except s2recovery_util.DownloadError as e:
            logger.info( repr(e) + " s2recovery: download pid:%s gid:%d haytack haystack_%s_%s file fail! "%
                         (remote_pid, gid, ver_num, fn_key) )
    else:
        raise

    return fpath
Ejemplo n.º 5
0
def create_haystack(pid, gid, files):

    for fn, fpath in files.items():

        checksum = fn.split('-', 1)[0]

        try:
            s2recovery_util.check_file_consistent(fpath, checksum)
        except s2recovery_util.FileDamaged as e:
            logger.info( repr(e) + ' ' + fpath )
            raise group.FileDamaged ( ('pid', pid), ('gid', gid), ('fn', fn) )

    needle_list = create_needle_list(files)

    hpath = get_haystack_path(pid, gid)
    _mkdir(hpath)

    port = partition.pid_port(pid)

    h = haystack.Haystack(hpath)

    try:

        h.create( needle_list, chunk_num = CHUNK_NUM,
                  switch_version_port = port,
                  switch_version_url = SWITCH_VERSION_PREFIX + pid + '/' + str(gid) )

    except haystack_version.VersionExisted as e:
        logger.info( 'haystack %s %s current version is existed ' % (pid, gid) )
Ejemplo n.º 6
0
def get_haystack_files_list(pid, gid):

    ips = _get_prt_ips(pid)
    uri = stoclient.get_haystack_files_list_uri( pid, {'group_id': gid}, timeout=36000)
    port = partition.pid_port(pid, mine = False)

    buf = s2recovery_util.http_get_to_buf(ips, port, uri)
    j = s2json.load( buf )

    return j
Ejemplo n.º 7
0
def remerge_by_original_files(pid, gid):

    logger.info('haystack_check: pid:%s, gid:%d, begin creating new haystack by original files!'%(pid, gid))

    clear_haystack_original_fns(pid, gid)

    try:
        s2recovery.recover_group(pid, gid)
    except s2recovery.GroupIncomplete as e:
        pass

    hash_files = get_hash_files(pid, gid)
    needle_list = create_needle_list(hash_files)

    hpath = get_haystack_path(pid, gid)
    h = haystack.Haystack(hpath)  
    ver_num = h.get_latest_version_num()

    if ver_num is not None:

        try:

            ver = haystack_version.HaystackVersion(hpath, ver_num)
            needles = ver.get_valid_needle_list( ver.get_damaged_chunks_indexes() )
            needle_list.extend(needles)

        except (haystack_version.VersionNotFound, haystack_version.FileDamaged) as e:
            logger.info( repr(e) + 'version %s error!' % ver_num )

    new_num = h.create_version(needle_list, CHUNK_NUM,
                                switch_version_port = partition.pid_port(pid),
                                switch_version_url = SWITCH_VERSION_PREFIX + pid + '/' + str(gid),
                                force = True)

    delete_files( hash_files.values() )
    delete_empty_hash_folders(pid, gid)

    logger.info('haystack_check: pid:%s, gid:%d, finish creating new haystack by original files, version num is %s !'
                %(pid, gid, ver_num))