Some remote filesystems are not accessible via the local filesystem calls, but libvirt needs means to do operations on such files. This patch adds internal APIs into the storage driver that will allow operations on various networked and other filesystems. --- Notes: Version 5: - changed error reporting scheme and re-documented - fix indentation of makefile - simplified conditions according to review - fixed typos docs/hvsupport.pl | 4 +- po/POTFILES.in | 1 + src/Makefile.am | 1 + src/check-drivername.pl | 1 + src/driver.h | 30 +++++++- src/libvirt_private.c | 180 +++++++++++++++++++++++++++++++++++++++++++++++ src/libvirt_private.h | 61 ++++++++++++++++ src/libvirt_private.syms | 9 +++ 8 files changed, 285 insertions(+), 2 deletions(-) create mode 100644 src/libvirt_private.c create mode 100644 src/libvirt_private.h diff --git a/docs/hvsupport.pl b/docs/hvsupport.pl index f8483f9..bed04f9 100755 --- a/docs/hvsupport.pl +++ b/docs/hvsupport.pl @@ -206,6 +206,8 @@ while (defined($line = <FILE>)) { $api = "vir$name"; } elsif ($name =~ /\w+(Open|Close)/) { next; + } elsif ($name =~ /^StorageFile\w+/) { + next; } else { die "driver $name does not have a public API"; } @@ -256,7 +258,7 @@ foreach my $src (@srcs) { my $meth = $2; my $vers = $3; - next if $api eq "no" || $api eq "name"; + next if $api eq "no" || $api eq "name" || $api =~ /^storageFile\w+/; die "Method $meth in $src is missing version" unless defined $vers; diff --git a/po/POTFILES.in b/po/POTFILES.in index 0359b2f..9304942 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -50,6 +50,7 @@ src/interface/interface_backend_netcf.c src/interface/interface_backend_udev.c src/internal.h src/libvirt.c +src/libvirt_private.c src/libvirt-lxc.c src/libvirt-qemu.c src/locking/lock_daemon.c diff --git a/src/Makefile.am b/src/Makefile.am index 3f8d22f..39447ed 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -174,6 +174,7 @@ DRIVER_SOURCES = \ fdstream.c fdstream.h \ $(NODE_INFO_SOURCES) \ libvirt.c libvirt_internal.h \ + libvirt_private.h libvirt_private.c \ locking/lock_manager.c locking/lock_manager.h \ locking/lock_driver.h \ locking/lock_driver_nop.h locking/lock_driver_nop.c \ diff --git a/src/check-drivername.pl b/src/check-drivername.pl index 5c8de0a..a98d7db 100755 --- a/src/check-drivername.pl +++ b/src/check-drivername.pl @@ -50,6 +50,7 @@ while (<DRVFILE>) { next if $drv =~ /virDrvState/; next if $drv =~ /virDrvDomainMigrate(Prepare|Perform|Confirm|Begin|Finish)/; + next if $drv =~ /virDrvStorageFile/; my $sym = $drv; $sym =~ s/virDrv/vir/; diff --git a/src/driver.h b/src/driver.h index 5f4cd8d..20f944a 100644 --- a/src/driver.h +++ b/src/driver.h @@ -2,7 +2,7 @@ * driver.h: description of the set of interfaces provided by a * entry point to the virtualization engine * - * Copyright (C) 2006-2013 Red Hat, Inc. + * Copyright (C) 2006-2014 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,6 +24,8 @@ # include <unistd.h> +# include <sys/stat.h> + # include "internal.h" # include "libvirt_internal.h" # include "viruri.h" @@ -1755,6 +1757,25 @@ typedef int (*virDrvStoragePoolIsPersistent)(virStoragePoolPtr pool); +/* -------- Internal storage driver APIs ----------- */ +typedef struct _virStorageFile virStorageFile; +typedef virStorageFile *virStorageFilePtr; + +typedef int +(*virDrvStorageFileInit)(virStorageFilePtr file); + +typedef void +(*virDrvStorageFileDeinit)(virStorageFilePtr file); + +typedef int +(*virDrvStorageFileCreate)(virStorageFilePtr file); + +typedef int +(*virDrvStorageFileUnlink)(virStorageFilePtr file); + +typedef int +(*virDrvStorageFileStat)(virStorageFilePtr file, + struct stat *st); typedef struct _virStorageDriver virStorageDriver; typedef virStorageDriver *virStorageDriverPtr; @@ -1813,6 +1834,13 @@ struct _virStorageDriver { virDrvStorageVolResize storageVolResize; virDrvStoragePoolIsActive storagePoolIsActive; virDrvStoragePoolIsPersistent storagePoolIsPersistent; + + /* -------- Internal storage driver APIs ----------- */ + virDrvStorageFileInit storageFileInit; + virDrvStorageFileDeinit storageFileDeinit; + virDrvStorageFileCreate storageFileCreate; + virDrvStorageFileUnlink storageFileUnlink; + virDrvStorageFileStat storageFileStat; }; # ifdef WITH_LIBVIRTD diff --git a/src/libvirt_private.c b/src/libvirt_private.c new file mode 100644 index 0000000..330dd88 --- /dev/null +++ b/src/libvirt_private.c @@ -0,0 +1,180 @@ +/** + * libvirt_private.c: internal driver APIs not exported via RPC + * + * Copyright (C) 2014 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + * + * Author: Peter Krempa <pkrempa@xxxxxxxxxx> + */ + +#include <config.h> + +#include "libvirt_private.h" + +#include "datatypes.h" +#include "internal.h" +#include "viralloc.h" + +#define VIR_FROM_THIS VIR_FROM_NONE +/* ----------- helpers for APIs cooperating with storage driver ------ */ +virStorageFilePtr +virStorageFileInitFromDiskDef(virConnectPtr conn, + virDomainDiskDefPtr disk) +{ + virStorageFilePtr file = NULL; + + if (!conn->storageDriver) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("can't initialize storage file: no storage driver")); + return NULL; + } + + if (VIR_ALLOC(file) < 0) + return NULL; + + file->driver = conn->storageDriver; + + file->path = disk->src; + file->type = disk->type; + file->protocol = disk->protocol; + file->nhosts = disk->nhosts; + if (!(file->hosts = virDomainDiskHostDefCopy(disk->nhosts, disk->hosts))) + goto error; + + if (file->driver->storageFileInit && + file->driver->storageFileInit(file) < 0) + goto error; + + return file; + +error: + virDomainDiskHostDefFree(file->nhosts, file->hosts); + VIR_FREE(file); + return NULL; +} + + +virStorageFilePtr +virStorageFileInitFromSnapshotDef(virConnectPtr conn, + virDomainSnapshotDiskDefPtr disk) +{ + virStorageFilePtr file = NULL; + + if (!conn->storageDriver) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("can't initialize storage file: no storage driver")); + return NULL; + } + + if (VIR_ALLOC(file) < 0) + return NULL; + + file->driver = conn->storageDriver; + + file->path = disk->file; + file->type = disk->type; + file->protocol = disk->protocol; + file->nhosts = disk->nhosts; + if (!(file->hosts = virDomainDiskHostDefCopy(disk->nhosts, disk->hosts))) + goto error; + + if (file->driver->storageFileInit && + file->driver->storageFileInit(file) < 0) + goto error; + + return file; + +error: + virDomainDiskHostDefFree(file->nhosts, file->hosts); + VIR_FREE(file); + return NULL; +} + + +void +virStorageFileFree(virStorageFilePtr file) +{ + if (!file) + return; + + if (file->driver->storageFileDeinit) + file->driver->storageFileDeinit(file); + + virDomainDiskHostDefFree(file->nhosts, file->hosts); + VIR_FREE(file); +} + +/* ----------- APIs cooperating with storage driver ------------------ */ + +/** + * virStorageFileCreate: Creates an empty storage file via storage driver + * + * @file: file structure pointing to the file + * + * Returns 0 on success, -2 if the function isn't supported by the backend, + * -1 on other failure. Errno is set in case of failure. + */ +int +virStorageFileCreate(virStorageFilePtr file) +{ + if (file->driver->storageFileCreate) + return file->driver->storageFileCreate(file); + + errno = ENOSYS; + return -2; +} + + +/** + * virStorageFileUnlink: Unlink storage file via storage driver + * + * @file: file structure pointing to the file + * + * Unlinks the file described by the @file structure. + * + * Returns 0 on success, -2 if the function isn't supported by the backend, + * -1 on other failure. Errno is set in case of failure. + */ +int +virStorageFileUnlink(virStorageFilePtr file) +{ + if (file->driver->storageFileUnlink) + return file->driver->storageFileUnlink(file); + + errno = ENOSYS; + return -2; +} + + +/** + * virStorageFileStat: returns stat struct of a file via storage driver + * + * @file: file structure pointing to the file + * @stat: stat structure to return data + * + * Returns 0 on success, -2 if the function isn't supported by the backend, + * -1 on other failure. Errno is set in case of failure. +*/ +int +virStorageFileStat(virStorageFilePtr file, + struct stat *stat) +{ + if (file->driver->storageFileStat) + return file->driver->storageFileStat(file, stat); + + errno = ENOSYS; + return -2; +} diff --git a/src/libvirt_private.h b/src/libvirt_private.h new file mode 100644 index 0000000..8b6dd30 --- /dev/null +++ b/src/libvirt_private.h @@ -0,0 +1,61 @@ +/** + * libvirt_private.h: internal driver APIs not exported via RPC + * + * Copyright (C) 2014 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + * + * Author: Peter Krempa <pkrempa@xxxxxxxxxx> + */ + +#ifndef __VIR_PRIVATE_H__ +# define __VIR_PRIVATE_H__ + +# include "driver.h" +# include "conf/domain_conf.h" +# include "conf/snapshot_conf.h" +# include "viruri.h" + +# include <sys/types.h> +# include <sys/stat.h> + +/* -------- APIs cooperating with storage driver ----------------------- */ +struct _virStorageFile { + virStorageDriverPtr driver; + void *priv; + + char *path; + int type; + int protocol; + + size_t nhosts; + virDomainDiskHostDefPtr hosts; +}; + + +virStorageFilePtr +virStorageFileInitFromDiskDef(virConnectPtr conn, + virDomainDiskDefPtr disk); +virStorageFilePtr +virStorageFileInitFromSnapshotDef(virConnectPtr conn, + virDomainSnapshotDiskDefPtr disk); +void virStorageFileFree(virStorageFilePtr file); + +int virStorageFileCreate(virStorageFilePtr file); +int virStorageFileUnlink(virStorageFilePtr file); +int virStorageFileStat(virStorageFilePtr file, + struct stat *stat); + +#endif /* #ifndef __VIR_PRIVATE_H__ */ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 2c9536a..7e2728f 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -820,6 +820,15 @@ virRegisterSecretDriver; virRegisterStorageDriver; +# libvirt_private.h +virStorageFileCreate; +virStorageFileFree; +virStorageFileInitFromDiskDef; +virStorageFileInitFromSnapshotDef; +virStorageFileStat; +virStorageFileUnlink; + + # locking/domain_lock.h virDomainLockDiskAttach; virDomainLockDiskDetach; -- 1.8.5.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list