Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / hci / commands / sanboot_cmd.c
1 /*
2  * Copyright (C) 2010 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  */
19
20 #include <stdio.h>
21 #include <string.h>
22 #include <errno.h>
23 #include <getopt.h>
24 #include <ipxe/command.h>
25 #include <ipxe/parseopt.h>
26 #include <ipxe/uri.h>
27 #include <ipxe/sanboot.h>
28 #include <usr/autoboot.h>
29
30 FILE_LICENCE ( GPL2_OR_LATER );
31
32 /** @file
33  *
34  * SAN commands
35  *
36  */
37
38 /** "sanboot" options */
39 struct sanboot_options {
40         /** Drive number */
41         unsigned int drive;
42         /** Do not describe SAN device */
43         int no_describe;
44         /** Keep SAN device */
45         int keep;
46 };
47
48 /** "sanboot" option list */
49 static union {
50         /* "sanboot" takes all three options */
51         struct option_descriptor sanboot[3];
52         /* "sanhook" takes only --drive and --no-describe */
53         struct option_descriptor sanhook[2];
54         /* "sanunhook" takes only --drive */
55         struct option_descriptor sanunhook[1];
56 } opts = {
57         .sanboot = {
58                 OPTION_DESC ( "drive", 'd', required_argument,
59                               struct sanboot_options, drive, parse_integer ),
60                 OPTION_DESC ( "no-describe", 'n', no_argument,
61                               struct sanboot_options, no_describe, parse_flag ),
62                 OPTION_DESC ( "keep", 'k', no_argument,
63                               struct sanboot_options, keep, parse_flag ),
64         },
65 };
66
67
68 /** "sanhook" command descriptor */
69 static struct command_descriptor sanhook_cmd =
70         COMMAND_DESC ( struct sanboot_options, opts.sanhook, 1, 1,
71                        "<root-path>" );
72
73 /** "sanboot" command descriptor */
74 static struct command_descriptor sanboot_cmd =
75         COMMAND_DESC ( struct sanboot_options, opts.sanboot, 0, 1,
76                        "[<root-path>]" );
77
78 /** "sanunhook" command descriptor */
79 static struct command_descriptor sanunhook_cmd =
80         COMMAND_DESC ( struct sanboot_options, opts.sanunhook, 0, 0, NULL );
81
82 /**
83  * The "sanboot", "sanhook" and "sanunhook" commands
84  *
85  * @v argc              Argument count
86  * @v argv              Argument list
87  * @v default_flags     Default set of flags for uriboot()
88  * @v no_root_path_flags Additional flags to apply if no root path is present
89  * @ret rc              Return status code
90  */
91 static int sanboot_core_exec ( int argc, char **argv,
92                                struct command_descriptor *cmd,
93                                int default_flags, int no_root_path_flags ) {
94         struct sanboot_options opts;
95         const char *root_path;
96         struct uri *uri;
97         int flags;
98         int rc;
99
100         /* Initialise options */
101         memset ( &opts, 0, sizeof ( opts ) );
102         opts.drive = san_default_drive();
103
104         /* Parse options */
105         if ( ( rc = reparse_options ( argc, argv, cmd, &opts ) ) != 0 )
106                 goto err_parse_options;
107
108         /* Parse root path, if present */
109         if ( argc > optind ) {
110                 root_path = argv[optind];
111                 uri = parse_uri ( root_path );
112                 if ( ! uri ) {
113                         rc = -ENOMEM;
114                         goto err_parse_uri;
115                 }
116         } else {
117                 root_path = NULL;
118                 uri = NULL;
119         }
120
121         /* Construct flags */
122         flags = default_flags;
123         if ( opts.no_describe )
124                 flags |= URIBOOT_NO_SAN_DESCRIBE;
125         if ( opts.keep )
126                 flags |= URIBOOT_NO_SAN_UNHOOK;
127         if ( ! root_path )
128                 flags |= no_root_path_flags;
129
130         /* Boot from root path */
131         if ( ( rc = uriboot ( NULL, uri, opts.drive, flags ) ) != 0 )
132                 goto err_uriboot;
133
134  err_uriboot:
135         uri_put ( uri );
136  err_parse_uri:
137  err_parse_options:
138         return rc;
139 }
140
141 /**
142  * The "sanhook" command
143  *
144  * @v argc              Argument count
145  * @v argv              Argument list
146  * @ret rc              Return status code
147  */
148 static int sanhook_exec ( int argc, char **argv ) {
149         return sanboot_core_exec ( argc, argv, &sanhook_cmd,
150                                    ( URIBOOT_NO_SAN_BOOT |
151                                      URIBOOT_NO_SAN_UNHOOK ), 0 );
152 }
153
154 /**
155  * The "sanboot" command
156  *
157  * @v argc              Argument count
158  * @v argv              Argument list
159  * @ret rc              Return status code
160  */
161 static int sanboot_exec ( int argc, char **argv ) {
162         return sanboot_core_exec ( argc, argv, &sanboot_cmd,
163                                    0, URIBOOT_NO_SAN_UNHOOK );
164 }
165
166 /**
167  * The "sanunhook" command
168  *
169  * @v argc              Argument count
170  * @v argv              Argument list
171  * @ret rc              Return status code
172  */
173 static int sanunhook_exec ( int argc, char **argv ) {
174         return sanboot_core_exec ( argc, argv, &sanunhook_cmd,
175                                    ( URIBOOT_NO_SAN_DESCRIBE |
176                                      URIBOOT_NO_SAN_BOOT ), 0 );
177 }
178
179 /** SAN commands */
180 struct command sanboot_commands[] __command = {
181         {
182                 .name = "sanhook",
183                 .exec = sanhook_exec,
184         },
185         {
186                 .name = "sanboot",
187                 .exec = sanboot_exec,
188         },
189         {
190                 .name = "sanunhook",
191                 .exec = sanunhook_exec,
192         },
193 };