]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[main] Add the "scriptlet" setting
authorMichael Brown <mcb30@ipxe.org>
Mon, 28 Mar 2011 17:48:48 +0000 (18:48 +0100)
committerMichael Brown <mcb30@ipxe.org>
Mon, 28 Mar 2011 17:50:27 +0000 (18:50 +0100)
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>
src/core/main.c
src/include/ipxe/dhcp.h

index aac27e9ba6661491c58d7976725bd3ee3714a2ba..9fd4a76ff8c075fed134f2536960b6868a579513 100644 (file)
@@ -15,6 +15,7 @@ Literature dealing with the network protocols:
 FILE_LICENCE ( GPL2_OR_LATER );
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <ipxe/init.h>
 #include <ipxe/features.h>
 #include <ipxe/shell.h>
@@ -28,6 +29,14 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #define BOLD   "\033[1m"
 #define CYAN   "\033[36m"
 
+/** The "scriptlet" setting */
+struct setting scriptlet_setting __setting ( SETTING_MISC ) = {
+       .name = "scriptlet",
+       .description = "Boot scriptlet",
+       .tag = DHCP_EB_SCRIPTLET,
+       .type = &setting_type_string,
+};
+
 /**
  * Prompt for shell entry
  *
@@ -51,6 +60,7 @@ static int shell_banner ( void ) {
 __asmcall int main ( void ) {
        struct feature *feature;
        struct image *image;
+       char *scriptlet;
 
        /* Some devices take an unreasonably long time to initialise */
        printf ( PRODUCT_SHORT_NAME " initialising devices..." );
@@ -82,11 +92,16 @@ __asmcall int main ( void ) {
        if ( ( image = first_image() ) != NULL ) {
                /* We have an embedded image; execute it */
                image_exec ( image );
+       } else if ( shell_banner() ) {
+               /* User wants shell; just give them a shell */
+               shell();
        } else {
-               /* Prompt for shell */
-               if ( shell_banner() ) {
-                       /* User wants shell; just give them a shell */
-                       shell();
+               fetch_string_setting_copy ( NULL, &scriptlet_setting,
+                                           &scriptlet );
+               if ( scriptlet ) {
+                       /* User has defined a scriptlet; execute it */
+                       system ( scriptlet );
+                       free ( scriptlet );
                } else {
                        /* Try booting.  If booting fails, offer the
                         * user another chance to enter the shell.
index 54a85f6614bbe37bf0f5d226d070e5c4402dfd8d..148e3d66f6beec2ee230133d4e137b133cb1450d 100644 (file)
@@ -307,10 +307,17 @@ struct dhcp_client_uuid {
 #define DHCP_EB_SKIP_SAN_BOOT DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x09 )
 
 /*
- * Tags in the range 0x10-0x7f are reserved for feature markers
+ * Tags in the range 0x10-0x4f are reserved for feature markers
  *
  */
 
+/** Scriptlet
+ *
+ * If a scriptlet exists, it will be executed in place of the usual
+ * call to autoboot()
+ */
+#define DHCP_EB_SCRIPTLET DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x51 )
+
 /** Skip PXE DHCP protocol extensions such as ProxyDHCP
  *
  * If set to a non-zero value, iPXE will not wait for ProxyDHCP offers