曾与蒿藜同雨露,한때 잡초와 쑥과 함께 비와 이슬을 나누던 곳이 이제는 소나무와 삼나무와 함께 서리와 눈을 견뎌내고 있다.终随松柏到冰霜.かつては雑草やヨモギと共に雨や露を分かち合っていたが、今では松やヒノキと共に霜や雪に耐えている。曾与蒿藜同雨露,Once sharing rain and dew with weeds and wormwood, now enduring frost and snow with pines and cypresses.终随松柏到冰霜.曾与蒿藜同雨露한때 잡초와 쑥과 함께 비와 이슬을 나누던 곳이 이제는 소나무와 삼나무와 함께 서리와 눈을 견뎌내고 있다.,终随松柏到冰霜.譖セ荳手珍阯懷酔髮ィ髴イ�檎サ磯囂譚セ譟丞芦蜀ー髴�曾与蒿藜同雨露,鏇句笌钂胯棞鍚岄洦闇诧紝缁堥殢鏉炬煆鍒板啺闇�终随松柏到冰霜.曾与蒿藜同雨露,한때 잡초와 쑥과 함께 비와 이슬을 나누던 곳이 이제는 소나무와 삼나무와 함께 서리와 눈을 견뎌내고 있다.终随松柏到冰霜.曾与蒿藜同雨露,终随松柏到冰霜.
import tuned.consts as consts
from . import base
from .decorators import *
from subprocess import Popen,PIPE
import tuned.logs
from tuned.utils.commands import commands
import glob
log = tuned.logs.get()
cmd = commands()
class MountsPlugin(base.Plugin):
"""
Plugin for tuning options of mount-points.
"""
@classmethod
def _generate_mountpoint_topology(cls):
"""
Gets the information about disks, partitions and mountpoints. Stores information about used filesystem and
creates a list of all underlying devices (in case of LVM) for each mountpoint.
"""
mountpoint_topology = {}
current_disk = None
stdout, stderr = Popen(["lsblk", "-rno", \
"TYPE,RM,KNAME,FSTYPE,MOUNTPOINT"], \
stdout=PIPE, stderr=PIPE, close_fds=True, \
universal_newlines = True).communicate()
for columns in [line.split() for line in stdout.splitlines()]:
if len(columns) < 3:
continue
device_type, device_removable, device_name = columns[:3]
filesystem = columns[3] if len(columns) > 3 else None
mountpoint = columns[4] if len(columns) > 4 else None
if device_type == "disk":
current_disk = device_name
continue
# skip removable, skip nonpartitions
if device_removable == "1" or device_type not in ["part", "lvm"]:
continue
if mountpoint is None or mountpoint == "[SWAP]":
continue
mountpoint_topology.setdefault(mountpoint, {"disks": set(), "device_name": device_name, "filesystem": filesystem})
mountpoint_topology[mountpoint]["disks"].add(current_disk)
cls._mountpoint_topology = mountpoint_topology
def _init_devices(self):
self._generate_mountpoint_topology()
self._devices_supported = True
self._free_devices = set(self._mountpoint_topology.keys())
self._assigned_devices = set()
@classmethod
def _get_config_options(self):
return {
"disable_barriers": None,
}
def _instance_init(self, instance):
instance._has_dynamic_tuning = False
instance._has_static_tuning = True
def _instance_cleanup(self, instance):
pass
def _get_device_cache_type(self, device):
"""
Get device cache type. This will work only for devices on SCSI kernel subsystem.
"""
source_filenames = glob.glob("/sys/block/%s/device/scsi_disk/*/cache_type" % device)
for source_filename in source_filenames:
return cmd.read_file(source_filename).strip()
return None
def _mountpoint_has_writeback_cache(self, mountpoint):
"""
Checks if the device has 'write back' cache. If the cache type cannot be determined, asume some other cache.
"""
for device in self._mountpoint_topology[mountpoint]["disks"]:
if self._get_device_cache_type(device) == "write back":
return True
return False
def _mountpoint_has_barriers(self, mountpoint):
"""
Checks if a given mountpoint is mounted with barriers enabled or disabled.
"""
with open("/proc/mounts") as mounts_file:
for line in mounts_file:
# device mountpoint filesystem options dump check
columns = line.split()
if columns[0][0] != "/":
continue
if columns[1] == mountpoint:
option_list = columns[3]
break
else:
return None
options = option_list.split(",")
for option in options:
(name, sep, value) = option.partition("=")
# nobarrier barrier=0
if name == "nobarrier" or (name == "barrier" and value == "0"):
return False
# barrier barrier=1
elif name == "barrier":
return True
else:
# default
return True
def _remount_partition(self, partition, options):
"""
Remounts partition.
"""
remount_command = ["/usr/bin/mount", partition, "-o", "remount,%s" % options]
cmd.execute(remount_command)
@command_custom("disable_barriers", per_device=True)
def _disable_barriers(self, start, value, mountpoint, verify, ignore_missing):
storage_key = self._storage_key(
command_name = "disable_barriers",
device_name = mountpoint)
force = str(value).lower() == "force"
value = force or self._option_bool(value)
if start:
if not value:
return None
reject_reason = None
if not self._mountpoint_topology[mountpoint]["filesystem"].startswith("ext"):
reject_reason = "filesystem not supported"
elif not force and self._mountpoint_has_writeback_cache(mountpoint):
reject_reason = "device uses write back cache"
else:
original_value = self._mountpoint_has_barriers(mountpoint)
if original_value is None:
reject_reason = "unknown current setting"
elif original_value == False:
if verify:
log.info(consts.STR_VERIFY_PROFILE_OK % mountpoint)
return True
else:
reject_reason = "barriers already disabled"
elif verify:
log.error(consts.STR_VERIFY_PROFILE_FAIL % mountpoint)
return False
if reject_reason is not None:
log.info("not disabling barriers on '%s' (%s)" % (mountpoint, reject_reason))
return None
self._storage.set(storage_key, original_value)
log.info("disabling barriers on '%s'" % mountpoint)
self._remount_partition(mountpoint, "barrier=0")
else:
if verify:
return None
original_value = self._storage.get(storage_key)
if original_value is None:
return None
log.info("enabling barriers on '%s'" % mountpoint)
self._remount_partition(mountpoint, "barrier=1")
self._storage.unset(storage_key)
return None