glusterfs

Форк
0
112 строк · 3.5 Кб
1
#
2
# Copyright (c) 2011-2014 Red Hat, Inc. <http://www.redhat.com>
3
# This file is part of GlusterFS.
4

5
# This file is licensed to you under your choice of the GNU Lesser
6
# General Public License, version 3 or any later version (LGPLv3 or
7
# later), or the GNU General Public License, version 2 (GPLv2), in all
8
# cases as published by the Free Software Foundation.
9
#
10

11
import os
12
from ctypes import CDLL, get_errno
13
from py2py3 import (bytearray_to_str, gr_create_string_buffer,
14
                    gr_query_xattr, gr_lsetxattr, gr_lremovexattr)
15

16

17
class Xattr(object):
18

19
    """singleton that wraps the extended attributes system
20
       interface for python using ctypes
21

22
       Just implement it to the degree we need it, in particular
23
       - we need just the l*xattr variants, ie. we never want symlinks to be
24
         followed
25
       - don't need size discovery for getxattr, as we always know the exact
26
         sizes we expect
27
    """
28

29
    libc = CDLL("libc.so.6", use_errno=True)
30

31
    @classmethod
32
    def geterrno(cls):
33
        return get_errno()
34

35
    @classmethod
36
    def raise_oserr(cls):
37
        errn = cls.geterrno()
38
        raise OSError(errn, os.strerror(errn))
39

40
    @classmethod
41
    def _query_xattr(cls, path, siz, syscall, *a):
42
        if siz:
43
            buf = gr_create_string_buffer(siz)
44
        else:
45
            buf = None
46
        ret = getattr(cls.libc, syscall)(*((path,) + a + (buf, siz)))
47
        if ret == -1:
48
            cls.raise_oserr()
49
        if siz:
50
            # py2 and py3 compatibility. Convert bytes array
51
            # to string
52
            result = bytearray_to_str(buf.raw)
53
            return result[:ret]
54
        else:
55
            return ret
56

57
    @classmethod
58
    def lgetxattr(cls, path, attr, siz=0):
59
        return gr_query_xattr(cls, path, siz, 'lgetxattr', attr)
60

61
    @classmethod
62
    def lgetxattr_buf(cls, path, attr):
63
        """lgetxattr variant with size discovery"""
64
        size = cls.lgetxattr(path, attr)
65
        if size == -1:
66
            cls.raise_oserr()
67
        if size == 0:
68
            return ''
69
        return cls.lgetxattr(path, attr, size)
70

71
    @classmethod
72
    def llistxattr(cls, path, siz=0):
73
        ret = gr_query_xattr(cls, path, siz, 'llistxattr')
74
        if isinstance(ret, str):
75
            ret = ret.strip('\0')
76
            ret = ret.split('\0') if ret else []
77
        return ret
78

79
    @classmethod
80
    def lsetxattr(cls, path, attr, val):
81
        ret = gr_lsetxattr(cls, path, attr, val)
82
        if ret == -1:
83
            cls.raise_oserr()
84

85
    @classmethod
86
    def lremovexattr(cls, path, attr):
87
        ret = gr_lremovexattr(cls, path, attr)
88
        if ret == -1:
89
            cls.raise_oserr()
90

91
    @classmethod
92
    def llistxattr_buf(cls, path):
93
        """listxattr variant with size discovery"""
94
        try:
95
            # Assuming no more than 100 xattrs in a file/directory and
96
            # each xattr key length will be less than 256 bytes
97
            # llistxattr will be called with bigger size so that
98
            # listxattr will not fail with ERANGE. OSError will be
99
            # raised if fails even with the large size specified.
100
            size = 256 * 100
101
            return cls.llistxattr(path, size)
102
        except OSError:
103
            # If fixed length failed for getting list of xattrs then
104
            # use the llistxattr call to get the size and use that
105
            # size to get the list of xattrs.
106
            size = cls.llistxattr(path)
107
            if size == -1:
108
                cls.raise_oserr()
109
            if size == 0:
110
                return []
111

112
            return cls.llistxattr(path, size)
113

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.