+static int
+add_disk (guestfs_h *g, const char *filename, const char *format,
+ void *optargs_vp)
+{
+ struct guestfs_add_drive_opts_argv *optargs = optargs_vp;
+
+ if (format) {
+ optargs->bitmask |= GUESTFS_ADD_DRIVE_OPTS_FORMAT_BITMASK;
+ optargs->format = format;
+ } else
+ optargs->bitmask &= ~GUESTFS_ADD_DRIVE_OPTS_FORMAT_BITMASK;
+
+ return guestfs__add_drive_opts (g, filename, optargs);
+}
+
+/* This was proposed as an external API, but it's not quite baked yet. */
+static int
+guestfs___add_libvirt_dom (guestfs_h *g, virDomainPtr dom,
+ const struct guestfs___add_libvirt_dom_argv *optargs)
+{
+ int r = -1;
+ virErrorPtr err;
+ int cmdline_pos;
+
+ cmdline_pos = guestfs___checkpoint_cmdline (g);
+
+ int readonly =
+ optargs->bitmask & GUESTFS___ADD_LIBVIRT_DOM_READONLY_BITMASK
+ ? optargs->readonly : 0;
+ const char *iface =
+ optargs->bitmask & GUESTFS___ADD_LIBVIRT_DOM_IFACE_BITMASK
+ ? optargs->iface : NULL;
+
+ if (!readonly) {
+ virDomainInfo info;
+ if (virDomainGetInfo (dom, &info) == -1) {
+ err = virGetLastError ();
+ error (g, _("error getting domain info: %s"), err->message);
+ goto cleanup;
+ }
+ if (info.state != VIR_DOMAIN_SHUTOFF) {
+ error (g, _("error: domain is a live virtual machine.\nYou must use readonly access because write access to a running virtual machine\ncan cause disk corruption."));
+ goto cleanup;
+ }
+ }
+
+ /* Add the disks. */
+ struct guestfs_add_drive_opts_argv optargs2 = { .bitmask = 0 };
+ if (readonly) {
+ optargs2.bitmask |= GUESTFS_ADD_DRIVE_OPTS_READONLY_BITMASK;
+ optargs2.readonly = readonly;
+ }
+ if (iface) {
+ optargs2.bitmask |= GUESTFS_ADD_DRIVE_OPTS_IFACE_BITMASK;
+ optargs2.iface = iface;
+ }
+
+ r = guestfs___for_each_disk (g, dom, add_disk, &optargs2);
+
+ cleanup:
+ if (r == -1) guestfs___rollback_cmdline (g, cmdline_pos);
+ return r;
+}
+