tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

options MODULAR improvements phase 1.5



     This phase fixes the regression from the last where <module>.prop
would override anything on the "command line".  In this phase, the
"command line" is merged with <module>.prop (i.e. options on the
"command line" will add to options found in <module>.prop and/or change
existing options found in <module>.prop).  It is not possible to use
the "command line" to delete options from <module>.prop.  If this is
deemed to be necessary, it would be possible by creating some kind of
magic option that specifies the option to be deleted.

     This is fairly simple code, only complicated by weirdness in the
proplib API.  It was lifted from a recent modification of modload(8)
and has been tested both there and in the kernel, so I'll allow 48
hours for comments.  I think the next major phase will be boot
properties.

Index: kern_module.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_module.c,v
retrieving revision 1.46
diff -u -r1.46 kern_module.c
--- kern_module.c       7 Jun 2009 09:47:31 -0000       1.46
+++ kern_module.c       7 Jun 2009 10:24:42 -0000
@@ -95,6 +95,7 @@
 static void    module_thread(void *);
 static int     module_load_plist_file(const char *, const bool, void **,
                    size_t *);
+static bool    module_merge_dicts(prop_dictionary_t, const prop_dictionary_t);

 /*
  * module_error:
@@ -797,6 +798,10 @@
                        filedict = prop_dictionary_internalize(plist);
                        if (filedict == NULL) {
                                error = EINVAL;
+                       } else if (!module_merge_dicts(filedict, props)) {
+                               error = EINVAL;
+                               prop_object_release(filedict);
+                               filedict = NULL;
                        }
                }
                if (plist != NULL) {
@@ -810,7 +815,7 @@
        KASSERT(module_active == NULL);
        module_active = mod;
        error = (*mi->mi_modcmd)(MODULE_CMD_INIT, (filedict != NULL) ?
-           filedict : props);
+           filedict : props);  /* props will have been merged with filedict */
        module_active = NULL;
        if (filedict != NULL) {
                prop_object_release(filedict);
@@ -1197,3 +1202,37 @@
        *basep = base;
        return error;
 }
+
+static bool
+module_merge_dicts(prop_dictionary_t existing_dict,
+                  const prop_dictionary_t new_dict)
+{
+       prop_dictionary_keysym_t props_keysym;
+       prop_object_iterator_t props_iter;
+       prop_object_t props_obj;
+       const char *props_key;
+       bool error;
+
+       error = false;
+       props_iter = prop_dictionary_iterator(new_dict);
+       if (props_iter == NULL) {
+               return false;
+       }
+
+       while ((props_obj = prop_object_iterator_next(props_iter)) != NULL) {
+               props_keysym = (prop_dictionary_keysym_t)props_obj;
+               props_key = prop_dictionary_keysym_cstring_nocopy(props_keysym);
+               props_obj = prop_dictionary_get_keysym(new_dict, props_keysym);
+               if ((props_obj == NULL) || !prop_dictionary_set(existing_dict,
+                   props_key, props_obj)) {
+                       error = true;
+                       goto out;
+               }
+       }
+       error = false;
+
+out:
+       prop_object_iterator_release(props_iter);
+
+       return !error;
+}


Home | Main Index | Thread Index | Old Index