diff options
| -rwxr-xr-x | tests/utils/gfid-access.py | 91 | ||||
| -rw-r--r-- | tests/utils/libcxattr.py | 94 | 
2 files changed, 185 insertions, 0 deletions
diff --git a/tests/utils/gfid-access.py b/tests/utils/gfid-access.py new file mode 100755 index 00000000000..25fe35bf50b --- /dev/null +++ b/tests/utils/gfid-access.py @@ -0,0 +1,91 @@ +# +# Copyright (c) 2011-2014 Red Hat, Inc. <http://www.redhat.com> +# This file is part of GlusterFS. + +# This file is licensed to you under your choice of the GNU Lesser +# General Public License, version 3 or any later version (LGPLv3 or +# later), or the GNU General Public License, version 2 (GPLv2), in all +# cases as published by the Free Software Foundation. +# + +import os +import sys +import stat +import time +import struct +import random +import libcxattr + +from errno import EEXIST + +Xattr = libcxattr.Xattr() + +def umask(): +    return os.umask(0) + +def _fmt_mknod(l): +    return "!II%dsI%dsIII" % (37, l+1) + +def _fmt_mkdir(l): +    return "!II%dsI%dsII" % (37, l+1) + +def _fmt_symlink(l1, l2): +    return "!II%dsI%ds%ds" % (37, l1+1, l2+1) + +def entry_pack_reg(gf, bn, mo, uid, gid): +    blen = len(bn) +    return struct.pack(_fmt_mknod(blen), +                       uid, gid, gf, mo, bn, +                       stat.S_IMODE(mo), 0, umask()) + +def entry_pack_dir(gf, bn, mo, uid, gid): +    blen = len(bn) +    return struct.pack(_fmt_mkdir(blen), +                       uid, gid, gf, mo, bn, +                       stat.S_IMODE(mo), umask()) + +def entry_pack_symlink(gf, bn, lnk, mo, uid, gid): +    blen = len(bn) +    llen = len(lnk) +    return struct.pack(_fmt_symlink(blen, llen), +                       uid, gid, gf, mo, bn, lnk) + +if __name__ == '__main__': +    if len(sys.argv) < 6: +        print("USAGE: %s <mount> <pargfid|ROOT> <filename> <GFID> <file type>" % (sys.argv[0])) +        sys.exit(-1) # nothing to do +    mtpt       = sys.argv[1] +    pargfid    = sys.argv[2] +    fname      = sys.argv[3] +    randomgfid = sys.argv[4] +    ftype      = sys.argv[5] + +    os.chdir(mtpt) +    if pargfid == 'ROOT': +        pargfid = '.gfid/00000000-0000-0000-0000-000000000001' +    else: +        pargfid = '.gfid/' + pargfid + +    blob = None + +    # entry op: use non-zero uid/gid (to catch gfid-access xlator bugs) +    if ftype == 'file': +        mode = stat.S_IFREG | 644 +        blob = entry_pack_reg(randomgfid, fname, mode, 10, 10) +    elif ftype =='dir': +        mode = stat.S_IFDIR | 755 +        blob = entry_pack_dir(randomgfid, fname, mode, 10, 10) +    else: # not yet... +        sys.exit(-1) + +    if blob == None: +        sys.exit(-1) +    try: +        Xattr.lsetxattr(pargfid, 'glusterfs.gfid.newfile', blob) +    except OSError: +        ex = sys.exc_info()[1] +        if not ex.errno in [EEXIST]: +            raise +            sys.exit(-1) +    print "File creation OK" +    sys.exit(0) diff --git a/tests/utils/libcxattr.py b/tests/utils/libcxattr.py new file mode 100644 index 00000000000..74d120fa196 --- /dev/null +++ b/tests/utils/libcxattr.py @@ -0,0 +1,94 @@ +# +# Copyright (c) 2011-2014 Red Hat, Inc. <http://www.redhat.com> +# This file is part of GlusterFS. + +# This file is licensed to you under your choice of the GNU Lesser +# General Public License, version 3 or any later version (LGPLv3 or +# later), or the GNU General Public License, version 2 (GPLv2), in all +# cases as published by the Free Software Foundation. +# + +import os +from ctypes import CDLL, c_int, create_string_buffer +from ctypes.util import find_library + + +class Xattr(object): + +    """singleton that wraps the extended attribues system +       interface for python using ctypes + +       Just implement it to the degree we need it, in particular +       - we need just the l*xattr variants, ie. we never want symlinks to be +         followed +       - don't need size discovery for getxattr, as we always know the exact +         sizes we expect +    """ + +    libc = CDLL(find_library("libc")) + +    @classmethod +    def geterrno(cls): +        return c_int.in_dll(cls.libc, 'errno').value + +    @classmethod +    def raise_oserr(cls): +        errn = cls.geterrno() +        raise OSError(errn, os.strerror(errn)) + +    @classmethod +    def _query_xattr(cls, path, siz, syscall, *a): +        if siz: +            buf = create_string_buffer('\0' * siz) +        else: +            buf = None +        ret = getattr(cls.libc, syscall)(*((path,) + a + (buf, siz))) +        if ret == -1: +            cls.raise_oserr() +        if siz: +            return buf.raw[:ret] +        else: +            return ret + +    @classmethod +    def lgetxattr(cls, path, attr, siz=0): +        return cls._query_xattr(path, siz, 'lgetxattr', attr) + +    @classmethod +    def lgetxattr_buf(cls, path, attr): +        """lgetxattr variant with size discovery""" +        size = cls.lgetxattr(path, attr) +        if size == -1: +            cls.raise_oserr() +        if size == 0: +            return '' +        return cls.lgetxattr(path, attr, size) + +    @classmethod +    def llistxattr(cls, path, siz=0): +        ret = cls._query_xattr(path, siz, 'llistxattr') +        if isinstance(ret, str): +            ret = ret.split('\0') +        return ret + +    @classmethod +    def lsetxattr(cls, path, attr, val): +        ret = cls.libc.lsetxattr(path, attr, val, len(val), 0) +        if ret == -1: +            cls.raise_oserr() + +    @classmethod +    def lremovexattr(cls, path, attr): +        ret = cls.libc.lremovexattr(path, attr) +        if ret == -1: +            cls.raise_oserr() + +    @classmethod +    def llistxattr_buf(cls, path): +        """listxattr variant with size discovery""" +        size = cls.llistxattr(path) +        if size == -1: +            cls.raise_oserr() +        if size == 0: +            return [] +        return cls.llistxattr(path, size)  | 
