Browse Source

[settings] Allow for multiple definitions of each predefined setting

Allow for multiple setting definitions with the same name but
different scopes and tags.  For example, allow for a "filename"
setting with default scope and tag value 67 (for DHCPv4) and a
corresponding "filename" setting with IPv6 scope and tag value 59 (for
DHCPv6).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 11 years ago
parent
commit
eaa8615648
3 changed files with 44 additions and 6 deletions
  1. 30
    4
      src/core/settings.c
  2. 10
    2
      src/hci/tui/settings_ui.c
  3. 4
    0
      src/interface/efi/efi_snp_hii.c

+ 30
- 4
src/core/settings.c View File

@@ -564,6 +564,31 @@ int setting_applies ( struct settings *settings,
564 564
 		 settings->op->applies ( settings, setting ) : 1 );
565 565
 }
566 566
 
567
+/**
568
+ * Find setting applicable to settings block, if any
569
+ *
570
+ * @v settings		Settings block
571
+ * @v setting		Setting
572
+ * @ret setting		Applicable setting, if any
573
+ */
574
+static const struct setting *
575
+applicable_setting ( struct settings *settings, const struct setting *setting ){
576
+	const struct setting *applicable;
577
+
578
+	/* If setting is already applicable, use it */
579
+	if ( setting_applies ( settings, setting ) )
580
+		return setting;
581
+
582
+	/* Otherwise, look for a matching predefined setting which does apply */
583
+	for_each_table_entry ( applicable, SETTINGS ) {
584
+		if ( ( setting_cmp ( setting, applicable ) == 0 ) &&
585
+		     ( setting_applies ( settings, applicable ) ) )
586
+			return applicable;
587
+	}
588
+
589
+	return NULL;
590
+}
591
+
567 592
 /**
568 593
  * Store value of setting
569 594
  *
@@ -580,7 +605,7 @@ int store_setting ( struct settings *settings, const struct setting *setting,
580 605
 	/* Find target settings block */
581 606
 	settings = settings_target ( settings );
582 607
 
583
-	/* Fail if tag does not apply to this settings block */
608
+	/* Fail if setting does not apply to this settings block */
584 609
 	if ( ! setting_applies ( settings, setting ) )
585 610
 		return -ENOTTY;
586 611
 
@@ -628,6 +653,7 @@ int store_setting ( struct settings *settings, const struct setting *setting,
628 653
 int fetch_setting ( struct settings *settings, const struct setting *setting,
629 654
 		    struct settings **origin, struct setting *fetched,
630 655
 		    void *data, size_t len ) {
656
+	const struct setting *applicable;
631 657
 	struct settings *child;
632 658
 	struct setting tmp;
633 659
 	int ret;
@@ -646,11 +672,11 @@ int fetch_setting ( struct settings *settings, const struct setting *setting,
646 672
 	if ( ! settings->op->fetch )
647 673
 		return -ENOTSUP;
648 674
 
649
-	/* Try this block first, if applicable */
650
-	if ( setting_applies ( settings, setting ) ) {
675
+	/* Try this block first, if an applicable setting exists */
676
+	if ( ( applicable = applicable_setting ( settings, setting ) ) ) {
651 677
 
652 678
 		/* Create modifiable copy of setting */
653
-		memcpy ( &tmp, setting, sizeof ( tmp ) );
679
+		memcpy ( &tmp, applicable, sizeof ( tmp ) );
654 680
 		if ( ( ret = settings->op->fetch ( settings, &tmp,
655 681
 						   data, len ) ) >= 0 ) {
656 682
 

+ 10
- 2
src/hci/tui/settings_ui.c View File

@@ -119,6 +119,7 @@ static unsigned int select_setting_row ( struct setting_widget *widget,
119 119
 					 unsigned int index ) {
120 120
 	struct settings *settings;
121 121
 	struct setting *setting;
122
+	struct setting *previous = NULL;
122 123
 	unsigned int count = 0;
123 124
 
124 125
 	/* Initialise structure */
@@ -146,11 +147,18 @@ static unsigned int select_setting_row ( struct setting_widget *widget,
146 147
 
147 148
 	/* Include any applicable settings */
148 149
 	for_each_table_entry ( setting, SETTINGS ) {
150
+
151
+		/* Skip inapplicable settings */
149 152
 		if ( ! setting_applies ( widget->settings, setting ) )
150 153
 			continue;
151
-		if ( count++ == index ) {
152 154
 
153
-			/* Read current setting value and origin */
155
+		/* Skip duplicate settings */
156
+		if ( previous && ( setting_cmp ( setting, previous ) == 0 ) )
157
+			continue;
158
+		previous = setting;
159
+
160
+		/* Read current setting value and origin */
161
+		if ( count++ == index ) {
154 162
 			fetchf_setting ( widget->settings, setting,
155 163
 					 &widget->row.origin,
156 164
 					 &widget->row.setting,

+ 4
- 0
src/interface/efi/efi_snp_hii.c View File

@@ -126,6 +126,7 @@ static void efi_snp_hii_questions ( struct efi_snp_device *snpdev,
126 126
 				    struct efi_ifr_builder *ifr,
127 127
 				    unsigned int varstore_id ) {
128 128
 	struct setting *setting;
129
+	struct setting *previous = NULL;
129 130
 	unsigned int name_id;
130 131
 	unsigned int prompt_id;
131 132
 	unsigned int help_id;
@@ -135,6 +136,9 @@ static void efi_snp_hii_questions ( struct efi_snp_device *snpdev,
135 136
 	for_each_table_entry ( setting, SETTINGS ) {
136 137
 		if ( ! efi_snp_hii_setting_applies ( snpdev, setting ) )
137 138
 			continue;
139
+		if ( previous && ( setting_cmp ( setting, previous ) == 0 ) )
140
+			continue;
141
+		previous = setting;
138 142
 		name_id = efi_ifr_string ( ifr, "%s", setting->name );
139 143
 		prompt_id = efi_ifr_string ( ifr, "%s", setting->description );
140 144
 		help_id = efi_ifr_string ( ifr, "http://ipxe.org/cfg/%s",

Loading…
Cancel
Save