Example #1
0
def write_metadata(path_or_fd, metadata):
    """
    Helper function to write serialized metadata for a File/Directory.

    :param path_or_fd: File/Directory path or fd to write the metadata
    :param metadata: dictionary of metadata write
    """
    assert isinstance(metadata, dict)
    metastr = serialize_metadata(metadata)
    key = 0
    while metastr:
        try:
            do_setxattr(path_or_fd, '%s%s' % (METADATA_KEY, key or ''),
                        metastr[:MAX_XATTR_SIZE])
        except IOError as err:
            if err.errno in (errno.ENOSPC, errno.EDQUOT):
                if isinstance(path_or_fd, int):
                    filename = get_filename_from_fd(path_or_fd)
                    do_log_rl("write_metadata(%d, metadata) failed: %s : %s",
                              path_or_fd, err, filename)
                else:
                    do_log_rl("write_metadata(%s, metadata) failed: %s",
                              path_or_fd, err)
                raise DiskFileNoSpace()
            else:
                raise SwiftOnFileSystemIOError(
                    err.errno, '%s, setxattr("%s", %s, metastr)' %
                    (err.strerror, path_or_fd, key))
        metastr = metastr[MAX_XATTR_SIZE:]
        key += 1
Example #2
0
def clean_metadata(path_or_fd):
    key = 0
    while True:
        try:
            do_removexattr(path_or_fd, '%s%s' % (METADATA_KEY, (key or '')))
        except IOError as err:
            if err.errno == errno.ENODATA:
                break
            raise SwiftOnFileSystemIOError(
                err.errno,
                '%s, removexattr("%s", %s)' % (err.strerror, path_or_fd, key))
        key += 1
Example #3
0
def read_metadata(path_or_fd):
    """
    Helper function to read the pickled metadata from a File/Directory.

    :param path_or_fd: File/Directory path or fd from which to read metadata.

    :returns: dictionary of metadata
    """
    metadata = None
    metadata_s = ''
    key = 0
    while metadata is None:
        try:
            metadata_s += do_getxattr(path_or_fd,
                                      '%s%s' % (METADATA_KEY, (key or '')))
        except IOError as err:
            if err.errno == errno.ENODATA:
                if key > 0:
                    # No errors reading the xattr keys, but since we have not
                    # been able to find enough chunks to get a successful
                    # unpickle operation, we consider the metadata lost, and
                    # drop the existing data so that the internal state can be
                    # recreated.
                    clean_metadata(path_or_fd)
                # We either could not find any metadata key, or we could find
                # some keys, but were not successful in performing the
                # unpickling (missing keys perhaps)? Either way, just report
                # to the caller we have no metadata.
                metadata = {}
            else:
                # Note that we don't touch the keys on errors fetching the
                # data since it could be a transient state.
                raise SwiftOnFileSystemIOError(
                    err.errno, '%s, getxattr("%s", %s)' % (err.strerror,
                                                           path_or_fd, key))
        else:
            try:
                # If this key provides all or the remaining part of the pickle
                # data, we don't need to keep searching for more keys. This
                # means if we only need to store data in N xattr key/value
                # pair, we only need to invoke xattr get N times. With large
                # keys sizes we are shooting for N = 1.
                metadata = pickle.loads(metadata_s)
                assert isinstance(metadata, dict)
            except (EOFError, pickle.UnpicklingError):
                # We still are not able recognize this existing data collected
                # as a pickled object. Make sure we loop around to try to get
                # more from another xattr key.
                metadata = None
                key += 1
    return metadata
Example #4
0
 def _mock_rm(path):
     print "_mock_rm-metadata_enoent(%s)" % path
     shutil.rmtree(path)
     raise SwiftOnFileSystemIOError(errno.ENOENT,
                                    os.strerror(errno.ENOENT))