/* Run supermin --build and tell it to generate the * appliance. */ static int run_supermin_build (guestfs_h *g, const char *lockfile, const char *appliancedir, const char *supermin_path) { CLEANUP_CMD_CLOSE struct command *cmd = guestfs_int_new_command (g); int r; #if 0 /* not supported in supermin 5 yet XXX */ uid_t uid = getuid (); uid_t euid = geteuid (); gid_t gid = getgid (); gid_t egid = getegid (); int pass_u_g_args = uid != euid || gid != egid; #endif guestfs_int_cmd_add_arg (cmd, SUPERMIN); guestfs_int_cmd_add_arg (cmd, "--build"); if (g->verbose) guestfs_int_cmd_add_arg (cmd, "--verbose"); guestfs_int_cmd_add_arg (cmd, "--if-newer"); guestfs_int_cmd_add_arg (cmd, "--lock"); guestfs_int_cmd_add_arg (cmd, lockfile); #if 0 if (pass_u_g_args) { guestfs_int_cmd_add_arg (cmd, "-u"); guestfs_int_cmd_add_arg_format (cmd, "%d", euid); guestfs_int_cmd_add_arg (cmd, "-g"); guestfs_int_cmd_add_arg_format (cmd, "%d", egid); } #endif guestfs_int_cmd_add_arg (cmd, "--copy-kernel"); guestfs_int_cmd_add_arg (cmd, "-f"); guestfs_int_cmd_add_arg (cmd, "ext2"); guestfs_int_cmd_add_arg (cmd, "--host-cpu"); guestfs_int_cmd_add_arg (cmd, host_cpu); #ifdef DTB_WILDCARD guestfs_int_cmd_add_arg (cmd, "--dtb"); guestfs_int_cmd_add_arg (cmd, DTB_WILDCARD); #endif guestfs_int_cmd_add_arg_format (cmd, "%s/supermin.d", supermin_path); guestfs_int_cmd_add_arg (cmd, "-o"); guestfs_int_cmd_add_arg (cmd, appliancedir); r = guestfs_int_cmd_run (cmd); if (r == -1) return -1; if (!WIFEXITED (r) || WEXITSTATUS (r) != 0) { guestfs_int_external_command_failed (g, r, SUPERMIN, NULL); return -1; } return 0; }
static json_t * get_json_output (guestfs_h *g, const char *filename) { CLEANUP_CMD_CLOSE struct command *cmd = guestfs_int_new_command (g); int r; json_t *tree = NULL; guestfs_int_cmd_add_arg (cmd, "qemu-img"); guestfs_int_cmd_add_arg (cmd, "info"); switch (qemu_img_supports_U_option (g)) { case -1: return NULL; case 0: break; default: guestfs_int_cmd_add_arg (cmd, "-U"); } guestfs_int_cmd_add_arg (cmd, "--output"); guestfs_int_cmd_add_arg (cmd, "json"); if (filename[0] == '/') guestfs_int_cmd_add_arg (cmd, filename); else guestfs_int_cmd_add_arg_format (cmd, "./%s", filename); guestfs_int_cmd_set_stdout_callback (cmd, parse_json, &tree, CMD_STDOUT_FLAG_WHOLE_BUFFER); set_child_rlimits (cmd); r = guestfs_int_cmd_run (cmd); if (r == -1) return NULL; if (!WIFEXITED (r) || WEXITSTATUS (r) != 0) { guestfs_int_external_command_failed (g, r, "qemu-img info", filename); return NULL; } if (tree == NULL) return NULL; /* parse_json callback already set an error */ if (tree == PARSE_JSON_NO_OUTPUT) { /* If this ever happened, it would indicate a bug in 'qemu-img info'. */ error (g, _("qemu-img info command produced no output, but didn't return an error status code")); return NULL; } return tree; /* caller must call json_decref (tree) */ }
static int disk_create_qcow2 (guestfs_h *g, const char *orig_filename, int64_t size, const char *backingfile, const struct guestfs_disk_create_argv *optargs) { CLEANUP_FREE char *filename = NULL; const char *backingformat = NULL; const char *preallocation = NULL; const char *compat = NULL; int clustersize = -1; CLEANUP_FREE_STRINGSBUF DECLARE_STRINGSBUF (optionsv); CLEANUP_CMD_CLOSE struct command *cmd = guestfs_int_new_command (g); int r; /* If the filename is something like "file:foo" then qemu-img will * try to interpret that as "foo" in the file:/// protocol. To * avoid that, if the path is relative prefix it with "./" since * qemu-img won't try to interpret such a path. */ if (orig_filename[0] != '/') filename = safe_asprintf (g, "./%s", orig_filename); else filename = safe_strdup (g, orig_filename); if (optargs->bitmask & GUESTFS_DISK_CREATE_BACKINGFORMAT_BITMASK) { backingformat = optargs->backingformat; /* Conservative whitelist. This can be extended with other * valid formats as required. */ if (STRNEQ (backingformat, "raw") && STRNEQ (backingformat, "qcow2") && STRNEQ (backingformat, "vmdk")) { error (g, _("invalid value for backingformat parameter '%s'"), backingformat); return -1; } } if (optargs->bitmask & GUESTFS_DISK_CREATE_PREALLOCATION_BITMASK) { if (STREQ (optargs->preallocation, "off") || STREQ (optargs->preallocation, "sparse")) preallocation = "off"; else if (STREQ (optargs->preallocation, "metadata")) preallocation = "metadata"; else if (STREQ (optargs->preallocation, "full")) /* Ugh: https://lists.gnu.org/archive/html/qemu-devel/2014-08/msg03863.html */ preallocation = "falloc"; else { error (g, _("invalid value for preallocation parameter '%s'"), preallocation); return -1; } } if (optargs->bitmask & GUESTFS_DISK_CREATE_COMPAT_BITMASK) { compat = optargs->compat; if (STRNEQ (compat, "0.10") && STRNEQ (compat, "1.1")) { error (g, _("invalid value for compat parameter '%s'"), compat); return -1; } } if (optargs->bitmask & GUESTFS_DISK_CREATE_CLUSTERSIZE_BITMASK) { clustersize = optargs->clustersize; if (clustersize < 512 || clustersize > 2097152 || !is_power_of_2 ((unsigned) clustersize)) { error (g, _("invalid value for clustersize parameter '%d'"), clustersize); return -1; } } /* Assemble the qemu-img command line. */ guestfs_int_cmd_add_arg (cmd, "qemu-img"); guestfs_int_cmd_add_arg (cmd, "create"); guestfs_int_cmd_add_arg (cmd, "-f"); guestfs_int_cmd_add_arg (cmd, "qcow2"); /* -o parameter. */ if (backingfile) { CLEANUP_FREE char *p = qemu_escape_param (g, backingfile); guestfs_int_add_sprintf (g, &optionsv, "backing_file=%s", p); } if (backingformat) guestfs_int_add_sprintf (g, &optionsv, "backing_fmt=%s", backingformat); if (preallocation) guestfs_int_add_sprintf (g, &optionsv, "preallocation=%s", preallocation); if (compat) guestfs_int_add_sprintf (g, &optionsv, "compat=%s", compat); if (clustersize >= 0) guestfs_int_add_sprintf (g, &optionsv, "cluster_size=%d", clustersize); guestfs_int_end_stringsbuf (g, &optionsv); if (optionsv.size > 1) { CLEANUP_FREE char *options = guestfs_int_join_strings (",", optionsv.argv); guestfs_int_cmd_add_arg (cmd, "-o"); guestfs_int_cmd_add_arg (cmd, options); } /* Complete the command line. */ guestfs_int_cmd_add_arg (cmd, filename); if (size >= 0) guestfs_int_cmd_add_arg_format (cmd, "%" PRIi64, size); r = guestfs_int_cmd_run (cmd); if (!WIFEXITED (r) || WEXITSTATUS (r) != 0) { guestfs_int_external_command_failed (g, r, "qemu-img", orig_filename); return -1; } return 0; }