+ *fatal_error = 0;
+ return dinfo;
+}
+
+static int drive_init_func(QemuOpts *opts, void *opaque)
+{
+ QEMUMachine *machine = opaque;
+ int fatal_error = 0;
+
+ if (drive_init(opts, machine, &fatal_error) == NULL) {
+ if (fatal_error)
+ return 1;
+ }
+ return 0;
+}
+
+static int drive_enable_snapshot(QemuOpts *opts, void *opaque)
+{
+ if (NULL == qemu_opt_get(opts, "snapshot")) {
+ qemu_opt_set(opts, "snapshot", "on");
+ }
+ return 0;
+}
+
+void qemu_register_boot_set(QEMUBootSetHandler *func, void *opaque)
+{
+ boot_set_handler = func;
+ boot_set_opaque = opaque;
+}
+
+int qemu_boot_set(const char *boot_devices)
+{
+ if (!boot_set_handler) {
+ return -EINVAL;
+ }
+ return boot_set_handler(boot_set_opaque, boot_devices);
+}
+
+static int parse_bootdevices(char *devices)
+{
+ /* We just do some generic consistency checks */
+ const char *p;
+ int bitmap = 0;
+
+ for (p = devices; *p != '\0'; p++) {
+ /* Allowed boot devices are:
+ * a-b: floppy disk drives
+ * c-f: IDE disk drives
+ * g-m: machine implementation dependant drives
+ * n-p: network devices
+ * It's up to each machine implementation to check if the given boot
+ * devices match the actual hardware implementation and firmware
+ * features.
+ */
+ if (*p < 'a' || *p > 'p') {
+ fprintf(stderr, "Invalid boot device '%c'\n", *p);
+ exit(1);
+ }
+ if (bitmap & (1 << (*p - 'a'))) {
+ fprintf(stderr, "Boot device '%c' was given twice\n", *p);
+ exit(1);
+ }
+ bitmap |= 1 << (*p - 'a');
+ }
+ return bitmap;
+}
+
+static void restore_boot_devices(void *opaque)
+{
+ char *standard_boot_devices = opaque;
+
+ qemu_boot_set(standard_boot_devices);
+
+ qemu_unregister_reset(restore_boot_devices, standard_boot_devices);
+ qemu_free(standard_boot_devices);