[PATCH] lib: direct: Remove support for virtio-blk as the default.
by Richard W.M. Jones
virtio-scsi has been supported in qemu since 2012, and it is superior
in every respect to virtio-blk. There's no reason to still be using
virtio-blk.
virtio-scsi support was initially added in 2012
(commit 0c0a7d0d868d153adf0600189f771459e1068b0a).
You can still use virtio-blk using the (deprecated) iface parameter,
but don't do that in new code.
---
lib/guestfs-internal.h | 1 -
lib/launch-direct.c | 87 ++++++++++++++------------------------------------
lib/qemu.c | 47 ---------------------------
3 files changed, 24 insertions(+), 111 deletions(-)
diff --git a/lib/guestfs-internal.h b/lib/guestfs-internal.h
index 5e9d97c07..a04ccff09 100644
--- a/lib/guestfs-internal.h
+++ b/lib/guestfs-internal.h
@@ -983,7 +983,6 @@ struct qemu_data;
extern struct qemu_data *guestfs_int_test_qemu (guestfs_h *g, struct version *qemu_version);
extern int guestfs_int_qemu_supports (guestfs_h *g, const struct qemu_data *, const char *option);
extern int guestfs_int_qemu_supports_device (guestfs_h *g, const struct qemu_data *, const char *device_name);
-extern int guestfs_int_qemu_supports_virtio_scsi (guestfs_h *g, struct qemu_data *, const struct version *qemu_version);
extern char *guestfs_int_drive_source_qemu_param (guestfs_h *g, const struct drive_source *src);
extern bool guestfs_int_discard_possible (guestfs_h *g, struct drive *drv, const struct version *qemu_version);
extern char *guestfs_int_qemu_escape_param (guestfs_h *g, const char *param);
diff --git a/lib/launch-direct.c b/lib/launch-direct.c
index db9b9f3ef..b0038c6a9 100644
--- a/lib/launch-direct.c
+++ b/lib/launch-direct.c
@@ -60,7 +60,7 @@ struct backend_direct_data {
};
static int is_openable (guestfs_h *g, const char *path, int flags);
-static char *make_appliance_dev (guestfs_h *g, int virtio_scsi);
+static char *make_appliance_dev (guestfs_h *g);
static void print_qemu_command_line (guestfs_h *g, char **argv);
static char *
@@ -234,7 +234,6 @@ launch_direct (guestfs_h *g, void *datav, const char *arg)
CLEANUP_FREE void *buf = NULL;
struct drive *drv;
size_t i;
- int virtio_scsi;
struct hv_param *hp;
bool has_kvm;
int force_tcg;
@@ -336,14 +335,10 @@ launch_direct (guestfs_h *g, void *datav, const char *arg)
ADD_CMDLINE (g->hv);
/* CVE-2011-4127 mitigation: Disable SCSI ioctls on virtio-blk
- * devices. The -global option must exist, but you can pass any
- * strings to it so we don't need to check for the specific virtio
- * feature.
+ * devices.
*/
- if (guestfs_int_qemu_supports (g, data->qemu_data, "-global")) {
- ADD_CMDLINE ("-global");
- ADD_CMDLINE (VIRTIO_BLK ".scsi=off");
- }
+ ADD_CMDLINE ("-global");
+ ADD_CMDLINE (VIRTIO_BLK ".scsi=off");
if (guestfs_int_qemu_supports (g, data->qemu_data, "-nodefconfig"))
ADD_CMDLINE ("-nodefconfig");
@@ -461,16 +456,11 @@ launch_direct (guestfs_h *g, void *datav, const char *arg)
ADD_CMDLINE ("virtio-rng-pci,rng=rng0");
}
- /* Add drives */
- virtio_scsi = guestfs_int_qemu_supports_virtio_scsi (g, data->qemu_data,
- &data->qemu_version);
-
- if (virtio_scsi) {
- /* Create the virtio-scsi bus. */
- ADD_CMDLINE ("-device");
- ADD_CMDLINE (VIRTIO_SCSI ",id=scsi");
- }
+ /* Create the virtio-scsi bus. */
+ ADD_CMDLINE ("-device");
+ ADD_CMDLINE (VIRTIO_SCSI ",id=scsi");
+ /* Add drives */
ITER_DRIVES (g, i, drv) {
CLEANUP_FREE char *file = NULL, *escaped_file = NULL, *param = NULL;
@@ -529,10 +519,14 @@ launch_direct (guestfs_h *g, void *datav, const char *arg)
}
/* If there's an explicit 'iface', use it. Otherwise default to
- * virtio-scsi if available. Otherwise default to virtio-blk.
+ * virtio-scsi.
*/
- if (drv->iface && STREQ (drv->iface, "virtio")) /* virtio-blk */
- goto virtio_blk;
+ if (drv->iface && STREQ (drv->iface, "virtio")) { /* virtio-blk */
+ ADD_CMDLINE ("-drive");
+ ADD_CMDLINE_PRINTF ("%s,if=none" /* sic */, param);
+ ADD_CMDLINE ("-device");
+ ADD_CMDLINE_PRINTF (VIRTIO_BLK ",drive=hd%zu", i);
+ }
#if defined(__arm__) || defined(__aarch64__) || defined(__powerpc__)
else if (drv->iface && STREQ (drv->iface, "ide")) {
error (g, "'ide' interface does not work on ARM or PowerPC");
@@ -543,19 +537,12 @@ launch_direct (guestfs_h *g, void *datav, const char *arg)
ADD_CMDLINE ("-drive");
ADD_CMDLINE_PRINTF ("%s,if=%s", param, drv->iface);
}
- else if (virtio_scsi) {
+ else /* virtio-scsi */ {
ADD_CMDLINE ("-drive");
ADD_CMDLINE_PRINTF ("%s,if=none" /* sic */, param);
ADD_CMDLINE ("-device");
ADD_CMDLINE_PRINTF ("scsi-hd,drive=hd%zu", i);
}
- else {
- virtio_blk:
- ADD_CMDLINE ("-drive");
- ADD_CMDLINE_PRINTF ("%s,if=none" /* sic */, param);
- ADD_CMDLINE ("-device");
- ADD_CMDLINE_PRINTF (VIRTIO_BLK ",drive=hd%zu", i);
- }
}
/* Add the ext2 appliance drive (after all the drives). */
@@ -565,16 +552,10 @@ launch_direct (guestfs_h *g, void *datav, const char *arg)
"cache=unsafe,if=none,format=raw",
appliance);
- if (virtio_scsi) {
- ADD_CMDLINE ("-device");
- ADD_CMDLINE ("scsi-hd,drive=appliance");
- }
- else {
- ADD_CMDLINE ("-device");
- ADD_CMDLINE (VIRTIO_BLK ",drive=appliance");
- }
+ ADD_CMDLINE ("-device");
+ ADD_CMDLINE ("scsi-hd,drive=appliance");
- appliance_dev = make_appliance_dev (g, virtio_scsi);
+ appliance_dev = make_appliance_dev (g);
}
/* Create the virtio serial bus. */
@@ -881,25 +862,18 @@ launch_direct (guestfs_h *g, void *datav, const char *arg)
* NULL, "ide" or "virtio" (which means virtio-blk). See RHBZ#975797.
*/
static char *
-make_appliance_dev (guestfs_h *g, int virtio_scsi)
+make_appliance_dev (guestfs_h *g)
{
size_t i, index = 0;
struct drive *drv;
- char dev[64] = "/dev/Xd";
+ char dev[64] = "/dev/sd";
/* Calculate the index of the drive. */
ITER_DRIVES (g, i, drv) {
- if (virtio_scsi) {
- if (drv->iface == NULL || STREQ (drv->iface, "ide"))
- index++;
- }
- else /* virtio-blk */ {
- if (drv->iface == NULL || STRNEQ (drv->iface, "virtio"))
- index++;
- }
+ if (drv->iface == NULL || STREQ (drv->iface, "ide"))
+ index++;
}
- dev[5] = virtio_scsi ? 's' : 'v';
guestfs_int_drive_name (index, &dev[7]);
return safe_strdup (g, dev); /* Caller frees. */
@@ -1012,20 +986,7 @@ get_pid_direct (guestfs_h *g, void *datav)
static int
max_disks_direct (guestfs_h *g, void *datav)
{
- struct backend_direct_data *data = datav;
-
- /* Get qemu help text and version. */
- if (data->qemu_data == NULL) {
- data->qemu_data = guestfs_int_test_qemu (g, &data->qemu_version);
- if (data->qemu_data == NULL)
- return -1;
- }
-
- if (guestfs_int_qemu_supports_virtio_scsi (g, data->qemu_data,
- &data->qemu_version))
- return 255;
- else
- return 27; /* conservative estimate */
+ return 255;
}
static struct backend_ops backend_direct_ops = {
diff --git a/lib/qemu.c b/lib/qemu.c
index 6d8fe3594..8bec6bab0 100644
--- a/lib/qemu.c
+++ b/lib/qemu.c
@@ -46,9 +46,6 @@
struct qemu_data {
char *qemu_help; /* Output of qemu -help. */
char *qemu_devices; /* Output of qemu -device ? */
-
- int virtio_scsi; /* See function
- guestfs_int_qemu_supports_virtio_scsi */
};
static int test_qemu (guestfs_h *g, struct qemu_data *data, struct version *qemu_version);
@@ -303,50 +300,6 @@ guestfs_int_qemu_supports_device (guestfs_h *g,
return strstr (data->qemu_devices, device_name) != NULL;
}
-static int
-old_or_broken_virtio_scsi (const struct version *qemu_version)
-{
- /* qemu 1.1 claims to support virtio-scsi but in reality it's broken. */
- if (!guestfs_int_version_ge (qemu_version, 1, 2, 0))
- return 1;
-
- return 0;
-}
-
-/**
- * Test if qemu supports virtio-scsi.
- *
- * Returns C<1> = use virtio-scsi, or C<0> = use virtio-blk.
- */
-int
-guestfs_int_qemu_supports_virtio_scsi (guestfs_h *g, struct qemu_data *data,
- const struct version *qemu_version)
-{
- int r;
-
- /* data->virtio_scsi has these values:
- * 0 = untested (after handle creation)
- * 1 = supported
- * 2 = not supported (use virtio-blk)
- * 3 = test failed (use virtio-blk)
- */
- if (data->virtio_scsi == 0) {
- if (old_or_broken_virtio_scsi (qemu_version))
- data->virtio_scsi = 2;
- else {
- r = guestfs_int_qemu_supports_device (g, data, VIRTIO_SCSI);
- if (r > 0)
- data->virtio_scsi = 1;
- else if (r == 0)
- data->virtio_scsi = 2;
- else
- data->virtio_scsi = 3;
- }
- }
-
- return data->virtio_scsi == 1;
-}
-
/**
* Escape a qemu parameter.
*
--
2.12.0
7 years, 8 months
[PATCH] daemon: Remove use of fixed-size stack buffers.
by Richard W.M. Jones
GCC 7 complains that the fixed size buffers are not large enough
(at least in theory) when using ‘-O3 -mtune=broadwell’.
---
daemon/devsparts.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/daemon/devsparts.c b/daemon/devsparts.c
index 584e7d8b8..eac79197e 100644
--- a/daemon/devsparts.c
+++ b/daemon/devsparts.c
@@ -125,13 +125,16 @@ foreach_block_device (block_dev_func_t func, bool return_md)
static int
add_device (const char *device, struct stringsbuf *r)
{
- char dev_path[256];
- snprintf (dev_path, sizeof dev_path, "/dev/%s", device);
+ CLEANUP_FREE char *dev_path;
- if (add_string (r, dev_path) == -1) {
+ if (asprintf (&dev_path, "/dev/%s", device) == -1) {
+ reply_with_perror ("asprintf");
return -1;
}
+ if (add_string (r, dev_path) == -1)
+ return -1;
+
return 0;
}
@@ -153,10 +156,13 @@ do_list_devices (void)
static int
add_partitions (const char *device, struct stringsbuf *r)
{
- char devdir[256];
+ CLEANUP_FREE char *devdir;
/* Open the device's directory under /sys/block */
- snprintf (devdir, sizeof devdir, "/sys/block/%s", device);
+ if (asprintf (&devdir, "/sys/block/%s", device) == -1) {
+ reply_with_perror ("asprintf");
+ return -1;
+ }
DIR *dir = opendir (devdir);
if (!dir) {
--
2.12.0
7 years, 8 months
[PATCH] daemon: Add an assertion to suppress a warning with GCC.
by Richard W.M. Jones
swap.c: In function 'do_mkswap_U':
swap.c:62:9: error: argument 1 null where non-null expected [-Werror=nonnull]
if (strlen (label) > SWAP_LABEL_MAX) {
^~~~~~~~~~~~~~
---
daemon/swap.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/daemon/swap.c b/daemon/swap.c
index 028bc1ee2..fea4a9dcf 100644
--- a/daemon/swap.c
+++ b/daemon/swap.c
@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <assert.h>
#include "guestfs_protocol.h"
#include "daemon.h"
@@ -58,6 +59,7 @@ do_mkswap (const char *device, const char *label, const char *uuid)
ADD_ARG (argv, i, "-f");
if (optargs_bitmask & GUESTFS_MKSWAP_LABEL_BITMASK) {
+ assert (label != NULL); /* suppress a warning with -O3 */
if (strlen (label) > SWAP_LABEL_MAX) {
reply_with_error ("%s: Linux swap labels are limited to %d bytes",
label, SWAP_LABEL_MAX);
--
2.12.0
7 years, 8 months
[PATCH] daemon: Move the useful 'is_zero' function into common code.
by Richard W.M. Jones
This is largely a simple refactoring, but it combines another
definition of this function from virt-builder which had a slightly
different prototype.
---
builder/pxzcat-c.c | 20 +-------------------
daemon/daemon.h | 18 ------------------
lib/guestfs-internal-all.h | 18 ++++++++++++++++++
3 files changed, 19 insertions(+), 37 deletions(-)
diff --git a/builder/pxzcat-c.c b/builder/pxzcat-c.c
index 33923b532..ef37849ed 100644
--- a/builder/pxzcat-c.c
+++ b/builder/pxzcat-c.c
@@ -409,24 +409,6 @@ parse_indexes (value filenamev, int fd)
return combined_index;
}
-/* Return true iff the buffer is all zero bytes.
- *
- * Note that gcc is smart enough to optimize this properly:
- * http://stackoverflow.com/questions/1493936/faster-means-of-checking-for-a...
- */
-static inline int
-is_zero (const unsigned char *buffer, size_t size)
-{
- size_t i;
-
- for (i = 0; i < size; ++i) {
- if (buffer[i] != 0)
- return 0;
- }
-
- return 1;
-}
-
struct global_state {
/* Current iterator. Threads update this, but it is protected by a
* mutex, and each thread takes a copy of it when working on it.
@@ -681,7 +663,7 @@ worker_thread (void *vp)
/* Don't write if the block is all zero, to preserve output file
* sparseness. However we have to update oposition.
*/
- if (!is_zero (outbuf, wsz)) {
+ if (!is_zero ((char *) outbuf, wsz)) {
if (xpwrite (global->ofd, outbuf, wsz, oposition) == -1) {
perror (global->outputfile);
return &state->status;
diff --git a/daemon/daemon.h b/daemon/daemon.h
index 332e2966a..a317139a5 100644
--- a/daemon/daemon.h
+++ b/daemon/daemon.h
@@ -327,24 +327,6 @@ extern void pulse_mode_cancel (void);
*/
extern void notify_progress_no_ratelimit (uint64_t position, uint64_t total, const struct timeval *now);
-/* Return true iff the buffer is all zero bytes.
- *
- * Note that gcc is smart enough to optimize this properly:
- * http://stackoverflow.com/questions/1493936/faster-means-of-checking-for-a...
- */
-static inline int
-is_zero (const char *buffer, size_t size)
-{
- size_t i;
-
- for (i = 0; i < size; ++i) {
- if (buffer[i] != 0)
- return 0;
- }
-
- return 1;
-}
-
/* Helper for functions that need a root filesystem mounted.
* NB. Cannot be used for FileIn functions.
*/
diff --git a/lib/guestfs-internal-all.h b/lib/guestfs-internal-all.h
index 0c841ff67..4f7433332 100644
--- a/lib/guestfs-internal-all.h
+++ b/lib/guestfs-internal-all.h
@@ -89,6 +89,24 @@
#define xdr_uint32_t xdr_u_int32_t
#endif
+/* Return true iff the buffer is all zero bytes.
+ *
+ * Note that gcc is smart enough to optimize this properly:
+ * http://stackoverflow.com/questions/1493936/faster-means-of-checking-for-a...
+ */
+static inline int
+is_zero (const char *buffer, size_t size)
+{
+ size_t i;
+
+ for (i = 0; i < size; ++i) {
+ if (buffer[i] != 0)
+ return 0;
+ }
+
+ return 1;
+}
+
/* Macro which compiles the regexp once when the program/library is
* loaded, and frees it when the library is unloaded.
*/
--
2.12.0
7 years, 8 months
[PATCH v6 0/7] Feature: Yara file scanning
by Matteo Cafasso
v6:
- use new test functions
- fix yara_detection struct field names
- revert yara_load function to initial version
With Pino we were exploring the idea of allowing Users to load multiple
rule files with subsequent calls to yara_load API.
https://www.redhat.com/archives/libguestfs/2016-November/msg00119.html
It turns out impractical due to YARA API limitations. It is possible
to load multiple rule source files into the compiler. Yet once compiled
no further rule file can be added.
This would make the yara_load API difficult to understand for the end User.
The yara tool iself cannot scan files with more than a rule file.
To combine multiple rule files the User is recommended to use the yarac tool.
This makes the yara_load API more similar to the yara workflow.
- further small fixes according to the v5 comments
After further
Matteo Cafasso (7):
daemon: expose file upload logic
appliance: add yara dependency
New API: yara_load
New API: yara_destroy
New API: internal_yara_scan
New API: yara_scan
yara_scan: added API tests
appliance/packagelist.in | 4 +
configure.ac | 1 +
daemon/Makefile.am | 4 +-
daemon/cleanups.c | 9 +
daemon/cleanups.h | 2 +
daemon/daemon.h | 3 +
daemon/upload.c | 70 +++----
daemon/yara.c | 303 +++++++++++++++++++++++++++++++
generator/Makefile.am | 3 +
generator/actions.ml | 6 +-
generator/actions_yara.ml | 92 ++++++++++
generator/actions_yara.mli | 22 +++
generator/proc_nr.ml | 3 +
generator/structs.ml | 9 +
gobject/Makefile.inc | 2 +
java/Makefile.inc | 1 +
java/com/redhat/et/libguestfs/.gitignore | 1 +
lib/MAX_PROC_NR | 2 +-
lib/Makefile.am | 1 +
lib/yara.c | 127 +++++++++++++
m4/guestfs_daemon.m4 | 14 ++
tests/yara/Makefile.am | 26 +++
tests/yara/test-yara-scan.sh | 61 +++++++
23 files changed, 731 insertions(+), 35 deletions(-)
create mode 100644 daemon/yara.c
create mode 100644 generator/actions_yara.ml
create mode 100644 generator/actions_yara.mli
create mode 100644 lib/yara.c
create mode 100644 tests/yara/Makefile.am
create mode 100755 tests/yara/test-yara-scan.sh
--
2.11.0
7 years, 8 months
[PATCH] v2v: ovf: store CPU model for oVirt
by Tomáš Golembiovský
If CPU model is available store it in OVF for oVirt. This affects
-o rhev and -o vdsm.
Signed-off-by: Tomáš Golembiovský <tgolembi(a)redhat.com>
---
v2v/create_ovf.ml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/v2v/create_ovf.ml b/v2v/create_ovf.ml
index f5dc64753..9d7341696 100644
--- a/v2v/create_ovf.ml
+++ b/v2v/create_ovf.ml
@@ -306,6 +306,12 @@ let rec create_ovf source targets guestcaps inspect
e "DefaultDisplayType" [] [PCData "1"];
] in
+ (match source.s_cpu_model with
+ | None -> ()
+ | Some model ->
+ push_back content_subnodes (e "CustomCpuName" [] [PCData model])
+ );
+
(* Add the <Origin/> element if we can. *)
(match origin_of_source_hypervisor source.s_hypervisor with
| None -> ()
--
2.12.1
7 years, 8 months
[PATCH v3 0/2] error accessing harddrive partitions
by Pavel Butsykin
virt-v2v fails when traverses each partition:
inspect_sources.ml:
...
and is_uefi_bootable_part part =
let dev = g#part_to_dev part in
parttype_is_gpt dev && is_uefi_ESP dev part
in
let partitions = Array.to_list (g#list_partitions ()) in
let partitions = List.filter is_uefi_bootable_part partitions in
log:
...
libguestfs: trace: v2v: list_partitions
guestfsd: main_loop: new request, len 0x28
guestfsd: main_loop: proc 8 (list_partitions) took 0.00 seconds
libguestfs: trace: v2v: list_partitions = ["/dev/sda1", "/dev/sda2", "/dev/sda3",
"/dev/sdb1", "/dev/sdb2", "/dev/sdb5", "/dev/sdc1", "/dev/sdc2", "/dev/sdc5",
"/dev/sdd1", "/dev/sdd2", "/dev/sdd5", "/dev/sde1", "/dev/sde2", "/dev/sde5",
"/dev/sdf1", "/dev/sdf2", "/dev/sdf5", "/dev/sdg1", "/dev/sdg2", "/dev/sdg5"]
...
libguestfs: trace: v2v: part_get_parttype "/dev/sdb"
guestfsd: main_loop: new request, len 0x34
commandrvf: stdout=y stderr=y flags=0x0
commandrvf: parted -m -s -- /dev/sdb unit b print
libguestfs: trace: v2v: part_get_parttype = "msdos"
libguestfs: trace: v2v: part_get_parttype "/dev/sdb"
guestfsd: main_loop: proc 214 (part_get_parttype) took 0.00 seconds
guestfsd: main_loop: new request, len 0x34
commandrvf: stdout=y stderr=y flags=0x0
commandrvf: parted -m -s -- /dev/sdb unit b print
libguestfs: trace: v2v: part_get_parttype = "msdos"
libguestfs: trace: v2v: part_to_dev "/dev/sdb5"
guestfsd: main_loop: proc 214 (part_get_parttype) took 0.00 seconds
[ 9.164666] sdb: sdb1 sdb2 < sdb5 >
guestfsd: main_loop: new request, len 0x38
/dev/sdb5: No such file or directory
call part_to_dev "/dev/sdb5" failed in is_root_device():
part_to_dev_stub()
RESOLVE_DEVICE()
is_root_device ():
{
struct stat statbuf;
if (stat (device, &statbuf) == -1) {
perror (device);
return 0;
...
let's look at the udev event log after the error:
KERNEL[10.527855] change /devices/pci0000:00/0000:00:03.0/virtio1/host2/target2:0:1/2:0:1:0/block/sdb (block)
UDEV [10.528693] change /devices/pci0000:00/0000:00:03.0/virtio1/host2/target2:0:0/2:0:0:0/block/sda/sda1 (block)
KERNEL[10.529156] add /devices/pci0000:00/0000:00:03.0/virtio1/host2/target2:0:1/2:0:1:0/block/sdb/sdb1 (block)
KERNEL[10.529618] add /devices/pci0000:00/0000:00:03.0/virtio1/host2/target2:0:1/2:0:1:0/block/sdb/sdb2 (block)
KERNEL[10.530096] add /devices/pci0000:00/0000:00:03.0/virtio1/host2/target2:0:1/2:0:1:0/block/sdb/sdb5 (block)
...
Apparently is_root_device("/dev/sdb5") was called before "/dev/sdb5" was added.
To solve issue we need to wait adding a partition before we can access it.
Another solution if we wait for adding all partitions somewhere in one place.
But there is at least one drawback, not for each task need to touch the disk
partitions and waiting for all partitions will slow such tasks.
Pavel Butsykin (2):
daemon: run 'udevadm settle' with --exit-if-exists option
daemon: add udev_settle_file to is_root_device
daemon/daemon.h | 2 ++
daemon/guestfsd.c | 34 +++++++++++++++++++++++++++-------
2 files changed, 29 insertions(+), 7 deletions(-)
--
2.11.0
7 years, 8 months