提交 7a227688 编写于 作者: J John Ferlan

storage: Add infrastructure to manage XML namespace options

Introduce the virStoragePoolFSMountOptionsDef to be used to
manage the Storage Pool XML Namespace for mount options.

Using a new virStorageBackendNamespaceInit function, set the
virStoragePoolXMLNamespace into the _virStoragePoolOptions when
the storage backend is loaded.

Modify the storagepool.rng to allow for the usage of a different
XML namespace to parse the fs_mount_opts to be included with
the fs and netfs storage pool definitions.

Modify the storagepoolxml2xmltest to utilize a properly modified
XML file to parse and format the namespace for a netfs storage pool.
Signed-off-by: NJohn Ferlan <jferlan@redhat.com>
Reviewed-by: NDaniel P. Berrangé <berrange@redhat.com>
上级 fa7a66d0
......@@ -508,6 +508,69 @@
device, measured in bytes. <span class="since">Since 0.4.1</span>
</p>
<h3><a id="StoragePoolNamespaces">Storage Pool Namespaces</a></h3>
<p>
Usage of Storage Pool Namespaces provides a mechanism to provide
pool type specific data in a free form or arbitrary manner via
XML syntax targeted solely for the needs of the specific pool type
which is not otherwise supported in standard XML. For the "fs" and
"netfs" pool types this provides a mechanism to provide additional
mount options on the command line.
</p>
<p>
Usage of namespaces comes with no support guarantees. It is intended
for developers testing out a concept prior to requesting an explicitly
supported XML option in libvirt, and thus should never be used in
production.
</p>
<dl>
<dt><code>fs:mount_opts</code></dt>
<dd>Provides an XML namespace mechanism to optionally utilize
specifically named options for the mount command via the "-o"
option for the <code>fs</code> or <code>netfs</code> type storage
pools. In order to designate that the Storage Pool will be using
the mechanism, the <code>pool</code> element must be modified to
provide the XML namespace attribute syntax as follows:
<p>
xmlns:fs='http://libvirt.org/schemas/storagepool/source/fs/1.0'
</p>
<p>
The <code>fs:mount_opts</code> defines the mount options by
specifying multiple <code>fs:option</code> subelements with
the attribute <code>name</code> specifying the mount option to
be added. The value of the named option is not checked since
it's possible options don't exist on all distributions. It is
expected that proper and valid options will be supplied for the
target host.
</p>
The following XML snippet shows the syntax required in order to
utilize for a netfs pool:
<pre>
&lt;pool type="netfs" xmlns:fs='http://libvirt.org/schemas/storagepool/source/fs/1.0'&gt;
&lt;name&gt;nfsimages&lt;/name&gt;
...
&lt;source&gt;
...
&lt;/source&gt;
...
&lt;target&gt;
...
&lt;/target&gt;
&lt;fs:mount_opts&gt;
&lt;fs:option name='sync'/&gt;
&lt;fs:option name='lazytime'/&gt;
&lt;/fs:mount_opts&gt;
&lt;/pool&gt;
...</pre>
<span class="since">Since 5.1.0.</span></dd>
</dl>
<h2><a id="StorageVol">Storage volume XML</a></h2>
<p>
A storage volume will generally be either a file or a device
......
......@@ -52,6 +52,9 @@
<ref name='sourcefs'/>
<ref name='target'/>
</interleave>
<optional>
<ref name='fs_mount_opts'/>
</optional>
</define>
<define name='poolnetfs'>
......@@ -64,6 +67,9 @@
<ref name='sourcenetfs'/>
<ref name='target'/>
</interleave>
<optional>
<ref name='fs_mount_opts'/>
</optional>
</define>
<define name='poollogical'>
......@@ -682,4 +688,21 @@
</data>
</define>
<!--
Optional storage pool extensions in their own namespace:
"fs" or "netfs"
-->
<define name="fs_mount_opts">
<element name="mount_opts" ns="http://libvirt.org/schemas/storagepool/source/fs/1.0">
<zeroOrMore>
<element name="option">
<attribute name='name'>
<text/>
</attribute>
</element>
</zeroOrMore>
</element>
</define>
</grammar>
......@@ -41,6 +41,7 @@ VIR_LOG_INIT("storage.storage_backend_fs");
#if WITH_STORAGE_FS
# include <libxml/xpathInternals.h>
# include <mntent.h>
struct _virNetfsDiscoverState {
......@@ -559,6 +560,122 @@ virStorageBackendFileSystemBuild(virStoragePoolObjPtr pool,
}
#if WITH_STORAGE_FS
# define STORAGE_POOL_FS_NAMESPACE_HREF "http://libvirt.org/schemas/storagepool/source/fs/1.0"
/* Backend XML Namespace handling for fs or netfs specific mount options to
* be added to the mount -o {options_list} command line that are not otherwise
* supplied by supported XML. The XML will use the format, such as:
*
* <fs:mount_opts>
* <fs:option name='sync'/>
* <fs:option name='lazytime'/>
* </fs:mount_opts>
*
* and the <pool type='fs'> or <pool type='netfs'> is required to have a
* "xmlns:fs='%s'" attribute using the STORAGE_POOL_FS_NAMESPACE_HREF
*/
static void
virStoragePoolDefFSNamespaceFree(void *nsdata)
{
virStoragePoolFSMountOptionsDefPtr cmdopts = nsdata;
size_t i;
if (!cmdopts)
return;
for (i = 0; i < cmdopts->noptions; i++)
VIR_FREE(cmdopts->options[i]);
VIR_FREE(cmdopts->options);
VIR_FREE(cmdopts);
}
static int
virStoragePoolDefFSNamespaceParse(xmlXPathContextPtr ctxt,
void **data)
{
virStoragePoolFSMountOptionsDefPtr cmdopts = NULL;
xmlNodePtr *nodes = NULL;
int nnodes;
size_t i;
int ret = -1;
if (xmlXPathRegisterNs(ctxt, BAD_CAST "fs",
BAD_CAST STORAGE_POOL_FS_NAMESPACE_HREF) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Failed to register xml namespace '%s'"),
STORAGE_POOL_FS_NAMESPACE_HREF);
return -1;
}
nnodes = virXPathNodeSet("./fs:mount_opts/fs:option", ctxt, &nodes);
if (nnodes < 0)
return -1;
if (nnodes == 0)
return 0;
if (VIR_ALLOC(cmdopts) < 0 ||
VIR_ALLOC_N(cmdopts->options, nnodes) < 0)
goto cleanup;
for (i = 0; i < nnodes; i++) {
if (!(cmdopts->options[cmdopts->noptions] =
virXMLPropString(nodes[i], "name"))) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("no fs mount option name specified"));
goto cleanup;
}
cmdopts->noptions++;
}
VIR_STEAL_PTR(*data, cmdopts);
ret = 0;
cleanup:
VIR_FREE(nodes);
virStoragePoolDefFSNamespaceFree(cmdopts);
return ret;
}
static int
virStoragePoolDefFSNamespaceFormatXML(virBufferPtr buf,
void *nsdata)
{
size_t i;
virStoragePoolFSMountOptionsDefPtr def = nsdata;
if (!def)
return 0;
virBufferAddLit(buf, "<fs:mount_opts>\n");
virBufferAdjustIndent(buf, 2);
for (i = 0; i < def->noptions; i++)
virBufferEscapeString(buf, "<fs:option name='%s'/>\n",
def->options[i]);
virBufferAdjustIndent(buf, -2);
virBufferAddLit(buf, "</fs:mount_opts>\n");
return 0;
}
static const char *
virStoragePoolDefFSNamespaceHref(void)
{
return "xmlns:fs='" STORAGE_POOL_FS_NAMESPACE_HREF "'";
}
#endif /* WITH_STORAGE_FS */
virStorageBackend virStorageBackendDirectory = {
.type = VIR_STORAGE_POOL_DIR,
......@@ -617,6 +734,13 @@ virStorageBackend virStorageBackendNetFileSystem = {
.downloadVol = virStorageBackendVolDownloadLocal,
.wipeVol = virStorageBackendVolWipeLocal,
};
static virStoragePoolXMLNamespace virStoragePoolFSXMLNamespace = {
.parse = virStoragePoolDefFSNamespaceParse,
.free = virStoragePoolDefFSNamespaceFree,
.format = virStoragePoolDefFSNamespaceFormatXML,
.href = virStoragePoolDefFSNamespaceHref,
};
#endif /* WITH_STORAGE_FS */
......@@ -630,8 +754,16 @@ virStorageBackendFsRegister(void)
if (virStorageBackendRegister(&virStorageBackendFileSystem) < 0)
return -1;
if (virStorageBackendNamespaceInit(VIR_STORAGE_POOL_FS,
&virStoragePoolFSXMLNamespace) < 0)
return -1;
if (virStorageBackendRegister(&virStorageBackendNetFileSystem) < 0)
return -1;
if (virStorageBackendNamespaceInit(VIR_STORAGE_POOL_NETFS,
&virStoragePoolFSXMLNamespace) < 0)
return -1;
#endif /* WITH_STORAGE_FS */
return 0;
......
......@@ -82,6 +82,22 @@
VIR_LOG_INIT("storage.storage_util");
/* virStorageBackendNamespaceInit:
* @poolType: virStoragePoolType
* @xmlns: Storage Pool specific namespace callback methods
*
* To be called during storage backend registration to configure the
* Storage Pool XML Namespace based on the backend's needs.
*/
int
virStorageBackendNamespaceInit(int poolType,
virStoragePoolXMLNamespacePtr xmlns)
{
return virStoragePoolOptionsPoolTypeSetXMLNamespace(poolType, xmlns);
}
#define READ_BLOCK_SIZE_DEFAULT (1024 * 1024)
#define WRITE_BLOCK_SIZE_DEFAULT (4 * 1024)
......
......@@ -26,6 +26,20 @@
# include "storage_driver.h"
# include "storage_backend.h"
/* Storage Pool Namespace options to share w/ storage_backend_fs.c and
* the virStorageBackendFileSystemMountCmd method */
typedef struct _virStoragePoolFSMountOptionsDef virStoragePoolFSMountOptionsDef;
typedef virStoragePoolFSMountOptionsDef *virStoragePoolFSMountOptionsDefPtr;
struct _virStoragePoolFSMountOptionsDef {
size_t noptions;
char **options;
};
int
virStorageBackendNamespaceInit(int poolType,
virStoragePoolXMLNamespacePtr xmlns);
/* File creation/cloning functions used for cloning between backends */
int
......
......@@ -937,7 +937,9 @@ storagevolxml2xmltest_LDADD = $(LDADDS)
storagepoolxml2xmltest_SOURCES = \
storagepoolxml2xmltest.c \
testutils.c testutils.h
storagepoolxml2xmltest_LDADD = $(LDADDS)
storagepoolxml2xmltest_LDADD = $(LDADDS) \
../src/libvirt_driver_storage_impl.la \
$(GNULIB_LIBS)
nodedevxml2xmltest_SOURCES = \
nodedevxml2xmltest.c \
......
<pool type='netfs' xmlns:fs='http://libvirt.org/schemas/storagepool/source/fs/1.0'>
<name>nfsimages</name>
<uuid>7641d5a8-af11-f730-a34e-0a7dfcede71f</uuid>
<capacity>0</capacity>
<allocation>0</allocation>
<available>0</available>
<source>
<host name='localhost'/>
<dir path='/var/lib/libvirt/images'/>
<format type='nfs'/>
<protocol ver='3'/>
</source>
<target>
<path>/mnt</path>
<permissions>
<mode>0700</mode>
<owner>0</owner>
<group>0</group>
</permissions>
</target>
<fs:mount_opts>
<fs:option name='sync'/>
<fs:option name='lazytime'/>
</fs:mount_opts>
</pool>
<pool type='netfs' xmlns:fs='http://libvirt.org/schemas/storagepool/source/fs/1.0'>
<name>nfsimages</name>
<uuid>7641d5a8-af11-f730-a34e-0a7dfcede71f</uuid>
<capacity unit='bytes'>0</capacity>
<allocation unit='bytes'>0</allocation>
<available unit='bytes'>0</available>
<source>
<host name='localhost'/>
<dir path='/var/lib/libvirt/images'/>
<format type='nfs'/>
<protocol ver='3'/>
</source>
<target>
<path>/mnt</path>
<permissions>
<mode>0700</mode>
<owner>0</owner>
<group>0</group>
</permissions>
</target>
<fs:mount_opts>
<fs:option name='sync'/>
<fs:option name='lazytime'/>
</fs:mount_opts>
</pool>
......@@ -11,6 +11,8 @@
#include "testutilsqemu.h"
#include "virstring.h"
#include "storage/storage_util.h"
#define VIR_FROM_THIS VIR_FROM_NONE
static int
......@@ -70,6 +72,9 @@ mymain(void)
testCompareXMLToXMLHelper, (name)) < 0) \
ret = -1
if (storageRegisterAll() < 0)
return EXIT_FAILURE;
DO_TEST("pool-dir");
DO_TEST("pool-dir-naming");
DO_TEST("pool-fs");
......@@ -86,6 +91,7 @@ mymain(void)
DO_TEST("pool-netfs-protocol-ver");
DO_TEST("pool-netfs-gluster");
DO_TEST("pool-netfs-cifs");
DO_TEST("pool-netfs-ns-mountopts");
DO_TEST("pool-scsi");
DO_TEST("pool-scsi-type-scsi-host");
DO_TEST("pool-scsi-type-fc-host");
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册