prepare builtins for blkid and kmod
This commit is contained in:
+15
-4
@@ -203,7 +203,7 @@ bin_PROGRAMS = \
|
||||
libexec_PROGRAMS = \
|
||||
udev/udevd
|
||||
|
||||
udev_common_sources =\
|
||||
udev_common_sources = \
|
||||
udev/udev.h \
|
||||
udev/udev-event.c \
|
||||
udev/udev-watch.c \
|
||||
@@ -213,14 +213,24 @@ udev_common_sources =\
|
||||
udev/udev-builtin.c \
|
||||
udev/udev-builtin-path_id.c \
|
||||
udev/udev-builtin-usb_id.c \
|
||||
udev/udev-builtin-input_id.c
|
||||
udev/udev-builtin-input_id.c \
|
||||
udev/udev-builtin-blkid.c \
|
||||
udev/udev-builtin-kmod.c
|
||||
|
||||
udev_common_CFLAGS = \
|
||||
$(BLKID_CFLAGS)
|
||||
|
||||
udev_common_LDADD = \
|
||||
libudev/libudev-private.la \
|
||||
$(BLKID_LIBS)
|
||||
|
||||
udev_udevd_SOURCES = \
|
||||
$(udev_common_sources) \
|
||||
udev/udevd.c \
|
||||
udev/sd-daemon.h \
|
||||
udev/sd-daemon.c
|
||||
udev_udevd_LDADD = libudev/libudev-private.la
|
||||
udev_udevd_CFLAGS = $(udev_common_CFLAGS)
|
||||
udev_udevd_LDADD = $(udev_common_LDADD)
|
||||
|
||||
udev_udevadm_SOURCES = \
|
||||
$(udev_common_sources) \
|
||||
@@ -232,7 +242,8 @@ udev_udevadm_SOURCES = \
|
||||
udev/udevadm-trigger.c \
|
||||
udev/udevadm-test.c \
|
||||
udev/udevadm-test-builtin.c
|
||||
udev_udevadm_LDADD = libudev/libudev-private.la
|
||||
udev_udevadm_CFLAGS = $(udev_common_CFLAGS)
|
||||
udev_udevadm_LDADD = $(udev_common_LDADD)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# udev man pages
|
||||
|
||||
@@ -73,6 +73,8 @@ AC_ARG_WITH([systemdsystemunitdir],
|
||||
AS_IF([test "x$with_systemdsystemunitdir" != "xno"], [ AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir]) ])
|
||||
AM_CONDITIONAL(WITH_SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != "xno" ])
|
||||
|
||||
PKG_CHECK_MODULES(BLKID, blkid >= 2.20)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# GUdev - libudev gobject interface
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* probe disks for filesystems and partitions
|
||||
*
|
||||
* Copyright (C) 2011 Kay Sievers <kay.sievers@vrfy.org>
|
||||
* Copyright (C) 2011 Karel Zak <kzak@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <blkid/blkid.h>
|
||||
|
||||
#include "udev.h"
|
||||
|
||||
static void print_property(const char *name, const char *value)
|
||||
{
|
||||
char enc[265], safe[256];
|
||||
size_t namelen = strlen(name);
|
||||
|
||||
enc[0] = '\0';
|
||||
safe[0] = '\0';
|
||||
|
||||
if (!strcmp(name, "TYPE") || !strcmp(name, "VERSION")) {
|
||||
blkid_encode_string(value, enc, sizeof(enc));
|
||||
printf("ID_FS_%s=%s\n", name, enc);
|
||||
|
||||
} else if (!strcmp(name, "UUID") ||
|
||||
!strcmp(name, "LABEL") ||
|
||||
!strcmp(name, "UUID_SUB")) {
|
||||
|
||||
blkid_safe_string(value, safe, sizeof(safe));
|
||||
printf("ID_FS_%s=%s\n", name, safe);
|
||||
|
||||
blkid_encode_string(value, enc, sizeof(enc));
|
||||
printf("ID_FS_%s_ENC=%s\n", name, enc);
|
||||
|
||||
} else if (!strcmp(name, "PTTYPE")) {
|
||||
printf("ID_PART_TABLE_TYPE=%s\n", value);
|
||||
|
||||
} else if (!strcmp(name, "PART_ENTRY_NAME") ||
|
||||
!strcmp(name, "PART_ENTRY_TYPE")) {
|
||||
|
||||
blkid_encode_string(value, enc, sizeof(enc));
|
||||
printf("ID_%s=%s\n", name, enc);
|
||||
|
||||
} else if (!strncmp(name, "PART_ENTRY_", 11))
|
||||
printf("ID_%s=%s\n", name, value);
|
||||
|
||||
else if (namelen >= 15 && (
|
||||
!strcmp(name + (namelen - 12), "_SECTOR_SIZE") ||
|
||||
!strcmp(name + (namelen - 8), "_IO_SIZE") ||
|
||||
!strcmp(name, "ALIGNMENT_OFFSET")))
|
||||
printf("ID_IOLIMIT_%s=%s\n", name, value);
|
||||
else
|
||||
printf("ID_FS_%s=%s\n", name, value);
|
||||
}
|
||||
|
||||
static int probe_superblocks(blkid_probe pr)
|
||||
{
|
||||
struct stat st;
|
||||
int rc;
|
||||
|
||||
if (fstat(blkid_probe_get_fd(pr), &st))
|
||||
return -1;
|
||||
|
||||
blkid_probe_enable_partitions(pr, 1);
|
||||
|
||||
if (!S_ISCHR(st.st_mode) && blkid_probe_get_size(pr) <= 1024 * 1440 &&
|
||||
blkid_probe_is_wholedisk(pr)) {
|
||||
/*
|
||||
* check if the small disk is partitioned, if yes then
|
||||
* don't probe for filesystems.
|
||||
*/
|
||||
blkid_probe_enable_superblocks(pr, 0);
|
||||
|
||||
rc = blkid_do_fullprobe(pr);
|
||||
if (rc < 0)
|
||||
return rc; /* -1 = error, 1 = nothing, 0 = succes */
|
||||
|
||||
if (blkid_probe_lookup_value(pr, "PTTYPE", NULL, NULL) == 0)
|
||||
return 0; /* partition table detected */
|
||||
}
|
||||
|
||||
blkid_probe_set_partitions_flags(pr, BLKID_PARTS_ENTRY_DETAILS);
|
||||
blkid_probe_enable_superblocks(pr, 1);
|
||||
|
||||
return blkid_do_safeprobe(pr);
|
||||
}
|
||||
|
||||
static int builtin_blkid(struct udev_device *dev, const char *command, bool test)
|
||||
{
|
||||
char *device = "/dev/sda3";
|
||||
int64_t offset = 0;
|
||||
//int noraid = 0;
|
||||
int fd = -1;
|
||||
blkid_probe pr;
|
||||
const char *data;
|
||||
const char *name;
|
||||
int nvals;
|
||||
int i;
|
||||
size_t len;
|
||||
int err = 0;
|
||||
|
||||
//FIXME: read offset, read noraid
|
||||
|
||||
pr = blkid_new_probe();
|
||||
if (!pr) {
|
||||
err = -ENOMEM;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
blkid_probe_set_superblocks_flags(pr,
|
||||
BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID |
|
||||
BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE |
|
||||
BLKID_SUBLKS_USAGE | BLKID_SUBLKS_VERSION);
|
||||
|
||||
fd = open(device, O_RDONLY|O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "error: %s: %m\n", device);
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = blkid_probe_set_device(pr, fd, offset, 0);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
|
||||
err = probe_superblocks(pr);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
|
||||
nvals = blkid_probe_numof_values(pr);
|
||||
for (i = 0; i < nvals; i++) {
|
||||
if (blkid_probe_get_value(pr, i, &name, &data, &len))
|
||||
continue;
|
||||
len = strnlen((char *) data, len);
|
||||
print_property(name, (char *) data);
|
||||
}
|
||||
|
||||
blkid_free_probe(pr);
|
||||
out:
|
||||
if (fd > 0)
|
||||
close(fd);
|
||||
if (err < 0)
|
||||
return EXIT_FAILURE;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
const struct udev_builtin udev_builtin_blkid = {
|
||||
.name = "blkid",
|
||||
.cmd = builtin_blkid,
|
||||
.help = "filesystem and partition probing",
|
||||
.run_once = false,
|
||||
};
|
||||
@@ -181,7 +181,7 @@ static void test_key (struct udev_device *dev,
|
||||
udev_builtin_add_property(dev, test, "ID_INPUT_KEYBOARD", "1");
|
||||
}
|
||||
|
||||
static int builtin_input_id(struct udev_device *dev, bool test)
|
||||
static int builtin_input_id(struct udev_device *dev, const char *command, bool test)
|
||||
{
|
||||
struct udev_device *pdev;
|
||||
unsigned long bitmask_ev[NBITS(EV_MAX)];
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* probe disks for filesystems and partitions
|
||||
*
|
||||
* Copyright (C) 2011 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "udev.h"
|
||||
|
||||
static int builtin_kmod(struct udev_device *dev, const char *command, bool test)
|
||||
{
|
||||
printf("soon we load a module here: '%s'\n", command);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
const struct udev_builtin udev_builtin_kmod = {
|
||||
.name = "kmod",
|
||||
.cmd = builtin_kmod,
|
||||
.help = "kernel module loader",
|
||||
.run_once = false,
|
||||
};
|
||||
@@ -390,7 +390,7 @@ out:
|
||||
return parent;
|
||||
}
|
||||
|
||||
static int builtin_path_id(struct udev_device *dev, bool test)
|
||||
static int builtin_path_id(struct udev_device *dev, const char *command, bool test)
|
||||
{
|
||||
struct udev_device *parent;
|
||||
char *path = NULL;
|
||||
@@ -483,4 +483,5 @@ const struct udev_builtin udev_builtin_path_id = {
|
||||
.name = "path_id",
|
||||
.cmd = builtin_path_id,
|
||||
.help = "compose persistent device path",
|
||||
.run_once = true,
|
||||
};
|
||||
|
||||
@@ -239,7 +239,7 @@ out:
|
||||
* 6.) If the device supplies a serial number, this number
|
||||
* is concatenated with the identification with an underscore '_'.
|
||||
*/
|
||||
static int builtin_usb_id(struct udev_device *dev, bool test)
|
||||
static int builtin_usb_id(struct udev_device *dev, const char *command, bool test)
|
||||
{
|
||||
char vendor_str[64];
|
||||
char vendor_str_enc[256];
|
||||
@@ -478,4 +478,5 @@ const struct udev_builtin udev_builtin_usb_id = {
|
||||
.name = "usb_id",
|
||||
.cmd = builtin_usb_id,
|
||||
.help = "usb device properties",
|
||||
.run_once = true,
|
||||
};
|
||||
|
||||
+17
-4
@@ -29,6 +29,8 @@ static const struct udev_builtin *builtins[] = {
|
||||
[UDEV_BUILTIN_PATH_ID] = &udev_builtin_path_id,
|
||||
[UDEV_BUILTIN_USB_ID] = &udev_builtin_usb_id,
|
||||
[UDEV_BUILTIN_INPUT_ID] = &udev_builtin_input_id,
|
||||
[UDEV_BUILTIN_BLKID] = &udev_builtin_blkid,
|
||||
[UDEV_BUILTIN_KMOD] = &udev_builtin_kmod,
|
||||
};
|
||||
|
||||
int udev_builtin_list(struct udev *udev)
|
||||
@@ -45,19 +47,30 @@ const char *udev_builtin_name(enum udev_builtin_cmd cmd)
|
||||
return builtins[cmd]->name;
|
||||
}
|
||||
|
||||
enum udev_builtin_cmd udev_builtin_lookup(const char *name)
|
||||
bool udev_builtin_run_once(enum udev_builtin_cmd cmd)
|
||||
{
|
||||
enum udev_builtin_cmd i;
|
||||
return builtins[cmd]->run_once;
|
||||
}
|
||||
|
||||
enum udev_builtin_cmd udev_builtin_lookup(const char *command)
|
||||
{
|
||||
char name[UTIL_PATH_SIZE];
|
||||
enum udev_builtin_cmd i;
|
||||
char *pos;
|
||||
|
||||
util_strscpy(name, sizeof(name), command);
|
||||
pos = strchr(name, ' ');
|
||||
if (pos)
|
||||
pos[0] = '\0';
|
||||
for (i = 0; i < ARRAY_SIZE(builtins); i++)
|
||||
if (strcmp(builtins[i]->name, name) == 0)
|
||||
return i;
|
||||
return UDEV_BUILTIN_MAX;
|
||||
}
|
||||
|
||||
int udev_builtin_run(struct udev_device *dev, enum udev_builtin_cmd cmd, bool test)
|
||||
int udev_builtin_run(struct udev_device *dev, enum udev_builtin_cmd cmd, const char *command, bool test)
|
||||
{
|
||||
return builtins[cmd]->cmd(dev, test);
|
||||
return builtins[cmd]->cmd(dev, command, test);
|
||||
}
|
||||
|
||||
int udev_builtin_add_property(struct udev_device *dev, bool test, const char *key, const char *val, ...)
|
||||
|
||||
+24
-24
@@ -364,7 +364,7 @@ static void dump_token(struct udev_rules *rules, struct token *token)
|
||||
token_str(type), operation_str(op), value, string_glob_str(glob));
|
||||
break;
|
||||
case TK_M_IMPORT_BUILTIN:
|
||||
dbg(rules->udev, "%s %i\n", token_str(type), token->key.builtin_cmd);
|
||||
dbg(rules->udev, "%s %i '%s'\n", token_str(type), token->key.builtin_cmd, value);
|
||||
break;
|
||||
case TK_M_ATTR:
|
||||
case TK_M_ATTRS:
|
||||
@@ -1039,6 +1039,7 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
|
||||
token->key.value_off = add_string(rule_tmp->rules, value);
|
||||
break;
|
||||
case TK_M_IMPORT_BUILTIN:
|
||||
token->key.value_off = add_string(rule_tmp->rules, value);
|
||||
token->key.builtin_cmd = *(enum udev_builtin_cmd *)data;
|
||||
break;
|
||||
case TK_M_ENV:
|
||||
@@ -1396,18 +1397,13 @@ static int add_rule(struct udev_rules *rules, char *line,
|
||||
if (strstr(attr, "program")) {
|
||||
/* find known built-in command */
|
||||
if (value[0] != '/') {
|
||||
char file[UTIL_PATH_SIZE];
|
||||
char *pos;
|
||||
enum udev_builtin_cmd cmd;
|
||||
|
||||
util_strscpy(file, sizeof(file), value);
|
||||
pos = strchr(file, ' ');
|
||||
if (pos)
|
||||
pos[0] = '\0';
|
||||
cmd = udev_builtin_lookup(file);
|
||||
cmd = udev_builtin_lookup(value);
|
||||
if (cmd < UDEV_BUILTIN_MAX) {
|
||||
info(rules->udev, "IMPORT found builtin '%s', replacing %s:%u\n", file, filename, lineno);
|
||||
rule_add_key(&rule_tmp, TK_M_IMPORT_BUILTIN, op, NULL, &cmd);
|
||||
info(rules->udev, "IMPORT found builtin '%s', replacing %s:%u\n",
|
||||
value, filename, lineno);
|
||||
rule_add_key(&rule_tmp, TK_M_IMPORT_BUILTIN, op, value, &cmd);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -1418,7 +1414,7 @@ static int add_rule(struct udev_rules *rules, char *line,
|
||||
|
||||
dbg(rules->udev, "IMPORT execute builtin\n");
|
||||
if (cmd < UDEV_BUILTIN_MAX)
|
||||
rule_add_key(&rule_tmp, TK_M_IMPORT_BUILTIN, op, NULL, &cmd);
|
||||
rule_add_key(&rule_tmp, TK_M_IMPORT_BUILTIN, op, value, &cmd);
|
||||
else
|
||||
err(rules->udev, "IMPORT{builtin}: '%s' unknown %s:%u\n", value, filename, lineno);
|
||||
} else if (strstr(attr, "file")) {
|
||||
@@ -2308,25 +2304,29 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
|
||||
break;
|
||||
}
|
||||
case TK_M_IMPORT_BUILTIN: {
|
||||
/* check if we ran already */
|
||||
if (event->builtin_run & (1 << cur->key.builtin_cmd)) {
|
||||
info(event->udev, "IMPORT builtin skip '%s' %s:%u\n",
|
||||
udev_builtin_name(cur->key.builtin_cmd),
|
||||
&rules->buf[rule->rule.filename_off],
|
||||
rule->rule.filename_line);
|
||||
/* return the result from earlier run */
|
||||
if (event->builtin_ret & (1 << cur->key.builtin_cmd))
|
||||
const char *command = &rules->buf[cur->key.value_off];
|
||||
|
||||
if (udev_builtin_run_once(cur->key.builtin_cmd)) {
|
||||
/* check if we ran already */
|
||||
if (event->builtin_run & (1 << cur->key.builtin_cmd)) {
|
||||
info(event->udev, "IMPORT builtin skip '%s' %s:%u\n",
|
||||
udev_builtin_name(cur->key.builtin_cmd),
|
||||
&rules->buf[rule->rule.filename_off],
|
||||
rule->rule.filename_line);
|
||||
/* return the result from earlier run */
|
||||
if (event->builtin_ret & (1 << cur->key.builtin_cmd))
|
||||
if (cur->key.op != OP_NOMATCH)
|
||||
goto nomatch;
|
||||
break;
|
||||
goto nomatch;
|
||||
break;
|
||||
}
|
||||
/* mark as ran */
|
||||
event->builtin_run |= (1 << cur->key.builtin_cmd);
|
||||
}
|
||||
/* mark as ran */
|
||||
event->builtin_run |= (1 << cur->key.builtin_cmd);
|
||||
info(event->udev, "IMPORT builtin '%s' %s:%u\n",
|
||||
udev_builtin_name(cur->key.builtin_cmd),
|
||||
&rules->buf[rule->rule.filename_off],
|
||||
rule->rule.filename_line);
|
||||
if (udev_builtin_run(event->dev, cur->key.builtin_cmd, false) != 0) {
|
||||
if (udev_builtin_run(event->dev, cur->key.builtin_cmd, command, false) != 0) {
|
||||
/* remember failure */
|
||||
info(rules->udev, "IMPORT builtin '%s' returned non-zero\n",
|
||||
udev_builtin_name(cur->key.builtin_cmd));
|
||||
|
||||
+9
-4
@@ -150,20 +150,25 @@ enum udev_builtin_cmd {
|
||||
UDEV_BUILTIN_PATH_ID,
|
||||
UDEV_BUILTIN_USB_ID,
|
||||
UDEV_BUILTIN_INPUT_ID,
|
||||
UDEV_BUILTIN_MODALIAS_MATCH,
|
||||
UDEV_BUILTIN_BLKID,
|
||||
UDEV_BUILTIN_KMOD,
|
||||
UDEV_BUILTIN_MAX
|
||||
};
|
||||
struct udev_builtin {
|
||||
const char *name;
|
||||
int (*cmd)(struct udev_device *dev, bool test);
|
||||
int (*cmd)(struct udev_device *dev, const char *command, bool test);
|
||||
const char *help;
|
||||
bool run_once;
|
||||
};
|
||||
extern const struct udev_builtin udev_builtin_path_id;
|
||||
extern const struct udev_builtin udev_builtin_usb_id;
|
||||
extern const struct udev_builtin udev_builtin_input_id;
|
||||
enum udev_builtin_cmd udev_builtin_lookup(const char *name);
|
||||
extern const struct udev_builtin udev_builtin_blkid;
|
||||
extern const struct udev_builtin udev_builtin_kmod;
|
||||
enum udev_builtin_cmd udev_builtin_lookup(const char *command);
|
||||
const char *udev_builtin_name(enum udev_builtin_cmd cmd);
|
||||
int udev_builtin_run(struct udev_device *dev, enum udev_builtin_cmd cmd, bool test);
|
||||
bool udev_builtin_run_once(enum udev_builtin_cmd cmd);
|
||||
int udev_builtin_run(struct udev_device *dev, enum udev_builtin_cmd cmd, const char *command, bool test);
|
||||
int udev_builtin_list(struct udev *udev);
|
||||
int udev_builtin_add_property(struct udev_device *dev, bool test, const char *key, const char *val, ...);
|
||||
#endif
|
||||
|
||||
@@ -107,7 +107,7 @@ static int adm_builtin(struct udev *udev, int argc, char *argv[])
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (udev_builtin_run(dev, cmd, true) < 0) {
|
||||
if (udev_builtin_run(dev, cmd, command, true) < 0) {
|
||||
fprintf(stderr, "error executing '%s'\n\n", command);
|
||||
rc = 6;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user