]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - libblkid/src/cache.c
a60495aa50e3053f6147419cdc7f39177261419f
2 * cache.c - allocation/initialization/free routines for cache
4 * Copyright (C) 2001 Andreas Dilger
5 * Copyright (C) 2003 Theodore Ts'o
8 * This file may be redistributed under the terms of the
9 * GNU Lesser General Public License.
21 #ifdef HAVE_SYS_STAT_H
27 int blkid_debug_mask
= 0;
32 * @short_description: basic routines to work with libblkid cache
34 * Block device information is normally kept in a cache file blkid.tab and is
35 * verified to still be valid before being returned to the user (if the user has
36 * read permission on the raw block device, otherwise not). The cache file also
37 * allows unprivileged users (normally anyone other than root, or those not in the
38 * "disk" group) to locate devices by label/id. The standard location of the
39 * cache file can be overridden by the environment variable BLKID_FILE.
41 * In situations where one is getting information about a single known device, it
42 * does not impact performance whether the cache is used or not (unless you are
43 * not able to read the block device directly). If you are dealing with multiple
44 * devices, use of the cache is highly recommended (even if empty) as devices will
45 * be scanned at most one time and the on-disk cache will be updated if possible.
46 * There is rarely a reason not to use the cache.
48 * In some cases (modular kernels), block devices are not even visible until after
49 * they are accessed the first time, so it is critical that there is some way to
50 * locate these devices without enumerating only visible devices, so the use of
51 * the cache file is required in this situation.
54 #if 0 /* ifdef CONFIG_BLKID_DEBUG */
55 static blkid_debug_dump_cache(int mask
, blkid_cache cache
)
60 printf("cache: NULL\n");
64 printf("cache: time = %lu\n", cache
->bic_time
);
65 printf("cache: flags = 0x%08X\n", cache
->bic_flags
);
67 list_for_each(p
, &cache
->bic_devs
) {
68 blkid_dev dev
= list_entry(p
, struct blkid_struct_dev
, bid_devs
);
69 blkid_debug_dump_dev(dev
);
74 #ifdef CONFIG_BLKID_DEBUG
75 void blkid_init_debug(int mask
)
77 if (blkid_debug_mask
& DEBUG_INIT
)
82 char *dstr
= getenv("LIBBLKID_DEBUG");
85 dstr
= getenv("BLKID_DEBUG"); /* for backward compatibility */
87 blkid_debug_mask
= strtoul(dstr
, 0, 0);
89 blkid_debug_mask
= mask
;
92 printf("libblkid: debug mask set to 0x%04x.\n", blkid_debug_mask
);
94 blkid_debug_mask
|= DEBUG_INIT
;
98 static const char *get_default_cache_filename(void)
102 if (stat(BLKID_RUNTIME_TOPDIR
, &st
) == 0 && S_ISDIR(st
.st_mode
))
103 return BLKID_CACHE_FILE
; /* cache in /run */
105 return BLKID_CACHE_FILE_OLD
; /* cache in /etc */
108 /* returns allocated path to cache */
109 char *blkid_get_cache_filename(struct blkid_config
*conf
)
113 filename
= safe_getenv("BLKID_FILE");
115 filename
= blkid_strdup(filename
);
117 filename
= blkid_strdup(conf
->cachefile
);
119 struct blkid_config
*c
= blkid_read_config(NULL
);
121 filename
= blkid_strdup(get_default_cache_filename());
123 filename
= c
->cachefile
; /* already allocated */
125 blkid_free_config(c
);
133 * @cache: pointer to return cache handler
134 * @filename: path to the cache file or NULL for the default path
136 * Allocates and initialize librray cache handler.
138 * Returns: 0 on success or number less than zero in case of error.
140 int blkid_get_cache(blkid_cache
*ret_cache
, const char *filename
)
146 DBG(DEBUG_CACHE
, printf("creating blkid cache (using %s)\n",
147 filename
? filename
: "default cache"));
149 if (!(cache
= (blkid_cache
) calloc(1, sizeof(struct blkid_struct_cache
))))
150 return -BLKID_ERR_MEM
;
152 INIT_LIST_HEAD(&cache
->bic_devs
);
153 INIT_LIST_HEAD(&cache
->bic_tags
);
155 if (filename
&& !*filename
)
158 cache
->bic_filename
= blkid_strdup(filename
);
160 cache
->bic_filename
= blkid_get_cache_filename(NULL
);
162 blkid_read_cache(cache
);
169 * @cache: cache handler
171 * Saves changes to cache file.
173 void blkid_put_cache(blkid_cache cache
)
178 (void) blkid_flush_cache(cache
);
180 DBG(DEBUG_CACHE
, printf("freeing cache struct\n"));
182 /* DBG(DEBUG_CACHE, blkid_debug_dump_cache(cache)); */
184 while (!list_empty(&cache
->bic_devs
)) {
185 blkid_dev dev
= list_entry(cache
->bic_devs
.next
,
186 struct blkid_struct_dev
,
191 while (!list_empty(&cache
->bic_tags
)) {
192 blkid_tag tag
= list_entry(cache
->bic_tags
.next
,
193 struct blkid_struct_tag
,
196 while (!list_empty(&tag
->bit_names
)) {
197 blkid_tag bad
= list_entry(tag
->bit_names
.next
,
198 struct blkid_struct_tag
,
201 DBG(DEBUG_CACHE
, printf("warning: unfreed tag %s=%s\n",
202 bad
->bit_name
, bad
->bit_val
));
208 blkid_free_probe(cache
->probe
);
210 free(cache
->bic_filename
);
216 * @cache: cache handler
218 * Removes garbage (non-existing devices) from the cache.
220 void blkid_gc_cache(blkid_cache cache
)
222 struct list_head
*p
, *pnext
;
228 list_for_each_safe(p
, pnext
, &cache
->bic_devs
) {
229 blkid_dev dev
= list_entry(p
, struct blkid_struct_dev
, bid_devs
);
230 if (stat(dev
->bid_name
, &st
) < 0) {
232 printf("freeing %s\n", dev
->bid_name
));
234 cache
->bic_flags
|= BLKID_BIC_FL_CHANGED
;
237 printf("Device %s exists\n", dev
->bid_name
));
243 int main(int argc
, char** argv
)
245 blkid_cache cache
= NULL
;
248 blkid_init_debug(DEBUG_ALL
);
251 fprintf(stderr
, "Usage: %s [filename] \n", argv
[0]);
255 if ((ret
= blkid_get_cache(&cache
, argv
[1])) < 0) {
256 fprintf(stderr
, "error %d parsing cache file %s\n", ret
,
257 argv
[1] ? argv
[1] : blkid_get_cache_filename(NULL
));
260 if ((ret
= blkid_get_cache(&cache
, "/dev/null")) != 0) {
261 fprintf(stderr
, "%s: error creating cache (%d)\n",
265 if ((ret
= blkid_probe_all(cache
)) < 0)
266 fprintf(stderr
, "error probing devices\n");
268 blkid_put_cache(cache
);