static int add_disk (guestfs_h *g, const char *filename, const char *format, int readonly_in_xml, const char *protocol, char *const *server, const char *username, void *datavp) { struct add_disk_data *data = datavp; /* Copy whole struct so we can make local changes: */ struct guestfs_add_drive_opts_argv optargs = data->optargs; int readonly = -1, error = 0, skip = 0; if (readonly_in_xml) { /* <readonly/> appears in the XML */ if (data->readonly) { /* asked to add disk read-only */ switch (data->readonlydisk) { case readonlydisk_error: readonly = 1; break; case readonlydisk_read: readonly = 1; break; case readonlydisk_write: readonly = 1; break; case readonlydisk_ignore: skip = 1; break; } } else { /* asked to add disk for read/write */ switch (data->readonlydisk) { case readonlydisk_error: error = 1; break; case readonlydisk_read: readonly = 1; break; case readonlydisk_write: readonly = 0; break; case readonlydisk_ignore: skip = 1; break; } } } else /* no <readonly/> in XML */ readonly = data->readonly; if (skip) return 0; if (error) { error (g, _("%s: disk is marked <readonly/> in libvirt XML, and readonlydisk was set to \"error\""), filename); return -1; } if (readonly == -1) abort (); optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_READONLY_BITMASK; optargs.readonly = readonly; if (format) { optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_FORMAT_BITMASK; optargs.format = format; } if (protocol) { optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_PROTOCOL_BITMASK; optargs.protocol = protocol; } if (server) { optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_SERVER_BITMASK; optargs.server = server; } if (username) { optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_USERNAME_BITMASK; optargs.username = username; } return guestfs_add_drive_opts_argv (g, filename, &optargs); }
char add_drives_handle (guestfs_h *g, struct drv *drv, char next_drive) { int r; struct guestfs_add_drive_opts_argv ad_optargs; if (next_drive > 'z') { fprintf (stderr, _("%s: too many drives added on the command line\n"), program_name); exit (EXIT_FAILURE); } if (drv) { next_drive = add_drives (drv->next, next_drive); free (drv->device); drv->device = NULL; if (asprintf (&drv->device, "/dev/sd%c", next_drive) == -1) { perror ("asprintf"); exit (EXIT_FAILURE); } switch (drv->type) { case drv_a: ad_optargs.bitmask = 0; if (read_only) { ad_optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_READONLY_BITMASK; ad_optargs.readonly = 1; } if (drv->a.format) { ad_optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_FORMAT_BITMASK; ad_optargs.format = drv->a.format; } if (drv->a.cachemode) { ad_optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_CACHEMODE_BITMASK; ad_optargs.cachemode = drv->a.cachemode; } if (drv->a.discard) { ad_optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_DISCARD_BITMASK; ad_optargs.discard = drv->a.discard; } r = guestfs_add_drive_opts_argv (g, drv->a.filename, &ad_optargs); if (r == -1) exit (EXIT_FAILURE); drv->nr_drives = 1; next_drive++; break; case drv_uri: ad_optargs.bitmask = 0; if (read_only) { ad_optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_READONLY_BITMASK; ad_optargs.readonly = 1; } if (drv->uri.format) { ad_optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_FORMAT_BITMASK; ad_optargs.format = drv->uri.format; } ad_optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_PROTOCOL_BITMASK; ad_optargs.protocol = drv->uri.protocol; if (drv->uri.server) { ad_optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_SERVER_BITMASK; ad_optargs.server = drv->uri.server; } if (drv->uri.username) { ad_optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_USERNAME_BITMASK; ad_optargs.username = drv->uri.username; } if (drv->uri.password) { ad_optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_SECRET_BITMASK; ad_optargs.secret = drv->uri.password; } r = guestfs_add_drive_opts_argv (g, drv->uri.path, &ad_optargs); if (r == -1) exit (EXIT_FAILURE); drv->nr_drives = 1; next_drive++; break; case drv_d: r = add_libvirt_drives (g, drv->d.guest); if (r == -1) exit (EXIT_FAILURE); drv->nr_drives = r; next_drive += r; break; #if COMPILING_GUESTFISH case drv_N: /* -N option is not affected by --ro */ r = guestfs_add_drive_opts (g, drv->N.filename, GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", -1); if (r == -1) exit (EXIT_FAILURE); drv->nr_drives = 1; next_drive++; break; #endif default: /* keep GCC happy */ abort (); } } return next_drive; }