|
@@ -271,6 +271,9 @@ struct settings * find_child_settings ( struct settings *parent,
|
271
|
271
|
const char *name ) {
|
272
|
272
|
struct settings *settings;
|
273
|
273
|
|
|
274
|
+ /* Find target parent settings block */
|
|
275
|
+ parent = settings_target ( parent );
|
|
276
|
+
|
274
|
277
|
/* Treat empty name as meaning "this block" */
|
275
|
278
|
if ( ! *name )
|
276
|
279
|
return parent;
|
|
@@ -278,7 +281,7 @@ struct settings * find_child_settings ( struct settings *parent,
|
278
|
281
|
/* Look for child with matching name */
|
279
|
282
|
list_for_each_entry ( settings, &parent->children, siblings ) {
|
280
|
283
|
if ( strcmp ( settings->name, name ) == 0 )
|
281
|
|
- return settings;
|
|
284
|
+ return settings_target ( settings );
|
282
|
285
|
}
|
283
|
286
|
|
284
|
287
|
return NULL;
|
|
@@ -299,6 +302,9 @@ static struct settings * autovivify_child_settings ( struct settings *parent,
|
299
|
302
|
} *new_child;
|
300
|
303
|
struct settings *settings;
|
301
|
304
|
|
|
305
|
+ /* Find target parent settings block */
|
|
306
|
+ parent = settings_target ( parent );
|
|
307
|
+
|
302
|
308
|
/* Return existing settings, if existent */
|
303
|
309
|
if ( ( settings = find_child_settings ( parent, name ) ) != NULL )
|
304
|
310
|
return settings;
|
|
@@ -330,6 +336,10 @@ const char * settings_name ( struct settings *settings ) {
|
330
|
336
|
static char buf[16];
|
331
|
337
|
char tmp[ sizeof ( buf ) ];
|
332
|
338
|
|
|
339
|
+ /* Find target settings block */
|
|
340
|
+ settings = settings_target ( settings );
|
|
341
|
+
|
|
342
|
+ /* Construct name */
|
333
|
343
|
for ( buf[2] = buf[0] = 0 ; settings ; settings = settings->parent ) {
|
334
|
344
|
memcpy ( tmp, buf, sizeof ( tmp ) );
|
335
|
345
|
snprintf ( buf, sizeof ( buf ), ".%s%s", settings->name, tmp );
|
|
@@ -359,20 +369,11 @@ parse_settings_name ( const char *name,
|
359
|
369
|
|
360
|
370
|
/* Parse each name component in turn */
|
361
|
371
|
while ( remainder ) {
|
362
|
|
- struct net_device *netdev;
|
363
|
|
-
|
364
|
372
|
subname = remainder;
|
365
|
373
|
remainder = strchr ( subname, '.' );
|
366
|
374
|
if ( remainder )
|
367
|
375
|
*(remainder++) = '\0';
|
368
|
|
-
|
369
|
|
- /* Special case "netX" root settings block */
|
370
|
|
- if ( ( subname == name_copy ) && ! strcmp ( subname, "netX" ) &&
|
371
|
|
- ( ( netdev = last_opened_netdev() ) != NULL ) )
|
372
|
|
- settings = get_child ( settings, netdev->name );
|
373
|
|
- else
|
374
|
|
- settings = get_child ( settings, subname );
|
375
|
|
-
|
|
376
|
+ settings = get_child ( settings, subname );
|
376
|
377
|
if ( ! settings )
|
377
|
378
|
break;
|
378
|
379
|
}
|
|
@@ -460,10 +461,11 @@ int register_settings ( struct settings *settings, struct settings *parent,
|
460
|
461
|
const char *name ) {
|
461
|
462
|
struct settings *old_settings;
|
462
|
463
|
|
463
|
|
- /* NULL parent => add to settings root */
|
|
464
|
+ /* Sanity check */
|
464
|
465
|
assert ( settings != NULL );
|
465
|
|
- if ( parent == NULL )
|
466
|
|
- parent = &settings_root;
|
|
466
|
+
|
|
467
|
+ /* Find target parent settings block */
|
|
468
|
+ parent = settings_target ( parent );
|
467
|
469
|
|
468
|
470
|
/* Apply settings block name */
|
469
|
471
|
settings->name = name;
|
|
@@ -523,6 +525,26 @@ void unregister_settings ( struct settings *settings ) {
|
523
|
525
|
******************************************************************************
|
524
|
526
|
*/
|
525
|
527
|
|
|
528
|
+/**
|
|
529
|
+ * Redirect to target settings block
|
|
530
|
+ *
|
|
531
|
+ * @v settings Settings block, or NULL
|
|
532
|
+ * @ret settings Underlying settings block
|
|
533
|
+ */
|
|
534
|
+struct settings * settings_target ( struct settings *settings ) {
|
|
535
|
+
|
|
536
|
+ /* NULL settings implies the global settings root */
|
|
537
|
+ if ( ! settings )
|
|
538
|
+ settings = &settings_root;
|
|
539
|
+
|
|
540
|
+ /* Redirect to underlying settings block, if applicable */
|
|
541
|
+ if ( settings->op->redirect )
|
|
542
|
+ return settings->op->redirect ( settings );
|
|
543
|
+
|
|
544
|
+ /* Otherwise, return this settings block */
|
|
545
|
+ return settings;
|
|
546
|
+}
|
|
547
|
+
|
526
|
548
|
/**
|
527
|
549
|
* Check applicability of setting
|
528
|
550
|
*
|
|
@@ -532,6 +554,10 @@ void unregister_settings ( struct settings *settings ) {
|
532
|
554
|
*/
|
533
|
555
|
int setting_applies ( struct settings *settings, struct setting *setting ) {
|
534
|
556
|
|
|
557
|
+ /* Find target settings block */
|
|
558
|
+ settings = settings_target ( settings );
|
|
559
|
+
|
|
560
|
+ /* Check applicability of setting */
|
535
|
561
|
return ( settings->op->applies ?
|
536
|
562
|
settings->op->applies ( settings, setting ) : 1 );
|
537
|
563
|
}
|
|
@@ -549,9 +575,8 @@ int store_setting ( struct settings *settings, struct setting *setting,
|
549
|
575
|
const void *data, size_t len ) {
|
550
|
576
|
int rc;
|
551
|
577
|
|
552
|
|
- /* NULL settings implies storing into the global settings root */
|
553
|
|
- if ( ! settings )
|
554
|
|
- settings = &settings_root;
|
|
578
|
+ /* Find target settings block */
|
|
579
|
+ settings = settings_target ( settings );
|
555
|
580
|
|
556
|
581
|
/* Fail if tag does not apply to this settings block */
|
557
|
582
|
if ( ! setting_applies ( settings, setting ) )
|
|
@@ -609,9 +634,8 @@ static int fetch_setting_and_origin ( struct settings *settings,
|
609
|
634
|
if ( origin )
|
610
|
635
|
*origin = NULL;
|
611
|
636
|
|
612
|
|
- /* NULL settings implies starting at the global settings root */
|
613
|
|
- if ( ! settings )
|
614
|
|
- settings = &settings_root;
|
|
637
|
+ /* Find target settings block */
|
|
638
|
+ settings = settings_target ( settings );
|
615
|
639
|
|
616
|
640
|
/* Sanity check */
|
617
|
641
|
if ( ! settings->op->fetch )
|
|
@@ -971,6 +995,11 @@ int fetch_uuid_setting ( struct settings *settings, struct setting *setting,
|
971
|
995
|
* @v settings Settings block
|
972
|
996
|
*/
|
973
|
997
|
void clear_settings ( struct settings *settings ) {
|
|
998
|
+
|
|
999
|
+ /* Find target settings block */
|
|
1000
|
+ settings = settings_target ( settings );
|
|
1001
|
+
|
|
1002
|
+ /* Clear settings, if applicable */
|
974
|
1003
|
if ( settings->op->clear )
|
975
|
1004
|
settings->op->clear ( settings );
|
976
|
1005
|
}
|
|
@@ -1230,9 +1259,7 @@ int setting_name ( struct settings *settings, struct setting *setting,
|
1230
|
1259
|
char *buf, size_t len ) {
|
1231
|
1260
|
const char *name;
|
1232
|
1261
|
|
1233
|
|
- if ( ! settings )
|
1234
|
|
- settings = &settings_root;
|
1235
|
|
-
|
|
1262
|
+ settings = settings_target ( settings );
|
1236
|
1263
|
name = settings_name ( settings );
|
1237
|
1264
|
return snprintf ( buf, len, "%s%s%s:%s", name, ( name[0] ? "/" : "" ),
|
1238
|
1265
|
setting->name, setting->type->name );
|