Exemplo n.º 1
0
/* Run uml_mkcow to create a COW overlay. */
static char *
make_cow_overlay (guestfs_h *g, const char *original)
{
  CLEANUP_CMD_CLOSE struct command *cmd = guestfs_int_new_command (g);
  char *overlay;
  int r;

  if (guestfs_int_lazy_make_tmpdir (g) == -1)
    return NULL;

  overlay = safe_asprintf (g, "%s/overlay%d", g->tmpdir, g->unique++);

  guestfs_int_cmd_add_arg (cmd, "uml_mkcow");
  guestfs_int_cmd_add_arg (cmd, overlay);
  guestfs_int_cmd_add_arg (cmd, original);
  r = guestfs_int_cmd_run (cmd);
  if (r == -1) {
    free (overlay);
    return NULL;
  }
  if (!WIFEXITED (r) || WEXITSTATUS (r) != 0) {
    guestfs_int_external_command_failed (g, r, "uml_mkcow", original);
    free (overlay);
    return NULL;
  }

  return overlay;
}
Exemplo n.º 2
0
static int
write_or_append (guestfs_h *g, const char *path,
                 const char *content, size_t size,
                 int append)
{
  CLEANUP_UNLINK_FREE char *tmpfile = NULL;
  int fd = -1;
  int64_t filesize;

  /* If the content is small enough, use guestfs_internal_write{,_append}
   * since that call is more efficient.
   */
  if (size <= 2*1024*1024)
    return
      (!append ? guestfs_internal_write : guestfs_internal_write_append)
      (g, path, content, size);

  if (guestfs_int_lazy_make_tmpdir (g) == -1)
    goto err;

  /* Write the content out to a temporary file. */
  tmpfile = safe_asprintf (g, "%s/write%d", g->tmpdir, ++g->unique);

  fd = open (tmpfile, O_WRONLY|O_CREAT|O_NOCTTY|O_CLOEXEC, 0600);
  if (fd == -1) {
    perrorf (g, "open: %s", tmpfile);
    goto err;
  }

  if (full_write (fd, content, size) != size) {
    perrorf (g, "write: %s", tmpfile);
    goto err;
  }

  if (close (fd) == -1) {
    perrorf (g, "close: %s", tmpfile);
    goto err;
  }
  fd = -1;

  if (!append) {
    if (guestfs_upload (g, tmpfile, path) == -1)
      goto err;
  }
  else {
    /* XXX Should have an 'upload-append' call to make this atomic. */
    filesize = guestfs_filesize (g, path);
    if (filesize == -1)
      goto err;
    if (guestfs_upload_offset (g, tmpfile, path, filesize) == -1)
      goto err;
  }

  return 0;

 err:
  if (fd >= 0)
    close (fd);
  return -1;
}
Exemplo n.º 3
0
int
guestfs_impl_launch (guestfs_h *g)
{
  /* Configured? */
  if (g->state != CONFIG) {
    error (g, _("the libguestfs handle has already been launched"));
    return -1;
  }

  /* Start the clock ... */
  gettimeofday (&g->launch_t, NULL);
  TRACE0 (launch_start);

  /* Make the temporary directory. */
  if (guestfs_int_lazy_make_tmpdir (g) == -1)
    return -1;

  /* Some common debugging information. */
  if (g->verbose) {
    CLEANUP_FREE_VERSION struct guestfs_version *v =
      guestfs_version (g);
    struct backend *b;
    CLEANUP_FREE char *backend = guestfs_get_backend (g);
    int mask;

    debug (g, "launch: program=%s", g->program);
    if (STRNEQ (g->identifier, ""))
      debug (g, "launch: identifier=%s", g->identifier);
    debug (g, "launch: version=%"PRIi64".%"PRIi64".%"PRIi64"%s",
           v->major, v->minor, v->release, v->extra);

    for (b = backends; b != NULL; b = b->next)
      debug (g, "launch: backend registered: %s", b->name);
    debug (g, "launch: backend=%s", backend);

    debug (g, "launch: tmpdir=%s", g->tmpdir);
    mask = guestfs_int_getumask (g);
    if (mask >= 0)
      debug (g, "launch: umask=0%03o", (unsigned) mask);
    debug (g, "launch: euid=%ju", (uintmax_t) geteuid ());
  }

  /* Launch the appliance. */
  if (g->backend_ops->launch (g, g->backend_data, g->backend_arg) == -1)
    return -1;

  return 0;
}
Exemplo n.º 4
0
char *
guestfs_impl_read_file (guestfs_h *g, const char *path, size_t *size_r)
{
  int fd = -1;
  size_t size;
  CLEANUP_UNLINK_FREE char *tmpfile = NULL;
  char *ret = NULL;
  struct stat statbuf;

  if (guestfs_int_lazy_make_tmpdir (g) == -1)
    goto err;

  tmpfile = safe_asprintf (g, "%s/cat%d", g->tmpdir, ++g->unique);

  if (guestfs_download (g, path, tmpfile) == -1)
    goto err;

  fd = open (tmpfile, O_RDONLY|O_CLOEXEC);
  if (fd == -1) {
    perrorf (g, "open: %s", tmpfile);
    goto err;
  }

  /* Read the whole file into memory. */
  if (fstat (fd, &statbuf) == -1) {
    perrorf (g, "stat: %s", tmpfile);
    goto err;
  }

  /* Don't use safe_malloc, because we want to return an errno to the caller. */
  size = statbuf.st_size;
  ret = malloc (size + 1);
  if (!ret) {
    perrorf (g, "malloc: %zu bytes", size + 1);
    goto err;
  }

  if (full_read (fd, ret, size) != size) {
    perrorf (g, "full-read: %s: %zu bytes", tmpfile, size + 1);
    goto err;
  }

  ret[size] = '\0';

  if (close (fd) == -1) {
    perrorf (g, "close: %s", tmpfile);
    goto err;
  }

  /* Mustn't touch *size_r until we are sure that we won't return any
   * error (RHBZ#589039).
   */
  *size_r = size;
  return ret;

 err:
  free (ret);
  if (fd >= 0)
    close (fd);
  return NULL;
}