From: Jean Tourrilhes <jt@hpl.hp.com>
To: linux-hotplug@vger.kernel.org
Subject: PATCH : new key MODEFILE
Date: Sat, 24 Feb 2007 02:36:14 +0000 [thread overview]
Message-ID: <20070224023614.GA28903@bougret.hpl.hp.com> (raw)
Hi,
I was looking into using the key name RUN and PROGRAM in udev,
and I realised that udev attempt to run those programs even if they
don't exist. This is a bit wasteful timewise...
In shell programming, you typically do something like this :
if [ -x /sbin/myprogram ]; then
/sbin/myprogram $MYARGS
fi
My first thought was to hack the RUN and PROGRAM keys to check
the existence of the program to be launched (cut to the first
whitespace...), but this was a bit hackish.
I also thought that a generic facility to test file
existence/permisions would be useful. Maybe we want to replicate this
kind of construct :
if [ -x /sbin/myprogram ] && [ -r /etc/itsconfigfile ]; then
/sbin/myprogram $MYARGS
fi
And you can think of many other interesting ideas along those
lines, where you can use dummy files to impact the rules as an
alternative to env variables...
So, I decided to create a real MODEMASK key in udev. This idea
is that this key take a filename and a permission key and verify that
the file has such permission.
The example above would be :
MODEMASK{/sbin/myprogram}="0100", MODEMASK{/etc/itsconfigfile}="0400",
The good news is that it was not so bad, and the changes very
localised. I tested it with udev-103, and verified that the patch
applies to udev-105.
Patch included...
Regards,
Jean
---------------------------------------------------------------------
diff -u -p udev-103-pristine/udev_rules.c udev-103/udev_rules.c
--- udev-103-pristine/udev_rules.c 2006-10-20 05:43:35.000000000 -0700
+++ udev-103/udev_rules.c 2007-02-23 18:13:54.000000000 -0800
@@ -609,6 +609,53 @@ static int match_key(const char *key_nam
return -1;
}
+static int match_modemask(const char *key_name, struct udev_rule *rule, struct key *key, const char *key_file)
+{
+ int match;
+ char value[PATH_SIZE];
+ char filename[PATH_SIZE];
+ struct stat stats;
+ mode_t modemask;
+ char *eptr;
+
+ if (key->operation != KEY_OP_MATCH &&
+ key->operation != KEY_OP_NOMATCH)
+ return 0;
+
+ strlcpy(value, rule->buf + key->val_off, sizeof(value));
+
+ /* Value should be a mode mask - octal integer */
+ modemask = strtol(value, &eptr, 8);
+ /* Parsing error = no match */
+ if(*eptr != '\0')
+ return -1;
+
+ /* Check if we have an absolute path, otherwise default to /dev */
+ if(key_file[0] = '/')
+ snprintf(filename, sizeof(filename), "%s", key_file);
+ else
+ snprintf(filename, sizeof(filename), "%s/%s", udev_root, key_file);
+ filename[sizeof(filename)-1] = '\0';
+
+ /* If file does not exist -> no match */
+ if (stat(filename, &stats) != 0)
+ return -1;
+ dbg("match %s '%o' <-> '%o'", key_name, modemask, stats.st_mode);
+
+ /* Check if match -> we make a binary AND of the two numbers */
+ match = stats.st_mode & modemask;
+ if (match && (key->operation != KEY_OP_NOMATCH)) {
+ dbg("%s is true (matching value)", key_name);
+ return 0;
+ }
+ if (!match && (key->operation = KEY_OP_NOMATCH)) {
+ dbg("%s is true (non-matching value)", key_name);
+ return 0;
+ }
+ dbg("%s is false", key_name);
+ return -1;
+}
+
/* match a single rule against a given device and possibly its parent devices */
static int match_rule(struct udevice *udev, struct udev_rule *rule)
{
@@ -690,6 +737,19 @@ static int match_rule(struct udevice *ud
}
}
+ /* Check for matching MODEMASK attribute pairs */
+ for (i = 0; i < rule->modemask.count; i++) {
+ struct key_pair *pair = &rule->modemask.keys[i];
+
+ if (pair->key.operation = KEY_OP_MATCH ||
+ pair->key.operation = KEY_OP_NOMATCH) {
+ const char *key_name = key_pair_name(rule, pair);
+
+ if (match_modemask("MODEMASK", rule, &pair->key, key_name))
+ goto nomatch;
+ }
+ }
+
/* walk up the chain of parent devices and find a match */
udev->dev_parent = udev->dev;
while (1) {
diff -u -p udev-103-pristine/udev_rules.h udev-103/udev_rules.h
--- udev-103-pristine/udev_rules.h 2006-10-20 05:43:35.000000000 -0700
+++ udev-103/udev_rules.h 2007-02-23 17:37:40.000000000 -0800
@@ -71,6 +71,7 @@ struct udev_rule {
struct key_pairs attrs;
struct key_pairs env;
+ struct key_pairs modemask;
struct key program;
struct key result;
struct key import;
diff -u -p udev-103-pristine/udev_rules_parse.c udev-103/udev_rules_parse.c
--- udev-103-pristine/udev_rules_parse.c 2006-10-20 05:43:35.000000000 -0700
+++ udev-103/udev_rules_parse.c 2007-02-23 17:17:56.000000000 -0800
@@ -400,6 +400,18 @@ static int add_to_rules(struct udev_rule
continue;
}
+ if (strncasecmp(key, "MODEMASK{", sizeof("MODEMASK{")-1) = 0) {
+ attr = get_key_attribute(key + sizeof("MODEMASK")-1);
+ if (attr = NULL) {
+ err("error parsing MODEMASK attribute");
+ goto invalid;
+ }
+ if (add_rule_key_pair(rule, &rule->modemask, operation, attr, value) != 0)
+ goto invalid;
+ valid = 1;
+ continue;
+ }
+
if (strcasecmp(key, "PROGRAM") = 0) {
add_rule_key(rule, &rule->program, operation, value);
valid = 1;
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CIDÞVDEV
_______________________________________________
Linux-hotplug-devel mailing list http://linux-hotplug.sourceforge.net
Linux-hotplug-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel
next reply other threads:[~2007-02-24 2:36 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-02-24 2:36 Jean Tourrilhes [this message]
2007-02-24 4:48 ` PATCH : new key MODEFILE Andrey Borzenkov
2007-02-24 14:34 ` Kay Sievers
2007-02-24 14:58 ` Marco d'Itri
2007-02-26 17:42 ` Jean Tourrilhes
2007-02-27 12:47 ` Kay Sievers
2007-02-27 17:19 ` Jean Tourrilhes
2007-03-16 0:55 ` Kay Sievers
2007-03-16 1:04 ` Jean Tourrilhes
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070224023614.GA28903@bougret.hpl.hp.com \
--to=jt@hpl.hp.com \
--cc=linux-hotplug@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).