]> git.ipfire.org Git - thirdparty/util-linux.git/blame - libblkid/src/cache.c
misc: Fix various typos
[thirdparty/util-linux.git] / libblkid / src / cache.c
CommitLineData
a0948ffe
KZ
1/*
2 * cache.c - allocation/initialization/free routines for cache
3 *
4 * Copyright (C) 2001 Andreas Dilger
5 * Copyright (C) 2003 Theodore Ts'o
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the
9 * GNU Lesser General Public License.
10 * %End-Header%
11 */
12
fbc333fe 13#ifdef HAVE_UNISTD_H
a0948ffe
KZ
14#include <unistd.h>
15#endif
16#ifdef HAVE_ERRNO_H
17#include <errno.h>
18#endif
19#include <stdlib.h>
20#include <string.h>
a0948ffe
KZ
21#ifdef HAVE_SYS_STAT_H
22#include <sys/stat.h>
23#endif
24#include "blkidP.h"
035507c8 25#include "env.h"
a0948ffe 26
488e52be
KZ
27/**
28 * SECTION:cache
29 * @title: Cache
30 * @short_description: basic routines to work with libblkid cache
31 *
b82590ad 32 * Block device information is normally kept in a cache file blkid.tab and is
488e52be
KZ
33 * verified to still be valid before being returned to the user (if the user has
34 * read permission on the raw block device, otherwise not). The cache file also
35 * allows unprivileged users (normally anyone other than root, or those not in the
36 * "disk" group) to locate devices by label/id. The standard location of the
37 * cache file can be overridden by the environment variable BLKID_FILE.
38 *
39 * In situations where one is getting information about a single known device, it
40 * does not impact performance whether the cache is used or not (unless you are
41 * not able to read the block device directly). If you are dealing with multiple
42 * devices, use of the cache is highly recommended (even if empty) as devices will
43 * be scanned at most one time and the on-disk cache will be updated if possible.
44 * There is rarely a reason not to use the cache.
45 *
46 * In some cases (modular kernels), block devices are not even visible until after
47 * they are accessed the first time, so it is critical that there is some way to
48 * locate these devices without enumerating only visible devices, so the use of
49 * the cache file is required in this situation.
50 */
b82590ad
KZ
51static const char *get_default_cache_filename(void)
52{
53 struct stat st;
54
55 if (stat(BLKID_RUNTIME_TOPDIR, &st) == 0 && S_ISDIR(st.st_mode))
56 return BLKID_CACHE_FILE; /* cache in /run */
57
58 return BLKID_CACHE_FILE_OLD; /* cache in /etc */
59}
60
bb5f2876
KZ
61/* returns allocated path to cache */
62char *blkid_get_cache_filename(struct blkid_config *conf)
63{
64 char *filename;
65
035507c8 66 filename = safe_getenv("BLKID_FILE");
bb5f2876 67 if (filename)
e0a9b8cf 68 filename = strdup(filename);
bb5f2876 69 else if (conf)
e0a9b8cf 70 filename = conf->cachefile ? strdup(conf->cachefile) : NULL;
bb5f2876
KZ
71 else {
72 struct blkid_config *c = blkid_read_config(NULL);
73 if (!c)
e0a9b8cf 74 filename = strdup(get_default_cache_filename());
30fce928
KZ
75 else {
76 filename = c->cachefile; /* already allocated */
77 c->cachefile = NULL;
78 blkid_free_config(c);
79 }
bb5f2876
KZ
80 }
81 return filename;
82}
83
488e52be
KZ
84/**
85 * blkid_get_cache:
86 * @cache: pointer to return cache handler
87 * @filename: path to the cache file or NULL for the default path
88 *
9e930041 89 * Allocates and initialize library cache handler.
488e52be
KZ
90 *
91 * Returns: 0 on success or number less than zero in case of error.
92 */
6644688a
KZ
93int blkid_get_cache(blkid_cache *ret_cache, const char *filename)
94{
95 blkid_cache cache;
96
e3436956
KZ
97 if (!ret_cache)
98 return -BLKID_ERR_PARAM;
99
7a458332 100 blkid_init_debug(0);
6644688a 101
fea1cbf7 102 if (!(cache = calloc(1, sizeof(struct blkid_struct_cache))))
a0948ffe
KZ
103 return -BLKID_ERR_MEM;
104
14308bc3 105 DBG(CACHE, ul_debugobj(cache, "alloc (from %s)", filename ? filename : "default cache"));
a0948ffe
KZ
106 INIT_LIST_HEAD(&cache->bic_devs);
107 INIT_LIST_HEAD(&cache->bic_tags);
108
568871ae
KZ
109 if (filename && !*filename)
110 filename = NULL;
568871ae 111 if (filename)
e0a9b8cf 112 cache->bic_filename = strdup(filename);
bb5f2876
KZ
113 else
114 cache->bic_filename = blkid_get_cache_filename(NULL);
a0948ffe
KZ
115
116 blkid_read_cache(cache);
a0948ffe
KZ
117 *ret_cache = cache;
118 return 0;
119}
120
488e52be
KZ
121/**
122 * blkid_put_cache:
123 * @cache: cache handler
124 *
125 * Saves changes to cache file.
126 */
a0948ffe
KZ
127void blkid_put_cache(blkid_cache cache)
128{
129 if (!cache)
130 return;
131
132 (void) blkid_flush_cache(cache);
133
14308bc3 134 DBG(CACHE, ul_debugobj(cache, "freeing cache struct"));
a0948ffe 135
c62a6311 136 /* DBG(CACHE, ul_debug_dump_cache(cache)); */
a0948ffe
KZ
137
138 while (!list_empty(&cache->bic_devs)) {
139 blkid_dev dev = list_entry(cache->bic_devs.next,
140 struct blkid_struct_dev,
141 bid_devs);
142 blkid_free_dev(dev);
143 }
144
14308bc3 145 DBG(CACHE, ul_debugobj(cache, "freeing cache tag heads"));
a0948ffe
KZ
146 while (!list_empty(&cache->bic_tags)) {
147 blkid_tag tag = list_entry(cache->bic_tags.next,
148 struct blkid_struct_tag,
149 bit_tags);
150
151 while (!list_empty(&tag->bit_names)) {
152 blkid_tag bad = list_entry(tag->bit_names.next,
153 struct blkid_struct_tag,
154 bit_names);
155
14308bc3 156 DBG(CACHE, ul_debugobj(cache, "warning: unfreed tag %s=%s",
a0948ffe
KZ
157 bad->bit_name, bad->bit_val));
158 blkid_free_tag(bad);
159 }
160 blkid_free_tag(tag);
161 }
a0948ffe 162
ebeafc50
KZ
163 blkid_free_probe(cache->probe);
164
165 free(cache->bic_filename);
a0948ffe
KZ
166 free(cache);
167}
168
488e52be
KZ
169/**
170 * blkid_gc_cache:
171 * @cache: cache handler
172 *
173 * Removes garbage (non-existing devices) from the cache.
174 */
a0948ffe
KZ
175void blkid_gc_cache(blkid_cache cache)
176{
177 struct list_head *p, *pnext;
178 struct stat st;
179
180 if (!cache)
181 return;
182
183 list_for_each_safe(p, pnext, &cache->bic_devs) {
184 blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs);
a0948ffe 185 if (stat(dev->bid_name, &st) < 0) {
14308bc3 186 DBG(CACHE, ul_debugobj(cache, "freeing non-exiting %s", dev->bid_name));
a0948ffe
KZ
187 blkid_free_dev(dev);
188 cache->bic_flags |= BLKID_BIC_FL_CHANGED;
189 } else {
c62a6311 190 DBG(CACHE, ul_debug("Device %s exists", dev->bid_name));
a0948ffe
KZ
191 }
192 }
193}
194
a0948ffe
KZ
195#ifdef TEST_PROGRAM
196int main(int argc, char** argv)
197{
198 blkid_cache cache = NULL;
199 int ret;
200
0540ea54 201 blkid_init_debug(BLKID_DEBUG_ALL);
6644688a 202
a0948ffe
KZ
203 if ((argc > 2)) {
204 fprintf(stderr, "Usage: %s [filename] \n", argv[0]);
205 exit(1);
206 }
207
208 if ((ret = blkid_get_cache(&cache, argv[1])) < 0) {
209 fprintf(stderr, "error %d parsing cache file %s\n", ret,
b82590ad 210 argv[1] ? argv[1] : blkid_get_cache_filename(NULL));
a0948ffe
KZ
211 exit(1);
212 }
213 if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) {
214 fprintf(stderr, "%s: error creating cache (%d)\n",
215 argv[0], ret);
216 exit(1);
217 }
07023b07 218 if ((ret = blkid_probe_all(cache)) < 0)
a0948ffe
KZ
219 fprintf(stderr, "error probing devices\n");
220
221 blkid_put_cache(cache);
222
223 return ret;
224}
225#endif