/* 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; }
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; }
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; }
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; }