Browse Source

[main] Add the "scriptlet" setting

A scriptlet is a single iPXE command that can be stored in
non-volatile option storage and used to override the default
"autoboot" behaviour without having to reflash the iPXE image.

For example, a scriptlet could contain

    autoboot || reboot

to instruct iPXE to reboot the system if booting fails.

Unlike an embedded image, the presence of a scriptlet does not inhibit
the initial "Press Ctrl-B..." prompt.  This allows the user to recover
from setting a faulty scriptlet.

Originally-implemented-by: Glenn Brown <glenn@myri.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 14 years ago
parent
commit
2f6e7bde77
2 changed files with 27 additions and 5 deletions
  1. 19
    4
      src/core/main.c
  2. 8
    1
      src/include/ipxe/dhcp.h

+ 19
- 4
src/core/main.c View File

15
 FILE_LICENCE ( GPL2_OR_LATER );
15
 FILE_LICENCE ( GPL2_OR_LATER );
16
 
16
 
17
 #include <stdio.h>
17
 #include <stdio.h>
18
+#include <stdlib.h>
18
 #include <ipxe/init.h>
19
 #include <ipxe/init.h>
19
 #include <ipxe/features.h>
20
 #include <ipxe/features.h>
20
 #include <ipxe/shell.h>
21
 #include <ipxe/shell.h>
28
 #define BOLD	"\033[1m"
29
 #define BOLD	"\033[1m"
29
 #define CYAN	"\033[36m"
30
 #define CYAN	"\033[36m"
30
 
31
 
32
+/** The "scriptlet" setting */
33
+struct setting scriptlet_setting __setting ( SETTING_MISC ) = {
34
+	.name = "scriptlet",
35
+	.description = "Boot scriptlet",
36
+	.tag = DHCP_EB_SCRIPTLET,
37
+	.type = &setting_type_string,
38
+};
39
+
31
 /**
40
 /**
32
  * Prompt for shell entry
41
  * Prompt for shell entry
33
  *
42
  *
51
 __asmcall int main ( void ) {
60
 __asmcall int main ( void ) {
52
 	struct feature *feature;
61
 	struct feature *feature;
53
 	struct image *image;
62
 	struct image *image;
63
+	char *scriptlet;
54
 
64
 
55
 	/* Some devices take an unreasonably long time to initialise */
65
 	/* Some devices take an unreasonably long time to initialise */
56
 	printf ( PRODUCT_SHORT_NAME " initialising devices..." );
66
 	printf ( PRODUCT_SHORT_NAME " initialising devices..." );
82
 	if ( ( image = first_image() ) != NULL ) {
92
 	if ( ( image = first_image() ) != NULL ) {
83
 		/* We have an embedded image; execute it */
93
 		/* We have an embedded image; execute it */
84
 		image_exec ( image );
94
 		image_exec ( image );
95
+	} else if ( shell_banner() ) {
96
+		/* User wants shell; just give them a shell */
97
+		shell();
85
 	} else {
98
 	} else {
86
-		/* Prompt for shell */
87
-		if ( shell_banner() ) {
88
-			/* User wants shell; just give them a shell */
89
-			shell();
99
+		fetch_string_setting_copy ( NULL, &scriptlet_setting,
100
+					    &scriptlet );
101
+		if ( scriptlet ) {
102
+			/* User has defined a scriptlet; execute it */
103
+			system ( scriptlet );
104
+			free ( scriptlet );
90
 		} else {
105
 		} else {
91
 			/* Try booting.  If booting fails, offer the
106
 			/* Try booting.  If booting fails, offer the
92
 			 * user another chance to enter the shell.
107
 			 * user another chance to enter the shell.

+ 8
- 1
src/include/ipxe/dhcp.h View File

307
 #define DHCP_EB_SKIP_SAN_BOOT DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x09 )
307
 #define DHCP_EB_SKIP_SAN_BOOT DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x09 )
308
 
308
 
309
 /*
309
 /*
310
- * Tags in the range 0x10-0x7f are reserved for feature markers
310
+ * Tags in the range 0x10-0x4f are reserved for feature markers
311
  *
311
  *
312
  */
312
  */
313
 
313
 
314
+/** Scriptlet
315
+ *
316
+ * If a scriptlet exists, it will be executed in place of the usual
317
+ * call to autoboot()
318
+ */
319
+#define DHCP_EB_SCRIPTLET DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x51 )
320
+
314
 /** Skip PXE DHCP protocol extensions such as ProxyDHCP
321
 /** Skip PXE DHCP protocol extensions such as ProxyDHCP
315
  *
322
  *
316
  * If set to a non-zero value, iPXE will not wait for ProxyDHCP offers
323
  * If set to a non-zero value, iPXE will not wait for ProxyDHCP offers

Loading…
Cancel
Save