84 Commits

Author SHA1 Message Date
Darrell Bishop
ea95d0092a Avoid infinite recursion in swift.obj.replicator.get_hashes.
Fixes bug 1089140.

Turns out that if an exception bails out of the pickle loading (eg.
zero-byte hahes_file), the if clause to determine whether or not to
write out a fresh hashes_file can evaluate to false, leading to an
infinite loop.

This patch fixes this infinite loop generally, by ensuring that if any
exception is thrown, a new hashes_file is written.

Change-Id: I344c5f8e261ce7c667bdafe1687263a4150b21dc
2012-12-11 15:32:09 -08:00
Peter Portante
7d70e05aeb Refactor DiskFile to hide temp file names and exts
This set of changes reworks the DiskFile class to remove the "extension"
parameter from the put() method, offering the new put_metadata() method with
an optional tombstone keyword boolean, and changes the mkstemp method to only
return the file descriptor.

Reviewing the code it was found that the temporary file name created as a
result of calling DiskFile.mkstemp() was never used by the caller, but the
caller was responsible for passing it back to the DiskFile.put() method. That
seems like too much information is exposed to the caller, when all the caller
requires is the file descriptor to write data into it.

Upon further review, the mkstemp() method was used in three places: PUT, POST
and DELETE method handling. Of those three cases, only PUT requires the file
descriptor, since it is responsible for writing the object contents. For POST
and DELETE, DiskFile only needs to associate metadata with the correct file
name. We abstract the pattern that those two use (once we also refactor the
code to move the fetch of the delete-at metadata, and subsequent
delete-at-update initiation, from under the mkstemp context) by adding the new
put_metadata() method.

As a result, the DiskFile class is then free to do whatever file system
operations it must to meet the API, without the caller having to know more
than just how to write data to a file descriptor. Note that DiskFile itself
key'd off of the '.ts' and '.meta' extensions for its operations, and for that
to work properly, the caller had to know to use those correctly. With this
change, the caller has no knowledge of how the file system is being used to
accomplish data and metadata storage.

See also Question 213796 at:
    https://answers.launchpad.net/swift/+question/213796

Change-Id: I267f68e64391ba627b2a13682393bec62600159d
Signed-off-by: Peter Portante <peter.portante@redhat.com>
2012-11-15 08:58:26 -05:00
Samuel Merritt
237a440cd1 Make DELETE requests to expired objects return 404.
It is already the case that a DELETE of a deleted object results in a
404, and GET/HEAD/POSTs to both expired and deleted objects result in
404s. However, a DELETE of an expired object resulted in a 202. This
change makes it consistent with the other verbs.

Fixes bug 1076245.

Change-Id: I793e62d72461a4fb9fb3404e10658ddcc4c3a7a6
2012-11-08 15:27:24 -08:00
gholt
f46a4d8a2f Fixed bugs with internal client and object expirer
These bug fixes are lumped together because they all caused problems
with the object expirer doing its job.

There was a bug with the internal client doing listings that happened
to run across a Unicode object name for use as a marker.

There was a bug with the object expirer not utf8 encoding object
names it got from json listings, causing deletes to fail.

There was a bug with the object expirer url quoting object names when
calling the internal client's make_request, when make_request already
handles that.

Change-Id: I29fdd351fd60c8e63874b44d604c5fdff35169d4
2012-11-08 00:05:35 +00:00
litong01
ce274b3532 blueprint Multi-range support implementation
This change adds multi range retrieval to OpenStack Swift. For non-
segmented data object, a client can use HTTP Range header to specify
multiple ranges to retrieve sections of the data object.

This implementation currently does not support segmented data object
multi range retrieval. When a client sends a multi range request
against a segmented data object, Swift will return HTTP status code
200. Support for segmented data multi range retrieval will be added
in near future.

This implementation is to bring Swift closer to CDMI multi range
data retrieval standard. Once support for segemented data multi
range is added, Swift will be compliant with CDMI standard in
this area.

DocImpact

Change-Id: I4ed1fb0a0a93c037ddb2f551ea62afe447945107
2012-11-01 20:45:30 -04:00
Samuel Merritt
851bbe2ea9 Track unlinks of async_pendings.
It's not sufficient to just look at swift.object-updater.successes to
see the async_pending unlink rate. There are two different spots where
unlinks happen: one when an async_pending has been successfully
processed, and another when the updater notices multiple
async_pendings for the same object. Both events are now tracked under
the same name: swift.object-updater.unlinks.

FakeLogger has now sprouted a couple of convenience methods for
testing logged metrics.

Fixed pep8 1.3.3's complaints in the files this diff touches.

Also: bonus speling and, grammar fixes in the admin guide.

Change-Id: I8c1493784adbe24ba2b5512615e87669b3d94505
2012-10-23 10:27:21 -07:00
Greg Lange
e7f3a9865e internal client unicode paths
made internal client handle unicode path parts by adding make_path method
fixed pep8 problems in internal client and its test
moved internal client unit test file to correct directory

Change-Id: Id1c81c9cb0db05342e4e8a8393db93552fda4647
2012-10-05 18:57:24 +00:00
Michael Barton
5e3e9a882d local WSGI Request and Response classes
This change replaces WebOb with a mostly compatible local library,
swift.common.swob.  Subtle changes to WebOb's API over the years have been a
huge headache.  Swift doesn't even run on the current version.

There are a few incompatibilities to simplify the implementation/interface:
 * It only implements the header properties we use.  More can be easily added.
 * Casts header values to str on assignment.
 * Response classes ("HTTPNotFound") are no longer subclasses, but partials
   on Response, so things like isinstance no longer work on them.
 * Unlike newer webob versions, will never return unicode objects.

Change-Id: I76617a0903ee2286b25a821b3c935c86ff95233f
2012-09-28 14:48:48 -07:00
David Goetz
a6c44d2764 allow replicator run_once to check specific devices/partitions
Change-Id: If45f77fda269ae6e251579542e70eb71bd11fe2a
2012-09-28 12:24:15 -07:00
David Goetz
d24e280bf4 obj replicator speed up
Change-Id: If02b573353dedea9c2368ce4733fe97599229b2e
2012-09-10 15:12:39 -07:00
Jenkins
3482eb26f9 Merge "swift constraints are now settable via config" 2012-09-07 23:21:47 +00:00
John Dickinson
a2ac5efaa6 swift constraints are now settable via config
Change previously hard-coded constants into config variables. This
allows deployers to tune their cluster more specifically based on
their needs. For example, a deployment that uses direct swift access
for public content may need to set a larger header value constraint to
allow for the full object name to be represented in the Content-
Disposition header (which browsers check to determine the name of a
downloaded object).

The new settings are set in the [swift-constraints] section of
/etc/swift/swift.conf. Comments were also added to this config file.

Cleaned up swift/common/constraints.py to pass pep8 1.3.3

Funtional tests now require constraints to be defined in /etc/test.conf or in
/etc/swift/swift.conf (in the case of running the functional tests against a
local swift cluster). To have any hope of tests passing, the defined
constraints must match the constraints on the tested cluster.

Removed a ton of "magic numbers" in both unit and functional tests.

Change-Id: Ie4588e052fd158314ddca6cd8fca9bc793311465
2012-09-07 11:18:42 -07:00
Darrell Bishop
46a093f068 Obj replicator cleans up files where part dirs should be.
If a partition directory was a file instead of a directory, the
object-replicator would attempt to listdir() it, raise an exception, and
try again next iteration.  This condition could arise after running
xfs_repair.

Now, collect_jobs() will reap any partition directories which are
actually files.  Fixes bug 1045954.

Change-Id: Id65d3eab2effd61c3f6b25250611c88c907b2a16
2012-09-05 23:54:16 +00:00
John Dickinson
eb5f89ac25 fallocate call error handling
fallocate() failures properly return HTTPInsufficientStorage from
object-server before reading from wsgi.input, allowing the proxy
server to error_limit that node.

Change-Id: Idfc293bbab2cff1e508edf58045108ca1ef5cec1
2012-08-28 10:25:33 -07:00
Michael Barton
da0e013d98 make obj replicator locking more optimistic
Basically, do all hashing in the replicator without a lock, then
lock briefly to rewrite the hashes file. Retry if someone else has
modified the hashes file in the mean time (which should be rare).

Also, a little refactoring.

Change-Id: I6257a53808d14b567bde70d2d18a9c58cb1e415a
2012-08-22 13:09:35 -07:00
gholt
61932d8506 Fixed bug where expirer would get confused by...
Fixed bug where expirer would get confused by odd deletion times.
Since this has already rolled out, I just capped things at ten 9s, or
Sat Nov 20 17:46:39 2286. I can't wait for the Y2286 world panic. :/

Change-Id: Iba10963faa344a418a1fa573d5c85f4ff864b574
2012-08-06 20:53:24 +00:00
Ionuț Arțăriși
9af3df9ee8 fix object replication on older rsync versions when using ipv4
Fixes bug 987388

Change-Id: I6eb5c45fe1f5844ad853a4ff9bc8fd23cc9abd5d
2012-06-06 10:07:56 +02:00
Ionuț Arțăriși
9f5a6bba1a only allow methods which implement HTTP verbs to be called remotely
This fixes 500 server crashes caused by requests such as:

curl -X__init__ "http://your-swift-object-server:6000/sda1/p/a/c/o"

Fixes bug 1005903

Change-Id: I6c0ad39a29e07ce5f46b0fdbd11a53a9a1010a04
2012-06-04 17:46:17 +02:00
Samuel Merritt
783f16035a Fix starvation in object server with fast clients.
When an object server was handling concurrent GET or POST requests
from very fast clients, it would starve other connected clients. The
greenthreads responsible for servicing the fast clients would hog the
processor and only rarely yield to another greenthread.

The reason this happens for GET requests is found in
eventlet.greenio.GreenSocket, in the send() method. When you call
.send(data) on a GreenSocket, it immediately calls .send(data) on its
underlying real socket (socket._socketobject). If the real socket
accepts all the data, then GreenSocket.send() returns without yielding
to another greenthread. Only if the real socket failed to accept all
the data (either .send(data) < len(data) or by raising EWOULDBLOCK)
does the GreenSocket yield control.

Under most workloads, this isn't a problem. The TCP connection to
client X can only consume data so quickly, and therefore the
greenthread serving client X will frequently encounter a full socket
buffer and yield control, so no clients starve. However, when there's
a lot of contention for a single object from a large number of fast
clients (e.g. on a LAN connected w/10Gb Ethernet), then one winds up
in a situation where reading from the disk is slower than writing to
the network, and so full socket buffers become rare, and therefore so
do context switches. The end result is that many clients time out
waiting for data.

The situation for PUT requests is analogous; GreenSocket.recv() seldom
encounters EWOULDBLOCK, so greenthreads seldom yield.

This patch calls eventlet.sleep() to yield control after each chunk,
preventing any one greenthread's IO from blocking the hub for very
long.

This code has the flaw that it will greenthread-switch twice when a
send() or recv() does block, but since there isn't a way to find out
if a switch occurred or not, there's no way to avoid it. Since
greenlet switches are quite fast (faster than system calls, which the
object server does a lot of), this shouldn't have a significant
performance impact.

Change-Id: I8549adfb4a198739b80979236c27b76df607eebf
2012-06-01 15:27:36 -07:00
Florian Hines
ccb6334c17 Expand recon middleware support
Expand recon middleware to include support for account and container
servers in addition to the existing object servers. Also add support
for retrieving recent information from auditors, replicators, and
updaters. In the case of certain checks (such as container auditors)
the stats returned are only for the most recent path processed.

The middleware has also been refactored and should now also handle
errors better in cases where stats are unavailable.

While new check's have been added the output from pre-existing
check's has not changed. This should allow existing 3rd party
utilities such as the Swift ZenPack to continue to function.

Change-Id: Ib9893a77b9b8a2f03179f2a73639bc4a6e264df7
2012-05-24 14:50:00 -05:00
Darrell Bishop
3d3ed34f44 Adding StatsD logging to Swift.
Documentation, including a list of metrics reported and their semantics,
is in the Admin Guide in a new section, "Reporting Metrics to StatsD".
An optional "metric prefix" may be configured which will be prepended to
every metric name sent to StatsD.

Here is the rationale for doing a deep integration like this versus only
sending metrics to StatsD in middleware.  It's the only way to report
some internal activities of Swift in a real-time manner. So to have one
way of reporting to StatsD and one place/style of configuration, even
some things (like, say, timing of PUT requests into the proxy-server)
which could be logged via middleware are consistently logged the same
way (deep integration via the logger delegate methods).

When log_statsd_host is configured, get_logger() injects a
swift.common.utils.StatsdClient object into the logger as
logger.statsd_client.  Then a set of delegate methods on LogAdapter
either pass through to the StatsdClient object or become no-ops. This
allows StatsD logging to look like:
    self.logger.increment('some.metric.here')
and do the right thing in all cases and with no messy conditional logic.

I wanted to use the pystatsd module for the StatsD client, but the
version on PyPi is lagging the git repo (and is missing both the prefix
functionality and timing_since() method).  So I wrote my
swift.common.utils.StatsdClient.  The interface is the same as
pystatsd.Client, but the code was written from scratch.  It's pretty
simple, and the tests I added cover it.  This also frees Swift from an
optional dependency on the pystatsd module, making this feature easier
to enable.

There's test coverage for the new code and all existing tests continue
to pass.

Refactored out _one_audit_pass() method in swift/account/auditor.py and
swift/container/auditor.py.

Fixed some misc. PEP8 violations.

Misc test cleanups and refactorings (particularly the way "fake logging"
is handled).

Change-Id: Ie968a9ae8771f59ee7591e2ae11999c44bfe33b2
2012-05-11 15:25:38 -07:00
Samuel Merritt
bb509dd863 As-unique-as-possible partition replica placement.
This commit introduces a new algorithm for assigning partition
replicas to devices. Basically, the ring builder organizes the devices
into tiers (first zone, then IP/port, then device ID). When placing a
replica, the ring builder looks for the emptiest device (biggest
parts_wanted) in the furthest-away tier.

In the case where zone-count >= replica-count, the new algorithm will
give the same results as the one it replaces. Thus, no migration is
needed.

In the case where zone-count < replica-count, the new algorithm
behaves differently from the old algorithm. The new algorithm will
distribute things evenly at each tier so that the replication is as
high-quality as possible, given the circumstances. The old algorithm
would just crash, so again, no migration is needed.

Handoffs have also been updated to use the new algorithm. When
generating handoff nodes, first the ring looks for nodes in other
zones, then other ips/ports, then any other drive. The first handoff
nodes (the ones in other zones) will be the same as before; this
commit just extends the list of handoff nodes.

The proxy server and replicators have been altered to avoid looking at
the ring's replica count directly. Previously, with a replica count of
C, RingData.get_nodes() and RingData.get_part_nodes() would return
lists of length C, so some other code used the replica count when it
needed the number of nodes. If two of a partition's replicas are on
the same device (e.g. with 3 replicas, 2 devices), then that
assumption is no longer true. Fortunately, all the proxy server and
replicators really needed was the number of nodes returned, which they
already had. (Bonus: now the only code that mentions replica_count
directly is in the ring and the ring builder.)

Change-Id: Iba2929edfc6ece89791890d0635d4763d821a3aa
2012-05-09 15:56:06 -07:00
Greg Lange
8d2fe89a7d Added an internal client.
Refactored object expirer to use this client.

Change-Id: Ibeca6dba873f8b4a558ecf3ba6e8d23d36f545b0
2012-05-04 18:07:54 +00:00
Jenkins
6682138b0a Merge "Make ring class interface slightly more abstracted from implementation." 2012-03-22 20:25:06 +00:00
John Dickinson
1ecf5ebba1 updated copyright date for all files
Change-Id: Ifd909d3561c2647770a7e0caa3cd91acd1b4f298
2012-03-19 13:45:34 -05:00
Michael Barton
e008c2ebb8 Make ring class interface slightly more abstracted from implementation.
Change-Id: I0f55d61c7b8de30460f17a69e5d9946494dbda6e
2012-03-14 22:00:30 +00:00
David Goetz
a98ce6eade Change tpooled_get_hashes back to err,err on Timeout, (object server REPLICATE needs it) and unit tests
Change-Id: Ic60c33570594fd2c0939043863b013aa2103505d
2012-02-08 10:22:39 -08:00
David Goetz
2b3aab86bb Fix object replicator to handle Timeouts fixes: lp 814263
Change-Id: I4c8b73d4cb0540fa105f240b2a9d481cf9c1e55c
2011-11-28 11:24:22 -08:00
Jenkins
a885fe3b14 Merge "Updated TimeoutError and except Exception refs..." 2011-11-14 18:26:56 +00:00
gholt
dd839048f1 Updated TimeoutError and except Exception refs...
Updated eventlet.TimeoutError (deprecated) references to
Timeout and, more importantly, updated many except Exception
clauses to except (Exception, Timeout).

Change-Id: Ib089265551bd20b94c00ea84f11140ccd795d301
2011-11-07 16:26:03 +00:00
gholt
0e2c101fba Fixed time-sensitive tests.
I noticed that a couple of tests I recently made were
time-sensitive. This can be shown with the following quick
script:

from sys import exit
from unittest import TestSuite, TextTestRunner

from test.unit.obj.test_server import TestObjectController

s = TestSuite()
s.addTest(TestObjectController('test_GET_but_expired'))
s.addTest(TestObjectController('test_HEAD_but_expired'))
for x in xrange(200):
    if TextTestRunner().run(s).failures:
        exit('!!!!!!!!!!!!!!! TEST FAILED !!!!!!!!!!!!!!!')
print '\o/ Test ran 200 times without failure.'

Change-Id: Ifdb1920e5266aaa278baa0759fc0bfaa1aff2d0d
2011-11-01 23:16:11 +00:00
gholt
872420efdb Expiring Objects Support
Please see the doc/source/overview_expiring_objects.rst for
more detail.

Change-Id: I4ab49e731248cf62ce10001016e0c819cc531738
2011-11-01 15:49:00 +00:00
David Goetz
fc4f6feb8f fix for unit test 2011-08-31 07:28:36 -07:00
David Goetz
daa057d597 make sure files always get closed 2011-08-30 14:29:19 -07:00
gholt
dfd61697c1 Fix bug; added test for quarantined a hash dir that becomes a file 2011-08-02 17:46:17 +00:00
gholt
ae5cc4f6ce Fix test to compare unpickled values since we really don't care to test pickling 2011-07-25 08:40:11 -07:00
Michael Barton
dc213d9746 update unit tests 2011-05-13 02:41:37 +00:00
Greg Lange
df0a61a649 only latest async pending is now sent 2011-04-21 20:52:49 +00:00
Greg Lange
71b076eb59 only latest async pending is now sent 2011-04-20 19:54:28 +00:00
John Dickinson
88b06d2487 made failing unit test for HEAD requests 2011-04-19 15:57:44 -05:00
David Goetz
b544570da5 merge to trunk conflicts 2011-03-28 19:29:20 -07:00
Michael Barton
716418ba9c refactor obj-rep a bit and move local hash recalculation to before rsync 2011-03-24 19:37:29 +00:00
John Dickinson
0c5aacb424 added default support for content-disposition and allows x-object-manifest to be manipulated like any other object metadata header 2011-03-24 13:03:49 -05:00
John Dickinson
09b7013dc2 fixed location of a test 2011-03-24 11:43:12 -05:00
John Dickinson
88ad83767b objects can now have arbitrary headers set in metadata that will be served back when they are fetched 2011-03-22 20:05:44 -05:00
John Dickinson
06094af359 fixed object POST so content encoding can be set and deleted 2011-03-22 18:17:47 -05:00
Michael Barton
765f5b5c3f refactor obj-rep a bit and move hash recalculate to before rsync step 2011-03-20 22:14:03 +00:00
David Goetz
863393c823 pep8 2011-03-16 09:04:00 -07:00
David Goetz
5482035bc0 change ite logic and add more tests 2011-03-16 07:55:07 -07:00
David Goetz
86c84c3bc3 unittests workng and added probe test 2011-03-15 22:12:03 -07:00