[libvirt] [Qemu-devel] [PATCH v2] Add support for fd: protocol
Corey Bryant
bryntcor at us.ibm.com
Mon Jun 20 13:08:36 UTC 2011
On 06/18/2011 04:50 PM, Blue Swirl wrote:
> On Thu, Jun 16, 2011 at 5:48 PM, Corey Bryant<bryntcor at us.ibm.com> wrote:
>>
>>
>> On 06/15/2011 03:12 PM, Blue Swirl wrote:
>>>
>>> On Tue, Jun 14, 2011 at 4:31 PM, Corey Bryant<bryntcor at us.ibm.com> wrote:
>>>>
>>>>> sVirt provides SELinux MAC isolation for Qemu guest processes and
>>>>> their
>>>>> corresponding resources (image files). sVirt provides this support
>>>>> by labeling guests and resources with security labels that are stored
>>>>> in file system extended attributes. Some file systems, such as NFS, do
>>>>> not support the extended attribute security namespace, which is needed
>>>>> for image file isolation when using the sVirt SELinux security driver
>>>>> in libvirt.
>>>>>
>>>>> The proposed solution entails a combination of Qemu, libvirt, and
>>>>> SELinux patches that work together to isolate multiple guests' images
>>>>> when they're stored in the same NFS mount. This results in an
>>>>> environment where sVirt isolation and NFS image file isolation can
>>>>> both
>>>>> be provided.
>>>>>
>>>>> This patch contains the Qemu code to support this solution. I would
>>>>> like to solicit input from the libvirt community prior to starting
>>>>> the libvirt patch.
>>>>>
>>>>> Currently, Qemu opens an image file in addition to performing the
>>>>> necessary read and write operations. The proposed solution will move
>>>>> the open out of Qemu and into libvirt. Once libvirt opens an image
>>>>> file for the guest, it will pass the file descriptor to Qemu via a
>>>>> new fd: protocol.
>>>>>
>>>>> If the image file resides in an NFS mount, the following SELinux
>>>>> policy
>>>>> changes will provide image isolation:
>>>>>
>>>>> - A new SELinux boolean is created (e.g. virt_read_write_nfs) to
>>>>> allow Qemu (svirt_t) to only have SELinux read and write
>>>>> permissions on nfs_t files
>>>>>
>>>>> - Qemu (svirt_t) also gets SELinux use permissions on libvirt
>>>>> (virtd_t) file descriptors
>>>>>
>>>>> Following is a sample invocation of Qemu using the fd: protocol on
>>>>> the command line:
>>>>>
>>>>> qemu -drive file=fd:4,format=qcow2
>>>>>
>>>>> The fd: protocol is also supported by the drive_add monitor command.
>>>>> This requires that the specified file descriptor is passed to the
>>>>> monitor alongside a prior getfd monitor command.
>>>>>
>>>>> There are some additional features provided by certain image types
>>>>> where Qemu reopens the image file. All of these scenarios will be
>>>>> unsupported for the fd: protocol, at least for this patch:
>>>>>
>>>>> - The -snapshot command line option
>>>>> - The savevm monitor command
>>>>> - The snapshot_blkdev monitor command
>>>>> - Starting Qemu with a backing file
>>>
>>> There's also native CDROM device. Did you consider adding an explicit
>>> reopen method to block layer?
>>
>> Thanks. Yes it looks like I overlooked CDROM reopens.
>>
>> I'm not sure that I'm clear on the purpose of the reopen function. Would the
>> goal be to funnel all block layer reopens through a single function,
>> enabling potential future support where a privileged layer of Qemu, or
>> libvirt, performs the open?
>
> Eventually yes, but I think it would help also now by moving the
> checks to a single place. It's a bit orthogonal to this patch though.
>
This would definitely simplify things, especially when reopen support is
added. I'm going to defer this until then.
>>>>> The thought is that this support can be added in the future, but is
>>>>> not required for the initial fd: support.
>>>>>
>>>>> This patch was tested with the following formats: raw, cow, qcow,
>>>>> qcow2, qed, and vmdk, using the fd: protocol from the command line
>>>>> and the monitor. Tests were also run to verify existing file name
>>>>> support and qemu-img were not regressed. Non-valid file descriptors,
>>>>> fd: without format, snapshot and backing files were also tested.
>>>>>
>>>>> Signed-off-by: Corey Bryant<coreyb at linux.vnet.ibm.com>
>>>>> ---
>>>>> block.c | 16 ++++++++++
>>>>> block.h | 1 +
>>>>> block/cow.c | 5 +++
>>>>> block/qcow.c | 5 +++
>>>>> block/qcow2.c | 5 +++
>>>>> block/qed.c | 4 ++
>>>>> block/raw-posix.c | 81
>>>>> +++++++++++++++++++++++++++++++++++++++++++++++------
>>>>> block/vmdk.c | 5 +++
>>>>> block_int.h | 1 +
>>>>> blockdev.c | 10 ++++++
>>>>> monitor.c | 5 +++
>>>>> monitor.h | 1 +
>>>>> qemu-options.hx | 8 +++--
>>>>> qemu-tool.c | 5 +++
>>>>> 14 files changed, 140 insertions(+), 12 deletions(-)
>>>>>
>>>>> diff --git a/block.c b/block.c
>>>>> index 24a25d5..500db84 100644
>>>>> --- a/block.c
>>>>> +++ b/block.c
>>>>> @@ -536,6 +536,10 @@ int bdrv_open(BlockDriverState *bs, const char
>>>>> *filename, int flags,
>>>>> char tmp_filename[PATH_MAX];
>>>>> char backing_filename[PATH_MAX];
>>>>>
>>>>> + if (bdrv_is_fd_protocol(bs)) {
>>>>> + return -ENOTSUP;
>>>>> + }
>>>>> +
>>>>> /* if snapshot, we create a temporary backing file and open
>>>>> it
>>>>> instead of opening 'filename' directly */
>>>>>
>>>>> @@ -585,6 +589,10 @@ int bdrv_open(BlockDriverState *bs, const char
>>>>> *filename, int flags,
>>>>>
>>>>> /* Find the right image format driver */
>>>>> if (!drv) {
>>>>> + /* format must be specified for fd: protocol */
>>>>> + if (bdrv_is_fd_protocol(bs)) {
>>>>> + return -ENOTSUP;
>>>>> + }
>>>>> ret = find_image_format(filename,&drv);
>>>>> }
>>>>>
>>>>> @@ -1460,6 +1468,11 @@ int bdrv_enable_write_cache(BlockDriverState
>>>>> *bs)
>>>>> return bs->enable_write_cache;
>>>>> }
>>>>>
>>>>> +int bdrv_is_fd_protocol(BlockDriverState *bs)
>>>>> +{
>>>>> + return bs->fd_protocol;
>>>>> +}
>>>>> +
>>>>> /* XXX: no longer used */
>>>>> void bdrv_set_change_cb(BlockDriverState *bs,
>>>>> void (*change_cb)(void *opaque, int reason),
>>>>> @@ -1964,6 +1977,9 @@ int bdrv_snapshot_create(BlockDriverState *bs,
>>>>> BlockDriver *drv = bs->drv;
>>>>> if (!drv)
>>>>> return -ENOMEDIUM;
>>>>> + if (bdrv_is_fd_protocol(bs)) {
>>>>> + return -ENOTSUP;
>>>>> + }
>>>>> if (drv->bdrv_snapshot_create)
>>>>> return drv->bdrv_snapshot_create(bs, sn_info);
>>>>> if (bs->file)
>>>>> diff --git a/block.h b/block.h
>>>>> index da7d39c..dd46d52 100644
>>>>> --- a/block.h
>>>>> +++ b/block.h
>>>>> @@ -182,6 +182,7 @@ int bdrv_is_removable(BlockDriverState *bs);
>>>>> int bdrv_is_read_only(BlockDriverState *bs);
>>>>> int bdrv_is_sg(BlockDriverState *bs);
>>>>> int bdrv_enable_write_cache(BlockDriverState *bs);
>>>>> +int bdrv_is_fd_protocol(BlockDriverState *bs);
>>>>> int bdrv_is_inserted(BlockDriverState *bs);
>>>>> int bdrv_media_changed(BlockDriverState *bs);
>>>>> int bdrv_is_locked(BlockDriverState *bs);
>>>>> diff --git a/block/cow.c b/block/cow.c
>>>>> index 4cf543c..e17f8e7 100644
>>>>> --- a/block/cow.c
>>>>> +++ b/block/cow.c
>>>>> @@ -82,6 +82,11 @@ static int cow_open(BlockDriverState *bs, int
>>>>> flags)
>>>>> pstrcpy(bs->backing_file, sizeof(bs->backing_file),
>>>>> cow_header.backing_file);
>>>>>
>>>>> + if (bs->backing_file[0] != '\0'&& bdrv_is_fd_protocol(bs)) {
>>>>> + /* backing file currently not supported by fd: protocol */
>>>>> + goto fail;
>>>>> + }
>>>>> +
>>>>> bitmap_size = ((bs->total_sectors + 7)>> 3) +
>>>>> sizeof(cow_header);
>>>>> s->cow_sectors_offset = (bitmap_size + 511)& ~511;
>>>>> return 0;
>>>>> diff --git a/block/qcow.c b/block/qcow.c
>>>>> index a26c886..1e46bdb 100644
>>>>> --- a/block/qcow.c
>>>>> +++ b/block/qcow.c
>>>>> @@ -157,6 +157,11 @@ static int qcow_open(BlockDriverState *bs, int
>>>>> flags)
>>>>> if (bdrv_pread(bs->file, header.backing_file_offset,
>>>>> bs->backing_file, len) != len)
>>>>> goto fail;
>>>>> bs->backing_file[len] = '\0';
>>>>> +
>>>>> + if (bs->backing_file[0] != '\0'&& bdrv_is_fd_protocol(bs)) {
>>>>> + /* backing file currently not supported by fd: protocol
>>>>> */
>>>>> + goto fail;
>>>>> + }
>>>>> }
>>>>> return 0;
>>>>>
>>>>> diff --git a/block/qcow2.c b/block/qcow2.c
>>>>> index 8451ded..8b9c160 100644
>>>>> --- a/block/qcow2.c
>>>>> +++ b/block/qcow2.c
>>>>> @@ -270,6 +270,11 @@ static int qcow2_open(BlockDriverState *bs, int
>>>>> flags)
>>>>> goto fail;
>>>>> }
>>>>> bs->backing_file[len] = '\0';
>>>>> +
>>>>> + if (bs->backing_file[0] != '\0'&& bdrv_is_fd_protocol(bs)) {
>>>>> + ret = -ENOTSUP;
>>>>> + goto fail;
>>>>> + }
>>>>> }
>>>>> if (qcow2_read_snapshots(bs)< 0) {
>>>>> ret = -EINVAL;
>>>>> diff --git a/block/qed.c b/block/qed.c
>>>>> index 3970379..5028897 100644
>>>>> --- a/block/qed.c
>>>>> +++ b/block/qed.c
>>>>> @@ -446,6 +446,10 @@ static int bdrv_qed_open(BlockDriverState *bs,
>>>>> int flags)
>>>>> return ret;
>>>>> }
>>>>>
>>>>> + if (bs->backing_file[0] != '\0'&& bdrv_is_fd_protocol(bs)) {
>>>>> + return -ENOTSUP;
>>>>> + }
>>>>> +
>>>>> if (s->header.features& QED_F_BACKING_FORMAT_NO_PROBE) {
>>>>> pstrcpy(bs->backing_format, sizeof(bs->backing_format),
>>>>> "raw");
>>>>> }
>>>>> diff --git a/block/raw-posix.c b/block/raw-posix.c
>>>>> index 4cd7d7a..c72de3d 100644
>>>>> --- a/block/raw-posix.c
>>>>> +++ b/block/raw-posix.c
>>>>> @@ -28,6 +28,7 @@
>>>>> #include "block_int.h"
>>>>> #include "module.h"
>>>>> #include "block/raw-posix-aio.h"
>>>>> +#include "monitor.h"
>>>>>
>>>>> #ifdef CONFIG_COCOA
>>>>> #include<paths.h>
>>>>> @@ -183,7 +184,8 @@ static int raw_open_common(BlockDriverState *bs,
>>>>> const char *filename,
>>>>> int bdrv_flags, int open_flags)
>>>>> {
>>>>> BDRVRawState *s = bs->opaque;
>>>>> - int fd, ret;
>>>>> + int fd = -1;
>>>>> + int ret;
>>>>>
>>>>> ret = raw_normalize_devicepath(&filename);
>>>>> if (ret != 0) {
>>>>> @@ -205,15 +207,17 @@ static int raw_open_common(BlockDriverState *bs,
>>>>> const char *filename,
>>>>> if (!(bdrv_flags& BDRV_O_CACHE_WB))
>>>>> s->open_flags |= O_DSYNC;
>>>>>
>>>>> - s->fd = -1;
>>>>> - fd = qemu_open(filename, s->open_flags, 0644);
>>>>> - if (fd< 0) {
>>>>> - ret = -errno;
>>>>> - if (ret == -EROFS)
>>>>> - ret = -EACCES;
>>>>> - return ret;
>>>>> + if (s->fd == -1) {
>>>>> + fd = qemu_open(filename, s->open_flags, 0644);
>>>>> + if (fd< 0) {
>>>>> + ret = -errno;
>>>>> + if (ret == -EROFS) {
>>>>> + ret = -EACCES;
>>>>> + }
>>>>> + return ret;
>>>>> + }
>>>>> + s->fd = fd;
>>>>> }
>>>>> - s->fd = fd;
>>>>> s->aligned_buf = NULL;
>>>>>
>>>>> if ((bdrv_flags& BDRV_O_NOCACHE)) {
>>>>> @@ -270,6 +274,7 @@ static int raw_open(BlockDriverState *bs, const
>>>>> char *filename, int flags)
>>>>> {
>>>>> BDRVRawState *s = bs->opaque;
>>>>>
>>>>> + s->fd = -1;
>>>>> s->type = FTYPE_FILE;
>>>>> return raw_open_common(bs, filename, flags, 0);
>>>>> }
>>>>> @@ -890,6 +895,60 @@ static BlockDriver bdrv_file = {
>>>>> .create_options = raw_create_options,
>>>>> };
>>>>>
>>>>> +static int raw_open_fd(BlockDriverState *bs, const char *filename,
>>>>> int flags)
>>>>> +{
>>>>> + BDRVRawState *s = bs->opaque;
>>>>> + const char *fd_str;
>>>>> + int fd;
>>>>> +
>>>>> + /* extract the file descriptor - fail if it's not fd: */
>>>>> + if (!strstart(filename, "fd:",&fd_str)) {
>>>>> + return -EINVAL;
>>>>> + }
>>>>> +
>>>>> + if (!qemu_isdigit(fd_str[0])) {
>>>>> + /* get fd from monitor */
>>>>> + fd = qemu_get_fd(fd_str);
>>>>> + if (fd == -1) {
>>>>> + return -EBADF;
>>>>> + }
>>>>> + } else {
>>>>> + char *endptr = NULL;
>>>>> +
>>>>> + fd = strtol(fd_str,&endptr, 10);
>>>>> + if (*endptr || (fd == 0&& fd_str == endptr)) {
>>>>> + return -EBADF;
>>>>> + }
>>>>> + }
>>>>> +
>>>>> + s->fd = fd;
>>>>> + s->type = FTYPE_FILE;
>>>>> +
>>>>> + return raw_open_common(bs, filename, flags, 0);
>>>>> +}
>>>>> +
>>>>> +static BlockDriver bdrv_file_fd = {
>>>>> + .format_name = "file",
>>>>> + .protocol_name = "fd",
>>>>> + .instance_size = sizeof(BDRVRawState),
>>>>> + .bdrv_probe = NULL, /* no probe for protocols */
>>>>> + .bdrv_file_open = raw_open_fd,
>>>>> + .bdrv_read = raw_read,
>>>>> + .bdrv_write = raw_write,
>>>>> + .bdrv_close = raw_close,
>>>>> + .bdrv_flush = raw_flush,
>>>>> + .bdrv_discard = raw_discard,
>>>>> +
>>>>> + .bdrv_aio_readv = raw_aio_readv,
>>>>> + .bdrv_aio_writev = raw_aio_writev,
>>>>> + .bdrv_aio_flush = raw_aio_flush,
>>>>> +
>>>>> + .bdrv_truncate = raw_truncate,
>>>>> + .bdrv_getlength = raw_getlength,
>>>>> +
>>>>> + .create_options = raw_create_options,
>>>>> +};
>>>>> +
>>>>> /***********************************************/
>>>>> /* host device */
>>>>>
>>>>> @@ -998,6 +1057,7 @@ static int hdev_open(BlockDriverState *bs, const
>>>>> char *filename, int flags)
>>>>> }
>>>>> #endif
>>>>>
>>>>> + s->fd = -1;
>>>>> s->type = FTYPE_FILE;
>>>>> #if defined(__linux__)
>>>>> {
>>>>> @@ -1168,6 +1228,7 @@ static int floppy_open(BlockDriverState *bs,
>>>>> const char *filename, int flags)
>>>>> BDRVRawState *s = bs->opaque;
>>>>> int ret;
>>>>>
>>>>> + s->fd = -1;
>>>>> s->type = FTYPE_FD;
>>>>>
>>>>> /* open will not fail even if no floppy is inserted, so add
>>>>> O_NONBLOCK */
>>>>> @@ -1280,6 +1341,7 @@ static int cdrom_open(BlockDriverState *bs,
>>>>> const char *filename, int flags)
>>>>> {
>>>>> BDRVRawState *s = bs->opaque;
>>>>>
>>>>> + s->fd = -1;
>>>>> s->type = FTYPE_CD;
>>>>>
>>>>> /* open will not fail even if no CD is inserted, so add
>>>>> O_NONBLOCK */
>>>>> @@ -1503,6 +1565,7 @@ static void bdrv_file_init(void)
>>>>> * Register all the drivers. Note that order is important, the
>>>>> driver
>>>>> * registered last will get probed first.
>>>>> */
>>>>> + bdrv_register(&bdrv_file_fd);
>>>>> bdrv_register(&bdrv_file);
>>>>> bdrv_register(&bdrv_host_device);
>>>>> #ifdef __linux__
>>>>> diff --git a/block/vmdk.c b/block/vmdk.c
>>>>> index 922b23d..2ea808e 100644
>>>>> --- a/block/vmdk.c
>>>>> +++ b/block/vmdk.c
>>>>> @@ -353,6 +353,11 @@ static int vmdk_parent_open(BlockDriverState *bs)
>>>>> return -1;
>>>>>
>>>>> pstrcpy(bs->backing_file, end_name - p_name + 1, p_name);
>>>>> +
>>>>> + if (bs->backing_file[0] != '\0'&& bdrv_is_fd_protocol(bs)) {
>>>>> + /* backing file currently not supported by fd: protocol
>>>>> */
>>>>> + return -1;
>>>>> + }
>>>>> }
>>>>>
>>>>> return 0;
>>>>> diff --git a/block_int.h b/block_int.h
>>>>> index fa91337..a305ee2 100644
>>>>> --- a/block_int.h
>>>>> +++ b/block_int.h
>>>>> @@ -152,6 +152,7 @@ struct BlockDriverState {
>>>>> int encrypted; /* if true, the media is encrypted */
>>>>> int valid_key; /* if true, a valid encryption key has been set */
>>>>> int sg; /* if true, the device is a /dev/sg* */
>>>>> + int fd_protocol; /* if true, the fd: protocol was specified */
>>>
>>> bool?
>>>
>> I was following suit here, but I agree that bool would be better. Or
>> better, these could all be reduced to bit flags. My thought is that I'll
>> stick with following suit here though.
>
> OK, better convert all at once with a separate patch.
>
Ok
>>>>> /* event callback when inserting/removing */
>>>>> void (*change_cb)(void *opaque, int reason);
>>>>> void *change_opaque;
>>>>> diff --git a/blockdev.c b/blockdev.c
>>>>> index e81e0ab..a536c20 100644
>>>>> --- a/blockdev.c
>>>>> +++ b/blockdev.c
>>>>> @@ -546,6 +546,10 @@ DriveInfo *drive_init(QemuOpts *opts, int
>>>>> default_to_scsi)
>>>>>
>>>>> bdrv_flags |= ro ? 0 : BDRV_O_RDWR;
>>>>>
>>>>> + if (strncmp(file, "fd:", 3) == 0) {
>>>>> + dinfo->bdrv->fd_protocol = 1;
>>>>> + }
>>>>> +
>>>>> ret = bdrv_open(dinfo->bdrv, file, bdrv_flags, drv);
>>>>> if (ret< 0) {
>>>>> error_report("could not open disk image %s: %s",
>>>>> @@ -606,6 +610,12 @@ int do_snapshot_blkdev(Monitor *mon, const QDict
>>>>> *qdict, QObject **ret_data)
>>>>> goto out;
>>>>> }
>>>>>
>>>>> + if (bdrv_is_fd_protocol(bs)) {
>>>>> + qerror_report(QERR_UNSUPPORTED);
>>>>> + ret = -1;
>>>>> + goto out;
>>>>> + }
>>>>> +
>>>>> pstrcpy(old_filename, sizeof(old_filename), bs->filename);
>>>>>
>>>>> old_drv = bs->drv;
>>>>> diff --git a/monitor.c b/monitor.c
>>>>> index 59a3e76..ea60be2 100644
>>>>> --- a/monitor.c
>>>>> +++ b/monitor.c
>>>>> @@ -2832,6 +2832,11 @@ int monitor_get_fd(Monitor *mon, const char
>>>>> *fdname)
>>>>> return -1;
>>>>> }
>>>>>
>>>>> +int qemu_get_fd(const char *fdname)
>>>>> +{
>>>>> + return cur_mon ? monitor_get_fd(cur_mon, fdname) : -1;
>>>>> +}
>>>>> +
>>>>> static const mon_cmd_t mon_cmds[] = {
>>>>> #include "hmp-commands.h"
>>>>> { NULL, NULL, },
>>>>> diff --git a/monitor.h b/monitor.h
>>>>> index 4f2d328..de5b987 100644
>>>>> --- a/monitor.h
>>>>> +++ b/monitor.h
>>>>> @@ -51,6 +51,7 @@ int monitor_read_bdrv_key_start(Monitor *mon,
>>>>> BlockDriverState *bs,
>>>>> void *opaque);
>>>>>
>>>>> int monitor_get_fd(Monitor *mon, const char *fdname);
>>>>> +int qemu_get_fd(const char *fdname);
>>>>>
>>>>> void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
>>>>> GCC_FMT_ATTR(2, 0);
>>>>> diff --git a/qemu-options.hx b/qemu-options.hx
>>>>> index 1d5ad8b..f9b66f4 100644
>>>>> --- a/qemu-options.hx
>>>>> +++ b/qemu-options.hx
>>>>> @@ -116,7 +116,7 @@ using @file{/dev/cdrom} as filename
>>>>> (@pxref{host_drives}).
>>>>> ETEXI
>>>>>
>>>>> DEF("drive", HAS_ARG, QEMU_OPTION_drive,
>>>>> - "-drive
>>>>> [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i]\n"
>>>>> + "-drive
>>>>> [file=[fd:]file][,if=type][,bus=n][,unit=m][,media=d][,index=i]\n"
>>>>> " [,cyls=c,heads=h,secs=s[,trans=t]][,snapshot=on|off]\n"
>>>>> " [,cache=writethrough|writeback|none|unsafe][,format=f]\n"
>>>>> " [,serial=s][,addr=A][,id=name][,aio=threads|native]\n"
>>>>> @@ -129,10 +129,12 @@ STEXI
>>>>> Define a new drive. Valid options are:
>>>>>
>>>>> @table @option
>>>>> - at item file=@var{file}
>>>>> + at item file=[fd:]@var{file}
>>>>> This option defines which disk image (@pxref{disk_images}) to use
>>>>> with
>>>>> this drive. If the filename contains comma, you must double it
>>>>> -(for instance, "file=my,,file" to use file "my,file").
>>>>> +(for instance, "file=my,,file" to use file "my,file").
>>>>> @option{fd:}@var{file}
>>>>> +specifies the file descriptor of an already open disk image.
>>>>> + at option{format=}@var{format} is required by @option{fd:}@var{file}.
>>>>> @item if=@var{interface}
>>>>> This option defines on which type on interface the drive is
>>>>> connected.
>>>>> Available types are: ide, scsi, sd, mtd, floppy, pflash, virtio.
>>>>> diff --git a/qemu-tool.c b/qemu-tool.c
>>>>> index 41e5c41..8fe6b8c 100644
>>>>> --- a/qemu-tool.c
>>>>> +++ b/qemu-tool.c
>>>>> @@ -96,3 +96,8 @@ int64_t qemu_get_clock_ns(QEMUClock *clock)
>>>>> {
>>>>> return 0;
>>>>> }
>>>>> +
>>>>> +int qemu_get_fd(const char *fdname)
>>>>> +{
>>>>> + return -1;
>>>>> +}
>>>>> --
>>>>> 1.7.1
>>>>>
>>>>>
>>>>>
>>
>>
>> Regards,
>> Corey Bryant
>>
--
Regards,
Corey Bryant
IBM Linux Technology Center - Security
845-435-8732 (T/L: 295-8732)
More information about the libvir-list
mailing list