2
* evaluate.c - very high-level API to evaluate LABELs or UUIDs
4
* Copyright (C) 2009 Karel Zak <kzak@redhat.com>
6
* This file may be redistributed under the terms of the
7
* GNU Lesser General Public License.
15
#include <sys/types.h>
16
#ifdef HAVE_SYS_STAT_H
25
#include "pathnames.h"
26
#include "canonicalize.h"
32
* @title: Tags evaluation
33
* @short_description: top-level API for LABEL and UUID evaluation.
35
* This API provides very simple and portable way how evaluate LABEL and UUID
36
* tags. The blkid_evaluate_tag() works on 2.4 and 2.6 systems and on systems
37
* with or without udev. Currently, the libblkid library supports "udev" and
38
* "scan" methods. The "udev" method uses udev /dev/disk/by-* symlinks and the
39
* "scan" method scans all block devices from the /proc/partitions file. The
40
* evaluation could be controlled by the /etc/blkid.conf config file. The
41
* default is to try "udev" and then "scan" method.
43
* The blkid_evaluate_tag() also automatically informs udevd when an obsolete
44
* /dev/disk/by-* symlink is detected.
46
* If you are not sure how translate LABEL or UUID to the device name use this
50
/* returns zero when the device has NAME=value (LABEL/UUID) */
51
static int verify_tag(const char *devname, const char *name, const char *value)
59
pr = blkid_new_probe();
63
blkid_probe_enable_superblocks(pr, TRUE);
64
blkid_probe_set_superblocks_flags(pr,
65
BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID);
67
fd = open(devname, O_RDONLY);
72
if (blkid_probe_set_device(pr, fd, 0, 0))
74
rc = blkid_do_safeprobe(pr);
77
rc = blkid_probe_lookup_value(pr, name, &data, &len);
79
rc = memcmp(value, data, len);
81
DBG(DEBUG_EVALUATE, printf("%s: %s verification %s\n",
82
devname, name, rc == 0 ? "PASS" : "FAILED"));
87
/* for non-root users we use unverified udev links */
88
return errsv == EACCES ? 0 : rc;
93
* @devname: absolute path to the device
95
* Returns: -1 in case of failure, or 0 on success.
97
int blkid_send_uevent(const char *devname, const char *action)
99
char uevent[PATH_MAX];
104
DBG(DEBUG_EVALUATE, printf("%s: uevent '%s' requested\n", devname, action));
106
if (!devname || !action)
108
if (stat(devname, &st) || !S_ISBLK(st.st_mode))
111
snprintf(uevent, sizeof(uevent), "/sys/dev/block/%d:%d/uevent",
112
major(st.st_rdev), minor(st.st_rdev));
114
f = fopen(uevent, "w");
117
if (fputs(action, f) >= 0)
121
DBG(DEBUG_EVALUATE, printf("%s: send uevent %s\n",
122
uevent, rc == 0 ? "SUCCES" : "FAILED"));
126
static char *evaluate_by_udev(const char *token, const char *value, int uevent)
134
printf("evaluating by udev %s=%s\n", token, value));
136
if (!strcmp(token, "UUID"))
137
strcpy(dev, _PATH_DEV_BYUUID "/");
138
else if (!strcmp(token, "LABEL"))
139
strcpy(dev, _PATH_DEV_BYLABEL "/");
142
printf("unsupported token %s\n", token));
143
return NULL; /* unsupported tag */
147
if (blkid_encode_string(value, &dev[len], sizeof(dev) - len) != 0)
151
printf("expected udev link: %s\n", dev));
154
goto failed; /* link or device does not exist */
156
if (!S_ISBLK(st.st_mode))
159
path = canonicalize_path(dev);
163
if (verify_tag(path, token, value))
168
DBG(DEBUG_EVALUATE, printf("failed to evaluate by udev\n"));
171
blkid_send_uevent(path, "change");
176
static char *evaluate_by_scan(const char *token, const char *value,
177
blkid_cache *cache, struct blkid_config *conf)
179
blkid_cache c = cache ? *cache : NULL;
183
printf("evaluating by blkid scan %s=%s\n", token, value));
186
char *cachefile = blkid_get_cache_filename(conf);
187
blkid_get_cache(&c, cachefile);
193
res = blkid_get_devname(c, token, value);
204
* blkid_evaluate_tag:
205
* @token: token name (e.g "LABEL" or "UUID")
207
* @cache: pointer to cache (or NULL when you don't want to re-use the cache)
209
* Returns: allocated string with a device name.
211
char *blkid_evaluate_tag(const char *token, const char *value, blkid_cache *cache)
213
struct blkid_config *conf = NULL;
214
char *t = NULL, *v = NULL;
221
if (!cache || !*cache)
225
printf("evaluating %s%s%s\n", token, value ? "=" : "",
226
value ? value : ""));
229
if (!strchr(token, '=')) {
230
ret = blkid_strdup(token);
233
blkid_parse_tag_string(token, &t, &v);
240
conf = blkid_read_config(NULL);
244
for (i = 0; i < conf->nevals; i++) {
245
if (conf->eval[i] == BLKID_EVAL_UDEV)
246
ret = evaluate_by_udev(token, value, conf->uevent);
247
else if (conf->eval[i] == BLKID_EVAL_SCAN)
248
ret = evaluate_by_scan(token, value, cache, conf);
254
printf("%s=%s evaluated as %s\n", token, value, ret));
256
blkid_free_config(conf);
263
int main(int argc, char *argv[])
265
blkid_cache cache = NULL;
269
fprintf(stderr, "usage: %s <token> <value>\n", argv[0]);
275
res = blkid_evaluate_tag(argv[1], argv[2], &cache);
279
blkid_put_cache(cache);
281
return res ? EXIT_SUCCESS : EXIT_FAILURE;