From ed772236c7289d178561ce014beb4879f726fc48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Lis=C3=A1k?= Date: Thu, 22 Oct 2015 10:19:49 +0200 Subject: [PATCH] Change schedule priority of daemon/server in config The goal is to modify schedule priority and I/O scheduling class and priority of daemon/server via configuration. Setting is optional, default keeps current behaviour. Use case: Prioritize object-server to object-auditor, because all user's requests needed to be served in peak hours and audit could wait. Co-Authored-By: Clay Gerrard DocImpact Change-Id: I1018a18f4706daabdb84574ffd9a58d831e68396 --- doc/manpages/account-server.conf.5 | 60 ++++++++++++ doc/manpages/container-server.conf.5 | 72 +++++++++++++++ doc/manpages/object-expirer.conf.5 | 24 +++++ doc/manpages/object-server.conf.5 | 66 +++++++++++++ doc/manpages/proxy-server.conf.5 | 30 ++++++ doc/source/deployment_guide.rst | 89 +++++++++++++++++- etc/account-server.conf-sample | 60 ++++++++++++ etc/container-reconciler.conf-sample | 24 +++++ etc/container-server.conf-sample | 72 +++++++++++++++ etc/object-expirer.conf-sample | 20 ++++ etc/object-server.conf-sample | 72 +++++++++++++++ etc/proxy-server.conf-sample | 24 +++++ swift/common/daemon.py | 3 + swift/common/utils.py | 133 ++++++++++++++++++++++++++- swift/common/wsgi.py | 3 + test/unit/common/test_utils.py | 68 +++++++++++++- 16 files changed, 816 insertions(+), 4 deletions(-) diff --git a/doc/manpages/account-server.conf.5 b/doc/manpages/account-server.conf.5 index ef52ad05a9..b9f8b9395c 100644 --- a/doc/manpages/account-server.conf.5 +++ b/doc/manpages/account-server.conf.5 @@ -125,6 +125,18 @@ You can set fallocate_reserve to the number of bytes or percentage of disk space you'd like fallocate to reserve, whether there is space for the given file size or not. Percentage will be used if the value ends with a '%'. The default is 1%. +.IP \fBnice_priority\fR +Modify scheduling priority of server processes. Niceness values range from -20 +(most favorable to the process) to 19 (least favorable to the process). +The default does not modify priority. +.IP \fBionice_class\fR +Modify I/O scheduling class of server processes. I/O niceness class values +are IOPRIO_CLASS_RT, IOPRIO_CLASS_BE and IOPRIO_CLASS_IDLE. The default does not modify class and priority. +Work only with ionice_priority. +.IP \fBionice_priority\fR +Modify I/O scheduling priority of server processes. I/O niceness priority +is a number which goes from 0 to 7. The higher the value, the lower +the I/O priority of the process. Work only with ionice_class. .RE .PD @@ -172,6 +184,18 @@ To handle all verbs, including replication verbs, do not specify set to a true value (e.g. "true" or "1"). To handle only non-replication verbs, set to "false". Unless you have a separate replication network, you should not specify any value for "replication_server". The default is empty. +.IP \fBnice_priority\fR +Modify scheduling priority of server processes. Niceness values range from -20 +(most favorable to the process) to 19 (least favorable to the process). +The default does not modify priority. +.IP \fBionice_class\fR +Modify I/O scheduling class of server processes. I/O niceness class values +are IOPRIO_CLASS_RT, IOPRIO_CLASS_BE and IOPRIO_CLASS_IDLE. The default does not modify class and priority. +Work only with ionice_priority. +.IP \fBionice_priority\fR +Modify I/O scheduling priority of server processes. I/O niceness priority +is a number which goes from 0 to 7. The higher the value, the lower +the I/O priority of the process. Work only with ionice_class. .RE .PD @@ -281,6 +305,18 @@ Format of the rysnc module where the replicator will send data. See etc/rsyncd.conf-sample for some usage examples. .IP \fBrecon_cache_path\fR Path to recon cache directory. The default is /var/cache/swift. +.IP \fBnice_priority\fR +Modify scheduling priority of server processes. Niceness values range from -20 +(most favorable to the process) to 19 (least favorable to the process). +The default does not modify priority. +.IP \fBionice_class\fR +Modify I/O scheduling class of server processes. I/O niceness class values +are IOPRIO_CLASS_RT, IOPRIO_CLASS_BE and IOPRIO_CLASS_IDLE. The default does not modify class and priority. +Work only with ionice_priority. +.IP \fBionice_priority\fR +Modify I/O scheduling priority of server processes. I/O niceness priority +is a number which goes from 0 to 7. The higher the value, the lower +the I/O priority of the process. Work only with ionice_class. .RE @@ -303,6 +339,18 @@ Will audit, at most, 1 account per device per interval. The default is 1800 seco Maximum accounts audited per second. Should be tuned according to individual system specs. 0 is unlimited. The default is 200. .IP \fBrecon_cache_path\fR Path to recon cache directory. The default is /var/cache/swift. +.IP \fBnice_priority\fR +Modify scheduling priority of server processes. Niceness values range from -20 +(most favorable to the process) to 19 (least favorable to the process). +The default does not modify priority. +.IP \fBionice_class\fR +Modify I/O scheduling class of server processes. I/O niceness class values +are IOPRIO_CLASS_RT, IOPRIO_CLASS_BE and IOPRIO_CLASS_IDLE. The default does not modify class and priority. +Work only with ionice_priority. +.IP \fBionice_priority\fR +Modify I/O scheduling priority of server processes. I/O niceness priority +is a number which goes from 0 to 7. The higher the value, the lower +the I/O priority of the process. Work only with ionice_class. .RE @@ -339,6 +387,18 @@ You can search logs for this message if space is not being reclaimed after you delete account(s). Default is 2592000 seconds (30 days). This is in addition to any time requested by delay_reaping. +.IP \fBnice_priority\fR +Modify scheduling priority of server processes. Niceness values range from -20 +(most favorable to the process) to 19 (least favorable to the process). +The default does not modify priority. +.IP \fBionice_class\fR +Modify I/O scheduling class of server processes. I/O niceness class values +are IOPRIO_CLASS_RT, IOPRIO_CLASS_BE and IOPRIO_CLASS_IDLE. The default does not modify class and priority. +Work only with ionice_priority. +.IP \fBionice_priority\fR +Modify I/O scheduling priority of server processes. I/O niceness priority +is a number which goes from 0 to 7. The higher the value, the lower +the I/O priority of the process. Work only with ionice_class. .RE .PD diff --git a/doc/manpages/container-server.conf.5 b/doc/manpages/container-server.conf.5 index 11eb109874..b396398d4b 100644 --- a/doc/manpages/container-server.conf.5 +++ b/doc/manpages/container-server.conf.5 @@ -131,6 +131,18 @@ You can set fallocate_reserve to the number of bytes or percentage of disk space you'd like fallocate to reserve, whether there is space for the given file size or not. Percentage will be used if the value ends with a '%'. The default is 1%. +.IP \fBnice_priority\fR +Modify scheduling priority of server processes. Niceness values range from -20 +(most favorable to the process) to 19 (least favorable to the process). +The default does not modify priority. +.IP \fBionice_class\fR +Modify I/O scheduling class of server processes. I/O niceness class values +are IOPRIO_CLASS_RT, IOPRIO_CLASS_BE and IOPRIO_CLASS_IDLE. The default does not modify class and priority. +Work only with ionice_priority. +.IP \fBionice_priority\fR +Modify I/O scheduling priority of server processes. I/O niceness priority +is a number which goes from 0 to 7. The higher the value, the lower +the I/O priority of the process. Work only with ionice_class. .RE .PD @@ -184,6 +196,18 @@ To handle all verbs, including replication verbs, do not specify set to a True value (e.g. "True" or "1"). To handle only non-replication verbs, set to "False". Unless you have a separate replication network, you should not specify any value for "replication_server". +.IP \fBnice_priority\fR +Modify scheduling priority of server processes. Niceness values range from -20 +(most favorable to the process) to 19 (least favorable to the process). +The default does not modify priority. +.IP \fBionice_class\fR +Modify I/O scheduling class of server processes. I/O niceness class values +are IOPRIO_CLASS_RT, IOPRIO_CLASS_BE and IOPRIO_CLASS_IDLE. The default does not modify class and priority. +Work only with ionice_priority. +.IP \fBionice_priority\fR +Modify I/O scheduling priority of server processes. I/O niceness priority +is a number which goes from 0 to 7. The higher the value, the lower +the I/O priority of the process. Work only with ionice_class. .RE .PD @@ -293,6 +317,18 @@ Format of the rysnc module where the replicator will send data. See etc/rsyncd.conf-sample for some usage examples. .IP \fBrecon_cache_path\fR Path to recon cache directory. The default is /var/cache/swift. +.IP \fBnice_priority\fR +Modify scheduling priority of server processes. Niceness values range from -20 +(most favorable to the process) to 19 (least favorable to the process). +The default does not modify priority. +.IP \fBionice_class\fR +Modify I/O scheduling class of server processes. I/O niceness class values +are IOPRIO_CLASS_RT, IOPRIO_CLASS_BE and IOPRIO_CLASS_IDLE. The default does not modify class and priority. +Work only with ionice_priority. +.IP \fBionice_priority\fR +Modify I/O scheduling priority of server processes. I/O niceness priority +is a number which goes from 0 to 7. The higher the value, the lower +the I/O priority of the process. Work only with ionice_class. .RE @@ -322,6 +358,18 @@ Slowdown will sleep that amount between containers. The default is 0.01 seconds. Seconds to suppress updating an account that has generated an error. The default is 60 seconds. .IP \fBrecon_cache_path\fR Path to recon cache directory. The default is /var/cache/swift. +.IP \fBnice_priority\fR +Modify scheduling priority of server processes. Niceness values range from -20 +(most favorable to the process) to 19 (least favorable to the process). +The default does not modify priority. +.IP \fBionice_class\fR +Modify I/O scheduling class of server processes. I/O niceness class values +are IOPRIO_CLASS_RT, IOPRIO_CLASS_BE and IOPRIO_CLASS_IDLE. The default does not modify class and priority. +Work only with ionice_priority. +.IP \fBionice_priority\fR +Modify I/O scheduling priority of server processes. I/O niceness priority +is a number which goes from 0 to 7. The higher the value, the lower +the I/O priority of the process. Work only with ionice_class. .RE .PD @@ -344,6 +392,18 @@ Will audit, at most, 1 container per device per interval. The default is 1800 se Maximum containers audited per second. Should be tuned according to individual system specs. 0 is unlimited. The default is 200. .IP \fBrecon_cache_path\fR Path to recon cache directory. The default is /var/cache/swift. +.IP \fBnice_priority\fR +Modify scheduling priority of server processes. Niceness values range from -20 +(most favorable to the process) to 19 (least favorable to the process). +The default does not modify priority. +.IP \fBionice_class\fR +Modify I/O scheduling class of server processes. I/O niceness class values +are IOPRIO_CLASS_RT, IOPRIO_CLASS_BE and IOPRIO_CLASS_IDLE. The default does not modify class and priority. +Work only with ionice_priority. +.IP \fBionice_priority\fR +Modify I/O scheduling priority of server processes. I/O niceness priority +is a number which goes from 0 to 7. The higher the value, the lower +the I/O priority of the process. Work only with ionice_class. .RE @@ -372,6 +432,18 @@ Connection timeout to external services. The default is 5 seconds. Server errors from requests will be retried by default. The default is 3. .IP \fBinternal_client_conf_path\fR Internal client config file path. +.IP \fBnice_priority\fR +Modify scheduling priority of server processes. Niceness values range from -20 +(most favorable to the process) to 19 (least favorable to the process). +The default does not modify priority. +.IP \fBionice_class\fR +Modify I/O scheduling class of server processes. I/O niceness class values +are IOPRIO_CLASS_RT, IOPRIO_CLASS_BE and IOPRIO_CLASS_IDLE. The default does not modify class and priority. +Work only with ionice_priority. +.IP \fBionice_priority\fR +Modify I/O scheduling priority of server processes. I/O niceness priority +is a number which goes from 0 to 7. The higher the value, the lower +the I/O priority of the process. Work only with ionice_class. .RE .PD diff --git a/doc/manpages/object-expirer.conf.5 b/doc/manpages/object-expirer.conf.5 index 2e5ea46a93..1e98216c10 100644 --- a/doc/manpages/object-expirer.conf.5 +++ b/doc/manpages/object-expirer.conf.5 @@ -88,6 +88,18 @@ The default is 1. The default is 1. .IP \fBlog_statsd_metric_prefix\fR The default is empty. +.IP \fBnice_priority\fR +Modify scheduling priority of server processes. Niceness values range from -20 +(most favorable to the process) to 19 (least favorable to the process). +The default does not modify priority. +.IP \fBionice_class\fR +Modify I/O scheduling class of server processes. I/O niceness class values +are IOPRIO_CLASS_RT, IOPRIO_CLASS_BE and IOPRIO_CLASS_IDLE. The default does not modify class and priority. +Work only with ionice_priority. +.IP \fBionice_priority\fR +Modify I/O scheduling priority of server processes. I/O niceness priority +is a number which goes from 0 to 7. The higher the value, the lower +the I/O priority of the process. Work only with ionice_class. .RE .PD @@ -115,6 +127,18 @@ that are acceptable within this section. .IP "\fBuse\fR" Entry point for paste.deploy for the object server. This is the reference to the installed python egg. The default is \fBegg:swift#proxy\fR. See proxy-server.conf-sample for options or See proxy-server.conf manpage. +.IP \fBnice_priority\fR +Modify scheduling priority of server processes. Niceness values range from -20 +(most favorable to the process) to 19 (least favorable to the process). +The default does not modify priority. +.IP \fBionice_class\fR +Modify I/O scheduling class of server processes. I/O niceness class values +are IOPRIO_CLASS_RT, IOPRIO_CLASS_BE and IOPRIO_CLASS_IDLE. The default does not modify class and priority. +Work only with ionice_priority. +.IP \fBionice_priority\fR +Modify I/O scheduling priority of server processes. I/O niceness priority +is a number which goes from 0 to 7. The higher the value, the lower +the I/O priority of the process. Work only with ionice_class. .RE .PD diff --git a/doc/manpages/object-server.conf.5 b/doc/manpages/object-server.conf.5 index 0649b86fb8..51e5bccf7b 100644 --- a/doc/manpages/object-server.conf.5 +++ b/doc/manpages/object-server.conf.5 @@ -142,6 +142,18 @@ backend node. The default is 60. The default is 65536. .IP \fBdisk_chunk_size\fR The default is 65536. +.IP \fBnice_priority\fR +Modify scheduling priority of server processes. Niceness values range from -20 +(most favorable to the process) to 19 (least favorable to the process). +The default does not modify priority. +.IP \fBionice_class\fR +Modify I/O scheduling class of server processes. I/O niceness class values +are IOPRIO_CLASS_RT, IOPRIO_CLASS_BE and IOPRIO_CLASS_IDLE. The default does not modify class and priority. +Work only with ionice_priority. +.IP \fBionice_priority\fR +Modify I/O scheduling priority of server processes. I/O niceness priority +is a number which goes from 0 to 7. The higher the value, the lower +the I/O priority of the process. Work only with ionice_class. .RE .PD @@ -233,6 +245,24 @@ version 3.0 or greater. If you set "splice = yes" but the kernel does not support it, error messages will appear in the object server logs at startup, but your object servers should continue to function. The default is false. +.IP \fBnode_timeout\fR +Request timeout to external services. The default is 3 seconds. +.IP \fBconn_timeout\fR +Connection timeout to external services. The default is 0.5 seconds. +.IP \fBcontainer_update_timeout\fR +Time to wait while sending a container update on object update. The default is 1 second. +.IP \fBnice_priority\fR +Modify scheduling priority of server processes. Niceness values range from -20 +(most favorable to the process) to 19 (least favorable to the process). +The default does not modify priority. +.IP \fBionice_class\fR +Modify I/O scheduling class of server processes. I/O niceness class values +are IOPRIO_CLASS_RT, IOPRIO_CLASS_BE and IOPRIO_CLASS_IDLE. The default does not modify class and priority. +Work only with ionice_priority. +.IP \fBionice_priority\fR +Modify I/O scheduling priority of server processes. I/O niceness priority +is a number which goes from 0 to 7. The higher the value, the lower +the I/O priority of the process. Work only with ionice_class. .RE .PD @@ -386,6 +416,18 @@ The handoffs_first and handoff_delete are options for a special case such as disk full in the cluster. These two options SHOULD NOT BE CHANGED, except for such an extreme situations. (e.g. disks filled up or are about to fill up. Anyway, DO NOT let your drives fill up). +.IP \fBnice_priority\fR +Modify scheduling priority of server processes. Niceness values range from -20 +(most favorable to the process) to 19 (least favorable to the process). +The default does not modify priority. +.IP \fBionice_class\fR +Modify I/O scheduling class of server processes. I/O niceness class values +are IOPRIO_CLASS_RT, IOPRIO_CLASS_BE and IOPRIO_CLASS_IDLE. The default does not modify class and priority. +Work only with ionice_priority. +.IP \fBionice_priority\fR +Modify I/O scheduling priority of server processes. I/O niceness priority +is a number which goes from 0 to 7. The higher the value, the lower +the I/O priority of the process. Work only with ionice_class. .RE @@ -461,6 +503,18 @@ Slowdown will sleep that amount between objects. The default is 0.01 seconds. The recon_cache_path simply sets the directory where stats for a few items will be stored. Depending on the method of deployment you may need to create this directory manually and ensure that swift has read/write. The default is /var/cache/swift. +.IP \fBnice_priority\fR +Modify scheduling priority of server processes. Niceness values range from -20 +(most favorable to the process) to 19 (least favorable to the process). +The default does not modify priority. +.IP \fBionice_class\fR +Modify I/O scheduling class of server processes. I/O niceness class values +are IOPRIO_CLASS_RT, IOPRIO_CLASS_BE and IOPRIO_CLASS_IDLE. The default does not modify class and priority. +Work only with ionice_priority. +.IP \fBionice_priority\fR +Modify I/O scheduling priority of server processes. I/O niceness priority +is a number which goes from 0 to 7. The higher the value, the lower +the I/O priority of the process. Work only with ionice_class. .RE .PD @@ -503,6 +557,18 @@ points and report the result after a full scan. .IP \fBrsync_tempfile_timeout\fR Time elapsed in seconds before rsync tempfiles will be unlinked. Config value of "auto" will try to use object-replicator's rsync_timeout + 900 or fall-back to 86400 (1 day). +.IP \fBnice_priority\fR +Modify scheduling priority of server processes. Niceness values range from -20 +(most favorable to the process) to 19 (least favorable to the process). +The default does not modify priority. +.IP \fBionice_class\fR +Modify I/O scheduling class of server processes. I/O niceness class values +are IOPRIO_CLASS_RT, IOPRIO_CLASS_BE and IOPRIO_CLASS_IDLE. The default does not modify class and priority. +Work only with ionice_priority. +.IP \fBionice_priority\fR +Modify I/O scheduling priority of server processes. I/O niceness priority +is a number which goes from 0 to 7. The higher the value, the lower +the I/O priority of the process. Work only with ionice_class. .RE diff --git a/doc/manpages/proxy-server.conf.5 b/doc/manpages/proxy-server.conf.5 index 22880db60d..6c11368fe8 100644 --- a/doc/manpages/proxy-server.conf.5 +++ b/doc/manpages/proxy-server.conf.5 @@ -143,6 +143,18 @@ This is very useful when one is managing more than one swift cluster. Use a comma separated list of full url (http://foo.bar:1234,https://foo.bar) .IP \fBstrict_cors_mode\fR The default is true. +.IP \fBnice_priority\fR +Modify scheduling priority of server processes. Niceness values range from -20 +(most favorable to the process) to 19 (least favorable to the process). +The default does not modify priority. +.IP \fBionice_class\fR +Modify I/O scheduling class of server processes. I/O niceness class values +are IOPRIO_CLASS_RT, IOPRIO_CLASS_BE and IOPRIO_CLASS_IDLE. The default does not modify class and priority. +Work only with ionice_priority. +.IP \fBionice_priority\fR +Modify I/O scheduling priority of server processes. I/O niceness priority +is a number which goes from 0 to 7. The higher the value, the lower +the I/O priority of the process. Work only with ionice_class. .RE .PD @@ -1030,6 +1042,24 @@ These are the headers whose values will only be shown to swift_owners. The exact definition of a swift_owner is up to the auth system in use, but usually indicates administrative responsibilities. The default is 'x-container-read, x-container-write, x-container-sync-key, x-container-sync-to, x-account-meta-temp-url-key, x-account-meta-temp-url-key-2, x-container-meta-temp-url-key, x-container-meta-temp-url-key-2, x-account-access-control'. +.IP \fBrate_limit_after_segment\fR +Start rate-limiting object segments after the Nth segment of a segmented +object. The default is 10 segments. +.IP \fBrate_limit_segments_per_sec\fR +Once segment rate-limiting kicks in for an object, limit segments served to N +per second. The default is 1. +.IP \fBnice_priority\fR +Modify scheduling priority of server processes. Niceness values range from -20 +(most favorable to the process) to 19 (least favorable to the process). +The default does not modify priority. +.IP \fBionice_class\fR +Modify I/O scheduling class of server processes. I/O niceness class values +are IOPRIO_CLASS_RT, IOPRIO_CLASS_BE and IOPRIO_CLASS_IDLE. The default does not modify class and priority. +Work only with ionice_priority. +.IP \fBionice_priority\fR +Modify I/O scheduling priority of server processes. I/O niceness priority +is a number which goes from 0 to 7. The higher the value, the lower +the I/O priority of the process. Work only with ionice_class. .RE .PD diff --git a/doc/source/deployment_guide.rst b/doc/source/deployment_guide.rst index c8aae9e555..524bab8c5c 100644 --- a/doc/source/deployment_guide.rst +++ b/doc/source/deployment_guide.rst @@ -1,4 +1,4 @@ -================ + Deployment Guide ================ @@ -515,6 +515,25 @@ network_chunk_size 65536 Size of chunks to read/write over t disk_chunk_size 65536 Size of chunks to read/write to disk container_update_timeout 1 Time to wait while sending a container update on object update. +nice_priority None Scheduling priority of server processes. + Niceness values range from -20 (most + favorable to the process) to 19 (least + favorable to the process). The default + does not modify priority. +ionice_class None I/O scheduling class of server processes. + I/O niceness class values are IOPRIO_CLASS_RT, + IOPRIO_CLASS_BE, and IOPRIO_CLASS_IDLE. + The default does not modify class and + priority. Linux supports io scheduling + priorities and classes since 2.6.13 with + the CFQ io scheduler. + Work only with ionice_priority. +ionice_priority None I/O scheduling priority of server + processes. I/O niceness priority is + a number which goes from 0 to 7. + The higher the value, the lower the I/O + priority of the process. Work only with + ionice_class. ================================ ========== ========================================== .. _object-server-options: @@ -821,6 +840,24 @@ db_preallocation off If you don't mind the extra disk sp in overhead, you can turn this on to preallocate disk space with SQLite databases to decrease fragmentation. +nice_priority None Scheduling priority of server processes. + Niceness values range from -20 (most + favorable to the process) to 19 (least + favorable to the process). The default + does not modify priority. +ionice_class None I/O scheduling class of server processes. + I/O niceness class values are IOPRIO_CLASS_RT, + IOPRIO_CLASS_BE, and IOPRIO_CLASS_IDLE. + The default does not modify class and + priority. Linux supports io scheduling + priorities and classes since 2.6.13 + with the CFQ io scheduler. + Work only with ionice_priority. +ionice_priority None I/O scheduling priority of server processes. + I/O niceness priority is a number which + goes from 0 to 7. The higher the value, + the lower the I/O priority of the process. + Work only with ionice_class. =============================== ========== ============================================ [container-server] @@ -1035,6 +1072,24 @@ fallocate_reserve 1% You can set fallocate_reserve to th they completely run out of space; you can make the services pretend they're out of space early. +nice_priority None Scheduling priority of server processes. + Niceness values range from -20 (most + favorable to the process) to 19 (least + favorable to the process). The default + does not modify priority. +ionice_class None I/O scheduling class of server processes. + I/O niceness class values are IOPRIO_CLASS_RT, + IOPRIO_CLASS_BE, and IOPRIO_CLASS_IDLE. + The default does not modify class and + priority. Linux supports io scheduling + priorities and classes since 2.6.13 with + the CFQ io scheduler. + Work only with ionice_priority. +ionice_priority None I/O scheduling priority of server processes. + I/O niceness priority is a number which + goes from 0 to 7. The higher the value, + the lower the I/O priority of the process. + Work only with ionice_class. =============================== ========== ============================================= [account-server] @@ -1276,6 +1331,28 @@ disallowed_sections swift.valid_api_versions Allows the abili the dict level with a ".". expiring_objects_container_divisor 86400 expiring_objects_account_name expiring_objects +nice_priority None Scheduling priority of server + processes. + Niceness values range from -20 (most + favorable to the process) to 19 (least + favorable to the process). The default + does not modify priority. +ionice_class None I/O scheduling class of server + processes. I/O niceness class values + are IOPRIO_CLASS_RT, IOPRIO_CLASS_BE and + IOPRIO_CLASS_IDLE. + The default does not + modify class and priority. Linux + supports io scheduling priorities + and classes since 2.6.13 with + the CFQ io scheduler. + Work only with ionice_priority. +ionice_priority None I/O scheduling priority of server + processes. I/O niceness priority is + a number which goes from 0 to 7. + The higher the value, the lower + the I/O priority of the process. + Work only with ionice_class. ==================================== ======================== ======================================== [proxy-server] @@ -1542,6 +1619,16 @@ more workers, raising the number of workers and lowering the maximum number of clients serviced per worker can lessen the impact of CPU intensive or stalled requests. +The `nice_priority` parameter can be used to set program scheduling priority. +The `ionice_class` and `ionice_priority` parameters can be used to set I/O scheduling +class and priority on the systems that use an I/O scheduler that supports +I/O priorities. As at kernel 2.6.17 the only such scheduler is the Completely +Fair Queuing (CFQ) I/O scheduler. If you run your Storage servers all together +on the same servers, you can slow down the auditors or prioritize +object-server I/O via these parameters (but probably do not need to change +it on the proxy). It is a new feature and the best practices are still +being developed. + The above configuration setting should be taken as suggestions and testing of configuration settings should be done to ensure best utilization of CPU, network connectivity, and disk I/O. diff --git a/etc/account-server.conf-sample b/etc/account-server.conf-sample index 7ef875e777..63584851e2 100644 --- a/etc/account-server.conf-sample +++ b/etc/account-server.conf-sample @@ -51,6 +51,18 @@ bind_port = 6202 # space you'd like fallocate to reserve, whether there is space for the given # file size or not. Percentage will be used if the value ends with a '%'. # fallocate_reserve = 1% +# +# You can set scheduling priority of processes. Niceness values range from -20 +# (most favorable to the process) to 19 (least favorable to the process). +# nice_priority = +# +# You can set I/O scheduling class and priority of processes. I/O niceness +# class values are IOPRIO_CLASS_RT (realtime), IOPRIO_CLASS_BE (best-effort) and +# IOPRIO_CLASS_IDLE (idle). I/O niceness priority is a number which goes from +# 0 to 7. The higher the value, the lower the I/O priority of the process. +# Work only with ionice_class. +# ionice_class = +# ionice_priority = [pipeline:main] pipeline = healthcheck recon account-server @@ -73,6 +85,18 @@ use = egg:swift#account # verbs, set to "False". Unless you have a separate replication network, you # should not specify any value for "replication_server". Default is empty. # replication_server = false +# +# You can set scheduling priority of processes. Niceness values range from -20 +# (most favorable to the process) to 19 (least favorable to the process). +# nice_priority = +# +# You can set I/O scheduling class and priority of processes. I/O niceness +# class values are IOPRIO_CLASS_RT (realtime), IOPRIO_CLASS_BE (best-effort) and +# IOPRIO_CLASS_IDLE (idle). I/O niceness priority is a number which goes from +# 0 to 7. The higher the value, the lower the I/O priority of the process. +# Work only with ionice_class. +# ionice_class = +# ionice_priority = [filter:healthcheck] use = egg:swift#healthcheck @@ -127,6 +151,18 @@ use = egg:swift#recon # rsync_module = {replication_ip}::account # # recon_cache_path = /var/cache/swift +# +# You can set scheduling priority of processes. Niceness values range from -20 +# (most favorable to the process) to 19 (least favorable to the process). +# nice_priority = +# +# You can set I/O scheduling class and priority of processes. I/O niceness +# class values are IOPRIO_CLASS_RT (realtime), IOPRIO_CLASS_BE (best-effort) and +# IOPRIO_CLASS_IDLE (idle). I/O niceness priority is a number which goes from +# 0 to 7. The higher the value, the lower the I/O priority of the process. +# Work only with ionice_class. +# ionice_class = +# ionice_priority = [account-auditor] # You can override the default log routing for this app here (don't use set!): @@ -140,6 +176,18 @@ use = egg:swift#recon # # accounts_per_second = 200 # recon_cache_path = /var/cache/swift +# +# You can set scheduling priority of processes. Niceness values range from -20 +# (most favorable to the process) to 19 (least favorable to the process). +# nice_priority = +# +# You can set I/O scheduling class and priority of processes. I/O niceness +# class values are IOPRIO_CLASS_RT (realtime), IOPRIO_CLASS_BE (best-effort) and +# IOPRIO_CLASS_IDLE (idle). I/O niceness priority is a number which goes from +# 0 to 7. The higher the value, the lower the I/O priority of the process. +# Work only with ionice_class. +# ionice_class = +# ionice_priority = [account-reaper] # You can override the default log routing for this app here (don't use set!): @@ -166,6 +214,18 @@ use = egg:swift#recon # Default is 2592000 seconds (30 days). This is in addition to any time # requested by delay_reaping. # reap_warn_after = 2592000 +# +# You can set scheduling priority of processes. Niceness values range from -20 +# (most favorable to the process) to 19 (least favorable to the process). +# nice_priority = +# +# You can set I/O scheduling class and priority of processes. I/O niceness +# class values are IOPRIO_CLASS_RT (realtime), IOPRIO_CLASS_BE (best-effort) and +# IOPRIO_CLASS_IDLE (idle). I/O niceness priority is a number which goes from +# 0 to 7. The higher the value, the lower the I/O priority of the process. +# Work only with ionice_class. +# ionice_class = +# ionice_priority = # Note: Put it at the beginning of the pipeline to profile all middleware. But # it is safer to put this after healthcheck. diff --git a/etc/container-reconciler.conf-sample b/etc/container-reconciler.conf-sample index 6e8f109f5d..ea8bc53a19 100644 --- a/etc/container-reconciler.conf-sample +++ b/etc/container-reconciler.conf-sample @@ -22,6 +22,18 @@ # log_statsd_default_sample_rate = 1.0 # log_statsd_sample_rate_factor = 1.0 # log_statsd_metric_prefix = +# +# You can set scheduling priority of processes. Niceness values range from -20 +# (most favorable to the process) to 19 (least favorable to the process). +# nice_priority = +# +# You can set I/O scheduling class and priority of processes. I/O niceness +# class values are IOPRIO_CLASS_RT (realtime), IOPRIO_CLASS_BE (best-effort) and +# IOPRIO_CLASS_IDLE (idle). I/O niceness priority is a number which goes from +# 0 to 7. The higher the value, the lower the I/O priority of the process. +# Work only with ionice_class. +# ionice_class = +# ionice_priority = [container-reconciler] # The reconciler will re-attempt reconciliation if the source object is not @@ -32,6 +44,18 @@ # interval = 30 # Server errors from requests will be retried by default # request_tries = 3 +# +# You can set scheduling priority of processes. Niceness values range from -20 +# (most favorable to the process) to 19 (least favorable to the process). +# nice_priority = +# +# You can set I/O scheduling class and priority of processes. I/O niceness +# class values are IOPRIO_CLASS_RT (realtime), IOPRIO_CLASS_BE (best-effort) and +# IOPRIO_CLASS_IDLE (idle). I/O niceness priority is a number which goes from +# 0 to 7. The higher the value, the lower the I/O priority of the process. +# Work only with ionice_class. +# ionice_class = +# ionice_priority = [pipeline:main] pipeline = catch_errors proxy-logging cache proxy-server diff --git a/etc/container-server.conf-sample b/etc/container-server.conf-sample index c5452a4c1e..89ac04817d 100644 --- a/etc/container-server.conf-sample +++ b/etc/container-server.conf-sample @@ -57,6 +57,18 @@ bind_port = 6201 # space you'd like fallocate to reserve, whether there is space for the given # file size or not. Percentage will be used if the value ends with a '%'. # fallocate_reserve = 1% +# +# You can set scheduling priority of processes. Niceness values range from -20 +# (most favorable to the process) to 19 (least favorable to the process). +# nice_priority = +# +# You can set I/O scheduling class and priority of processes. I/O niceness +# class values are IOPRIO_CLASS_RT (realtime), IOPRIO_CLASS_BE (best-effort) and +# IOPRIO_CLASS_IDLE (idle). I/O niceness priority is a number which goes from +# 0 to 7. The higher the value, the lower the I/O priority of the process. +# Work only with ionice_class. +# ionice_class = +# ionice_priority = [pipeline:main] pipeline = healthcheck recon container-server @@ -82,6 +94,18 @@ use = egg:swift#container # verbs, set to "False". Unless you have a separate replication network, you # should not specify any value for "replication_server". # replication_server = false +# +# You can set scheduling priority of processes. Niceness values range from -20 +# (most favorable to the process) to 19 (least favorable to the process). +# nice_priority = +# +# You can set I/O scheduling class and priority of processes. I/O niceness +# class values are IOPRIO_CLASS_RT (realtime), IOPRIO_CLASS_BE (best-effort) and +# IOPRIO_CLASS_IDLE (idle). I/O niceness priority is a number which goes from +# 0 to 7. The higher the value, the lower the I/O priority of the process. +# Work only with ionice_class. +# ionice_class = +# ionice_priority = [filter:healthcheck] use = egg:swift#healthcheck @@ -136,6 +160,18 @@ use = egg:swift#recon # rsync_module = {replication_ip}::container # # recon_cache_path = /var/cache/swift +# +# You can set scheduling priority of processes. Niceness values range from -20 +# (most favorable to the process) to 19 (least favorable to the process). +# nice_priority = +# +# You can set I/O scheduling class and priority of processes. I/O niceness +# class values are IOPRIO_CLASS_RT (realtime), IOPRIO_CLASS_BE (best-effort) and +# IOPRIO_CLASS_IDLE (idle). I/O niceness priority is a number which goes from +# 0 to 7. The higher the value, the lower the I/O priority of the process. +# Work only with ionice_class. +# ionice_class = +# ionice_priority = [container-updater] # You can override the default log routing for this app here (don't use set!): @@ -156,6 +192,18 @@ use = egg:swift#recon # account_suppression_time = 60 # # recon_cache_path = /var/cache/swift +# +# You can set scheduling priority of processes. Niceness values range from -20 +# (most favorable to the process) to 19 (least favorable to the process). +# nice_priority = +# +# You can set I/O scheduling class and priority of processes. I/O niceness +# class values are IOPRIO_CLASS_RT (realtime), IOPRIO_CLASS_BE (best-effort) and +# IOPRIO_CLASS_IDLE (idle). I/O niceness priority is a number which goes from +# 0 to 7. The higher the value, the lower the I/O priority of the process. +# Work only with ionice_class. +# ionice_class = +# ionice_priority = [container-auditor] # You can override the default log routing for this app here (don't use set!): @@ -169,6 +217,18 @@ use = egg:swift#recon # # containers_per_second = 200 # recon_cache_path = /var/cache/swift +# +# You can set scheduling priority of processes. Niceness values range from -20 +# (most favorable to the process) to 19 (least favorable to the process). +# nice_priority = +# +# You can set I/O scheduling class and priority of processes. I/O niceness +# class values are IOPRIO_CLASS_RT (realtime), IOPRIO_CLASS_BE (best-effort) and +# IOPRIO_CLASS_IDLE (idle). I/O niceness priority is a number which goes from +# 0 to 7. The higher the value, the lower the I/O priority of the process. +# Work only with ionice_class. +# ionice_class = +# ionice_priority = [container-sync] # You can override the default log routing for this app here (don't use set!): @@ -195,6 +255,18 @@ use = egg:swift#recon # # Internal client config file path # internal_client_conf_path = /etc/swift/internal-client.conf +# +# You can set scheduling priority of processes. Niceness values range from -20 +# (most favorable to the process) to 19 (least favorable to the process). +# nice_priority = +# +# You can set I/O scheduling class and priority of processes. I/O niceness +# class values are IOPRIO_CLASS_RT (realtime), IOPRIO_CLASS_BE (best-effort) and +# IOPRIO_CLASS_IDLE (idle). I/O niceness priority is a number which goes from +# 0 to 7. The higher the value, the lower the I/O priority of the process. +# Work only with ionice_class. +# ionice_class = +# ionice_priority = # Note: Put it at the beginning of the pipeline to profile all middleware. But # it is safer to put this after healthcheck. diff --git a/etc/object-expirer.conf-sample b/etc/object-expirer.conf-sample index 4b161de1d5..b60c204b4b 100644 --- a/etc/object-expirer.conf-sample +++ b/etc/object-expirer.conf-sample @@ -25,6 +25,16 @@ # log_statsd_default_sample_rate = 1.0 # log_statsd_sample_rate_factor = 1.0 # log_statsd_metric_prefix = +# +# You can set scheduling priority of processes. Niceness values range from -20 +# (most favorable to the process) to 19 (least favorable to the process). +# nice_priority = +# You can set I/O scheduling class and priority of processes. I/O niceness +# class values are realtime, best-effort and idle. I/O niceness +# priority is a number which goes from 0 to 7. The higher the value, the lower +# the I/O priority of the process. Work only with ionice_class. +# ionice_class = +# ionice_priority = [object-expirer] # interval = 300 @@ -51,6 +61,16 @@ # queue. # reclaim_age = 604800 # recon_cache_path = /var/cache/swift +# +# You can set scheduling priority of processes. Niceness values range from -20 +# (most favorable to the process) to 19 (least favorable to the process). +# nice_priority = +# You can set I/O scheduling class and priority of processes. I/O niceness +# class values are realtime, best-effort and idle. I/O niceness +# priority is a number which goes from 0 to 7. The higher the value, the lower +# the I/O priority of the process. Work only with ionice_class. +# ionice_class = +# ionice_priority = [pipeline:main] pipeline = catch_errors proxy-logging cache proxy-server diff --git a/etc/object-server.conf-sample b/etc/object-server.conf-sample index b0361c4d65..a1dea066c4 100644 --- a/etc/object-server.conf-sample +++ b/etc/object-server.conf-sample @@ -68,6 +68,18 @@ bind_port = 6200 # # network_chunk_size = 65536 # disk_chunk_size = 65536 +# +# You can set scheduling priority of processes. Niceness values range from -20 +# (most favorable to the process) to 19 (least favorable to the process). +# nice_priority = +# +# You can set I/O scheduling class and priority of processes. I/O niceness +# class values are IOPRIO_CLASS_RT (realtime), IOPRIO_CLASS_BE (best-effort) and +# IOPRIO_CLASS_IDLE (idle). I/O niceness priority is a number which goes from +# 0 to 7. The higher the value, the lower the I/O priority of the process. +# Work only with ionice_class. +# ionice_class = +# ionice_priority = [pipeline:main] pipeline = healthcheck recon object-server @@ -145,6 +157,18 @@ use = egg:swift#object # logs at startup, but your object servers should continue to function. # # splice = no +# +# You can set scheduling priority of processes. Niceness values range from -20 +# (most favorable to the process) to 19 (least favorable to the process). +# nice_priority = +# +# You can set I/O scheduling class and priority of processes. I/O niceness +# class values are IOPRIO_CLASS_RT (realtime), IOPRIO_CLASS_BE (best-effort) and +# IOPRIO_CLASS_IDLE (idle). I/O niceness priority is a number which goes from +# 0 to 7. The higher the value, the lower the I/O priority of the process. +# Work only with ionice_class. +# ionice_class = +# ionice_priority = [filter:healthcheck] use = egg:swift#healthcheck @@ -233,6 +257,18 @@ use = egg:swift#recon # than or equal to this number. By default(auto), handoff partitions will be # removed when it has successfully replicated to all the canonical nodes. # handoff_delete = auto +# +# You can set scheduling priority of processes. Niceness values range from -20 +# (most favorable to the process) to 19 (least favorable to the process). +# nice_priority = +# +# You can set I/O scheduling class and priority of processes. I/O niceness +# class values are IOPRIO_CLASS_RT (realtime), IOPRIO_CLASS_BE (best-effort) and +# IOPRIO_CLASS_IDLE (idle). I/O niceness priority is a number which goes from +# 0 to 7. The higher the value, the lower the I/O priority of the process. +# Work only with ionice_class. +# ionice_class = +# ionice_priority = [object-reconstructor] # You can override the default log routing for this app here (don't use set!): @@ -261,6 +297,18 @@ use = egg:swift#recon # ring_check_interval = 15 # recon_cache_path = /var/cache/swift # handoffs_first = False +# +# You can set scheduling priority of processes. Niceness values range from -20 +# (most favorable to the process) to 19 (least favorable to the process). +# nice_priority = +# +# You can set I/O scheduling class and priority of processes. I/O niceness +# class values are IOPRIO_CLASS_RT (realtime), IOPRIO_CLASS_BE (best-effort) and +# IOPRIO_CLASS_IDLE (idle). I/O niceness priority is a number which goes from +# 0 to 7. The higher the value, the lower the I/O priority of the process. +# Work only with ionice_class. +# ionice_class = +# ionice_priority = [object-updater] # You can override the default log routing for this app here (don't use set!): @@ -276,6 +324,18 @@ use = egg:swift#recon # slowdown = 0.01 # # recon_cache_path = /var/cache/swift +# +# You can set scheduling priority of processes. Niceness values range from -20 +# (most favorable to the process) to 19 (least favorable to the process). +# nice_priority = +# +# You can set I/O scheduling class and priority of processes. I/O niceness +# class values are IOPRIO_CLASS_RT (realtime), IOPRIO_CLASS_BE (best-effort) and +# IOPRIO_CLASS_IDLE (idle). I/O niceness priority is a number which goes from +# 0 to 7. The higher the value, the lower the I/O priority of the process. +# Work only with ionice_class. +# ionice_class = +# ionice_priority = [object-auditor] # You can override the default log routing for this app here (don't use set!): @@ -301,6 +361,18 @@ use = egg:swift#recon # increment a counter for every object whose size is <= to the given break # points and report the result after a full scan. # object_size_stats = +# +# You can set scheduling priority of processes. Niceness values range from -20 +# (most favorable to the process) to 19 (least favorable to the process). +# nice_priority = +# +# You can set I/O scheduling class and priority of processes. I/O niceness +# class values are IOPRIO_CLASS_RT (realtime), IOPRIO_CLASS_BE (best-effort) and +# IOPRIO_CLASS_IDLE (idle). I/O niceness priority is a number which goes from +# 0 to 7. The higher the value, the lower the I/O priority of the process. +# Work only with ionice_class. +# ionice_class = +# ionice_priority = # The auditor will cleanup old rsync tempfiles after they are "old # enough" to delete. You can configure the time elapsed in seconds diff --git a/etc/proxy-server.conf-sample b/etc/proxy-server.conf-sample index a74320b1b0..3bcdc4b508 100644 --- a/etc/proxy-server.conf-sample +++ b/etc/proxy-server.conf-sample @@ -75,6 +75,18 @@ bind_port = 8080 # # client_timeout = 60 # eventlet_debug = false +# +# You can set scheduling priority of processes. Niceness values range from -20 +# (most favorable to the process) to 19 (least favorable to the process). +# nice_priority = +# +# You can set I/O scheduling class and priority of processes. I/O niceness +# class values are IOPRIO_CLASS_RT (realtime), IOPRIO_CLASS_BE (best-effort) and +# IOPRIO_CLASS_IDLE (idle). I/O niceness priority is a number which goes from +# 0 to 7. The higher the value, the lower the I/O priority of the process. +# Work only with ionice_class. +# ionice_class = +# ionice_priority = [pipeline:main] # This sample pipeline uses tempauth and is used for SAIO dev work and @@ -218,6 +230,18 @@ use = egg:swift#proxy # exact definition of a swift_owner is up to the auth system in use, but # usually indicates administrative responsibilities. # swift_owner_headers = x-container-read, x-container-write, x-container-sync-key, x-container-sync-to, x-account-meta-temp-url-key, x-account-meta-temp-url-key-2, x-container-meta-temp-url-key, x-container-meta-temp-url-key-2, x-account-access-control +# +# You can set scheduling priority of processes. Niceness values range from -20 +# (most favorable to the process) to 19 (least favorable to the process). +# nice_priority = +# +# You can set I/O scheduling class and priority of processes. I/O niceness +# class values are IOPRIO_CLASS_RT (realtime), IOPRIO_CLASS_BE (best-effort) and +# IOPRIO_CLASS_IDLE (idle). I/O niceness priority is a number which goes from +# 0 to 7. The higher the value, the lower the I/O priority of the process. +# Work only with ionice_class. +# ionice_class = +# ionice_priority = [filter:tempauth] use = egg:swift#tempauth diff --git a/swift/common/daemon.py b/swift/common/daemon.py index a5d415638f..9a14024310 100644 --- a/swift/common/daemon.py +++ b/swift/common/daemon.py @@ -88,6 +88,9 @@ def run_daemon(klass, conf_file, section_name='', once=False, **kwargs): log_to_console=kwargs.pop('verbose', False), log_route=section_name) + # optional nice/ionice priority scheduling + utils.modify_priority(conf, logger) + # disable fallocate if desired if utils.config_true_value(conf.get('disable_fallocate', 'no')): utils.disable_fallocate() diff --git a/swift/common/utils.py b/swift/common/utils.py index 57e0e9be3f..08c1fd254a 100644 --- a/swift/common/utils.py +++ b/swift/common/utils.py @@ -31,6 +31,7 @@ import sys import time import uuid import functools +import platform import email.parser from hashlib import md5, sha1 from random import random, shuffle @@ -92,6 +93,10 @@ _posix_fadvise = None _libc_socket = None _libc_bind = None _libc_accept = None +# see man -s 2 setpriority +_libc_setpriority = None +# see man -s 2 syscall +_posix_syscall = None # If set to non-zero, fallocate routines will fail based on free space # available being at or below this amount, in bytes. @@ -100,6 +105,53 @@ FALLOCATE_RESERVE = 0 # the number of bytes (False). FALLOCATE_IS_PERCENT = False +# from /usr/src/linux-headers-*/include/uapi/linux/resource.h +PRIO_PROCESS = 0 + + +# /usr/include/x86_64-linux-gnu/asm/unistd_64.h defines syscalls there +# are many like it, but this one is mine, see man -s 2 ioprio_set +def NR_ioprio_set(): + """Give __NR_ioprio_set value for your system.""" + architecture = os.uname()[4] + arch_bits = platform.architecture()[0] + # check if supported system, now support only x86_64 + if architecture == 'x86_64' and arch_bits == '64bit': + return 251 + raise OSError("Swift doesn't support ionice priority for %s %s" % + (architecture, arch_bits)) + +# this syscall integer probably only works on x86_64 linux systems, you +# can check if it's correct on yours with something like this: +""" +#include +#include + +int main(int argc, const char* argv[]) { + printf("%d\n", __NR_ioprio_set); + return 0; +} +""" + +# this is the value for "which" that says our who value will be a pid +# pulled out of /usr/src/linux-headers-*/include/linux/ioprio.h +IOPRIO_WHO_PROCESS = 1 + + +IO_CLASS_ENUM = { + 'IOPRIO_CLASS_RT': 1, + 'IOPRIO_CLASS_BE': 2, + 'IOPRIO_CLASS_IDLE': 3, +} + +# the IOPRIO_PRIO_VALUE "macro" is also pulled from +# /usr/src/linux-headers-*/include/linux/ioprio.h +IOPRIO_CLASS_SHIFT = 13 + + +def IOPRIO_PRIO_VALUE(class_, data): + return (((class_) << IOPRIO_CLASS_SHIFT) | data) + # Used by hash_path to offer a bit more security when generating hashes for # paths. It simply appends this value to all paths; guessing the hash a path # will end up with would also require knowing this suffix. @@ -382,7 +434,7 @@ def validate_configuration(): def load_libc_function(func_name, log_error=True, - fail_if_missing=False): + fail_if_missing=False, errcheck=False): """ Attempt to find the function in libc, otherwise return a no-op func. @@ -390,10 +442,13 @@ def load_libc_function(func_name, log_error=True, :param log_error: log an error when a function can't be found :param fail_if_missing: raise an exception when a function can't be found. Default behavior is to return a no-op function. + :param errcheck: boolean, if true install a wrapper on the function + to check for a return values of -1 and call + ctype.get_errno and raise an OSError """ try: libc = ctypes.CDLL(ctypes.util.find_library('c'), use_errno=True) - return getattr(libc, func_name) + func = getattr(libc, func_name) except AttributeError: if fail_if_missing: raise @@ -401,6 +456,14 @@ def load_libc_function(func_name, log_error=True, logging.warning(_("Unable to locate %s in libc. Leaving as a " "no-op."), func_name) return noop_libc_function + if errcheck: + def _errcheck(result, f, args): + if result == -1: + errcode = ctypes.get_errno() + raise OSError(errcode, os.strerror(errcode)) + return result + func.errcheck = _errcheck + return func def generate_trans_id(trans_id_suffix): @@ -3897,3 +3960,69 @@ def get_md5_socket(): raise IOError(ctypes.get_errno(), "Failed to accept MD5 socket") return md5_sockfd + + +def modify_priority(conf, logger): + """ + Modify priority by nice and ionice. + """ + + global _libc_setpriority + if _libc_setpriority is None: + _libc_setpriority = load_libc_function('setpriority', + errcheck=True) + + def _setpriority(nice_priority): + """ + setpriority for this pid + + :param nice_priority: valid values are -19 to 20 + """ + try: + _libc_setpriority(PRIO_PROCESS, os.getpid(), + int(nice_priority)) + except (ValueError, OSError): + print(_("WARNING: Unable to modify scheduling priority of process." + " Keeping unchanged! Check logs for more info. ")) + logger.exception('Unable to modify nice priority') + else: + logger.debug('set nice priority to %s' % nice_priority) + + nice_priority = conf.get('nice_priority') + if nice_priority is not None: + _setpriority(nice_priority) + + global _posix_syscall + if _posix_syscall is None: + _posix_syscall = load_libc_function('syscall', errcheck=True) + + def _ioprio_set(io_class, io_priority): + """ + ioprio_set for this process + + :param io_class: the I/O class component, can be + IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, + or IOPRIO_CLASS_IDLE + :param io_priority: priority value in the I/O class + """ + try: + io_class = IO_CLASS_ENUM[io_class] + io_priority = int(io_priority) + _posix_syscall(NR_ioprio_set(), + IOPRIO_WHO_PROCESS, + os.getpid(), + IOPRIO_PRIO_VALUE(io_class, io_priority)) + except (KeyError, ValueError, OSError): + print(_("WARNING: Unable to modify I/O scheduling class " + "and priority of process. Keeping unchanged! " + "Check logs for more info.")) + logger.exception("Unable to modify ionice priority") + else: + logger.debug('set ionice class %s priority %s', + io_class, io_priority) + + io_class = conf.get("ionice_class") + if io_class is None: + return + io_priority = conf.get("ionice_priority", 0) + _ioprio_set(io_class, io_priority) diff --git a/swift/common/wsgi.py b/swift/common/wsgi.py index 88e61f2293..79c3961246 100644 --- a/swift/common/wsgi.py +++ b/swift/common/wsgi.py @@ -877,6 +877,9 @@ def run_wsgi(conf_path, app_section, *args, **kwargs): print(e) return 1 + # optional nice/ionice priority scheduling + utils.modify_priority(conf, logger) + servers_per_port = int(conf.get('servers_per_port', '0') or 0) # NOTE: for now servers_per_port is object-server-only; future work could diff --git a/test/unit/common/test_utils.py b/test/unit/common/test_utils.py index 707a293d6e..bfa7ddb072 100644 --- a/test/unit/common/test_utils.py +++ b/test/unit/common/test_utils.py @@ -15,7 +15,7 @@ """Tests for swift.common.utils""" from __future__ import print_function -from test.unit import temptree +from test.unit import temptree, debug_logger import ctypes import contextlib @@ -3524,6 +3524,72 @@ cluster_dfw1 = http://dfw1.host/v1/ if tempdir: shutil.rmtree(tempdir) + def test_modify_priority(self): + pid = os.getpid() + logger = debug_logger() + called = {} + + def _fake_setpriority(*args): + called['setpriority'] = args + + def _fake_syscall(*args): + called['syscall'] = args + + with patch('swift.common.utils._libc_setpriority', + _fake_setpriority), \ + patch('swift.common.utils._posix_syscall', _fake_syscall): + called = {} + # not set / default + utils.modify_priority({}, logger) + self.assertEqual(called, {}) + called = {} + # just nice + utils.modify_priority({'nice_priority': '1'}, logger) + self.assertEqual(called, {'setpriority': (0, pid, 1)}) + called = {} + # just ionice class uses default priority 0 + utils.modify_priority({'ionice_class': 'IOPRIO_CLASS_RT'}, logger) + self.assertEqual(called, {'syscall': (251, 1, pid, 1 << 13)}) + called = {} + # just ionice priority is ignored + utils.modify_priority({'ionice_priority': '4'}, logger) + self.assertEqual(called, {}) + called = {} + # bad ionice class + utils.modify_priority({'ionice_class': 'class_foo'}, logger) + self.assertEqual(called, {}) + called = {} + # ionice class & priority + utils.modify_priority({ + 'ionice_class': 'IOPRIO_CLASS_BE', + 'ionice_priority': '4', + }, logger) + self.assertEqual(called, {'syscall': (251, 1, pid, 2 << 13 | 4)}) + called = {} + # all + utils.modify_priority({ + 'nice_priority': '-15', + 'ionice_class': 'IOPRIO_CLASS_IDLE', + 'ionice_priority': '6', + }, logger) + self.assertEqual(called, { + 'setpriority': (0, pid, -15), + 'syscall': (251, 1, pid, 3 << 13 | 6), + }) + + def test__NR_ioprio_set(self): + with patch('os.uname', return_value=('', '', '', '', 'x86_64')), \ + patch('platform.architecture', return_value=('64bit', '')): + self.assertEqual(251, utils.NR_ioprio_set()) + + with patch('os.uname', return_value=('', '', '', '', 'x86_64')), \ + patch('platform.architecture', return_value=('32bit', '')): + self.assertRaises(OSError, utils.NR_ioprio_set) + + with patch('os.uname', return_value=('', '', '', '', 'alpha')), \ + patch('platform.architecture', return_value=('64bit', '')): + self.assertRaises(OSError, utils.NR_ioprio_set) + class ResellerConfReader(unittest.TestCase):