hal: Branch 'master'
David Zeuthen
david at kemper.freedesktop.org
Sat Mar 3 20:13:58 PST 2007
hald/create_cache.c | 248 ++++++++++++++++++++++++++++++++--------------------
hald/mmap_cache.c | 2
2 files changed, 156 insertions(+), 94 deletions(-)
New commits:
diff-tree 3cfc81b52931009aad2dd2115374233ab212b968 (from 495ef758750134a335bb95cd1456d217ec63b7e0)
Author: David Zeuthen <davidz at redhat.com>
Date: Sat Mar 3 23:13:55 2007 -0500
relax error handling for fdi files
- hald should never ever DIE() if cache generation fails
- report fdi syntax and semantic errors via the syslog facility
- if a single fdi file is bad, just skip it
- remove some options for verbose and "use syslog"; in general only
hald will invoke the cache generator
diff --git a/hald/create_cache.c b/hald/create_cache.c
index 86148cb..0dae85d 100644
--- a/hald/create_cache.c
+++ b/hald/create_cache.c
@@ -47,6 +47,9 @@
#include "logger.h"
#include "rule.h"
+static XML_Parser parser;
+static char s_error[256];
+
/* ctx of the current fdi file used for parsing */
struct fdi_context {
int depth;
@@ -199,7 +202,7 @@ static void store_key(struct fdi_context
pad32_write(fdi_ctx->cache_fd, fdi_ctx->position + sizeof(struct rule),
(void*)key, fdi_ctx->rule.key_len);
- HAL_INFO(("Storing key '%s' at rule=%08lx", key, fdi_ctx->position));
+ /*HAL_INFO(("Storing key '%s' at rule=%08lx", key, fdi_ctx->position));*/
}
/* stores value string to data file which we'll mmap next */
@@ -238,8 +241,8 @@ static void store_value(struct fdi_conte
memcpy(p, value, value_len);
p[value_len] = '\0';
- HAL_INFO(("Storing value '%s', value_len=%d, at rule=%08lx, offset=%08lx",
- p, value_len, fdi_ctx->position, offset));
+ /*HAL_INFO(("Storing value '%s', value_len=%d, at rule=%08lx, offset=%08lx",
+ p, value_len, fdi_ctx->position, offset));*/
free(p);
}
@@ -256,6 +259,7 @@ static void store_rule(struct fdi_contex
pad32_write(fdi_ctx->cache_fd, fdi_ctx->position,
&fdi_ctx->rule, sizeof(struct rule));
+/*
HAL_INFO(("rule=%08lx, rule_size=%d, rtype=%d",
fdi_ctx->position, fdi_ctx->rule.rule_size, fdi_ctx->rule.rtype));
@@ -266,6 +270,7 @@ static void store_rule(struct fdi_contex
HAL_INFO((" value_len=%d, value_offset=%08lx",
fdi_ctx->rule.value_len, fdi_ctx->rule.value_offset));
+*/
init_rule_struct(&fdi_ctx->rule);
}
@@ -289,9 +294,10 @@ static void set_jump_position(struct fdi
pad32_write(fdi_ctx->cache_fd,
fdi_ctx->match_at_depth[fdi_ctx->depth] + offsetof(struct rule, jump_position),
&offset, sizeof(fdi_ctx->rule.jump_position));
-
+/*
HAL_INFO(("modify rule=0x%08x, set jump to 0x%08x",
fdi_ctx->match_at_depth[fdi_ctx->depth], offset));
+*/
}
/* expat cb for start, e.g. <match foo=bar */
@@ -313,16 +319,22 @@ start (void *data, const char *el, const
/* get key and attribute for current rule */
for (i = 0; attr[i] != NULL; i+=2) {
if (strcmp (attr[i], "key") == 0) {
- if (fdi_ctx->rule.key_len > 0)
- DIE(("Bad rule: key already defined"));
+ if (fdi_ctx->rule.key_len > 0) {
+ snprintf (s_error, sizeof (s_error), "Bad rule: key already defined");
+ XML_StopParser (parser, FALSE);
+ return;
+ }
store_key(fdi_ctx, attr[i + 1]);
continue;
}
if (fdi_ctx->rule.rtype == RULE_SPAWN) {
if (strcmp(attr[i], "udi") == 0) {
- if (fdi_ctx->rule.key_len > 0)
- DIE(("Bad rule: key already defined"));
+ if (fdi_ctx->rule.key_len > 0) {
+ snprintf (s_error, sizeof (s_error), "Bad rule: key already defined");
+ XML_StopParser (parser, FALSE);
+ return;
+ }
store_key(fdi_ctx, attr[i + 1]);
continue;
@@ -331,13 +343,19 @@ start (void *data, const char *el, const
continue;
} else if (fdi_ctx->rule.rtype == RULE_MATCH) {
- if (fdi_ctx->rule.key_len == 0)
- DIE(("Bad rule: value without a key"));
+ if (fdi_ctx->rule.key_len == 0) {
+ snprintf (s_error, sizeof (s_error), "Bad rule: value without a key");
+ XML_StopParser (parser, FALSE);
+ return;
+ }
fdi_ctx->rule.type_match = get_match_type(attr[i]);
- if (fdi_ctx->rule.type_match == MATCH_UNKNOWN)
- DIE(("Bad rule: unknown type_match"));
+ if (fdi_ctx->rule.type_match == MATCH_UNKNOWN) {
+ snprintf (s_error, sizeof (s_error), "Bad rule: unknown type_match");
+ XML_StopParser (parser, FALSE);
+ return;
+ }
store_value(fdi_ctx, attr[i + 1], strlen(attr[i + 1]));
continue;
@@ -348,15 +366,21 @@ start (void *data, const char *el, const
}
fdi_ctx->rule.type_merge = get_merge_type(attr[i + 1]);
- if (fdi_ctx->rule.type_merge == MERGE_UNKNOWN)
- DIE(("Bad rule: unknown type_merge"));
+ if (fdi_ctx->rule.type_merge == MERGE_UNKNOWN) {
+ snprintf (s_error, sizeof (s_error), "Bad rule: unknown type_merge");
+ XML_StopParser (parser, FALSE);
+ return;
+ }
continue;
}
}
- if (fdi_ctx->rule.key_len == 0)
- DIE(("Bad rule: key not found"));
+ if (fdi_ctx->rule.key_len == 0) {
+ snprintf (s_error, sizeof (s_error), "Bad rule: key not found");
+ XML_StopParser (parser, FALSE);
+ return;
+ }
/* match rules remember the current nesting and
the label to jump to if not matching */
@@ -394,21 +418,28 @@ end (void *data, const char *el){
}
/* only valid if element is in the current context */
- if (fdi_ctx->rule.rtype != rtype){
- DIE(("Unexpected tag '%s'", el));
+ if (fdi_ctx->rule.rtype != rtype) {
+ snprintf (s_error, sizeof (s_error), "Unexpected tag '%s'", el);
+ XML_StopParser (parser, FALSE);
+ return;
}
store_rule(fdi_ctx);
}
/* decompile an fdi file into a list of rules as this is quicker than opening then each time we want to search */
static int
-rules_add_fdi_file (const char *filename, int fd){
- struct fdi_context *fdi_ctx;
- char *buf;
- gsize buflen;
- int rc;
+rules_add_fdi_file (const char *filename, int fd)
+{
+ struct fdi_context *fdi_ctx;
+ char *buf;
+ gsize buflen;
+ int rc;
+ int ret;
+
+ ret = -1;
- if (!g_file_get_contents (filename, &buf, &buflen, NULL)) return -1;
+ if (!g_file_get_contents (filename, &buf, &buflen, NULL))
+ goto out;
/* create new context */
fdi_ctx = g_new0 (struct fdi_context, 1);
@@ -416,19 +447,44 @@ rules_add_fdi_file (const char *filename
init_rule_struct(&fdi_ctx->rule);
fdi_ctx->cache_fd = fd;
- XML_Parser parser = XML_ParserCreate (NULL);
+ parser = XML_ParserCreate (NULL);
if (parser == NULL) {
- fprintf (stderr, "Couldn't allocate memory for parser\n");
- return -1;
+ HAL_ERROR (("Couldn't allocate memory for parser"));
+ goto out;
}
XML_SetUserData (parser, fdi_ctx);
XML_SetElementHandler (parser, start, end);
XML_SetCharacterDataHandler (parser, cdata);
rc = XML_Parse (parser, buf, buflen, 1);
- if (rc == 0)
- fprintf (stderr, "Parse error at line %i:\n%s\n",
- (int) XML_GetCurrentLineNumber (parser),
- XML_ErrorString (XML_GetErrorCode (parser)));
+ if (rc == 0) {
+ if (XML_GetErrorCode (parser) == XML_ERROR_ABORTED) {
+ HAL_ERROR (("%s:%d: semantic error: %s",
+ filename,
+ (int) XML_GetCurrentLineNumber (parser),
+ s_error));
+ syslog (LOG_ERR,
+ "error in fdi file %s:%d: %s",
+ filename,
+ (int) XML_GetCurrentLineNumber (parser),
+ s_error);
+
+ } else {
+ HAL_ERROR (("%s:%d: XML parse error: %s",
+ filename,
+ (int) XML_GetCurrentLineNumber (parser),
+ XML_ErrorString (XML_GetErrorCode (parser))));
+ syslog (LOG_ERR,
+ "error in fdi file %s:%d: %s",
+ filename,
+ (int) XML_GetCurrentLineNumber (parser),
+ XML_ErrorString (XML_GetErrorCode (parser)));
+ }
+
+ XML_ParserFree (parser);
+ g_free (buf);
+ g_free (fdi_ctx);
+ goto out;
+ }
XML_ParserFree (parser);
g_free (buf);
@@ -439,25 +495,30 @@ rules_add_fdi_file (const char *filename
store_key(fdi_ctx, filename);
store_value(fdi_ctx, "", 0);
store_rule(fdi_ctx);
-
g_free (fdi_ctx);
+ ret = lseek(fd, 0, SEEK_END);
+out:
+ return ret;
- if (rc == 0) return -1;
- return lseek(fd, 0, SEEK_END);
}
/* recurse a directory tree, searching and adding fdi files */
-static int
+static gboolean
rules_search_and_add_fdi_files (const char *dir, int fd)
{
int i;
int num_entries;
struct dirent **name_list;
+ gboolean ret;
+
+ ret = FALSE;
num_entries = scandir (dir, &name_list, 0, _alphasort);
- if (num_entries == -1)
- return -1;
+ if (num_entries == -1) {
+ HAL_ERROR (("Cannot scan '%s': %s", strerror (errno)));
+ goto out;
+ }
for (i = num_entries - 1; i >= 0; i--) {
int len;
@@ -470,9 +531,19 @@ rules_search_and_add_fdi_files (const ch
if (g_file_test (full_path, (G_FILE_TEST_IS_REGULAR))) {
if (len >= 5 && strcmp(&filename[len - 4], ".fdi") == 0) {
int fdi_rules_size;
+ off_t offset_before;
+ offset_before = lseek (fd, 0, SEEK_CUR);
fdi_rules_size = rules_add_fdi_file (full_path, fd);
- if (fdi_rules_size < 0)
- HAL_WARNING (("error processing fdi file '%s'", full_path));
+ if (fdi_rules_size < 0) {
+ HAL_ERROR (("error processing fdi file '%s'", full_path));
+ /* try to just skip this file */
+ if (ftruncate (fd, offset_before) != 0) {
+ HAL_ERROR (("Cannot truncate rules fdi"));
+ goto out;
+ }
+ lseek (fd, 0, SEEK_END);
+ HAL_INFO (("skipped fdi file '%s'", full_path));
+ }
}
} else if (g_file_test (full_path, (G_FILE_TEST_IS_DIR)) && filename[0] != '.') {
int num_bytes;
@@ -484,21 +555,24 @@ rules_search_and_add_fdi_files (const ch
break;
snprintf (dirname, num_bytes, "%s/%s", dir, filename);
- rules_search_and_add_fdi_files (dirname, fd);
+ if (!rules_search_and_add_fdi_files (dirname, fd))
+ goto out;
free (dirname);
}
g_free (full_path);
free (name_list[i]);
}
- for (; i >= 0; i--) free (name_list[i]);
+ for (; i >= 0; i--) {
+ free (name_list[i]);
+ }
free (name_list);
- return 0;
+ ret = TRUE;
+out:
+ return ret;
}
-int haldc_is_verbose = 0;
-int haldc_use_syslog = 0;
int haldc_force_recreate = 0;
@@ -506,9 +580,8 @@ static void
di_rules_init (void)
{
char * cachename;
- int fd;
+ int fd = -1;
struct cache_header header;
- struct stat st;
char cachename_temp [PATH_MAX+1];
char *hal_fdi_source_preprobe = getenv ("HAL_FDI_SOURCE_PREPROBE");
char *hal_fdi_source_information = getenv ("HAL_FDI_SOURCE_INFORMATION");
@@ -522,36 +595,46 @@ di_rules_init (void)
strncpy(cachename_temp, cachename, PATH_MAX);
strncat(cachename_temp, "~", PATH_MAX);
- fd = open(cachename_temp, O_CREAT|O_RDWR|O_EXCL|O_TRUNC, 0644);
+ fd = open(cachename_temp, O_CREAT|O_RDWR|O_TRUNC, 0644);
if(fd < 0) {
- DIE(("Unable to open fdi cache '%s' file for writing: %s", cachename, strerror(errno)));
+ HAL_ERROR (("Unable to open fdi cache '%s' file for writing: %s", cachename_temp, strerror(errno)));
+ goto error;
}
memset(&header, 0, sizeof(struct cache_header));
pad32_write(fd, 0, &header, sizeof(struct cache_header));
header.fdi_rules_preprobe = lseek(fd, 0, SEEK_END);
- if (hal_fdi_source_preprobe != NULL)
- rules_search_and_add_fdi_files (hal_fdi_source_preprobe, fd);
- else{
- rules_search_and_add_fdi_files (PACKAGE_DATA_DIR "/hal/fdi/preprobe", fd);
- rules_search_and_add_fdi_files (PACKAGE_SYSCONF_DIR "/hal/fdi/preprobe", fd);
+ if (hal_fdi_source_preprobe != NULL) {
+ if (!rules_search_and_add_fdi_files (hal_fdi_source_preprobe, fd))
+ goto error;
+ } else {
+ if (!rules_search_and_add_fdi_files (PACKAGE_DATA_DIR "/hal/fdi/preprobe", fd))
+ goto error;
+ if (!rules_search_and_add_fdi_files (PACKAGE_SYSCONF_DIR "/hal/fdi/preprobe", fd))
+ goto error;
}
header.fdi_rules_information = lseek(fd, 0, SEEK_END);
- if (hal_fdi_source_information != NULL)
- rules_search_and_add_fdi_files (hal_fdi_source_information, fd);
- else {
- rules_search_and_add_fdi_files (PACKAGE_DATA_DIR "/hal/fdi/information", fd);
- rules_search_and_add_fdi_files (PACKAGE_SYSCONF_DIR "/hal/fdi/information", fd);
+ if (hal_fdi_source_information != NULL) {
+ if (!rules_search_and_add_fdi_files (hal_fdi_source_information, fd))
+ goto error;
+ } else {
+ if (!rules_search_and_add_fdi_files (PACKAGE_DATA_DIR "/hal/fdi/information", fd))
+ goto error;
+ if (!rules_search_and_add_fdi_files (PACKAGE_SYSCONF_DIR "/hal/fdi/information", fd))
+ goto error;
}
header.fdi_rules_policy = lseek(fd, 0, SEEK_END);
- if (hal_fdi_source_policy != NULL)
- rules_search_and_add_fdi_files (hal_fdi_source_policy, fd);
- else {
- rules_search_and_add_fdi_files (PACKAGE_DATA_DIR "/hal/fdi/policy", fd);
- rules_search_and_add_fdi_files (PACKAGE_SYSCONF_DIR "/hal/fdi/policy", fd);
+ if (hal_fdi_source_policy != NULL) {
+ if (!rules_search_and_add_fdi_files (hal_fdi_source_policy, fd))
+ goto error;
+ } else {
+ if (!rules_search_and_add_fdi_files (PACKAGE_DATA_DIR "/hal/fdi/policy", fd))
+ goto error;
+ if (!rules_search_and_add_fdi_files (PACKAGE_SYSCONF_DIR "/hal/fdi/policy", fd))
+ goto error;
}
header.all_rules_size = lseek(fd, 0, SEEK_END);
@@ -559,7 +642,8 @@ di_rules_init (void)
close(fd);
if (rename (cachename_temp, cachename) != 0) {
unlink (cachename_temp);
- DIE (("Cannot rename '%s' to '%s'", cachename_temp, cachename));
+ HAL_ERROR (("Cannot rename '%s' to '%s': %s", cachename_temp, cachename, strerror (errno)));
+ return;
}
HAL_INFO(("preprobe: offset=%08lx, size=%d", header.fdi_rules_preprobe,
@@ -570,6 +654,12 @@ di_rules_init (void)
header.all_rules_size - header.fdi_rules_policy));
HAL_INFO (("Generating rules done (occupying %d bytes)", header.all_rules_size));
+ return;
+error:
+ HAL_ERROR (("Error generating fdi cache"));
+ if (fd < 0)
+ close (fd);
+ unlink (cachename_temp);
}
/**
@@ -584,9 +674,6 @@ usage ()
fprintf (stderr, "\n" "usage : hald-cache [--verbose=yes|no] [--use-syslog] [--help]\n");
fprintf (stderr,
"\n"
- " --verbose=yes|no Print out debug (overrides HALD_VERBOSE).\n"
- " --use-syslog Print out debug messages to syslog instead of\n"
- " stderr. Use this option to get debug messages.\n"
" --force Force regeneration of cache.\n"
" --help Show this information and exit.\n"
" --version Output version information and exit.\n"
@@ -600,7 +687,7 @@ usage ()
int main(int argc, char * argv[])
{
- openlog ("hald-cache", LOG_PID, LOG_DAEMON);
+ openlog ("hald", LOG_PID, LOG_DAEMON);
while (1) {
int c;
@@ -608,10 +695,6 @@ int main(int argc, char * argv[])
const char *opt;
static struct option long_options[] = {
{"exit-after-probing", 0, NULL, 0},
- {"daemon", 1, NULL, 0},
- {"verbose", 1, NULL, 0},
- {"retain-privileges", 0, NULL, 0},
- {"use-syslog", 0, NULL, 0},
{"help", 0, NULL, 0},
{"version", 0, NULL, 0},
{"force", 0, NULL, 0},
@@ -633,17 +716,6 @@ int main(int argc, char * argv[])
} else if (strcmp (opt, "version") == 0) {
fprintf (stderr, "HAL package version: " PACKAGE_VERSION "\n");
return 0;
- } else if (strcmp (opt, "verbose") == 0) {
- if (strcmp ("yes", optarg) == 0) {
- haldc_is_verbose = 1;
- } else if (strcmp ("no", optarg) == 0) {
- haldc_is_verbose = 0;
- } else {
- usage ();
- return 1;
- }
- } else if (strcmp (opt, "use-syslog") == 0) {
- haldc_use_syslog = 1;
} else if (strcmp (opt, "force") == 0) {
haldc_force_recreate = 1;
}
@@ -657,16 +729,6 @@ int main(int argc, char * argv[])
}
}
- if (haldc_is_verbose)
- logger_enable ();
- else
- logger_disable ();
-
- if (haldc_use_syslog)
- logger_enable_syslog ();
- else
- logger_disable_syslog ();
-
di_rules_init();
return 0;
}
diff --git a/hald/mmap_cache.c b/hald/mmap_cache.c
index 7371661..c785cc1 100644
--- a/hald/mmap_cache.c
+++ b/hald/mmap_cache.c
@@ -184,7 +184,7 @@ regen_cache (void)
}
if (!regen_cache_success) {
- DIE (("fdi cache regeneration failed!"));
+ HAL_ERROR (("fdi cache regeneration failed!"));
}
HAL_INFO (("fdi cache generation done"));
More information about the hal-commit
mailing list