object-storage: Refactor to use pyxattr's get/set/remove methods

These methods are not deprecated, the old ones with the xattr suffix are
considered deprecated starting with 0.4 of pyxattr.

Backport of commit: 1105b880d06128e1428578dcf73c6680a98b35b8
BZ: 865858

Change-Id: Ie8fd9a98e7e117f555076dadfa5e587f75280d3c
Signed-off-by: Peter Portante <peter.portante@redhat.com>
object-storage: remove unnecessary system calls around xattr ops

The following is a simple refactoring of the read and write metadata methods
to just make calls to get/set/remove xattr operations instead of trying to
stat/open/close the file. For a single GET operation, this brings down the
number of system calls made from 13 to 3 for a file object with no
significantly sized metadata (meaning, only 1 xattr key/value pair is needed
to store the metadata).

Backport of commit: 51eace9fe9420ee3626f2622c282d00d23489d1b
BZ: 865858

Change-Id: Id509acc8e6e75cfd36cea890316cadaa69d7077a
Signed-off-by: Peter Portante <peter.portante@redhat.com>
object-storage: reduce the number of getxattr system calls by one

Initial step towards addressing BZ 865619.

Prior to the patch, reading metadata for a given object or container involves
at minimum three getxattr system calls for objects that use only one xattr
key/value pair:

    1. (via pyxattr)  getxattr() to see if key exists and get its value
       length (so it can allocate memory for second call below)
    2. (from pyxattr) getxattr() to get actual value data
    3. (via pyxattr)  getxattr() to see if following key exists

For objects and containers that only have to use one xattr key/value pair,
this patch reduces the number system calls by one. This can be significant
given that almost every Swift API operation requires reads of the object or
containers metadata.

This patch is mostly a change to plugins.utils.read_metadata() to try to
unpickle the accumulated metadata as each key/value pair is read, rather than
trying to accumulate all the key/value pairs and unpickle at the end. Once we
get enough data to form the pickle, we no longer keep trying to get more keys,
even if those keys exist.

The extra keys can exist when the size of the stored metadata shrinks below a
key threshold. See https://bugzilla.redhat.com/show_bug.cgi?id=865619 for more
details.

See also https://bugzilla.redhat.com/show_bug.cgi?id=865858.

This patch also adds a unit test infrastructure, and uses it to test with full
coverage, the read_metadata, write_metadata and clean_metadata functions. As a
result, we found that an infinite loop would occur in clean_metadata() when an
unexpected IOError would occur trying to remove a key (this patch contains a
fix).

Backport of commit: 1f3ee888df53d0b22b4d732850f206e20af619a4

Change-Id: Iddd6931eaf0be67d5cfa562ae818244161e4ab87
Signed-off-by: Peter Portante <peter.portante@redhat.com>
object-storage: further reduce extd attr rds/wrs

More refactoring towards reducing the number of extended attribute
reads/writes to the file system. See BZ 868120:
    http://bugzilla.redhat.com/show_bug.cgi?id=868120

Basically the redundant routines restore_object, restore_account and
restore_container have been collapsed to one routine, restore_metadata, which
will only write out metadata if the new metadata is different from what was
originally read.

Backport of commit: 8ede7774470259e7849b11c1d3fa2d13daa06068

Change-Id: I6d037e90432f1c7be1b8dfaa55ad88257bf8a1a3
Signed-off-by: Peter Portante <peter.portante@redhat.com>
object-storage: reduce stat calls gen'ing metadata

Reduce the number of stat/fstat system calls made while generating metadata.

This address BZ 868086, https://bugzilla.redhat.com/show_bug.cgi?id=868086

This refactoring consolidates the code a bit, and uses os.stat calls to get
all the information in one call when gathering the metadata for an object. The
five stat system calls (invoked via all the os.path.*() calls) have been
reduced to one.

Backport of commit: a79e6f63dc3f4dc10d1c2993231659a0387a9a33

Change-Id: I0fd16b75845f561cc7d9e12496a94b0a2ca1d43f
Signed-off-by: Peter Portante <peter.portante@redhat.com>
object-storage: fix ismount; don't read conf on req

Write our own ismount() method which only calls lstat() 2 times
instead of 3.

Read the swift.conf and fs.conf files once per module instead of for
every request. This is a partial backport of commit:
    fe083592e91f2505ddb536a9df29d6dc84c4f2b3

Change-Id: I51bef6139a545c7c98ee6cdadbb4bd86ffc1fee8
Signed-off-by: Peter Portante <peter.portante@redhat.com>
object-storage: don't call fallocate() for Gluster FS

Swift always calls fallocate(), even though it always returns
ENOTSUPP. When using Gluster, don't make that call.

Change-Id: I1284fc0131dcac39635b7a64f52bca3190da8b5d
Signed-off-by: Peter Portante <peter.portante@redhat.com>
object-storage: remove extraneous system calls

Remove a number of stat() system calls that were redundant, and a few others...

[Update the comment later]

Change-Id: Ie6b16596796c935286dd55f1788fd4c37a0e1f21
Signed-off-by: Peter Portante <peter.portante@redhat.com>