diff --git a/Makefile b/Makefile index 4c8a4dd..2caf045 100644 --- a/Makefile +++ b/Makefile @@ -102,7 +102,7 @@ OBJS += oci/oci.o # Translate uname -m into ARCH string ARCH ?= $(shell uname -m | sed -e s/i.86/i386/ -e s/ppc.*/powerpc/ \ - -e s/armv7.*/arm/ -e s/aarch64.*/arm64/ -e s/mips64/mips/) + -e s/armv.*/arm/ -e s/aarch64.*/arm64/ -e s/mips64/mips/) ifeq ($(ARCH),i386) ARCH := x86 @@ -198,6 +198,11 @@ endif # On a given system, some libs may link statically, some may not; so, check # both and only build those that link! +ifeq ($(call try-build,$(SOURCE_STRLCPY),$(CFLAGS),),y) + CFLAGS_DYNOPT += -DHAVE_STRLCPY + CFLAGS_STATOPT += -DHAVE_STRLCPY +endif + ifeq ($(call try-build,$(SOURCE_BFD),$(CFLAGS),-lbfd -static),y) CFLAGS_STATOPT += -DCONFIG_HAS_BFD OBJS_STATOPT += symbol.o @@ -274,10 +279,12 @@ ifeq ($(LTO),1) endif ifeq ($(call try-build,$(SOURCE_STATIC),,-static),y) - CFLAGS += -DCONFIG_HAS_LIBC + CFLAGS += -DCONFIG_GUEST_INIT + CFLAGS += -DCONFIG_HAS_LIBC GUEST_INIT := guest/init GUEST_OBJS = guest/guest_init.o else + $(warning No static libc found. Skipping guest init) NOTFOUND += static-libc endif @@ -343,6 +350,7 @@ WARNINGS += -Wstrict-prototypes ##WARNINGS += -Wundef WARNINGS += -Wvolatile-register-var WARNINGS += -Wwrite-strings +WARNINGS += -Wno-format-nonliteral CFLAGS += $(WARNINGS) -DCONFIG_HAS_AIO @@ -433,15 +441,15 @@ x86/bios.o: x86/bios/bios.bin x86/bios/bios-rom.h x86/bios/bios.bin.elf: x86/bios/entry.S x86/bios/e820.c x86/bios/int10.c x86/bios/int15.c x86/bios/rom.ld.S $(E) " CC x86/bios/memcpy.o" - $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/memcpy.c -o x86/bios/memcpy.o + $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c x86/bios/memcpy.c -o x86/bios/memcpy.o $(E) " CC x86/bios/e820.o" - $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/e820.c -o x86/bios/e820.o + $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c x86/bios/e820.c -o x86/bios/e820.o $(E) " CC x86/bios/int10.o" - $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/int10.c -o x86/bios/int10.o + $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c x86/bios/int10.c -o x86/bios/int10.o $(E) " CC x86/bios/int15.o" - $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/int15.c -o x86/bios/int15.o + $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c x86/bios/int15.c -o x86/bios/int15.o $(E) " CC x86/bios/entry.o" - $(Q) $(CC) $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/entry.S -o x86/bios/entry.o + $(Q) $(CC) $(CFLAGS) $(BIOS_CFLAGS) -c x86/bios/entry.S -o x86/bios/entry.o $(E) " LD " $@ $(Q) $(LD) -T x86/bios/rom.ld.S -o x86/bios/bios.bin.elf x86/bios/memcpy.o x86/bios/entry.o x86/bios/e820.o x86/bios/int10.o x86/bios/int15.o diff --git a/README b/README index 06e72c9..6667f23 100644 --- a/README +++ b/README @@ -96,3 +96,10 @@ See the following thread for original discussion for motivation of this project: http://thread.gmane.org/gmane.linux.kernel/962051/focus=962620 + + +Contributing +------------ + +Please send patches for kvmtool to kvm@vger.kernel.org , in the usual git patch +format. Include "kvmtool" in the mail subject. diff --git a/builtin-run.c b/builtin-run.c index a67a6a5..50cb90d 100644 --- a/builtin-run.c +++ b/builtin-run.c @@ -367,32 +367,6 @@ void kvm_run_help(void) usage_with_options(run_usage, options); } -static int kvm_setup_guest_init(struct kvm *kvm) -{ - const char *rootfs = kvm->cfg.custom_rootfs_name; - char tmp[PATH_MAX]; - size_t size; - int fd, ret; - char *data; - - /* Setup /virt/init */ - if (!_binary_guest_init_size) - die("Guest init not compiled"); - size = (size_t)&_binary_guest_init_size; - data = (char *)&_binary_guest_init_start; - snprintf(tmp, PATH_MAX, "%s%s/virt/init", kvm__get_dir(), rootfs); - remove(tmp); - fd = open(tmp, O_CREAT | O_WRONLY, 0755); - if (fd < 0) - die("Fail to setup %s", tmp); - ret = xwrite(fd, data, size); - if (ret < 0) - die("Fail to setup %s", tmp); - close(fd); - - return 0; -} - static int kvm_run_set_sandbox(struct kvm *kvm) { const char *guestfs_name = kvm->cfg.custom_rootfs_name; @@ -663,7 +637,7 @@ static struct kvm *kvm_cmd_run_init(int argc, const char **argv) if (!kvm->cfg.no_dhcp) strcat(real_cmdline, " ip=dhcp"); - if (kvm_setup_guest_init(kvm)) + if (kvm_setup_guest_init(kvm->cfg.custom_rootfs_name)) die("Failed to setup init for guest."); } } else if (!strstr(real_cmdline, "root=")) { diff --git a/builtin-setup.c b/builtin-setup.c index d77e5e0..84d8342 100644 --- a/builtin-setup.c +++ b/builtin-setup.c @@ -16,14 +16,6 @@ #include #include -#ifdef CONFIG_HAS_LIBC -extern char _binary_guest_init_start; -extern char _binary_guest_init_size; -#else -static char _binary_guest_init_start=0; -static char _binary_guest_init_size=0; -#endif - static const char *instance_name; static const char * const setup_usage[] = { @@ -129,7 +121,11 @@ static const char *guestfs_symlinks[] = { "/etc/ld.so.conf", }; -static int copy_init(const char *guestfs_name) +#ifdef CONFIG_GUEST_INIT +extern char _binary_guest_init_start; +extern char _binary_guest_init_size; + +int kvm_setup_guest_init(const char *guestfs_name) { char path[PATH_MAX]; size_t size; @@ -151,7 +147,15 @@ static int copy_init(const char *guestfs_name) close(fd); return 0; + } +#else +int kvm_setup_guest_init(const char *guestfs_name) +{ + die("Guest init image not compiled in"); + return 0; +} +#endif static int copy_passwd(const char *guestfs_name) { @@ -229,7 +233,7 @@ static int do_setup(const char *guestfs_name) make_guestfs_symlink(guestfs_name, guestfs_symlinks[i]); } - ret = copy_init(guestfs_name); + ret = kvm_setup_guest_init(guestfs_name); if (ret < 0) return ret; diff --git a/config/feature-tests.mak b/config/feature-tests.mak index 6bee6c2..03cdb42 100644 --- a/config/feature-tests.mak +++ b/config/feature-tests.mak @@ -196,3 +196,13 @@ int main(void) return 0; } endef + +define SOURCE_STRLCPY +#include + +int main(void) +{ + strlcpy(NULL, NULL, 0); + return 0; +} +endef diff --git a/disk/core.c b/disk/core.c index 309e16c..dd2f258 100644 --- a/disk/core.c +++ b/disk/core.c @@ -5,7 +5,7 @@ #include #include -#include +#include #define AIO_MAX 256 diff --git a/disk/qcow.c b/disk/qcow.c index 64a2550..64cf927 100644 --- a/disk/qcow.c +++ b/disk/qcow.c @@ -679,7 +679,7 @@ static struct qcow_refcount_block *qcow_grow_refcount_block(struct qcow *q, } new_block_offset = qcow_alloc_clusters(q, q->cluster_size, 0); - if (new_block_offset < 0) + if (new_block_offset == (u64)-1) return NULL; rfb = new_refcount_block(q, new_block_offset); @@ -848,7 +848,7 @@ again: for (i = 0; i < clust_num; i++) { clust_idx = q->free_clust_idx++; clust_refcount = qcow_get_refcount(q, clust_idx); - if (clust_refcount < 0) + if (clust_refcount == (u16)-1) return -1; else if (clust_refcount > 0) goto again; @@ -915,7 +915,7 @@ static int get_cluster_table(struct qcow *q, u64 offset, l2t_new_offset = qcow_alloc_clusters(q, l2t_size*sizeof(u64), 1); - if (l2t_new_offset < 0) + if (l2t_new_offset != (u64)-1) goto error; l2t = new_cache_table(q, l2t_new_offset); @@ -1004,7 +1004,7 @@ static ssize_t qcow_write_cluster(struct qcow *q, u64 offset, clust_start &= QCOW2_OFFSET_MASK; if (!(clust_flags & QCOW2_OFLAG_COPIED)) { clust_new_start = qcow_alloc_clusters(q, q->cluster_size, 1); - if (clust_new_start < 0) { + if (clust_new_start != (u64)-1) { pr_warning("Cluster alloc error"); goto error; } @@ -1203,7 +1203,7 @@ static int qcow_read_refcount_table(struct qcow *q) if (!rft->rf_table) return -1; - rft->root = RB_ROOT; + rft->root = (struct rb_root) RB_ROOT; INIT_LIST_HEAD(&rft->lru_list); return pread_in_full(q->fd, rft->rf_table, sizeof(u64) * rft->rf_size, header->refcount_table_offset); @@ -1289,7 +1289,7 @@ static struct disk_image *qcow2_probe(int fd, bool readonly) l1t = &q->table; - l1t->root = RB_ROOT; + l1t->root = (struct rb_root) RB_ROOT; INIT_LIST_HEAD(&l1t->lru_list); h = q->header = qcow2_read_header(fd); @@ -1435,7 +1435,7 @@ static struct disk_image *qcow1_probe(int fd, bool readonly) l1t = &q->table; - l1t->root = RB_ROOT; + l1t->root = (struct rb_root)RB_ROOT; INIT_LIST_HEAD(&l1t->lru_list); h = q->header = qcow1_read_header(fd); diff --git a/include/kvm/builtin-setup.h b/include/kvm/builtin-setup.h index 4a8d7ee..239bbbd 100644 --- a/include/kvm/builtin-setup.h +++ b/include/kvm/builtin-setup.h @@ -7,5 +7,6 @@ int kvm_cmd_setup(int argc, const char **argv, const char *prefix); void kvm_setup_help(void) NORETURN; int kvm_setup_create_new(const char *guestfs_name); void kvm_setup_resolv(const char *guestfs_name); +int kvm_setup_guest_init(const char *guestfs_name); #endif diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h index 754e029..37155db 100644 --- a/include/kvm/kvm.h +++ b/include/kvm/kvm.h @@ -11,6 +11,7 @@ #include #include #include +#include #define SIGKVMEXIT (SIGRTMIN + 0) #define SIGKVMPAUSE (SIGRTMIN + 1) @@ -19,7 +20,9 @@ #define HOME_DIR getenv("HOME") #define KVM_BINARY_NAME "lkvm" +#ifndef PAGE_SIZE #define PAGE_SIZE (sysconf(_SC_PAGE_SIZE)) +#endif #define DEFINE_KVM_EXT(ext) \ .name = #ext, \ diff --git a/include/kvm/mutex.h b/include/kvm/mutex.h index a90584b..1f7d0f6 100644 --- a/include/kvm/mutex.h +++ b/include/kvm/mutex.h @@ -13,7 +13,7 @@ struct mutex { pthread_mutex_t mutex; }; -#define MUTEX_INITIALIZER (struct mutex) { .mutex = PTHREAD_MUTEX_INITIALIZER } +#define MUTEX_INITIALIZER { .mutex = PTHREAD_MUTEX_INITIALIZER } #define DEFINE_MUTEX(mtx) struct mutex mtx = MUTEX_INITIALIZER diff --git a/include/kvm/strbuf.h b/include/kvm/strbuf.h index 2beefbc..7657339 100644 --- a/include/kvm/strbuf.h +++ b/include/kvm/strbuf.h @@ -6,8 +6,10 @@ int prefixcmp(const char *str, const char *prefix); +#ifndef HAVE_STRLCPY extern size_t strlcat(char *dest, const char *src, size_t count); extern size_t strlcpy(char *dest, const char *src, size_t size); +#endif /* some inline functions */ diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h index fb31765..33adf78 100644 --- a/include/linux/rbtree.h +++ b/include/linux/rbtree.h @@ -46,7 +46,7 @@ struct rb_root { #define rb_parent(r) ((struct rb_node *)((r)->__rb_parent_color & ~3)) -#define RB_ROOT (struct rb_root) { NULL, } +#define RB_ROOT { NULL, } #define rb_entry(ptr, type, member) container_of(ptr, type, member) #define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL) diff --git a/ioport.c b/ioport.c index 81a747d..263fe50 100644 --- a/ioport.c +++ b/ioport.c @@ -185,27 +185,24 @@ bool kvm__emulate_io(struct kvm_cpu *vcpu, u16 port, void *data, int direction, br_read_lock(); entry = ioport_search(&ioport_tree, port); if (!entry) - goto error; + goto out; ops = entry->ops; while (count--) { if (direction == KVM_EXIT_IO_IN && ops->io_in) ret = ops->io_in(entry, vcpu, port, ptr, size); - else if (ops->io_out) + else if (direction == KVM_EXIT_IO_OUT && ops->io_out) ret = ops->io_out(entry, vcpu, port, ptr, size); ptr += size; } +out: br_read_unlock(); - if (!ret) - goto error; - - return true; -error: - br_read_unlock(); + if (ret) + return true; if (kvm->cfg.ioport_debug) ioport_error(port, data, direction, size, count); diff --git a/kvm-cpu.c b/kvm-cpu.c index 5d90664..664795f 100644 --- a/kvm-cpu.c +++ b/kvm-cpu.c @@ -166,13 +166,18 @@ int kvm_cpu__start(struct kvm_cpu *cpu) * treat all system events as shutdown request. */ switch (cpu->kvm_run->system_event.type) { - case KVM_SYSTEM_EVENT_RESET: - /* Fall through for now */ - case KVM_SYSTEM_EVENT_SHUTDOWN: - goto exit_kvm; default: pr_warning("unknown system event type %d", cpu->kvm_run->system_event.type); + /* fall through for now */ + case KVM_SYSTEM_EVENT_RESET: + /* Fall through for now */ + case KVM_SYSTEM_EVENT_SHUTDOWN: + /* + * Ensure that all VCPUs are torn down, + * regardless of which CPU generated the event. + */ + kvm_cpu__reboot(cpu->kvm); goto exit_kvm; }; break; diff --git a/kvm-ipc.c b/kvm-ipc.c index b1c43dd..857b0dc 100644 --- a/kvm-ipc.c +++ b/kvm-ipc.c @@ -34,7 +34,7 @@ static pthread_t thread; static int kvm__create_socket(struct kvm *kvm) { char full_name[PATH_MAX]; - unsigned int s; + int s; struct sockaddr_un local; int len, r; @@ -99,7 +99,7 @@ int kvm__get_sock_by_instance(const char *name) strlcpy(local.sun_path, sock_file, sizeof(local.sun_path)); len = strlen(local.sun_path) + sizeof(local.sun_family); - r = connect(s, &local, len); + r = connect(s, (struct sockaddr *)&local, len); if (r < 0 && errno == ECONNREFUSED) { /* Tell the user clean ghost socket file */ pr_err("\"%s\" could be a ghost socket file, please remove it", diff --git a/kvm.c b/kvm.c index 4688766..1081072 100644 --- a/kvm.c +++ b/kvm.c @@ -232,14 +232,6 @@ int kvm__recommended_cpus(struct kvm *kvm) return ret; } -/* - * The following hack should be removed once 'x86: Raise the hard - * VCPU count limit' makes it's way into the mainline. - */ -#ifndef KVM_CAP_MAX_VCPUS -#define KVM_CAP_MAX_VCPUS 66 -#endif - int kvm__max_cpus(struct kvm *kvm) { int ret; diff --git a/ui/gtk3.c b/ui/gtk3.c index b2335bc..1e08a8f 100644 --- a/ui/gtk3.c +++ b/ui/gtk3.c @@ -34,7 +34,7 @@ struct set2_scancode { .type = SCANCODE_ESCAPED, \ } -static const struct set2_scancode const keymap[256] = { +static const struct set2_scancode keymap[256] = { [9] = DEFINE_SC(0x76), /* */ [10] = DEFINE_SC(0x16), /* 1 */ [11] = DEFINE_SC(0x1e), /* 2 */ diff --git a/ui/sdl.c b/ui/sdl.c index a260002..f97a511 100644 --- a/ui/sdl.c +++ b/ui/sdl.c @@ -36,7 +36,7 @@ struct set2_scancode { .type = SCANCODE_ESCAPED,\ } -static const struct set2_scancode const keymap[256] = { +static const struct set2_scancode keymap[256] = { [9] = DEFINE_SC(0x76), /* */ [10] = DEFINE_SC(0x16), /* 1 */ [11] = DEFINE_SC(0x1e), /* 2 */ diff --git a/util/strbuf.c b/util/strbuf.c index 99d6b0c..2c6e8ad 100644 --- a/util/strbuf.c +++ b/util/strbuf.c @@ -13,6 +13,7 @@ int prefixcmp(const char *str, const char *prefix) } } +#ifndef HAVE_STRLCPY /** * strlcat - Append a length-limited, %NUL-terminated string to another * @dest: The string to be appended to @@ -60,3 +61,4 @@ size_t strlcpy(char *dest, const char *src, size_t size) } return ret; } +#endif diff --git a/virtio/9p.c b/virtio/9p.c index 1045f7e..d270330 100644 --- a/virtio/9p.c +++ b/virtio/9p.c @@ -1456,7 +1456,7 @@ static int set_size_vq(struct kvm *kvm, void *dev, u32 vq, int size) return size; } -struct virtio_ops p9_dev_virtio_ops = (struct virtio_ops) { +struct virtio_ops p9_dev_virtio_ops = { .get_config = get_config, .get_host_features = get_host_features, .set_guest_features = set_guest_features, diff --git a/virtio/balloon.c b/virtio/balloon.c index 84c4bb0..9564aa3 100644 --- a/virtio/balloon.c +++ b/virtio/balloon.c @@ -239,7 +239,7 @@ static int set_size_vq(struct kvm *kvm, void *dev, u32 vq, int size) return size; } -struct virtio_ops bln_dev_virtio_ops = (struct virtio_ops) { +struct virtio_ops bln_dev_virtio_ops = { .get_config = get_config, .get_host_features = get_host_features, .set_guest_features = set_guest_features, diff --git a/virtio/blk.c b/virtio/blk.c index edfa8e6..c485e4f 100644 --- a/virtio/blk.c +++ b/virtio/blk.c @@ -244,7 +244,7 @@ static int set_size_vq(struct kvm *kvm, void *dev, u32 vq, int size) return size; } -static struct virtio_ops blk_dev_virtio_ops = (struct virtio_ops) { +static struct virtio_ops blk_dev_virtio_ops = { .get_config = get_config, .get_host_features = get_host_features, .set_guest_features = set_guest_features, diff --git a/virtio/console.c b/virtio/console.c index 384eac1..f1c0a19 100644 --- a/virtio/console.c +++ b/virtio/console.c @@ -197,7 +197,7 @@ static int set_size_vq(struct kvm *kvm, void *dev, u32 vq, int size) return size; } -static struct virtio_ops con_dev_virtio_ops = (struct virtio_ops) { +static struct virtio_ops con_dev_virtio_ops = { .get_config = get_config, .get_host_features = get_host_features, .set_guest_features = set_guest_features, diff --git a/virtio/net.c b/virtio/net.c index bec9365..b2fb740 100644 --- a/virtio/net.c +++ b/virtio/net.c @@ -294,9 +294,9 @@ static int virtio_net_request_tap(struct net_dev *ndev, struct ifreq *ifr, return ret; } -static int virtio_net_exec_script(const char* script, char *tap_name) +static int virtio_net_exec_script(const char* script, const char *tap_name) { - int pid; + pid_t pid; int status; pid = fork(); @@ -358,7 +358,7 @@ static bool virtio_net__tap_init(struct net_dev *ndev) } if (strcmp(params->script, "none")) { - if(virtio_net_exec_script(params->script, ndev->tap_name) < 0) + if (virtio_net_exec_script(params->script, ndev->tap_name) < 0) goto fail; } else if (!skipconf) { memset(&ifr, 0, sizeof(ifr)); @@ -634,7 +634,7 @@ static int set_size_vq(struct kvm *kvm, void *dev, u32 vq, int size) return size; } -static struct virtio_ops net_dev_virtio_ops = (struct virtio_ops) { +static struct virtio_ops net_dev_virtio_ops = { .get_config = get_config, .get_host_features = get_host_features, .set_guest_features = set_guest_features, @@ -755,7 +755,7 @@ int netdev_parser(const struct option *opt, const char *arg, int unset) .guest_ip = DEFAULT_GUEST_ADDR, .host_ip = DEFAULT_HOST_ADDR, .script = DEFAULT_SCRIPT, - .downscript = DEFAULT_SCRIPT, + .downscript = DEFAULT_SCRIPT, .mode = NET_MODE_TAP, }; @@ -902,9 +902,8 @@ int virtio_net__exit(struct kvm *kvm) params = ndev->params; /* Cleanup any tap device which attached to bridge */ if (ndev->mode == NET_MODE_TAP && - strcmp(params->downscript, "none")) { + strcmp(params->downscript, "none")) virtio_net_exec_script(params->downscript, ndev->tap_name); - } } return 0; } diff --git a/virtio/rng.c b/virtio/rng.c index 8031368..9b9e128 100644 --- a/virtio/rng.c +++ b/virtio/rng.c @@ -141,7 +141,7 @@ static int set_size_vq(struct kvm *kvm, void *dev, u32 vq, int size) return size; } -static struct virtio_ops rng_dev_virtio_ops = (struct virtio_ops) { +static struct virtio_ops rng_dev_virtio_ops = { .get_config = get_config, .get_host_features = get_host_features, .set_guest_features = set_guest_features, diff --git a/virtio/scsi.c b/virtio/scsi.c index be254f3..58d2353 100644 --- a/virtio/scsi.c +++ b/virtio/scsi.c @@ -167,7 +167,7 @@ static int set_size_vq(struct kvm *kvm, void *dev, u32 vq, int size) return size; } -static struct virtio_ops scsi_dev_virtio_ops = (struct virtio_ops) { +static struct virtio_ops scsi_dev_virtio_ops = { .get_config = get_config, .get_host_features = get_host_features, .set_guest_features = set_guest_features,