Bases: object
Walk through file system to audit objects
Entrypoint to object_audit, with a failsafe generic exception handler.
Audits the given object location.
Parameters: | location – an audit location (from diskfile.object_audit_location_generator) |
---|
Based on config’s object_size_stats will keep track of how many objects fall into the specified ranges. For example with the following:
object_size_stats = 10, 100, 1024
and your system has 3 objects of sizes: 5, 20, and 10000 bytes the log will look like: {“10”: 1, “100”: 1, “1024”: 0, “OVER”: 1}
Bases: swift.common.daemon.Daemon
Audit objects.
Parallel audit loop
Clear recon cache entries
Child execution
Run the object audit
Run the object audit until stopped.
Run the object audit once
Disk File Interface for the Swift Object Server
The DiskFile, DiskFileWriter and DiskFileReader classes combined define the on-disk abstraction layer for supporting the object server REST API interfaces (excluding REPLICATE). Other implementations wishing to provide an alternative backend for the object server must implement the three classes. An example alternative implementation can be found in the mem_server.py and mem_diskfile.py modules along size this one.
The DiskFileManager is a reference implemenation specific class and is not part of the backend API.
The remaining methods in this module are considered implementation specific and are also not considered part of the backend API.
Bases: object
Represents an object location to be audited.
Other than being a bucket of data, the only useful thing this does is stringify to a filesystem path so the auditor’s logs look okay.
Bases: object
Manage object files.
This specific implementation manages object files on a disk formatted with a POSIX-compliant file system that supports extended attributes as metadata on a file or directory.
Note
The arguments to the constructor are considered implementation specific. The API does not define the constructor arguments.
The following path format is used for data file locations: <devices_path/<device_dir>/<datadir>/<partdir>/<suffixdir>/<hashdir>/ <datafile>.<ext>
Parameters: |
|
---|
Context manager to create a file. We create a temporary file first, and then return a DiskFileWriter object to encapsulate the state.
Note
An implementation is not required to perform on-disk preallocations even if the parameter is specified. But if it does and it fails, it must raise a DiskFileNoSpace exception.
Parameters: | size – optional initial size of file to explicitly allocate on disk |
---|---|
Raises DiskFileNoSpace: | |
if a size is specified and allocation fails |
Delete the object.
This implementation creates a tombstone file using the given timestamp, and removes any older versions of the object file. Any file that has an older timestamp than timestamp will be deleted.
Note
An implementation is free to use or ignore the timestamp parameter.
Parameters: | timestamp – timestamp to compare with each file |
---|---|
Raises DiskFileError: | |
this implementation will raise the same errors as the create() method. |
Provides the timestamp of the newest data file found in the object directory.
Returns: | A Timestamp instance, or None if no data file was found. |
---|---|
Raises DiskFileNotOpen: | |
if the open() method has not been previously called on this instance. |
Provide the datafile metadata for a previously opened object as a dictionary. This is metadata that was included when the object was first PUT, and does not include metadata set by any subsequent POST.
Returns: | object’s datafile metadata dictionary |
---|---|
Raises DiskFileNotOpen: | |
if the swift.obj.diskfile.DiskFile.open() method was not previously invoked |
Provide the metadata for a previously opened object as a dictionary.
Returns: | object’s metadata dictionary |
---|---|
Raises DiskFileNotOpen: | |
if the swift.obj.diskfile.DiskFile.open() method was not previously invoked |
Provide the metafile metadata for a previously opened object as a dictionary. This is metadata that was written by a POST and does not include any persistent metadata that was set by the original PUT.
Returns: | object’s .meta file metadata dictionary, or None if there is no .meta file |
---|---|
Raises DiskFileNotOpen: | |
if the swift.obj.diskfile.DiskFile.open() method was not previously invoked |
Open the object.
This implementation opens the data file representing the object, reads the associated metadata in the extended attributes, additionally combining metadata from fast-POST .meta files.
Note
An implementation is allowed to raise any of the following exceptions, but is only required to raise DiskFileNotExist when the object representation does not exist.
Raises: |
|
---|---|
Returns: | itself for use as a context manager |
Return the metadata for an object without requiring the caller to open the object first.
Returns: | metadata dictionary for an object |
---|---|
Raises DiskFileError: | |
this implementation will raise the same errors as the open() method. |
Return a swift.common.swob.Response class compatible “app_iter” object as defined by swift.obj.diskfile.DiskFileReader.
For this implementation, the responsibility of closing the open file is passed to the swift.obj.diskfile.DiskFileReader object.
Parameters: |
|
---|---|
Returns: | a swift.obj.diskfile.DiskFileReader object |
Write a block of metadata to an object without requiring the caller to create the object first. Supports fast-POST behavior semantics.
Parameters: | metadata – dictionary of metadata to be associated with the object |
---|---|
Raises DiskFileError: | |
this implementation will raise the same errors as the create() method. |
Bases: object
Management class for devices, providing common place for shared parameters and methods not provided by the DiskFile class (which primarily services the object server REST API layer).
The get_diskfile() method is how this implementation creates a DiskFile object.
Note
This class is reference implementation specific and not part of the pluggable on-disk backend API.
Note
TODO(portante): Not sure what the right name to recommend here, as “manager” seemed generic enough, though suggestions are welcome.
Parameters: |
|
---|
Clean up on-disk files that are obsolete and gather the set of valid on-disk files for an object.
Parameters: |
|
---|---|
Returns: | a dict that may contain: valid on disk files keyed by their filename extension; a list of obsolete files stored under the key ‘obsolete’; a list of files remaining in the directory, reverse sorted, stored under the key ‘files’. |
Construct the path to a device without checking if it is mounted.
Parameters: | device – name of target device |
---|---|
Returns: | full path to the device |
Return the path to a device, first checking to see if either it is a proper mount point, or at least a directory depending on the mount_check configuration option.
Parameters: |
|
---|---|
Returns: | full path to the device, None if the path to the device is not a proper mount point or directory. |
Returns a BaseDiskFile instance for an object based on the object’s partition, path parts and policy.
Parameters: |
|
---|
Returns a BaseDiskFile instance for an object at the given AuditLocation.
Parameters: | audit_location – object location to be audited |
---|
Returns a DiskFile instance for an object at the given object_hash. Just in case someone thinks of refactoring, be sure DiskFileDeleted is not raised, but the DiskFile instance representing the tombstoned object is returned instead.
Parameters: |
|
---|---|
Raises DiskFileNotExist: | |
if the object does not exist |
|
Returns: | an instance of BaseDiskFile |
Parameters: |
|
---|---|
Returns: | a dictionary that maps suffix directories |
Given a simple list of files names, determine the files that constitute a valid fileset i.e. a set of files that defines the state of an object, and determine the files that are obsolete and could be deleted. Note that some files may fall into neither category.
If a file is considered part of a valid fileset then its info dict will be added to the results dict, keyed by <extension>_info. Any files that are no longer required will have their info dicts added to a list stored under the key ‘obsolete’.
The results dict will always contain entries with keys ‘ts_file’, ‘data_file’ and ‘meta_file’. Their values will be the fully qualified path to a file of the corresponding type if there is such a file in the valid fileset, or None.
Parameters: |
|
---|---|
Returns: |
|
Returns filename for given timestamp.
Parameters: | |
---|---|
Returns: | a file name |
Yield an AuditLocation for all objects stored under device_dirs.
Parameters: |
|
---|
Parse an on disk file name.
Parameters: | filename – the file name including extension |
---|---|
Returns: | a dict, with keys for timestamp, ext and ctype_timestamp:
Subclasses may override this method to add further keys to the returned dict. |
Raises DiskFileError: | |
if any part of the filename is not able to be validated. |
Write data describing a container update notification to a pickle file in the async_pending directory.
Parameters: |
|
---|
A context manager that will lock on the device given, if configured to do so.
Parameters: | device – name of target device |
---|---|
Raises ReplicationLockTimeout: | |
If the lock on the device cannot be granted within the configured timeout. |
Yields tuples of (full_path, hash_only, timestamps) for object information stored for the given device, partition, and (optionally) suffixes. If suffixes is None, all stored suffixes will be searched for object hashes. Note that if suffixes is not None but empty, such as [], then nothing will be yielded.
timestamps is a dict which may contain items mapping:
where timestamps are instances of Timestamp
Parameters: |
|
---|
Yields tuples of (full_path, suffix_only) for suffixes stored on the given device and partition.
Parameters: |
|
---|
Bases: object
Encapsulation of the WSGI read context for servicing GET REST API requests. Serves as the context manager object for the swift.obj.diskfile.DiskFile class’s swift.obj.diskfile.DiskFile.reader() method.
Note
The quarantining behavior of this method is considered implementation specific, and is not required of the API.
Note
The arguments to the constructor are considered implementation specific. The API does not define the constructor arguments.
Parameters: |
|
---|
Returns an iterator over the data file for range (start, stop)
Returns an iterator over the data file for a set of ranges
Close the open file handle if present.
For this specific implementation, this method will handle quarantining the file if necessary.
Does some magic with splice() and tee() to move stuff from disk to network without ever touching userspace.
Parameters: | wsockfd – file descriptor (integer) of the socket out which to send data |
---|
Bases: object
Encapsulation of the write context for servicing PUT REST API requests. Serves as the context manager object for the swift.obj.diskfile.DiskFile class’s swift.obj.diskfile.DiskFile.create() method.
Note
It is the responsibility of the swift.obj.diskfile.DiskFile.create() method context manager to close the open file descriptor.
Note
The arguments to the constructor are considered implementation specific. The API does not define the constructor arguments.
Parameters: |
|
---|
Perform any operations necessary to mark the object as durable. For replication policy type this is a no-op.
Parameters: | timestamp – object put timestamp, an instance of Timestamp |
---|
Finalize writing the file on disk.
Parameters: | metadata – dictionary of metadata to be associated with the object |
---|
Write a chunk of data to disk. All invocations of this method must come before invoking the :func:
For this implementation, the data is written into a temporary file.
Parameters: | chunk – the chunk of data to write as a string object |
---|---|
Returns: | the total number of bytes written to an object |
Bases: swift.obj.diskfile.BaseDiskFile
alias of DiskFileReader
alias of DiskFileWriter
Bases: object
Decorator for Storage Policy implementations to register their DiskFile implementation.
Bases: swift.obj.diskfile.BaseDiskFileWriter
Finalize writing the file on disk.
Parameters: | metadata – dictionary of metadata to be associated with the object |
---|
Bases: swift.obj.diskfile.BaseDiskFile
Provides the timestamp of the newest durable file found in the object directory.
Returns: | A Timestamp instance, or None if no durable file was found. |
---|---|
Raises DiskFileNotOpen: | |
if the open() method has not been previously called on this instance. |
Provides information about all fragments that were found in the object directory, including fragments without a matching durable file, and including any fragment chosen to construct the opened diskfile.
Returns: | A dict mapping <Timestamp instance> -> <list of frag indexes>, or None if the diskfile has not been opened or no fragments were found. |
---|
Remove a tombstone file matching the specified timestamp or datafile matching the specified timestamp and fragment index from the object directory.
This provides the EC reconstructor/ssync process with a way to remove a tombstone or fragment from a handoff node after reverting it to its primary node.
The hash will be invalidated, and if empty or invalid the hsh_path will be removed on next cleanup_ondisk_files.
Parameters: |
|
---|
alias of ECDiskFileReader
alias of ECDiskFileWriter
Bases: swift.obj.diskfile.BaseDiskFileManager
alias of ECDiskFile
Returns the EC specific filename for given timestamp.
Parameters: |
|
---|---|
Returns: | a file name |
Raises DiskFileError: | |
if ext==’.data’ and the kwarg frag_index is not a whole number |
Returns timestamp(s) and other info extracted from a policy specific file name. For EC policy the data file name includes a fragment index which must be stripped off to retrieve the timestamp.
Parameters: | filename – the file name including extension |
---|---|
Returns: |
|
Raises DiskFileError: | |
if any part of the filename is not able to be validated. |
Return int representation of frag_index, or raise a DiskFileError if frag_index is not a whole number.
Parameters: | frag_index – a fragment archive index |
---|
Bases: swift.obj.diskfile.BaseDiskFileWriter
Finalize put by writing a timestamp.durable file for the object. We do this for EC policy because it requires a 2-phase put commit confirmation.
Parameters: | timestamp – object put timestamp, an instance of Timestamp |
---|
The only difference between this method and the replication policy DiskFileWriter method is adding the frag index to the metadata.
Parameters: | metadata – dictionary of metadata to be associated with object |
---|
Take what’s in hashes.pkl and hashes.invalid, combine them, write the result back to hashes.pkl, and clear out hashes.invalid.
Parameters: | suffix_dir – absolute path to partition dir containing hashes.pkl and hashes.invalid |
---|---|
Returns: | the hashes, or None if there’s no hashes.pkl. |
Extracts the policy for an object (based on the name of the objects directory) given the device-relative path to the object. Returns None in the event that the path is malformed in some way.
The device-relative path is everything after the mount point; for example:
would have device-relative path:
objects-5/30/179/485dc017205a81df3af616d917c90179/1401811134.873649.data
Parameters: | obj_path – device-relative path of an object, or the full path |
---|---|
Returns: | a BaseStoragePolicy or None |
Invalidates the hash for a suffix_dir in the partition’s hashes file.
Parameters: | suffix_dir – absolute path to suffix dir whose hash needs invalidating |
---|
Given a devices path (e.g. “/srv/node”), yield an AuditLocation for all objects stored under that directory if device_dirs isn’t set. If device_dirs is set, only yield AuditLocation for the objects under the entries in device_dirs. The AuditLocation only knows the path to the hash directory, not to the .data file therein (if any). This is to avoid a double listdir(hash_dir); the DiskFile object will always do one, so we don’t.
Parameters: |
|
---|
In the case that a file is corrupted, move it to a quarantined area to allow replication to fix it.
Params device_path: | |
---|---|
The path to the device the corrupted file is on. | |
Params corrupted_file_path: | |
The path to the file you want quarantined. | |
Returns: | path (str) of directory the file was moved to |
Raises OSError: | re-raises non errno.EEXIST / errno.ENOTEMPTY exceptions from rename |
Helper function to read the pickled metadata from an object file.
Parameters: | fd – file descriptor or filename to load the metadata from |
---|---|
Returns: | dictionary of metadata |
Wrapper to attach module level functions to base class.
Helper function to write pickled metadata for an object file.
Parameters: |
|
---|
Bases: swift.common.daemon.Daemon
Replicate objects.
Encapsulates most logic and data needed by the object replication process. Each call to .replicate() performs one replication pass. It’s up to the caller to do this in a loop.
Helper function for collect_jobs to build jobs for replication using replication style storage policy
Check to see if the ring has been updated :param object_ring: the ring to check
Returns: | boolean indicating whether or not the ring has changed |
---|
Returns a sorted list of jobs (dictionaries) that specify the partitions, nodes, etc to be rsynced.
Parameters: |
|
---|
In testing, the pool.waitall() call very occasionally failed to return. This is an attempt to make sure the replicator finishes its replication pass in some eventuality.
Loop that runs in the background during replication. It periodically logs progress.
Utility function that kills all coroutines currently running.
Make sure the policy’s rings are loaded.
Parameters: | policy – the StoragePolicy instance |
---|---|
Returns: | appropriate ring object |
Run a replication pass
Uses rsync to implement the sync method. This was the first sync method in Swift.
Logs various stats for the currently running replication pass.
Synchronize local suffix directories from a partition with a remote node.
Parameters: |
|
---|---|
Returns: | boolean and dictionary, boolean indicating success or failure |
High-level method that replicates a single partition.
Parameters: | job – a dict containing info about the partition to be replicated |
---|
High-level method that replicates a single partition that doesn’t belong on this node.
Parameters: | job – a dict containing info about the partition to be replicated |
---|
Bases: object
Sends SSYNC requests to the object server.
These requests are eventually handled by ssync_receiver and full documentation about the process is there.
Establishes a connection and starts an SSYNC request with the object server.
Closes down the connection to the object server once done with the SSYNC request.
Handles the sender-side of the MISSING_CHECK step of a SSYNC request.
Full documentation of this can be found at Receiver.missing_check().
Reads a line from the SSYNC response body.
httplib has no readline and will block on read(x) until x is read, so we have to do the work ourselves. A bit of this is taken from Python’s httplib itself.
Sends a DELETE subrequest with the given information.
Sends a PUT subrequest for the url_path using the source df (DiskFile) and content_length.
Handles the sender-side of the UPDATES step of an SSYNC request.
Full documentation of this can be found at Receiver.updates().
Parse missing_check line parts to determine which parts of local diskfile were wanted by the receiver.
The encoder for parts is encode_wanted()
Returns a string representing the object hash, its data file timestamp and the delta forwards to its metafile and content-type timestamps, if non-zero, in the form: <hash> <ts_data> [m:<hex delta to ts_meta>[,t:<hex delta to ts_ctype>]]
The decoder for this line is decode_missing()
Bases: object
Handles incoming SSYNC requests to the object server.
These requests come from the object-replicator daemon that uses ssync_sender.
The number of concurrent SSYNC requests is restricted by use of a replication_semaphore and can be configured with the object-server.conf [object-server] replication_concurrency setting.
An SSYNC request is really just an HTTP conduit for sender/receiver replication communication. The overall SSYNC request should always succeed, but it will contain multiple requests within its request and response bodies. This “hack” is done so that replication concurrency can be managed.
The general process inside an SSYNC request is:
- Initialize the request: Basic request validation, mount check, acquire semaphore lock, etc..
- Missing check: Sender sends the hashes and timestamps of the object information it can send, receiver sends back the hashes it wants (doesn’t have or has an older timestamp).
- Updates: Sender sends the object information requested.
- Close down: Release semaphore lock, etc.
Basic validation of request and mount check.
This function will be called before attempting to acquire a replication semaphore lock, so contains only quick checks.
Handles the receiver-side of the MISSING_CHECK step of a SSYNC request.
Receives a list of hashes and timestamps of object information the sender can provide and responds with a list of hashes desired, either because they’re missing or have an older timestamp locally.
The process is generally:
Sender sends :MISSING_CHECK: START and begins sending hash timestamp lines.
Receiver gets :MISSING_CHECK: START and begins reading the hash timestamp lines, collecting the hashes of those it desires.
Sender sends :MISSING_CHECK: END.
Receiver gets :MISSING_CHECK: END, responds with :MISSING_CHECK: START, followed by the list of <wanted_hash> specifiers it collected as being wanted (one per line), :MISSING_CHECK: END, and flushes any buffers.
Each <wanted_hash> specifier has the form <hash>[ <parts>] where <parts> is a string containing characters ‘d’ and/or ‘m’ indicating that only data or meta part of object respectively is required to be sync’d.
Sender gets :MISSING_CHECK: START and reads the list of hashes desired by the receiver until reading :MISSING_CHECK: END.
The collection and then response is so the sender doesn’t have to read while it writes to ensure network buffers don’t fill up and block everything.
Handles the UPDATES step of an SSYNC request.
Receives a set of PUT and DELETE subrequests that will be routed to the object server itself for processing. These contain the information requested by the MISSING_CHECK step.
The PUT and DELETE subrequests are formatted pretty much exactly like regular HTTP requests, excepting the HTTP version on the first request line.
The process is generally:
- Sender sends :UPDATES: START and begins sending the PUT and DELETE subrequests.
- Receiver gets :UPDATES: START and begins routing the subrequests to the object server.
- Sender sends :UPDATES: END.
- Receiver gets :UPDATES: END and sends :UPDATES: START and :UPDATES: END (assuming no errors).
- Sender gets :UPDATES: START and :UPDATES: END.
If too many subrequests fail, as configured by replication_failure_threshold and replication_failure_ratio, the receiver will hang up the request early so as to not waste any more time.
At step 4, the receiver will send back an error if there were any failures (that didn’t cause a hangup due to the above thresholds) so the sender knows the whole was not entirely a success. This is so the sender knows if it can remove an out of place partition, for example.
Parse a string of the form generated by encode_missing() and return a dict with keys object_hash, ts_data, ts_meta, ts_ctype.
The encoder for this line is encode_missing()
Compare a remote and local results and generate a wanted line.
Parameters: |
|
---|
The decoder for this line is decode_wanted()
Object Server for Swift
Bases: str
Eventlet won’t send headers until it’s accumulated at least eventlet.wsgi.MINIMUM_CHUNK_SIZE bytes or the app iter is exhausted. If we want to send the response body behind Eventlet’s back, perhaps with some zero-copy wizardry, then we have to unclog the plumbing in eventlet.wsgi to force the headers out, so we use an EventletPlungerString to empty out all of Eventlet’s buffers.
Bases: swift.common.base_storage_server.BaseStorageServer
Implements the WSGI application for the Swift Object Server.
Handle HTTP DELETE requests for the Swift Object Server.
Handle HTTP GET requests for the Swift Object Server.
Handle HTTP HEAD requests for the Swift Object Server.
Handle HTTP POST requests for the Swift Object Server.
Handle HTTP PUT requests for the Swift Object Server.
Handle REPLICATE requests for the Swift Object Server. This is used by the object replicator to get hashes for directories.
Note that the name REPLICATE is preserved for historical reasons as this verb really just returns the hashes information for the specified parameters and is used, for example, by both replication and EC.
Sends or saves an async update.
Parameters: |
|
---|
Update the container when objects are updated.
Parameters: |
|
---|
Update the expiring objects container when objects are updated.
Parameters: |
|
---|
Utility method for instantiating a DiskFile object supporting a given REST API.
An implementation of the object server that wants to use a different DiskFile class would simply over-ride this method to provide that behavior.
Implementation specific setup. This method is called at the very end by the constructor to allow a specific implementation to modify existing attributes or add its own attributes.
Parameters: | conf – WSGI configuration parameter |
---|
paste.deploy app factory for creating WSGI object server apps
Read and discard any bytes from file_like.
Parameters: |
|
---|---|
Raises ChunkReadTimeout: | |
if no chunk was read in time |
Callback for swift.common.wsgi.run_wsgi during the global_conf creation so that we can add our replication_semaphore, used to limit the number of concurrent SSYNC_REQUESTS across all workers.
Parameters: |
|
---|
Bases: swift.common.daemon.Daemon
Update object information in container listings.
Get the container ring. Load it, if it hasn’t been yet.
If there are async pendings on the device, walk each one and update.
Parameters: | device – path to device |
---|
Perform the object update to the container
Parameters: |
|
---|
Process the object information to be updated and update.
Parameters: |
|
---|
Run the updater continuously.
Run the updater once.