]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - libblkid/src/evaluate.c
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") or unparsed tag (e.g. "LABEL=foo")
206 * @value: token data (e.g. "foo")
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 * blkid_evaluate_spec:
264 * @spec: unparsed tag (e.g. "LABEL=foo") or path (e.g. /dev/dm-0)
265 * @cache: pointer to cache (or NULL when you don't want to re-use the cache)
267 * All returned paths are canonicalized, device-mapper paths are converted
268 * to the /dev/mapper/<name> format.
270 * Returns: allocated string with a device name.
272 char *blkid_evaluate_spec(const char *spec
, blkid_cache
*cache
)
274 char *t
= NULL
, *v
= NULL
, *res
;
279 if (strchr(spec
, '=') &&
280 blkid_parse_tag_string(spec
, &t
, &v
) != 0) /* parse error */
284 res
= blkid_evaluate_tag(t
, v
, cache
);
286 res
= canonicalize_path(spec
);
295 int main(int argc
, char *argv
[])
297 blkid_cache cache
= NULL
;
301 fprintf(stderr
, "usage: %s <tag> | <spec>\n", argv
[0]);
307 res
= blkid_evaluate_spec(argv
[1], &cache
);
311 blkid_put_cache(cache
);
313 return res
? EXIT_SUCCESS
: EXIT_FAILURE
;