|
Packit Service |
35f350 |
#!/usr/bin/python3
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
# Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com/>
|
|
Packit Service |
e080da |
# This file is part of GlusterFS.
|
|
Packit Service |
e080da |
#
|
|
Packit Service |
e080da |
# This file is licensed to you under your choice of the GNU Lesser
|
|
Packit Service |
e080da |
# General Public License, version 3 or any later version (LGPLv3 or
|
|
Packit Service |
e080da |
# later), or the GNU General Public License, version 2 (GPLv2), in all
|
|
Packit Service |
e080da |
# cases as published by the Free Software Foundation.
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
import sys
|
|
Packit Service |
e080da |
import os
|
|
Packit Service |
e080da |
import xattr
|
|
Packit Service |
e080da |
import uuid
|
|
Packit Service |
e080da |
import re
|
|
Packit Service |
e080da |
import errno
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
CHANGELOG_SEARCH_MAX_TRY = 31
|
|
Packit Service |
e080da |
DEC_CTIME_START = 5
|
|
Packit Service |
e080da |
ROOT_GFID = "00000000-0000-0000-0000-000000000001"
|
|
Packit Service |
e080da |
MAX_NUM_CHANGELOGS_TRY = 2
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
def output_not_found(gfid):
|
|
Packit Service |
e080da |
# Write GFID to stderr
|
|
Packit Service |
e080da |
sys.stderr.write("%s\n" % gfid)
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
def output_success(path):
|
|
Packit Service |
e080da |
# Write converted Path to Stdout
|
|
Packit Service |
e080da |
sys.stdout.write("%s\n" % path)
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
def full_dir_path(gfid):
|
|
Packit Service |
e080da |
out_path = ""
|
|
Packit Service |
e080da |
while True:
|
|
Packit Service |
e080da |
path = os.path.join(".glusterfs", gfid[0:2], gfid[2:4], gfid)
|
|
Packit Service |
e080da |
path_readlink = os.readlink(path)
|
|
Packit Service |
e080da |
pgfid = os.path.dirname(path_readlink)
|
|
Packit Service |
e080da |
out_path = os.path.join(os.path.basename(path_readlink), out_path)
|
|
Packit Service |
e080da |
if pgfid == "../../00/00/%s" % ROOT_GFID:
|
|
Packit Service |
e080da |
out_path = os.path.join("./", out_path)
|
|
Packit Service |
e080da |
break
|
|
Packit Service |
e080da |
gfid = os.path.basename(pgfid)
|
|
Packit Service |
e080da |
return out_path
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
def find_path_from_changelog(fd, gfid):
|
|
Packit Service |
e080da |
"""
|
|
Packit Service |
e080da |
In given Changelog File, finds using following pattern
|
|
Packit Service |
e080da |
<T><GFID>\x00<TYPE>\x00<MODE>\x00<UID>\x00<GID>\x00<PARGFID>/<BASENAME>
|
|
Packit Service |
e080da |
Pattern search finds PARGFID and BASENAME, Convert PARGFID to Path
|
|
Packit Service |
e080da |
Using readlink and add basename to form Full path.
|
|
Packit Service |
e080da |
"""
|
|
Packit Service |
e080da |
content = fd.read()
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
pattern = "E%s" % gfid
|
|
Packit Service |
e080da |
pattern += "\x00(3|23)\x00\d+\x00\d+\x00\d+\x00([^\x00]+)/([^\x00]+)"
|
|
Packit Service |
e080da |
pat = re.compile(pattern)
|
|
Packit Service |
e080da |
match = pat.search(content)
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if match:
|
|
Packit Service |
e080da |
pgfid = match.group(2)
|
|
Packit Service |
e080da |
basename = match.group(3)
|
|
Packit Service |
e080da |
if pgfid == ROOT_GFID:
|
|
Packit Service |
e080da |
return os.path.join("./", basename)
|
|
Packit Service |
e080da |
else:
|
|
Packit Service |
e080da |
full_path_parent = full_dir_path(pgfid)
|
|
Packit Service |
e080da |
if full_path_parent:
|
|
Packit Service |
e080da |
return os.path.join(full_path_parent, basename)
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
return None
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
def gfid_to_path(gfid):
|
|
Packit Service |
e080da |
"""
|
|
Packit Service |
e080da |
Try readlink, if it is directory it succeeds.
|
|
Packit Service |
e080da |
Get ctime of the GFID file, Decrement by 5 sec
|
|
Packit Service |
e080da |
Search for Changelog filename, Since Changelog file generated
|
|
Packit Service |
e080da |
every 15 sec, Search and get immediate next Changelog after the file
|
|
Packit Service |
e080da |
Creation. Get the Path by searching in Changelog file.
|
|
Packit Service |
e080da |
Get the resultant file's GFID and Compare with the input, If these
|
|
Packit Service |
e080da |
GFIDs are different then Some thing is changed(May be Rename)
|
|
Packit Service |
e080da |
"""
|
|
Packit Service |
e080da |
gfid = gfid.strip()
|
|
Packit Service |
e080da |
gpath = os.path.join(".glusterfs", gfid[0:2], gfid[2:4], gfid)
|
|
Packit Service |
e080da |
try:
|
|
Packit Service |
e080da |
output_success(full_dir_path(gfid))
|
|
Packit Service |
e080da |
return
|
|
Packit Service |
e080da |
except OSError:
|
|
Packit Service |
e080da |
# Not an SymLink
|
|
Packit Service |
e080da |
pass
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
try:
|
|
Packit Service |
e080da |
ctime = int(os.stat(gpath).st_ctime)
|
|
Packit Service |
e080da |
ctime -= DEC_CTIME_START
|
|
Packit Service |
e080da |
except (OSError, IOError):
|
|
Packit Service |
e080da |
output_not_found(gfid)
|
|
Packit Service |
e080da |
return
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
path = None
|
|
Packit Service |
e080da |
found_changelog = False
|
|
Packit Service |
e080da |
changelog_parse_try = 0
|
|
Packit Service |
e080da |
for i in range(CHANGELOG_SEARCH_MAX_TRY):
|
|
Packit Service |
e080da |
cl = os.path.join(".glusterfs/changelogs", "CHANGELOG.%s" % ctime)
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
try:
|
|
Packit Service |
e080da |
with open(cl, "rb") as f:
|
|
Packit Service |
e080da |
changelog_parse_try += 1
|
|
Packit Service |
e080da |
found_changelog = True
|
|
Packit Service |
e080da |
path = find_path_from_changelog(f, gfid)
|
|
Packit Service |
e080da |
if not path and changelog_parse_try < MAX_NUM_CHANGELOGS_TRY:
|
|
Packit Service |
e080da |
ctime += 1
|
|
Packit Service |
e080da |
continue
|
|
Packit Service |
e080da |
break
|
|
Packit Service |
e080da |
except (IOError, OSError) as e:
|
|
Packit Service |
e080da |
if e.errno == errno.ENOENT:
|
|
Packit Service |
e080da |
ctime += 1
|
|
Packit Service |
e080da |
else:
|
|
Packit Service |
e080da |
break
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if not found_changelog:
|
|
Packit Service |
e080da |
output_not_found(gfid)
|
|
Packit Service |
e080da |
return
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if not path:
|
|
Packit Service |
e080da |
output_not_found(gfid)
|
|
Packit Service |
e080da |
return
|
|
Packit Service |
e080da |
gfid1 = str(uuid.UUID(bytes=xattr.get(path, "trusted.gfid")))
|
|
Packit Service |
e080da |
if gfid != gfid1:
|
|
Packit Service |
e080da |
output_not_found(gfid)
|
|
Packit Service |
e080da |
return
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
output_success(path)
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
def main():
|
|
Packit Service |
e080da |
num_arguments = 3
|
|
Packit Service |
e080da |
if not sys.stdin.isatty():
|
|
Packit Service |
e080da |
num_arguments = 2
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if len(sys.argv) != num_arguments:
|
|
Packit Service |
e080da |
sys.stderr.write("Invalid arguments\nUsage: "
|
|
Packit Service |
e080da |
"%s <BRICK_PATH> <GFID_FILE>\n" % sys.argv[0])
|
|
Packit Service |
e080da |
sys.exit(1)
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
path = sys.argv[1]
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if sys.stdin.isatty():
|
|
Packit Service |
e080da |
gfid_list = os.path.abspath(sys.argv[2])
|
|
Packit Service |
e080da |
os.chdir(path)
|
|
Packit Service |
e080da |
with open(gfid_list) as f:
|
|
Packit Service |
e080da |
for gfid in f:
|
|
Packit Service |
e080da |
gfid_to_path(gfid)
|
|
Packit Service |
e080da |
else:
|
|
Packit Service |
e080da |
os.chdir(path)
|
|
Packit Service |
e080da |
for gfid in sys.stdin:
|
|
Packit Service |
e080da |
gfid_to_path(gfid)
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
|
|
Packit Service |
e080da |
if __name__ == "__main__":
|
|
Packit Service |
e080da |
main()
|