while (len > 0) {
r = read (fd, buf, len);
- if (r == -1)
+ if (r == -1) {
+ if (errno == EINTR || errno == EAGAIN)
+ continue;
return -1;
+ }
buf += r;
len -= r;
int
guestfs_add_drive (guestfs_h *g, const char *filename)
{
- int len = strlen (filename) + 64;
+ size_t len = strlen (filename) + 64;
char buf[len];
if (strchr (filename, ',') != NULL) {
guestfs_launch (guestfs_h *g)
{
static const char *dir_template = "/tmp/libguestfsXXXXXX";
- int r, i, len, pmore, memsize;
+ int r, i, pmore, memsize;
+ size_t len;
int wfd[2], rfd[2];
int tries;
const char *kernel_name = "vmlinuz." REPO "." host_cpu;
char *kernel = NULL, *initrd = NULL;
char unixsock[256];
struct sockaddr_un addr;
- struct stat statbuf;
/* Configured? */
if (!g->cmdline) {
goto cleanup0;
}
- /* Choose a suitable memory size (in MB). This is more art
- * than science, but you can help by doing
- * ./configure --enable-debug-command
- * and then running:
- * debug sh free
- * debug mem ''
- * and seeing how much free memory is left for particular
- * configurations.
- *
- * It's also helpful to report both the compressed and uncompressed
- * size of the initramfs (ls -lh initramfs*.img; du -sh initramfs).
- *
- * XXX KVM virtio balloon driver?
+ /* Choose a suitable memory size. Previously we tried to choose
+ * a minimal memory size, but this isn't really necessary since
+ * recent QEMU and KVM don't do anything nasty like locking
+ * memory into core any more. This we can safely choose a
+ * large, generous amount of memory, and it'll just get swapped
+ * on smaller systems.
*/
- if (stat (initrd, &statbuf) != -1) {
- /* Approximate size of the initramfs after it is decompressed
- * in kernel memory. The compression factor is ~2.5-3.
- */
- memsize = 3 * statbuf.st_size / 1024 / 1024;
-
- /* Approximate size used by the kernel. */
- memsize += 10;
-
- /* Want to give userspace some room, so: */
- memsize += 128;
-
-#if SIZEOF_LONG == 8
- /* On 64 bit, assume some overhead. */
- memsize += 64;
-#endif
- } else
- memsize = 512;
-
+ memsize = 384;
/* Make the temporary directory containing the socket. */
if (!g->tmpdir) {
/* Linux kernel command line. */
snprintf (append, sizeof append,
- "console=ttyS0 guestfs=%s:%d%s",
+ "panic=1 console=ttyS0 guestfs=%s:%d%s",
VMCHANNEL_ADDR, VMCHANNEL_PORT,
g->verbose ? " guestfs_verbose=1" : "");
#if 0
add_cmdline (g, "-no-kqemu"); /* Avoids a warning. */
#endif
+ add_cmdline (g, "-no-reboot"); /* Force exit instead of reboot on panic */
add_cmdline (g, "-kernel");
add_cmdline (g, (char *) kernel);
add_cmdline (g, "-initrd");
}
if (n == -1) {
- if (errno != EAGAIN)
+ if (errno != EINTR && errno != EAGAIN)
perrorf (g, "read");
return;
}
int watch, int fd, int events)
{
XDR xdr;
- unsigned len;
+ u_int32_t len;
int n;
if (g->verbose)
return;
if (n == -1) {
- if (errno != EAGAIN)
+ if (errno != EINTR && errno != EAGAIN)
perrorf (g, "read");
return;
}
{
struct guestfs_message_header hdr;
XDR xdr;
- unsigned len;
+ u_int32_t len;
int serial = g->msg_next_serial++;
int sent;
guestfs_main_loop *ml = guestfs_get_main_loop (g);
}
/* Send file in chunked encoding. */
- while (!cancel && (r = read (fd, buf, sizeof buf)) > 0) {
+ while (!cancel) {
+ r = read (fd, buf, sizeof buf);
+ if (r == -1 && (errno == EINTR || errno == EAGAIN))
+ continue;
+ if (r <= 0) break;
err = send_file_data_sync (g, buf, r);
if (err < 0) {
if (err == -2) /* daemon sent cancellation */
static int
send_file_chunk_sync (guestfs_h *g, int cancel, const char *buf, size_t buflen)
{
- unsigned len;
+ u_int32_t len;
int sent;
guestfs_chunk chunk;
XDR xdr;
/* Synchronously receive a file. */
/* Returns -1 = error, 0 = EOF, 1 = more data */
-static int receive_file_data_sync (guestfs_h *g, void **buf, int *len);
+static int receive_file_data_sync (guestfs_h *g, void **buf, size_t *len);
int
guestfs__receive_file_sync (guestfs_h *g, const char *filename)
{
void *buf;
- int fd, r, len;
+ int fd, r;
+ size_t len;
fd = open (filename, O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY, 0666);
if (fd == -1) {
/* Receive a chunk of file data. */
/* Returns -1 = error, 0 = EOF, 1 = more data */
static int
-receive_file_data_sync (guestfs_h *g, void **buf, int *len_r)
+receive_file_data_sync (guestfs_h *g, void **buf, size_t *len_r)
{
struct receive_file_ctx ctx;
guestfs_main_loop *ml = guestfs_get_main_loop (g);
- int i, len;
+ int i;
+ size_t len;
ctx.count = 0;
ctx.chunks = NULL;