162306a36Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci=================================== 462306a36Sopenharmony_ciCache on Already Mounted Filesystem 562306a36Sopenharmony_ci=================================== 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci.. Contents: 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci (*) Overview. 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci (*) Requirements. 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci (*) Configuration. 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci (*) Starting the cache. 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci (*) Things to avoid. 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci (*) Cache culling. 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci (*) Cache structure. 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci (*) Security model and SELinux. 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci (*) A note on security. 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci (*) Statistical information. 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci (*) Debugging. 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci (*) On-demand Read. 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ciOverview 3562306a36Sopenharmony_ci======== 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ciCacheFiles is a caching backend that's meant to use as a cache a directory on 3862306a36Sopenharmony_cian already mounted filesystem of a local type (such as Ext3). 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ciCacheFiles uses a userspace daemon to do some of the cache management - such as 4162306a36Sopenharmony_cireaping stale nodes and culling. This is called cachefilesd and lives in 4262306a36Sopenharmony_ci/sbin. 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ciThe filesystem and data integrity of the cache are only as good as those of the 4562306a36Sopenharmony_cifilesystem providing the backing services. Note that CacheFiles does not 4662306a36Sopenharmony_ciattempt to journal anything since the journalling interfaces of the various 4762306a36Sopenharmony_cifilesystems are very specific in nature. 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ciCacheFiles creates a misc character device - "/dev/cachefiles" - that is used 5062306a36Sopenharmony_cito communication with the daemon. Only one thing may have this open at once, 5162306a36Sopenharmony_ciand while it is open, a cache is at least partially in existence. The daemon 5262306a36Sopenharmony_ciopens this and sends commands down it to control the cache. 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ciCacheFiles is currently limited to a single cache. 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ciCacheFiles attempts to maintain at least a certain percentage of free space on 5762306a36Sopenharmony_cithe filesystem, shrinking the cache by culling the objects it contains to make 5862306a36Sopenharmony_cispace if necessary - see the "Cache Culling" section. This means it can be 5962306a36Sopenharmony_ciplaced on the same medium as a live set of data, and will expand to make use of 6062306a36Sopenharmony_cispare space and automatically contract when the set of data requires more 6162306a36Sopenharmony_cispace. 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ciRequirements 6662306a36Sopenharmony_ci============ 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ciThe use of CacheFiles and its daemon requires the following features to be 6962306a36Sopenharmony_ciavailable in the system and in the cache filesystem: 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci - dnotify. 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci - extended attributes (xattrs). 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci - openat() and friends. 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci - bmap() support on files in the filesystem (FIBMAP ioctl). 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci - The use of bmap() to detect a partial page at the end of the file. 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ciIt is strongly recommended that the "dir_index" option is enabled on Ext3 8262306a36Sopenharmony_cifilesystems being used as a cache. 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ciConfiguration 8662306a36Sopenharmony_ci============= 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ciThe cache is configured by a script in /etc/cachefilesd.conf. These commands 8962306a36Sopenharmony_ciset up cache ready for use. The following script commands are available: 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci brun <N>%, bcull <N>%, bstop <N>%, frun <N>%, fcull <N>%, fstop <N>% 9262306a36Sopenharmony_ci Configure the culling limits. Optional. See the section on culling 9362306a36Sopenharmony_ci The defaults are 7% (run), 5% (cull) and 1% (stop) respectively. 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci The commands beginning with a 'b' are file space (block) limits, those 9662306a36Sopenharmony_ci beginning with an 'f' are file count limits. 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci dir <path> 9962306a36Sopenharmony_ci Specify the directory containing the root of the cache. Mandatory. 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci tag <name> 10262306a36Sopenharmony_ci Specify a tag to FS-Cache to use in distinguishing multiple caches. 10362306a36Sopenharmony_ci Optional. The default is "CacheFiles". 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci debug <mask> 10662306a36Sopenharmony_ci Specify a numeric bitmask to control debugging in the kernel module. 10762306a36Sopenharmony_ci Optional. The default is zero (all off). The following values can be 10862306a36Sopenharmony_ci OR'd into the mask to collect various information: 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci == ================================================= 11162306a36Sopenharmony_ci 1 Turn on trace of function entry (_enter() macros) 11262306a36Sopenharmony_ci 2 Turn on trace of function exit (_leave() macros) 11362306a36Sopenharmony_ci 4 Turn on trace of internal debug points (_debug()) 11462306a36Sopenharmony_ci == ================================================= 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci This mask can also be set through sysfs, eg:: 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci echo 5 >/sys/modules/cachefiles/parameters/debug 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ciStarting the Cache 12262306a36Sopenharmony_ci================== 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ciThe cache is started by running the daemon. The daemon opens the cache device, 12562306a36Sopenharmony_ciconfigures the cache and tells it to begin caching. At that point the cache 12662306a36Sopenharmony_cibinds to fscache and the cache becomes live. 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ciThe daemon is run as follows:: 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci /sbin/cachefilesd [-d]* [-s] [-n] [-f <configfile>] 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ciThe flags are: 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci ``-d`` 13562306a36Sopenharmony_ci Increase the debugging level. This can be specified multiple times and 13662306a36Sopenharmony_ci is cumulative with itself. 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci ``-s`` 13962306a36Sopenharmony_ci Send messages to stderr instead of syslog. 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci ``-n`` 14262306a36Sopenharmony_ci Don't daemonise and go into background. 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci ``-f <configfile>`` 14562306a36Sopenharmony_ci Use an alternative configuration file rather than the default one. 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ciThings to Avoid 14962306a36Sopenharmony_ci=============== 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ciDo not mount other things within the cache as this will cause problems. The 15262306a36Sopenharmony_cikernel module contains its own very cut-down path walking facility that ignores 15362306a36Sopenharmony_cimountpoints, but the daemon can't avoid them. 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ciDo not create, rename or unlink files and directories in the cache while the 15662306a36Sopenharmony_cicache is active, as this may cause the state to become uncertain. 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ciRenaming files in the cache might make objects appear to be other objects (the 15962306a36Sopenharmony_cifilename is part of the lookup key). 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ciDo not change or remove the extended attributes attached to cache files by the 16262306a36Sopenharmony_cicache as this will cause the cache state management to get confused. 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ciDo not create files or directories in the cache, lest the cache get confused or 16562306a36Sopenharmony_ciserve incorrect data. 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ciDo not chmod files in the cache. The module creates things with minimal 16862306a36Sopenharmony_cipermissions to prevent random users being able to access them directly. 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ciCache Culling 17262306a36Sopenharmony_ci============= 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ciThe cache may need culling occasionally to make space. This involves 17562306a36Sopenharmony_cidiscarding objects from the cache that have been used less recently than 17662306a36Sopenharmony_cianything else. Culling is based on the access time of data objects. Empty 17762306a36Sopenharmony_cidirectories are culled if not in use. 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ciCache culling is done on the basis of the percentage of blocks and the 18062306a36Sopenharmony_cipercentage of files available in the underlying filesystem. There are six 18162306a36Sopenharmony_ci"limits": 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci brun, frun 18462306a36Sopenharmony_ci If the amount of free space and the number of available files in the cache 18562306a36Sopenharmony_ci rises above both these limits, then culling is turned off. 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci bcull, fcull 18862306a36Sopenharmony_ci If the amount of available space or the number of available files in the 18962306a36Sopenharmony_ci cache falls below either of these limits, then culling is started. 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci bstop, fstop 19262306a36Sopenharmony_ci If the amount of available space or the number of available files in the 19362306a36Sopenharmony_ci cache falls below either of these limits, then no further allocation of 19462306a36Sopenharmony_ci disk space or files is permitted until culling has raised things above 19562306a36Sopenharmony_ci these limits again. 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ciThese must be configured thusly:: 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci 0 <= bstop < bcull < brun < 100 20062306a36Sopenharmony_ci 0 <= fstop < fcull < frun < 100 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ciNote that these are percentages of available space and available files, and do 20362306a36Sopenharmony_ci_not_ appear as 100 minus the percentage displayed by the "df" program. 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ciThe userspace daemon scans the cache to build up a table of cullable objects. 20662306a36Sopenharmony_ciThese are then culled in least recently used order. A new scan of the cache is 20762306a36Sopenharmony_cistarted as soon as space is made in the table. Objects will be skipped if 20862306a36Sopenharmony_citheir atimes have changed or if the kernel module says it is still using them. 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ciCache Structure 21262306a36Sopenharmony_ci=============== 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ciThe CacheFiles module will create two directories in the directory it was 21562306a36Sopenharmony_cigiven: 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci * cache/ 21862306a36Sopenharmony_ci * graveyard/ 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ciThe active cache objects all reside in the first directory. The CacheFiles 22162306a36Sopenharmony_cikernel module moves any retired or culled objects that it can't simply unlink 22262306a36Sopenharmony_cito the graveyard from which the daemon will actually delete them. 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ciThe daemon uses dnotify to monitor the graveyard directory, and will delete 22562306a36Sopenharmony_cianything that appears therein. 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ciThe module represents index objects as directories with the filename "I..." or 22962306a36Sopenharmony_ci"J...". Note that the "cache/" directory is itself a special index. 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ciData objects are represented as files if they have no children, or directories 23262306a36Sopenharmony_ciif they do. Their filenames all begin "D..." or "E...". If represented as a 23362306a36Sopenharmony_cidirectory, data objects will have a file in the directory called "data" that 23462306a36Sopenharmony_ciactually holds the data. 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ciSpecial objects are similar to data objects, except their filenames begin 23762306a36Sopenharmony_ci"S..." or "T...". 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ciIf an object has children, then it will be represented as a directory. 24162306a36Sopenharmony_ciImmediately in the representative directory are a collection of directories 24262306a36Sopenharmony_cinamed for hash values of the child object keys with an '@' prepended. Into 24362306a36Sopenharmony_cithis directory, if possible, will be placed the representations of the child 24462306a36Sopenharmony_ciobjects:: 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci /INDEX /INDEX /INDEX /DATA FILES 24762306a36Sopenharmony_ci /=========/==========/=================================/================ 24862306a36Sopenharmony_ci cache/@4a/I03nfs/@30/Ji000000000000000--fHg8hi8400 24962306a36Sopenharmony_ci cache/@4a/I03nfs/@30/Ji000000000000000--fHg8hi8400/@75/Es0g000w...DB1ry 25062306a36Sopenharmony_ci cache/@4a/I03nfs/@30/Ji000000000000000--fHg8hi8400/@75/Es0g000w...N22ry 25162306a36Sopenharmony_ci cache/@4a/I03nfs/@30/Ji000000000000000--fHg8hi8400/@75/Es0g000w...FP1ry 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ciIf the key is so long that it exceeds NAME_MAX with the decorations added on to 25562306a36Sopenharmony_ciit, then it will be cut into pieces, the first few of which will be used to 25662306a36Sopenharmony_cimake a nest of directories, and the last one of which will be the objects 25762306a36Sopenharmony_ciinside the last directory. The names of the intermediate directories will have 25862306a36Sopenharmony_ci'+' prepended:: 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci J1223/@23/+xy...z/+kl...m/Epqr 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ciNote that keys are raw data, and not only may they exceed NAME_MAX in size, 26462306a36Sopenharmony_cithey may also contain things like '/' and NUL characters, and so they may not 26562306a36Sopenharmony_cibe suitable for turning directly into a filename. 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ciTo handle this, CacheFiles will use a suitably printable filename directly and 26862306a36Sopenharmony_ci"base-64" encode ones that aren't directly suitable. The two versions of 26962306a36Sopenharmony_ciobject filenames indicate the encoding: 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci =============== =============== =============== 27262306a36Sopenharmony_ci OBJECT TYPE PRINTABLE ENCODED 27362306a36Sopenharmony_ci =============== =============== =============== 27462306a36Sopenharmony_ci Index "I..." "J..." 27562306a36Sopenharmony_ci Data "D..." "E..." 27662306a36Sopenharmony_ci Special "S..." "T..." 27762306a36Sopenharmony_ci =============== =============== =============== 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ciIntermediate directories are always "@" or "+" as appropriate. 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ciEach object in the cache has an extended attribute label that holds the object 28362306a36Sopenharmony_citype ID (required to distinguish special objects) and the auxiliary data from 28462306a36Sopenharmony_cithe netfs. The latter is used to detect stale objects in the cache and update 28562306a36Sopenharmony_cior retire them. 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ciNote that CacheFiles will erase from the cache any file it doesn't recognise or 28962306a36Sopenharmony_ciany file of an incorrect type (such as a FIFO file or a device file). 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ciSecurity Model and SELinux 29362306a36Sopenharmony_ci========================== 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ciCacheFiles is implemented to deal properly with the LSM security features of 29662306a36Sopenharmony_cithe Linux kernel and the SELinux facility. 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_ciOne of the problems that CacheFiles faces is that it is generally acting on 29962306a36Sopenharmony_cibehalf of a process, and running in that process's context, and that includes a 30062306a36Sopenharmony_cisecurity context that is not appropriate for accessing the cache - either 30162306a36Sopenharmony_cibecause the files in the cache are inaccessible to that process, or because if 30262306a36Sopenharmony_cithe process creates a file in the cache, that file may be inaccessible to other 30362306a36Sopenharmony_ciprocesses. 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ciThe way CacheFiles works is to temporarily change the security context (fsuid, 30662306a36Sopenharmony_cifsgid and actor security label) that the process acts as - without changing the 30762306a36Sopenharmony_cisecurity context of the process when it the target of an operation performed by 30862306a36Sopenharmony_cisome other process (so signalling and suchlike still work correctly). 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ciWhen the CacheFiles module is asked to bind to its cache, it: 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci (1) Finds the security label attached to the root cache directory and uses 31462306a36Sopenharmony_ci that as the security label with which it will create files. By default, 31562306a36Sopenharmony_ci this is:: 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci cachefiles_var_t 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_ci (2) Finds the security label of the process which issued the bind request 32062306a36Sopenharmony_ci (presumed to be the cachefilesd daemon), which by default will be:: 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci cachefilesd_t 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci and asks LSM to supply a security ID as which it should act given the 32562306a36Sopenharmony_ci daemon's label. By default, this will be:: 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci cachefiles_kernel_t 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_ci SELinux transitions the daemon's security ID to the module's security ID 33062306a36Sopenharmony_ci based on a rule of this form in the policy:: 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci type_transition <daemon's-ID> kernel_t : process <module's-ID>; 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci For instance:: 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci type_transition cachefilesd_t kernel_t : process cachefiles_kernel_t; 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ciThe module's security ID gives it permission to create, move and remove files 34062306a36Sopenharmony_ciand directories in the cache, to find and access directories and files in the 34162306a36Sopenharmony_cicache, to set and access extended attributes on cache objects, and to read and 34262306a36Sopenharmony_ciwrite files in the cache. 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ciThe daemon's security ID gives it only a very restricted set of permissions: it 34562306a36Sopenharmony_cimay scan directories, stat files and erase files and directories. It may 34662306a36Sopenharmony_cinot read or write files in the cache, and so it is precluded from accessing the 34762306a36Sopenharmony_cidata cached therein; nor is it permitted to create new files in the cache. 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_ciThere are policy source files available in: 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_ci https://people.redhat.com/~dhowells/fscache/cachefilesd-0.8.tar.bz2 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ciand later versions. In that tarball, see the files:: 35562306a36Sopenharmony_ci 35662306a36Sopenharmony_ci cachefilesd.te 35762306a36Sopenharmony_ci cachefilesd.fc 35862306a36Sopenharmony_ci cachefilesd.if 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_ciThey are built and installed directly by the RPM. 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ciIf a non-RPM based system is being used, then copy the above files to their own 36362306a36Sopenharmony_cidirectory and run:: 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ci make -f /usr/share/selinux/devel/Makefile 36662306a36Sopenharmony_ci semodule -i cachefilesd.pp 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_ciYou will need checkpolicy and selinux-policy-devel installed prior to the 36962306a36Sopenharmony_cibuild. 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_ciBy default, the cache is located in /var/fscache, but if it is desirable that 37362306a36Sopenharmony_ciit should be elsewhere, than either the above policy files must be altered, or 37462306a36Sopenharmony_cian auxiliary policy must be installed to label the alternate location of the 37562306a36Sopenharmony_cicache. 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ciFor instructions on how to add an auxiliary policy to enable the cache to be 37862306a36Sopenharmony_cilocated elsewhere when SELinux is in enforcing mode, please see:: 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_ci /usr/share/doc/cachefilesd-*/move-cache.txt 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_ciWhen the cachefilesd rpm is installed; alternatively, the document can be found 38362306a36Sopenharmony_ciin the sources. 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ciA Note on Security 38762306a36Sopenharmony_ci================== 38862306a36Sopenharmony_ci 38962306a36Sopenharmony_ciCacheFiles makes use of the split security in the task_struct. It allocates 39062306a36Sopenharmony_ciits own task_security structure, and redirects current->cred to point to it 39162306a36Sopenharmony_ciwhen it acts on behalf of another process, in that process's context. 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_ciThe reason it does this is that it calls vfs_mkdir() and suchlike rather than 39462306a36Sopenharmony_cibypassing security and calling inode ops directly. Therefore the VFS and LSM 39562306a36Sopenharmony_cimay deny the CacheFiles access to the cache data because under some 39662306a36Sopenharmony_cicircumstances the caching code is running in the security context of whatever 39762306a36Sopenharmony_ciprocess issued the original syscall on the netfs. 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_ciFurthermore, should CacheFiles create a file or directory, the security 40062306a36Sopenharmony_ciparameters with that object is created (UID, GID, security label) would be 40162306a36Sopenharmony_ciderived from that process that issued the system call, thus potentially 40262306a36Sopenharmony_cipreventing other processes from accessing the cache - including CacheFiles's 40362306a36Sopenharmony_cicache management daemon (cachefilesd). 40462306a36Sopenharmony_ci 40562306a36Sopenharmony_ciWhat is required is to temporarily override the security of the process that 40662306a36Sopenharmony_ciissued the system call. We can't, however, just do an in-place change of the 40762306a36Sopenharmony_cisecurity data as that affects the process as an object, not just as a subject. 40862306a36Sopenharmony_ciThis means it may lose signals or ptrace events for example, and affects what 40962306a36Sopenharmony_cithe process looks like in /proc. 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_ciSo CacheFiles makes use of a logical split in the security between the 41262306a36Sopenharmony_ciobjective security (task->real_cred) and the subjective security (task->cred). 41362306a36Sopenharmony_ciThe objective security holds the intrinsic security properties of a process and 41462306a36Sopenharmony_ciis never overridden. This is what appears in /proc, and is what is used when a 41562306a36Sopenharmony_ciprocess is the target of an operation by some other process (SIGKILL for 41662306a36Sopenharmony_ciexample). 41762306a36Sopenharmony_ci 41862306a36Sopenharmony_ciThe subjective security holds the active security properties of a process, and 41962306a36Sopenharmony_cimay be overridden. This is not seen externally, and is used when a process 42062306a36Sopenharmony_ciacts upon another object, for example SIGKILLing another process or opening a 42162306a36Sopenharmony_cifile. 42262306a36Sopenharmony_ci 42362306a36Sopenharmony_ciLSM hooks exist that allow SELinux (or Smack or whatever) to reject a request 42462306a36Sopenharmony_cifor CacheFiles to run in a context of a specific security label, or to create 42562306a36Sopenharmony_cifiles and directories with another security label. 42662306a36Sopenharmony_ci 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_ciStatistical Information 42962306a36Sopenharmony_ci======================= 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_ciIf FS-Cache is compiled with the following option enabled:: 43262306a36Sopenharmony_ci 43362306a36Sopenharmony_ci CONFIG_CACHEFILES_HISTOGRAM=y 43462306a36Sopenharmony_ci 43562306a36Sopenharmony_cithen it will gather certain statistics and display them through a proc file. 43662306a36Sopenharmony_ci 43762306a36Sopenharmony_ci /proc/fs/cachefiles/histogram 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_ci :: 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci cat /proc/fs/cachefiles/histogram 44262306a36Sopenharmony_ci JIFS SECS LOOKUPS MKDIRS CREATES 44362306a36Sopenharmony_ci ===== ===== ========= ========= ========= 44462306a36Sopenharmony_ci 44562306a36Sopenharmony_ci This shows the breakdown of the number of times each amount of time 44662306a36Sopenharmony_ci between 0 jiffies and HZ-1 jiffies a variety of tasks took to run. The 44762306a36Sopenharmony_ci columns are as follows: 44862306a36Sopenharmony_ci 44962306a36Sopenharmony_ci ======= ======================================================= 45062306a36Sopenharmony_ci COLUMN TIME MEASUREMENT 45162306a36Sopenharmony_ci ======= ======================================================= 45262306a36Sopenharmony_ci LOOKUPS Length of time to perform a lookup on the backing fs 45362306a36Sopenharmony_ci MKDIRS Length of time to perform a mkdir on the backing fs 45462306a36Sopenharmony_ci CREATES Length of time to perform a create on the backing fs 45562306a36Sopenharmony_ci ======= ======================================================= 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_ci Each row shows the number of events that took a particular range of times. 45862306a36Sopenharmony_ci Each step is 1 jiffy in size. The JIFS column indicates the particular 45962306a36Sopenharmony_ci jiffy range covered, and the SECS field the equivalent number of seconds. 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_ci 46262306a36Sopenharmony_ciDebugging 46362306a36Sopenharmony_ci========= 46462306a36Sopenharmony_ci 46562306a36Sopenharmony_ciIf CONFIG_CACHEFILES_DEBUG is enabled, the CacheFiles facility can have runtime 46662306a36Sopenharmony_cidebugging enabled by adjusting the value in:: 46762306a36Sopenharmony_ci 46862306a36Sopenharmony_ci /sys/module/cachefiles/parameters/debug 46962306a36Sopenharmony_ci 47062306a36Sopenharmony_ciThis is a bitmask of debugging streams to enable: 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_ci ======= ======= =============================== ======================= 47362306a36Sopenharmony_ci BIT VALUE STREAM POINT 47462306a36Sopenharmony_ci ======= ======= =============================== ======================= 47562306a36Sopenharmony_ci 0 1 General Function entry trace 47662306a36Sopenharmony_ci 1 2 Function exit trace 47762306a36Sopenharmony_ci 2 4 General 47862306a36Sopenharmony_ci ======= ======= =============================== ======================= 47962306a36Sopenharmony_ci 48062306a36Sopenharmony_ciThe appropriate set of values should be OR'd together and the result written to 48162306a36Sopenharmony_cithe control file. For example:: 48262306a36Sopenharmony_ci 48362306a36Sopenharmony_ci echo $((1|4|8)) >/sys/module/cachefiles/parameters/debug 48462306a36Sopenharmony_ci 48562306a36Sopenharmony_ciwill turn on all function entry debugging. 48662306a36Sopenharmony_ci 48762306a36Sopenharmony_ci 48862306a36Sopenharmony_ciOn-demand Read 48962306a36Sopenharmony_ci============== 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_ciWhen working in its original mode, CacheFiles serves as a local cache for a 49262306a36Sopenharmony_ciremote networking fs - while in on-demand read mode, CacheFiles can boost the 49362306a36Sopenharmony_ciscenario where on-demand read semantics are needed, e.g. container image 49462306a36Sopenharmony_cidistribution. 49562306a36Sopenharmony_ci 49662306a36Sopenharmony_ciThe essential difference between these two modes is seen when a cache miss 49762306a36Sopenharmony_cioccurs: In the original mode, the netfs will fetch the data from the remote 49862306a36Sopenharmony_ciserver and then write it to the cache file; in on-demand read mode, fetching 49962306a36Sopenharmony_cithe data and writing it into the cache is delegated to a user daemon. 50062306a36Sopenharmony_ci 50162306a36Sopenharmony_ci``CONFIG_CACHEFILES_ONDEMAND`` should be enabled to support on-demand read mode. 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_ciProtocol Communication 50562306a36Sopenharmony_ci---------------------- 50662306a36Sopenharmony_ci 50762306a36Sopenharmony_ciThe on-demand read mode uses a simple protocol for communication between kernel 50862306a36Sopenharmony_ciand user daemon. The protocol can be modeled as:: 50962306a36Sopenharmony_ci 51062306a36Sopenharmony_ci kernel --[request]--> user daemon --[reply]--> kernel 51162306a36Sopenharmony_ci 51262306a36Sopenharmony_ciCacheFiles will send requests to the user daemon when needed. The user daemon 51362306a36Sopenharmony_cishould poll the devnode ('/dev/cachefiles') to check if there's a pending 51462306a36Sopenharmony_cirequest to be processed. A POLLIN event will be returned when there's a pending 51562306a36Sopenharmony_cirequest. 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_ciThe user daemon then reads the devnode to fetch a request to process. It should 51862306a36Sopenharmony_cibe noted that each read only gets one request. When it has finished processing 51962306a36Sopenharmony_cithe request, the user daemon should write the reply to the devnode. 52062306a36Sopenharmony_ci 52162306a36Sopenharmony_ciEach request starts with a message header of the form:: 52262306a36Sopenharmony_ci 52362306a36Sopenharmony_ci struct cachefiles_msg { 52462306a36Sopenharmony_ci __u32 msg_id; 52562306a36Sopenharmony_ci __u32 opcode; 52662306a36Sopenharmony_ci __u32 len; 52762306a36Sopenharmony_ci __u32 object_id; 52862306a36Sopenharmony_ci __u8 data[]; 52962306a36Sopenharmony_ci }; 53062306a36Sopenharmony_ci 53162306a36Sopenharmony_ciwhere: 53262306a36Sopenharmony_ci 53362306a36Sopenharmony_ci * ``msg_id`` is a unique ID identifying this request among all pending 53462306a36Sopenharmony_ci requests. 53562306a36Sopenharmony_ci 53662306a36Sopenharmony_ci * ``opcode`` indicates the type of this request. 53762306a36Sopenharmony_ci 53862306a36Sopenharmony_ci * ``object_id`` is a unique ID identifying the cache file operated on. 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ci * ``data`` indicates the payload of this request. 54162306a36Sopenharmony_ci 54262306a36Sopenharmony_ci * ``len`` indicates the whole length of this request, including the 54362306a36Sopenharmony_ci header and following type-specific payload. 54462306a36Sopenharmony_ci 54562306a36Sopenharmony_ci 54662306a36Sopenharmony_ciTurning on On-demand Mode 54762306a36Sopenharmony_ci------------------------- 54862306a36Sopenharmony_ci 54962306a36Sopenharmony_ciAn optional parameter becomes available to the "bind" command:: 55062306a36Sopenharmony_ci 55162306a36Sopenharmony_ci bind [ondemand] 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_ciWhen the "bind" command is given no argument, it defaults to the original mode. 55462306a36Sopenharmony_ciWhen it is given the "ondemand" argument, i.e. "bind ondemand", on-demand read 55562306a36Sopenharmony_cimode will be enabled. 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_ci 55862306a36Sopenharmony_ciThe OPEN Request 55962306a36Sopenharmony_ci---------------- 56062306a36Sopenharmony_ci 56162306a36Sopenharmony_ciWhen the netfs opens a cache file for the first time, a request with the 56262306a36Sopenharmony_ciCACHEFILES_OP_OPEN opcode, a.k.a an OPEN request will be sent to the user 56362306a36Sopenharmony_cidaemon. The payload format is of the form:: 56462306a36Sopenharmony_ci 56562306a36Sopenharmony_ci struct cachefiles_open { 56662306a36Sopenharmony_ci __u32 volume_key_size; 56762306a36Sopenharmony_ci __u32 cookie_key_size; 56862306a36Sopenharmony_ci __u32 fd; 56962306a36Sopenharmony_ci __u32 flags; 57062306a36Sopenharmony_ci __u8 data[]; 57162306a36Sopenharmony_ci }; 57262306a36Sopenharmony_ci 57362306a36Sopenharmony_ciwhere: 57462306a36Sopenharmony_ci 57562306a36Sopenharmony_ci * ``data`` contains the volume_key followed directly by the cookie_key. 57662306a36Sopenharmony_ci The volume key is a NUL-terminated string; the cookie key is binary 57762306a36Sopenharmony_ci data. 57862306a36Sopenharmony_ci 57962306a36Sopenharmony_ci * ``volume_key_size`` indicates the size of the volume key in bytes. 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_ci * ``cookie_key_size`` indicates the size of the cookie key in bytes. 58262306a36Sopenharmony_ci 58362306a36Sopenharmony_ci * ``fd`` indicates an anonymous fd referring to the cache file, through 58462306a36Sopenharmony_ci which the user daemon can perform write/llseek file operations on the 58562306a36Sopenharmony_ci cache file. 58662306a36Sopenharmony_ci 58762306a36Sopenharmony_ci 58862306a36Sopenharmony_ciThe user daemon can use the given (volume_key, cookie_key) pair to distinguish 58962306a36Sopenharmony_cithe requested cache file. With the given anonymous fd, the user daemon can 59062306a36Sopenharmony_cifetch the data and write it to the cache file in the background, even when 59162306a36Sopenharmony_cikernel has not triggered a cache miss yet. 59262306a36Sopenharmony_ci 59362306a36Sopenharmony_ciBe noted that each cache file has a unique object_id, while it may have multiple 59462306a36Sopenharmony_cianonymous fds. The user daemon may duplicate anonymous fds from the initial 59562306a36Sopenharmony_cianonymous fd indicated by the @fd field through dup(). Thus each object_id can 59662306a36Sopenharmony_cibe mapped to multiple anonymous fds, while the usr daemon itself needs to 59762306a36Sopenharmony_cimaintain the mapping. 59862306a36Sopenharmony_ci 59962306a36Sopenharmony_ciWhen implementing a user daemon, please be careful of RLIMIT_NOFILE, 60062306a36Sopenharmony_ci``/proc/sys/fs/nr_open`` and ``/proc/sys/fs/file-max``. Typically these needn't 60162306a36Sopenharmony_cibe huge since they're related to the number of open device blobs rather than 60262306a36Sopenharmony_ciopen files of each individual filesystem. 60362306a36Sopenharmony_ci 60462306a36Sopenharmony_ciThe user daemon should reply the OPEN request by issuing a "copen" (complete 60562306a36Sopenharmony_ciopen) command on the devnode:: 60662306a36Sopenharmony_ci 60762306a36Sopenharmony_ci copen <msg_id>,<cache_size> 60862306a36Sopenharmony_ci 60962306a36Sopenharmony_ciwhere: 61062306a36Sopenharmony_ci 61162306a36Sopenharmony_ci * ``msg_id`` must match the msg_id field of the OPEN request. 61262306a36Sopenharmony_ci 61362306a36Sopenharmony_ci * When >= 0, ``cache_size`` indicates the size of the cache file; 61462306a36Sopenharmony_ci when < 0, ``cache_size`` indicates any error code encountered by the 61562306a36Sopenharmony_ci user daemon. 61662306a36Sopenharmony_ci 61762306a36Sopenharmony_ci 61862306a36Sopenharmony_ciThe CLOSE Request 61962306a36Sopenharmony_ci----------------- 62062306a36Sopenharmony_ci 62162306a36Sopenharmony_ciWhen a cookie withdrawn, a CLOSE request (opcode CACHEFILES_OP_CLOSE) will be 62262306a36Sopenharmony_cisent to the user daemon. This tells the user daemon to close all anonymous fds 62362306a36Sopenharmony_ciassociated with the given object_id. The CLOSE request has no extra payload, 62462306a36Sopenharmony_ciand shouldn't be replied. 62562306a36Sopenharmony_ci 62662306a36Sopenharmony_ci 62762306a36Sopenharmony_ciThe READ Request 62862306a36Sopenharmony_ci---------------- 62962306a36Sopenharmony_ci 63062306a36Sopenharmony_ciWhen a cache miss is encountered in on-demand read mode, CacheFiles will send a 63162306a36Sopenharmony_ciREAD request (opcode CACHEFILES_OP_READ) to the user daemon. This tells the user 63262306a36Sopenharmony_cidaemon to fetch the contents of the requested file range. The payload is of the 63362306a36Sopenharmony_ciform:: 63462306a36Sopenharmony_ci 63562306a36Sopenharmony_ci struct cachefiles_read { 63662306a36Sopenharmony_ci __u64 off; 63762306a36Sopenharmony_ci __u64 len; 63862306a36Sopenharmony_ci }; 63962306a36Sopenharmony_ci 64062306a36Sopenharmony_ciwhere: 64162306a36Sopenharmony_ci 64262306a36Sopenharmony_ci * ``off`` indicates the starting offset of the requested file range. 64362306a36Sopenharmony_ci 64462306a36Sopenharmony_ci * ``len`` indicates the length of the requested file range. 64562306a36Sopenharmony_ci 64662306a36Sopenharmony_ci 64762306a36Sopenharmony_ciWhen it receives a READ request, the user daemon should fetch the requested data 64862306a36Sopenharmony_ciand write it to the cache file identified by object_id. 64962306a36Sopenharmony_ci 65062306a36Sopenharmony_ciWhen it has finished processing the READ request, the user daemon should reply 65162306a36Sopenharmony_ciby using the CACHEFILES_IOC_READ_COMPLETE ioctl on one of the anonymous fds 65262306a36Sopenharmony_ciassociated with the object_id given in the READ request. The ioctl is of the 65362306a36Sopenharmony_ciform:: 65462306a36Sopenharmony_ci 65562306a36Sopenharmony_ci ioctl(fd, CACHEFILES_IOC_READ_COMPLETE, msg_id); 65662306a36Sopenharmony_ci 65762306a36Sopenharmony_ciwhere: 65862306a36Sopenharmony_ci 65962306a36Sopenharmony_ci * ``fd`` is one of the anonymous fds associated with the object_id 66062306a36Sopenharmony_ci given. 66162306a36Sopenharmony_ci 66262306a36Sopenharmony_ci * ``msg_id`` must match the msg_id field of the READ request. 663