Discussion:
[Libstoragemgmt-devel] [PATCH] Moved git repo to github
Gris Ge
2015-04-02 07:06:05 UTC
Permalink
* Removed everything except one new file `MOVED_TO_GITHUB.TXT`:

https://github.com/libstorage/libstoragemgmt

Signed-off-by: Gris Ge <***@redhat.com>
---
AUTHORS | 31 -
COPYING.LIB | 508 ----
ChangeLog | 0
INSTALL | 370 ---
MOVED_TO_GITHUB.TXT | 1 +
Makefile.am | 28 -
NEWS | 271 --
README | 5 -
autogen.sh | 9 -
c_binding/Makefile.am | 15 -
c_binding/include/Makefile.am | 6 -
c_binding/include/libstoragemgmt/Makefile.am | 30 -
c_binding/include/libstoragemgmt/libstoragemgmt.h | 871 ------
.../libstoragemgmt/libstoragemgmt_accessgroups.h | 94 -
.../libstoragemgmt/libstoragemgmt_blockrange.h | 98 -
.../libstoragemgmt/libstoragemgmt_capabilities.h | 151 -
.../include/libstoragemgmt/libstoragemgmt_common.h | 136 -
.../include/libstoragemgmt/libstoragemgmt_disk.h | 119 -
.../include/libstoragemgmt/libstoragemgmt_error.h | 166 --
.../include/libstoragemgmt/libstoragemgmt_fs.h | 97 -
.../include/libstoragemgmt/libstoragemgmt_hash.h | 89 -
.../libstoragemgmt/libstoragemgmt_nfsexport.h | 189 --
.../libstoragemgmt/libstoragemgmt_plug_interface.h | 1358 ---------
.../include/libstoragemgmt/libstoragemgmt_pool.h | 121 -
.../libstoragemgmt/libstoragemgmt_snapshot.h | 76 -
.../libstoragemgmt/libstoragemgmt_systems.h | 83 -
.../libstoragemgmt/libstoragemgmt_targetport.h | 107 -
.../include/libstoragemgmt/libstoragemgmt_types.h | 287 --
.../libstoragemgmt/libstoragemgmt_version.h.in | 29 -
.../libstoragemgmt/libstoragemgmt_volumes.h | 116 -
c_binding/lsm_convert.cpp | 619 ----
c_binding/lsm_convert.hpp | 287 --
c_binding/lsm_datatypes.cpp | 1977 -------------
c_binding/lsm_datatypes.hpp | 379 ---
c_binding/lsm_ipc.cpp | 913 ------
c_binding/lsm_ipc.hpp | 481 ----
c_binding/lsm_mgmt.cpp | 2210 ---------------
c_binding/lsm_plugin_ipc.cpp | 2629 -----------------
c_binding/lsm_plugin_ipc.hpp | 49 -
c_binding/test.cpp | 76 -
c_binding/util/misc.cpp | 48 -
c_binding/util/misc.h | 108 -
c_binding/util/qparams.c | 242 --
c_binding/util/qparams.h | 88 -
config/Makefile.am | 18 -
config/lsmd.conf | 1 -
config/pluginconf.d/hpsa.conf | 1 -
config/pluginconf.d/megaraid.conf | 1 -
config/pluginconf.d/sim.conf | 1 -
configure.ac | 290 --
daemon/Makefile.am | 15 -
daemon/lsm_daemon.c | 914 ------
daemon/lsm_rest.c | 517 ----
daemon/lsm_rest.h | 79 -
doc/Makefile.am | 3 -
doc/REST_API_Doc | 36 -
doc/doxygen.conf.in | 1562 -----------
doc/man/Makefile.am | 11 -
doc/man/hpsa_lsmplugin.1.in | 50 -
doc/man/lsmcli.1.in | 727 -----
doc/man/lsmd.1.in | 26 -
doc/man/lsmd.conf.5.in | 56 -
doc/man/megaraid_lsmplugin.1.in | 52 -
examples/client_example.c | 75 -
examples/plugin_example.c | 81 -
libstoragemgmt.pc.in | 11 -
m4/README | 1 -
m4/ax_python_module.m4 | 49 -
packaging/Makefile.am | 5 -
packaging/daemon/Makefile.am | 13 -
packaging/daemon/libstoragemgmt-rest.service | 13 -
packaging/daemon/libstoragemgmt.service | 12 -
packaging/daemon/libstoragemgmtd | 124 -
packaging/daemon/lsm-tmpfiles.conf | 2 -
packaging/libstoragemgmt.spec.in | 912 ------
plugin/Makefile.am | 48 -
plugin/__init__.py | 0
plugin/hpsa/Makefile.am | 8 -
plugin/hpsa/__init__.py | 1 -
plugin/hpsa/hpsa.py | 533 ----
plugin/hpsa/hpsa_lsmplugin | 37 -
plugin/hpsa/utils.py | 58 -
plugin/megaraid/Makefile.am | 8 -
plugin/megaraid/__init__.py | 1 -
plugin/megaraid/megaraid.py | 548 ----
plugin/megaraid/megaraid_lsmplugin | 37 -
plugin/megaraid/utils.py | 47 -
plugin/nstor/__init__.py | 0
plugin/nstor/nstor.py | 879 ------
plugin/nstor/nstor_lsmplugin | 39 -
plugin/ontap/__init__.py | 0
plugin/ontap/na.py | 840 ------
plugin/ontap/ontap.py | 1332 ---------
plugin/ontap/ontap_lsmplugin | 37 -
plugin/sim/__init__.py | 0
plugin/sim/sim_lsmplugin | 37 -
plugin/sim/simarray.py | 2280 ---------------
plugin/sim/simulator.py | 294 --
plugin/simc/Makefile.am | 11 -
plugin/simc/simc_lsmplugin.c | 2301 ---------------
plugin/smispy/__init__.py | 0
plugin/smispy/dmtf.py | 246 --
plugin/smispy/smis.py | 2017 -------------
plugin/smispy/smis_ag.py | 285 --
plugin/smispy/smis_cap.py | 372 ---
plugin/smispy/smis_common.py | 645 -----
plugin/smispy/smis_disk.py | 225 --
plugin/smispy/smis_pool.py | 268 --
plugin/smispy/smis_sys.py | 159 --
plugin/smispy/smis_vol.py | 245 --
plugin/smispy/smispy_lsmplugin | 37 -
plugin/smispy/utils.py | 89 -
plugin/targetd/__init__.py | 0
plugin/targetd/targetd.py | 996 -------
plugin/targetd/targetd_lsmplugin | 37 -
python_binding/Makefile.am | 17 -
python_binding/lsm/__init__.py | 15 -
python_binding/lsm/_client.py | 1076 -------
python_binding/lsm/_common.py | 588 ----
python_binding/lsm/_data.py | 817 ------
python_binding/lsm/_iplugin.py | 481 ----
python_binding/lsm/_pluginrunner.py | 153 -
python_binding/lsm/_transport.py | 271 --
python_binding/lsm/external/__init__.py | 0
python_binding/lsm/external/xmltodict.py | 147 -
python_binding/lsm/version.py.in | 19 -
test/Makefile.am | 13 -
test/cmdtest.py | 753 -----
test/plugin_test.py | 1348 ---------
test/runtests.sh | 179 --
test/tester.c | 2953 --------------------
test/webtest/test.css | 126 -
test/webtest/test_automated.py | 123 -
test/webtest/test_hardware.py | 143 -
test/webtest/test_results.py | 235 --
tools/Makefile.am | 3 -
tools/bash_completion/Makefile.am | 4 -
tools/bash_completion/lsmcli | 421 ---
tools/lsmcli/Makefile.am | 8 -
tools/lsmcli/__init__.py | 1 -
tools/lsmcli/cmdline.py | 1451 ----------
tools/lsmcli/data_display.py | 768 -----
tools/lsmcli/lsmcli | 25 -
tools/lsmenv | 287 --
tools/netapp/netapp.py | 76 -
tools/smiscli/BlockMgmt.cpp | 547 ----
tools/smiscli/BlockMgmt.h | 192 --
tools/smiscli/Makefile.am | 4 -
tools/smiscli/README | 1 -
tools/smiscli/smiscli.cpp | 209 --
tools/udev/90-scsi-ua.rules | 5 -
tools/udev/Makefile.am | 5 -
tools/udev/scan-scsi-target.c | 206 --
tools/utility/Makefile.am | 1 -
tools/utility/check_const.pl | 489 ----
tools/utility/public_symbols.py | 120 -
tools/utility/web_cap.py | 121 -
157 files changed, 1 insertion(+), 50622 deletions(-)
delete mode 100644 AUTHORS
delete mode 100644 COPYING.LIB
delete mode 100644 ChangeLog
delete mode 100644 INSTALL
create mode 100644 MOVED_TO_GITHUB.TXT
delete mode 100644 Makefile.am
delete mode 100644 NEWS
delete mode 100644 README
delete mode 100755 autogen.sh
delete mode 100644 c_binding/Makefile.am
delete mode 100644 c_binding/include/Makefile.am
delete mode 100644 c_binding/include/libstoragemgmt/Makefile.am
delete mode 100644 c_binding/include/libstoragemgmt/libstoragemgmt.h
delete mode 100644 c_binding/include/libstoragemgmt/libstoragemgmt_accessgroups.h
delete mode 100644 c_binding/include/libstoragemgmt/libstoragemgmt_blockrange.h
delete mode 100644 c_binding/include/libstoragemgmt/libstoragemgmt_capabilities.h
delete mode 100644 c_binding/include/libstoragemgmt/libstoragemgmt_common.h
delete mode 100644 c_binding/include/libstoragemgmt/libstoragemgmt_disk.h
delete mode 100644 c_binding/include/libstoragemgmt/libstoragemgmt_error.h
delete mode 100644 c_binding/include/libstoragemgmt/libstoragemgmt_fs.h
delete mode 100644 c_binding/include/libstoragemgmt/libstoragemgmt_hash.h
delete mode 100644 c_binding/include/libstoragemgmt/libstoragemgmt_nfsexport.h
delete mode 100644 c_binding/include/libstoragemgmt/libstoragemgmt_plug_interface.h
delete mode 100644 c_binding/include/libstoragemgmt/libstoragemgmt_pool.h
delete mode 100644 c_binding/include/libstoragemgmt/libstoragemgmt_snapshot.h
delete mode 100644 c_binding/include/libstoragemgmt/libstoragemgmt_systems.h
delete mode 100644 c_binding/include/libstoragemgmt/libstoragemgmt_targetport.h
delete mode 100644 c_binding/include/libstoragemgmt/libstoragemgmt_types.h
delete mode 100644 c_binding/include/libstoragemgmt/libstoragemgmt_version.h.in
delete mode 100644 c_binding/include/libstoragemgmt/libstoragemgmt_volumes.h
delete mode 100644 c_binding/lsm_convert.cpp
delete mode 100644 c_binding/lsm_convert.hpp
delete mode 100644 c_binding/lsm_datatypes.cpp
delete mode 100644 c_binding/lsm_datatypes.hpp
delete mode 100644 c_binding/lsm_ipc.cpp
delete mode 100644 c_binding/lsm_ipc.hpp
delete mode 100644 c_binding/lsm_mgmt.cpp
delete mode 100644 c_binding/lsm_plugin_ipc.cpp
delete mode 100644 c_binding/lsm_plugin_ipc.hpp
delete mode 100644 c_binding/test.cpp
delete mode 100644 c_binding/util/misc.cpp
delete mode 100644 c_binding/util/misc.h
delete mode 100644 c_binding/util/qparams.c
delete mode 100644 c_binding/util/qparams.h
delete mode 100644 config/Makefile.am
delete mode 100644 config/lsmd.conf
delete mode 100644 config/pluginconf.d/hpsa.conf
delete mode 100644 config/pluginconf.d/megaraid.conf
delete mode 100644 config/pluginconf.d/sim.conf
delete mode 100644 configure.ac
delete mode 100644 daemon/Makefile.am
delete mode 100644 daemon/lsm_daemon.c
delete mode 100644 daemon/lsm_rest.c
delete mode 100644 daemon/lsm_rest.h
delete mode 100644 doc/Makefile.am
delete mode 100644 doc/REST_API_Doc
delete mode 100644 doc/doxygen.conf.in
delete mode 100644 doc/man/Makefile.am
delete mode 100644 doc/man/hpsa_lsmplugin.1.in
delete mode 100644 doc/man/lsmcli.1.in
delete mode 100644 doc/man/lsmd.1.in
delete mode 100644 doc/man/lsmd.conf.5.in
delete mode 100644 doc/man/megaraid_lsmplugin.1.in
delete mode 100644 examples/client_example.c
delete mode 100644 examples/plugin_example.c
delete mode 100644 libstoragemgmt.pc.in
delete mode 100644 m4/README
delete mode 100644 m4/ax_python_module.m4
delete mode 100644 packaging/Makefile.am
delete mode 100644 packaging/daemon/Makefile.am
delete mode 100644 packaging/daemon/libstoragemgmt-rest.service
delete mode 100644 packaging/daemon/libstoragemgmt.service
delete mode 100755 packaging/daemon/libstoragemgmtd
delete mode 100644 packaging/daemon/lsm-tmpfiles.conf
delete mode 100644 packaging/libstoragemgmt.spec.in
delete mode 100644 plugin/Makefile.am
delete mode 100644 plugin/__init__.py
delete mode 100644 plugin/hpsa/Makefile.am
delete mode 100644 plugin/hpsa/__init__.py
delete mode 100644 plugin/hpsa/hpsa.py
delete mode 100755 plugin/hpsa/hpsa_lsmplugin
delete mode 100644 plugin/hpsa/utils.py
delete mode 100644 plugin/megaraid/Makefile.am
delete mode 100644 plugin/megaraid/__init__.py
delete mode 100644 plugin/megaraid/megaraid.py
delete mode 100755 plugin/megaraid/megaraid_lsmplugin
delete mode 100644 plugin/megaraid/utils.py
delete mode 100644 plugin/nstor/__init__.py
delete mode 100644 plugin/nstor/nstor.py
delete mode 100755 plugin/nstor/nstor_lsmplugin
delete mode 100644 plugin/ontap/__init__.py
delete mode 100644 plugin/ontap/na.py
delete mode 100644 plugin/ontap/ontap.py
delete mode 100755 plugin/ontap/ontap_lsmplugin
delete mode 100644 plugin/sim/__init__.py
delete mode 100755 plugin/sim/sim_lsmplugin
delete mode 100644 plugin/sim/simarray.py
delete mode 100644 plugin/sim/simulator.py
delete mode 100644 plugin/simc/Makefile.am
delete mode 100644 plugin/simc/simc_lsmplugin.c
delete mode 100644 plugin/smispy/__init__.py
delete mode 100644 plugin/smispy/dmtf.py
delete mode 100644 plugin/smispy/smis.py
delete mode 100644 plugin/smispy/smis_ag.py
delete mode 100644 plugin/smispy/smis_cap.py
delete mode 100644 plugin/smispy/smis_common.py
delete mode 100644 plugin/smispy/smis_disk.py
delete mode 100644 plugin/smispy/smis_pool.py
delete mode 100644 plugin/smispy/smis_sys.py
delete mode 100644 plugin/smispy/smis_vol.py
delete mode 100755 plugin/smispy/smispy_lsmplugin
delete mode 100644 plugin/smispy/utils.py
delete mode 100644 plugin/targetd/__init__.py
delete mode 100644 plugin/targetd/targetd.py
delete mode 100755 plugin/targetd/targetd_lsmplugin
delete mode 100644 python_binding/Makefile.am
delete mode 100644 python_binding/lsm/__init__.py
delete mode 100644 python_binding/lsm/_client.py
delete mode 100644 python_binding/lsm/_common.py
delete mode 100644 python_binding/lsm/_data.py
delete mode 100644 python_binding/lsm/_iplugin.py
delete mode 100644 python_binding/lsm/_pluginrunner.py
delete mode 100644 python_binding/lsm/_transport.py
delete mode 100644 python_binding/lsm/external/__init__.py
delete mode 100644 python_binding/lsm/external/xmltodict.py
delete mode 100644 python_binding/lsm/version.py.in
delete mode 100644 test/Makefile.am
delete mode 100755 test/cmdtest.py
delete mode 100755 test/plugin_test.py
delete mode 100755 test/runtests.sh
delete mode 100644 test/tester.c
delete mode 100644 test/webtest/test.css
delete mode 100755 test/webtest/test_automated.py
delete mode 100755 test/webtest/test_hardware.py
delete mode 100755 test/webtest/test_results.py
delete mode 100644 tools/Makefile.am
delete mode 100644 tools/bash_completion/Makefile.am
delete mode 100644 tools/bash_completion/lsmcli
delete mode 100644 tools/lsmcli/Makefile.am
delete mode 100644 tools/lsmcli/__init__.py
delete mode 100644 tools/lsmcli/cmdline.py
delete mode 100644 tools/lsmcli/data_display.py
delete mode 100755 tools/lsmcli/lsmcli
delete mode 100755 tools/lsmenv
delete mode 100755 tools/netapp/netapp.py
delete mode 100644 tools/smiscli/BlockMgmt.cpp
delete mode 100644 tools/smiscli/BlockMgmt.h
delete mode 100644 tools/smiscli/Makefile.am
delete mode 100644 tools/smiscli/README
delete mode 100644 tools/smiscli/smiscli.cpp
delete mode 100644 tools/udev/90-scsi-ua.rules
delete mode 100644 tools/udev/Makefile.am
delete mode 100644 tools/udev/scan-scsi-target.c
delete mode 100644 tools/utility/Makefile.am
delete mode 100644 tools/utility/check_const.pl
delete mode 100755 tools/utility/public_symbols.py
delete mode 100755 tools/utility/web_cap.py

diff --git a/AUTHORS b/AUTHORS
deleted file mode 100644
index d192794..0000000
--- a/AUTHORS
+++ /dev/null
@@ -1,31 +0,0 @@
-
-libStorageMgmt Authors
-
-The libStorageMgmt project was initiated by:
-
- Tony Asleson <***@redhat.com>
-
-The primary maintainer(s) and people with commit access rights:
-
- Tony Asleson <***@redhat.com>
- Andy Grover <***@redhat.com>
- Eduardo Lima <***@br.ibm.com>
- Gris Ge <***@redhat.com>
- Ma Shimiao <***@cn.fujitsu.com>
-
-Patches have also been contributed by:
-
- Daniel Veillard <***@redhat.com>
- Christophe Fergeau <***@redhat.com>
- Eduardo Lima <***@br.ibm.com>
- Dustin Schoenbrun <***@netapp.com>
- Ritesh Raj Sarraf <***@netapp.com>
- Andy Grover <***@redhat.com>
- Anatoly Legkodymov <***@fastmail.fm>
- Deepak C Shetty <***@linux.vnet.ibm.com>
- Gris Ge <***@redhat.com>
- Ma Shimiao <***@cn.fujitsu.com>
- Ewan Milne <***@redhat.com>
-
-
-[....send patches to get your name here....]
diff --git a/COPYING.LIB b/COPYING.LIB
deleted file mode 100644
index 3599d82..0000000
--- a/COPYING.LIB
+++ /dev/null
@@ -1,508 +0,0 @@
-
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL. It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
- This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it. You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations
-below.
-
- When we speak of free software, we are referring to freedom of use,
-not price. Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
- To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights. These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
- For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you. You must make sure that they, too, receive or can get the source
-code. If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it. And you must show them these terms so they know their rights.
-
- We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
- To protect each distributor, we want to make it very clear that
-there is no warranty for the free library. Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-^L
- Finally, software patents pose a constant threat to the existence of
-any free program. We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder. Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
- Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License. This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License. We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
- When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library. The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom. The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
- We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License. It also provides other free software developers Less
-of an advantage over competing non-free programs. These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries. However, the Lesser license provides advantages in certain
-special circumstances.
-
- For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it
-becomes a de-facto standard. To achieve this, non-free programs must
-be allowed to use the library. A more frequent case is that a free
-library does the same job as widely used non-free libraries. In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
- In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software. For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
- Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
- The precise terms and conditions for copying, distribution and
-modification follow. Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library". The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-^L
- GNU LESSER GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
- A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
- The "Library", below, refers to any such software library or work
-which has been distributed under these terms. A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language. (Hereinafter, translation is
-included without limitation in the term "modification".)
-
- "Source code" for a work means the preferred form of the work for
-making modifications to it. For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control
-compilation and installation of the library.
-
- Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it). Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
- 1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
- You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
- 2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) The modified work must itself be a software library.
-
- b) You must cause the files modified to carry prominent notices
- stating that you changed the files and the date of any change.
-
- c) You must cause the whole of the work to be licensed at no
- charge to all third parties under the terms of this License.
-
- d) If a facility in the modified Library refers to a function or a
- table of data to be supplied by an application program that uses
- the facility, other than as an argument passed when the facility
- is invoked, then you must make a good faith effort to ensure that,
- in the event an application does not supply such function or
- table, the facility still operates, and performs whatever part of
- its purpose remains meaningful.
-
- (For example, a function in a library to compute square roots has
- a purpose that is entirely well-defined independent of the
- application. Therefore, Subsection 2d requires that any
- application-supplied function or table used by this function must
- be optional: if the application does not supply it, the square
- root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library. To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License. (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.) Do not make any other change in
-these notices.
-^L
- Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
- This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
- 4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
- If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library". Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
- However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library". The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
- When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library. The
-threshold for this to be true is not precisely defined by law.
-
- If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work. (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
- Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-^L
- 6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
- You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License. You must supply a copy of this License. If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License. Also, you must do one
-of these things:
-
- a) Accompany the work with the complete corresponding
- machine-readable source code for the Library including whatever
- changes were used in the work (which must be distributed under
- Sections 1 and 2 above); and, if the work is an executable linked
- with the Library, with the complete machine-readable "work that
- uses the Library", as object code and/or source code, so that the
- user can modify the Library and then relink to produce a modified
- executable containing the modified Library. (It is understood
- that the user who changes the contents of definitions files in the
- Library will not necessarily be able to recompile the application
- to use the modified definitions.)
-
- b) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (1) uses at run time a
- copy of the library already present on the user's computer system,
- rather than copying library functions into the executable, and (2)
- will operate properly with a modified version of the library, if
- the user installs one, as long as the modified version is
- interface-compatible with the version that the work was made with.
-
- c) Accompany the work with a written offer, valid for at least
- three years, to give the same user the materials specified in
- Subsection 6a, above, for a charge no more than the cost of
- performing this distribution.
-
- d) If distribution of the work is made by offering access to copy
- from a designated place, offer equivalent access to copy the above
- specified materials from the same place.
-
- e) Verify that the user has already received a copy of these
- materials or that you have already sent this user a copy.
-
- For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it. However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
- It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system. Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-^L
- 7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities. This must be distributed under the terms of the
- Sections above.
-
- b) Give prominent notice with the combined library of the fact
- that part of it is a work based on the Library, and explaining
- where to find the accompanying uncombined form of the same work.
-
- 8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License. Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License. However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
- 9. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Library or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
- 10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-^L
- 11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all. For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply, and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License
-may add an explicit geographical distribution limitation excluding those
-countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation. If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-^L
- 14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission. For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this. Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
- NO WARRANTY
-
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
- END OF TERMS AND CONDITIONS
-^L
- How to Apply These Terms to Your New Libraries
-
- If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change. You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms
-of the ordinary General Public License).
-
- To apply these terms, attach the following notices to the library.
-It is safest to attach them to the start of each source file to most
-effectively convey the exclusion of warranty; and each file should
-have at least the "copyright" line and a pointer to where the full
-notice is found.
-
-
- <one line to give the library's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- 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, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or
-your school, if any, to sign a "copyright disclaimer" for the library,
-if necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James
- Random Hacker.
-
- <signature of Ty Coon>, 1 April 1990
- Ty Coon, President of Vice
-
-That's all there is to it!
diff --git a/ChangeLog b/ChangeLog
deleted file mode 100644
index e69de29..0000000
diff --git a/INSTALL b/INSTALL
deleted file mode 100644
index 007e939..0000000
--- a/INSTALL
+++ /dev/null
@@ -1,370 +0,0 @@
-Installation Instructions
-*************************
-
-Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation,
-Inc.
-
- Copying and distribution of this file, with or without modification,
-are permitted in any medium without royalty provided the copyright
-notice and this notice are preserved. This file is offered as-is,
-without warranty of any kind.
-
-Basic Installation
-==================
-
- Briefly, the shell commands `./configure; make; make install' should
-configure, build, and install this package. The following
-more-detailed instructions are generic; see the `README' file for
-instructions specific to this package. Some packages provide this
-`INSTALL' file but do not implement all of the features documented
-below. The lack of an optional feature in a given package is not
-necessarily a bug. More recommendations for GNU packages can be found
-in *note Makefile Conventions: (standards)Makefile Conventions.
-
- The `configure' shell script attempts to guess correct values for
-various system-dependent variables used during compilation. It uses
-those values to create a `Makefile' in each directory of the package.
-It may also create one or more `.h' files containing system-dependent
-definitions. Finally, it creates a shell script `config.status' that
-you can run in the future to recreate the current configuration, and a
-file `config.log' containing compiler output (useful mainly for
-debugging `configure').
-
- It can also use an optional file (typically called `config.cache'
-and enabled with `--cache-file=config.cache' or simply `-C') that saves
-the results of its tests to speed up reconfiguring. Caching is
-disabled by default to prevent problems with accidental use of stale
-cache files.
-
- If you need to do unusual things to compile the package, please try
-to figure out how `configure' could check whether to do them, and mail
-diffs or instructions to the address given in the `README' so they can
-be considered for the next release. If you are using the cache, and at
-some point `config.cache' contains results you don't want to keep, you
-may remove or edit it.
-
- The file `configure.ac' (or `configure.in') is used to create
-`configure' by a program called `autoconf'. You need `configure.ac' if
-you want to change it or regenerate `configure' using a newer version
-of `autoconf'.
-
- The simplest way to compile this package is:
-
- 1. `cd' to the directory containing the package's source code and type
- `./configure' to configure the package for your system.
-
- Running `configure' might take a while. While running, it prints
- some messages telling which features it is checking for.
-
- 2. Type `make' to compile the package.
-
- 3. Optionally, type `make check' to run any self-tests that come with
- the package, generally using the just-built uninstalled binaries.
-
- 4. Type `make install' to install the programs and any data files and
- documentation. When installing into a prefix owned by root, it is
- recommended that the package be configured and built as a regular
- user, and only the `make install' phase executed with root
- privileges.
-
- 5. Optionally, type `make installcheck' to repeat any self-tests, but
- this time using the binaries in their final installed location.
- This target does not install anything. Running this target as a
- regular user, particularly if the prior `make install' required
- root privileges, verifies that the installation completed
- correctly.
-
- 6. You can remove the program binaries and object files from the
- source code directory by typing `make clean'. To also remove the
- files that `configure' created (so you can compile the package for
- a different kind of computer), type `make distclean'. There is
- also a `make maintainer-clean' target, but that is intended mainly
- for the package's developers. If you use it, you may have to get
- all sorts of other programs in order to regenerate files that came
- with the distribution.
-
- 7. Often, you can also type `make uninstall' to remove the installed
- files again. In practice, not all packages have tested that
- uninstallation works correctly, even though it is required by the
- GNU Coding Standards.
-
- 8. Some packages, particularly those that use Automake, provide `make
- distcheck', which can by used by developers to test that all other
- targets like `make install' and `make uninstall' work correctly.
- This target is generally not run by end users.
-
-Compilers and Options
-=====================
-
- Some systems require unusual options for compilation or linking that
-the `configure' script does not know about. Run `./configure --help'
-for details on some of the pertinent environment variables.
-
- You can give `configure' initial values for configuration parameters
-by setting variables in the command line or in the environment. Here
-is an example:
-
- ./configure CC=c99 CFLAGS=-g LIBS=-lposix
-
- *Note Defining Variables::, for more details.
-
-Compiling For Multiple Architectures
-====================================
-
- You can compile the package for more than one kind of computer at the
-same time, by placing the object files for each architecture in their
-own directory. To do this, you can use GNU `make'. `cd' to the
-directory where you want the object files and executables to go and run
-the `configure' script. `configure' automatically checks for the
-source code in the directory that `configure' is in and in `..'. This
-is known as a "VPATH" build.
-
- With a non-GNU `make', it is safer to compile the package for one
-architecture at a time in the source code directory. After you have
-installed the package for one architecture, use `make distclean' before
-reconfiguring for another architecture.
-
- On MacOS X 10.5 and later systems, you can create libraries and
-executables that work on multiple system types--known as "fat" or
-"universal" binaries--by specifying multiple `-arch' options to the
-compiler but only a single `-arch' option to the preprocessor. Like
-this:
-
- ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
- CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
- CPP="gcc -E" CXXCPP="g++ -E"
-
- This is not guaranteed to produce working output in all cases, you
-may have to build one architecture at a time and combine the results
-using the `lipo' tool if you have problems.
-
-Installation Names
-==================
-
- By default, `make install' installs the package's commands under
-`/usr/local/bin', include files under `/usr/local/include', etc. You
-can specify an installation prefix other than `/usr/local' by giving
-`configure' the option `--prefix=PREFIX', where PREFIX must be an
-absolute file name.
-
- You can specify separate installation prefixes for
-architecture-specific files and architecture-independent files. If you
-pass the option `--exec-prefix=PREFIX' to `configure', the package uses
-PREFIX as the prefix for installing programs and libraries.
-Documentation and other data files still use the regular prefix.
-
- In addition, if you use an unusual directory layout you can give
-options like `--bindir=DIR' to specify different values for particular
-kinds of files. Run `configure --help' for a list of the directories
-you can set and what kinds of files go in them. In general, the
-default for these options is expressed in terms of `${prefix}', so that
-specifying just `--prefix' will affect all of the other directory
-specifications that were not explicitly provided.
-
- The most portable way to affect installation locations is to pass the
-correct locations to `configure'; however, many packages provide one or
-both of the following shortcuts of passing variable assignments to the
-`make install' command line to change installation locations without
-having to reconfigure or recompile.
-
- The first method involves providing an override variable for each
-affected directory. For example, `make install
-prefix=/alternate/directory' will choose an alternate location for all
-directory configuration variables that were expressed in terms of
-`${prefix}'. Any directories that were specified during `configure',
-but not in terms of `${prefix}', must each be overridden at install
-time for the entire installation to be relocated. The approach of
-makefile variable overrides for each directory variable is required by
-the GNU Coding Standards, and ideally causes no recompilation.
-However, some platforms have known limitations with the semantics of
-shared libraries that end up requiring recompilation when using this
-method, particularly noticeable in packages that use GNU Libtool.
-
- The second method involves providing the `DESTDIR' variable. For
-example, `make install DESTDIR=/alternate/directory' will prepend
-`/alternate/directory' before all installation names. The approach of
-`DESTDIR' overrides is not required by the GNU Coding Standards, and
-does not work on platforms that have drive letters. On the other hand,
-it does better at avoiding recompilation issues, and works well even
-when some directory options were not specified in terms of `${prefix}'
-at `configure' time.
-
-Optional Features
-=================
-
- If the package supports it, you can cause programs to be installed
-with an extra prefix or suffix on their names by giving `configure' the
-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
-
- Some packages pay attention to `--enable-FEATURE' options to
-`configure', where FEATURE indicates an optional part of the package.
-They may also pay attention to `--with-PACKAGE' options, where PACKAGE
-is something like `gnu-as' or `x' (for the X Window System). The
-`README' should mention any `--enable-' and `--with-' options that the
-package recognizes.
-
- For packages that use the X Window System, `configure' can usually
-find the X include and library files automatically, but if it doesn't,
-you can use the `configure' options `--x-includes=DIR' and
-`--x-libraries=DIR' to specify their locations.
-
- Some packages offer the ability to configure how verbose the
-execution of `make' will be. For these packages, running `./configure
---enable-silent-rules' sets the default to minimal output, which can be
-overridden with `make V=1'; while running `./configure
---disable-silent-rules' sets the default to verbose, which can be
-overridden with `make V=0'.
-
-Particular systems
-==================
-
- On HP-UX, the default C compiler is not ANSI C compatible. If GNU
-CC is not installed, it is recommended to use the following options in
-order to use an ANSI C compiler:
-
- ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
-
-and if that doesn't work, install pre-built binaries of GCC for HP-UX.
-
- HP-UX `make' updates targets which have the same time stamps as
-their prerequisites, which makes it generally unusable when shipped
-generated files such as `configure' are involved. Use GNU `make'
-instead.
-
- On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
-parse its `<wchar.h>' header file. The option `-nodtk' can be used as
-a workaround. If GNU CC is not installed, it is therefore recommended
-to try
-
- ./configure CC="cc"
-
-and if that doesn't work, try
-
- ./configure CC="cc -nodtk"
-
- On Solaris, don't put `/usr/ucb' early in your `PATH'. This
-directory contains several dysfunctional programs; working variants of
-these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
-in your `PATH', put it _after_ `/usr/bin'.
-
- On Haiku, software installed for all users goes in `/boot/common',
-not `/usr/local'. It is recommended to use the following options:
-
- ./configure --prefix=/boot/common
-
-Specifying the System Type
-==========================
-
- There may be some features `configure' cannot figure out
-automatically, but needs to determine by the type of machine the package
-will run on. Usually, assuming the package is built to be run on the
-_same_ architectures, `configure' can figure that out, but if it prints
-a message saying it cannot guess the machine type, give it the
-`--build=TYPE' option. TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name which has the form:
-
- CPU-COMPANY-SYSTEM
-
-where SYSTEM can have one of these forms:
-
- OS
- KERNEL-OS
-
- See the file `config.sub' for the possible values of each field. If
-`config.sub' isn't included in this package, then this package doesn't
-need to know the machine type.
-
- If you are _building_ compiler tools for cross-compiling, you should
-use the option `--target=TYPE' to select the type of system they will
-produce code for.
-
- If you want to _use_ a cross compiler, that generates code for a
-platform different from the build platform, you should specify the
-"host" platform (i.e., that on which the generated programs will
-eventually be run) with `--host=TYPE'.
-
-Sharing Defaults
-================
-
- If you want to set default values for `configure' scripts to share,
-you can create a site shell script called `config.site' that gives
-default values for variables like `CC', `cache_file', and `prefix'.
-`configure' looks for `PREFIX/share/config.site' if it exists, then
-`PREFIX/etc/config.site' if it exists. Or, you can set the
-`CONFIG_SITE' environment variable to the location of the site script.
-A warning: not all `configure' scripts look for a site script.
-
-Defining Variables
-==================
-
- Variables not defined in a site shell script can be set in the
-environment passed to `configure'. However, some packages may run
-configure again during the build, and the customized values of these
-variables may be lost. In order to avoid this problem, you should set
-them in the `configure' command line, using `VAR=value'. For example:
-
- ./configure CC=/usr/local2/bin/gcc
-
-causes the specified `gcc' to be used as the C compiler (unless it is
-overridden in the site shell script).
-
-Unfortunately, this technique does not work for `CONFIG_SHELL' due to
-an Autoconf limitation. Until the limitation is lifted, you can use
-this workaround:
-
- CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
-
-`configure' Invocation
-======================
-
- `configure' recognizes the following options to control how it
-operates.
-
-`--help'
-`-h'
- Print a summary of all of the options to `configure', and exit.
-
-`--help=short'
-`--help=recursive'
- Print a summary of the options unique to this package's
- `configure', and exit. The `short' variant lists options used
- only in the top level, while the `recursive' variant lists options
- also present in any nested packages.
-
-`--version'
-`-V'
- Print the version of Autoconf used to generate the `configure'
- script, and exit.
-
-`--cache-file=FILE'
- Enable the cache: use and save the results of the tests in FILE,
- traditionally `config.cache'. FILE defaults to `/dev/null' to
- disable caching.
-
-`--config-cache'
-`-C'
- Alias for `--cache-file=config.cache'.
-
-`--quiet'
-`--silent'
-`-q'
- Do not print messages saying which checks are being made. To
- suppress all normal output, redirect it to `/dev/null' (any error
- messages will still be shown).
-
-`--srcdir=DIR'
- Look for the package's source code in directory DIR. Usually
- `configure' can determine that directory automatically.
-
-`--prefix=DIR'
- Use DIR as the installation prefix. *note Installation Names::
- for more details, including other options available for fine-tuning
- the installation locations.
-
-`--no-create'
-`-n'
- Run the configure checks, but stop before creating any output
- files.
-
-`configure' also accepts some other, not widely useful, options. Run
-`configure --help' for more details.
diff --git a/MOVED_TO_GITHUB.TXT b/MOVED_TO_GITHUB.TXT
new file mode 100644
index 0000000..a849b1b
--- /dev/null
+++ b/MOVED_TO_GITHUB.TXT
@@ -0,0 +1 @@
+Moved to https://github.com/libstorage/libstoragemgmt
diff --git a/Makefile.am b/Makefile.am
deleted file mode 100644
index 2452931..0000000
--- a/Makefile.am
+++ /dev/null
@@ -1,28 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-ACLOCAL_AMFLAGS = -I m4
-
-DISTCHECK_CONFIGURE_FLAGS = --with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)
-
-SUBDIRS= c_binding python_binding plugin doc tools daemon packaging config
-
-if BUILD_C_UNIT
-SUBDIRS += test
-endif
-
-EXTRA_DIST = \
- libstoragemgmt.pc.in \
- libstoragemgmt.pc \
- autogen.sh
-
-pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = libstoragemgmt.pc
-
-#Source code documentation
-docs:
- doxygen doc/doxygen.conf
-
-rpm: clean
- @(unset CDPATH ; $(MAKE) dist && rpmbuild -ta $(distdir).tar.gz)
-
-MAINTAINERCLEANFILES = .git-module-status
diff --git a/NEWS b/NEWS
deleted file mode 100644
index 1f8fed3..0000000
--- a/NEWS
+++ /dev/null
@@ -1,271 +0,0 @@
-News for libStorageMgmt
-
-1.1.1: Dec 4 2014
- - Library adds:
-
- API Constants for new pool element types and plugin changes to support it
- * C constants:
- LSM_POOL_ELEMENT_TYPE_VOLUME_FULL, LSM_POOL_ELEMENT_TYPE_VOLUME_THIN
- * Py constants:
- Pool.ELEMENT_TYPE_VOLUME_FULL, Poll.ELEMENT_TYPE_THIN
-
- lsmcli:
- * lt - Alias for 'list --type target_ports'
- * Removed --init for volume-mask, it was broken for targetd (the only
- user) and instead of fixing we are going to improve targetd to support
- access groups in the next release
-
- - Numerous code improvements, including a big SMI-S plugin refactor,
- source code documentation corrections
-
- - Bug fix: Use correct default values for anonymous uid/gid in lsmcli
- - Bug fix: simc simulator not working for allowable NULL parameters for:
- * fs_child_dependency
- * fs_child_dependency_rm
- * fs_snapshot_restore
- - Bug fix: lsm_restd memory leak corrections
- - Bug fix: NetApp plugin, correctly set export path when caller specifies
- default in API
- - Bug fix: Add file locking to sim plugin to prevent concurrent modification
- - Bug fix: Consistently report common error conditions for NO_STATE_CHANGE,
- EXISTS_INITIATOR for all plugins
- - Bug fix: Number of bugs addressed in SMI-S plugin including:
- * EMC: Correct error path when replicating a volume with a duplicate
- volume name
- * HDS: Correctly create thinly provisioned volume on thinly provisioned
- pool
-
-1.0.0: Sep 7 2014
- - Release version 1
- - Numerous constants re-naming & removing
- - Removed the pool create/delete until things work better,
- esp. WRT SMI-S
- - Added checks for initiator ID verification
- - Added checks for vpd 0x83 verification
- - Simplified error logging (removed domain & level)
- - Re-named functions for online,offline -> enable,disable
- - Always use objects instead of object ID in function
- params
- - Removed individual files from fs snapshot creation
- - Add unsupported actions for pools
- - lsm_capability_set_n uses a -1 to terminate list
- - Volume status removed, replaced with admin state
- - Removed ibmiv7k plugin
- - Explicitly specify python2
- - Error path consistency changes (same error for same condition
- across plug-ins)
- - Numerous bug fixes
-
-0.1.0: Jul 3 2014
- - Release candidate for a 1.0.0 release
- - Optional data removed
- - Initiator only functions removed
- - Pool create from from volumes removed
- - Code directory structure updated
- - Target port listing added
-
-0.0.24: Jan 30 2014
- - Command line interface (CLI) re-factored and improved to be easier to use
- and more consistent, man pages have been updated
- - Command line output now has '-s, --script' for an additional way to output
- information for consumption in scripts
- - Command line option '-o' for retrieving optional/extended data for disks &
- pools
- - Pool creation/deleting in CLI & python API
- - Numerous small bug fixes
- - C API, added ability to list disks, list plugins and retrieve optional
- data for disks
- - SSL for SMI-S is more stringent on certificate checking for newer
- distributions, new URI option "no_ssl_verify=yes" to disable
-
-0.0.23: Nov 27 2013
- - Addition of listing disks implemented for SMI-S and Ontap plugins
- (new, not in C library yet)
- - Add the ability to list currently installed and usable plug-ins
- - Verify return types are correct in python client calls
- - Added the ability to retrieve optional data (new, not in C library yet)
- - Visibility reductions for python code (somethings were public when should be
- private
- - Add calls to create/delete pools (new, not in C library yet)
- - Add missing initiator type for SAS
- - Improved vpd83 retrieval for SMI-S
- - Performance improvements for SMI-S plug-in
- - Numerous small bug fixes
- - Nstor plugin, additional testing and bug fixes
- - lsmd, added call to setgroups and enable full relo and PIE (ASLR) for
- security improvements
- - simulator state is now versioned
- - SCSI Unit Attention uevent handling
-
-0.0.22: Aug 12 2013
- - Numerous code improvments/fixes
- - BZ 968384
- - BZ 990577
-
-0.0.21: Jul 16 2013
- - IEC binary size handling
- - Functionality improvements for IBM V7K array
- - Workaround for python bug on F19
- - Bugfix (BZ 968384)
- - Package plug-ins as separately in rpm packages
-
-0.0.20: May 24 2013
- - Python library files now in separate rpm
- - Additional debug for plug-ins when exceptions occur
- - iSCSI CHAP support modified to handle both inbound and outbound authentication
- - VOLUME_THIN Added as new capability flag
- - IBM V7000 storage array support
- - NFS export support for targetd
- - EXPORT_CUSTOM_PATH added capability flag
-
-0.0.19: Apr 20 2013
- - Improved E-Series array support
- - Ontap plug-in: improve performance with many Volumes
- - lsmcli: Number of corrections on handling unit specifiers
- - lsmcli: Correct stack track when stdout is written to while closed
- - Fix build to work with automake >= 1.12
-
-0.0.18: Mar 7 2013
- - lsmd: Re-written in C
- - Simplify fs_delete
- - Corrections for C client against Python plugin
- - Testing: Run cross language unit test too
- - Initial FS support for targetd plugin
- - Fix multi-arch python issues which prevent py and compiled py files
- from being identical on different arches
-
-0.0.17: Jan 31 2013
- - Inconsistency corrections between C and Python API
- - Source code documentation updates
- - NexentaStor plug-in has been added
-
-0.0.16: Jan 1 2013
- - lsmcli: Add confirmation prompt for data loss operations
- - lsmcli: Display enumerated values as text
- - lsmcli: Exit with 7 for --job-status when not complete
- - Fixed URI example to reference an existing plug-in
- - lsmcli: Retrieve plug-in desc. and version (lsmcli --plugin-info)
- - simc: Implement CHAP auth function (no-op)
- - lsmcli: Change check for determining if lsmd is running
- - Disable mirroring for SMI-S as it needs some re-work
-
-0.0.15: Nov 20 2012
- - Pool parameter is optional when replicating a volume
- - Code improvements(Memory leak fix, lsmcli checks if lsmd is running)
- - Source code documentation updates
- - Ability to override simulator data storage location
- - make check target added to run unit tests
-
-0.0.14: Oct 19 2012
- - test/cmdline.py added to automatically test what an array supports
- - Bug fixes (local plug-in execution, smi-s delete clone, code warnings)
- - targetd: (uri syntax consistency change, initialization code change)
- - Pool id added to volume information
- - lsmcli: Added --replicate-volume-range-block-size <system id> to retrieve
- replicated block size
-
-0.0.13: Sep 28 2012
- - targetD Feature adds/fixes for initiators, init_granted_to_volume,
- volumes_accessible_by_init, initiator_grant, initiator_revoke
- - SMI-S added compatibility with CIM_StorageConfigurationService
- - SMI-S bug fixes/changes to support XIV arrays (Basic functionality verified)
- - SMI-S Proxy layer added to allow different internal implementations of smi-s
- client
- - Added missing version information for C plug-in API
- - lsmcli URI can be stored in file .lsmcli in users home directory
-
-0.0.12: Sep 7 2012
- - SMI-S plug-in enhancements (Detach before delete, bug fixes for eSeries)
- - Added version specifier for non-opaque structs in plug-in callback interface
- - Documentation updates (doxygen, man pages)
- - Ontap plug-in: support timeout values
- - lsmcli, return back async. values other than volumes when using --job-status
-
-0.0.11: Aug 13 2012
- - SMI-S fixes and improvements (WaitForCopyState, _get_class_instance)
- - Methods for arrays that don't support access groups to grant access
- for luns to initiators etc.
- - ISCSI Chap authentication
- - System level status field for overall array status
- - targetd updates for mapping targets to initiators
- - Simulator updates (python & C)
- - Removed tog-pegasus dependency (SMI-S is python plug-in)
- - Removed lsmVolumeStatus as it was implemented and redundant
- - initscript, check for /var/run and create if missing
-
-0.0.10: July 20 2012
- - Simulator plug-in written in C, simc_lsmplugin is available
- - Numerous updates and re-name for plug-in targetd_lsmplugin
- - targetd_lsmplugin included in release
- - Memory leak fixes and improved unit tests
- - Initial capability query support, implemented for all plug-ins
- - Flags variable added to API calls, (Warning: C API/ABI breakage, python
- unaffected)
- - Bug fixes for NetApp ontap plug-in
- - SMI-S bug fixes (initiator listing and replication, mode and sync types)
- - Added ability to specify mirroring async or sync for replication
- - Added version header file to allow client version header checks
-
-0.0.9: June 12 2012
- - Initial checkin of lio plug-in
- - System filtering via URI (smispy)
- - Error code mapping (ontap)
- - Fixed build so same build tarball is used for all binaries
-
-0.0.8: June 4 2012
- - Make building of SMI-S CPP plugin optional
- - Add pkg-config file
- - SMIS: Fix exception while retrieving Volumes
- - SMIS: Fix exception while retrieving Volumes
- - lsm: Add package imports
- - Make Smis class available in lsm python package
- - Add option to disable building C unit test
- - Make simulator classes available in lsm python package
- - Make ontap class available in lsm python package
- - Changes to support building on Fedora 17 (v2)
- - Spec. file updates from feedback from T. Callaway (spot)
- - F17 linker symbol visibility correction
- - Remove unneeded build dependencies and cleaned up some warnings
- - C Updates, client C library feature parity with python
-
-0.0.7: May 11 2012
- - Bug fix for smi-s constants
- - Display formatting improvements
- - Added header option for lsmcli
- - Improved version handling for builds
- - Made terminology consistent
- - Ability to list visibility for access groups and volumes
- - Simulator plug-in fully supports all block operations
- - Added support for multiple systems with a single plug-in instance
-
-0.0.6: Apr 20 2012
- - Documentation improvements (man & source code)
- - Support for access groups
- - Unified spec files Fedora/RHEL
- - Package version auto generate
- - Rpm target added to make
- - Bug fix for missing optional property on volume retrieval (smispy plug-in)
-
-0.0.5: Apr 6 2012
- - Spec file clean-up improvements
- - Async. operation added to lsmcli and ability to check on job status
- - Sub volume replication support
- - Ability to check for child dependencies on VOLUMES, FS and files
- - SMI-S Bug fixes and improvements
-
-0.0.4: Mar 26 2012
- - Restore from snapshot
- - Job identifiers string instead of integer
- - Updated license address
-
-0.0.3: Mar 19 2012
- - Updated to support better packaging
- - Fixes for NFS export handling
- - Simulator persistent state
-
-0.0.2: Mar 11 2012
- - Native plugin for NetApp
-
-0.0.1alpha: Feb 3 2012
- - First release in package form
- - Basic operation utilizing SMI-S providers.
diff --git a/README b/README
deleted file mode 100644
index 3c57723..0000000
--- a/README
+++ /dev/null
@@ -1,5 +0,0 @@
-
-libStorageMgmt : A library for storage management
-
-More information available: https://sourceforge.net/projects/libstoragemgmt/
-Wiki: https://sourceforge.net/p/libstoragemgmt/wiki/Home/
diff --git a/autogen.sh b/autogen.sh
deleted file mode 100755
index 318362c..0000000
--- a/autogen.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/bash
-
-#Clean stuff up to ensure a clean autobuild
-rm -rf autom4te.cache/*
-rm -rf build-aux/*
-rm -f m4/l*
-rm -f aclocal.m4
-
-autoreconf -f -i
diff --git a/c_binding/Makefile.am b/c_binding/Makefile.am
deleted file mode 100644
index e4b8e1b..0000000
--- a/c_binding/Makefile.am
+++ /dev/null
@@ -1,15 +0,0 @@
-SUBDIRS = include
-
-AM_CPPFLAGS = -I$(top_srcdir)/c_binding/include \
- -I$(top_builddir)/c_binding/include \
- -***@srcdir@/c_binding/include \
- $(LIBXML_CFLAGS) $(LIBGLIB_CFLAGS)
-
-lib_LTLIBRARIES = libstoragemgmt.la
-
-libstoragemgmt_la_LIBADD=$(LIBXML_LIBS) $(YAJL_LIBS) $(LIBGLIB_LIBS)
-libstoragemgmt_la_LDFLAGS= -version-info $(LIBSM_LIBTOOL_VERSION)
-libstoragemgmt_la_SOURCES= \
- lsm_mgmt.cpp lsm_datatypes.hpp lsm_datatypes.cpp lsm_convert.hpp \
- lsm_convert.cpp lsm_ipc.hpp lsm_ipc.cpp lsm_plugin_ipc.hpp \
- lsm_plugin_ipc.cpp util/qparams.c util/qparams.h
diff --git a/c_binding/include/Makefile.am b/c_binding/include/Makefile.am
deleted file mode 100644
index 32b3220..0000000
--- a/c_binding/include/Makefile.am
+++ /dev/null
@@ -1,6 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-## Copyright (C) 2011 Red Hat, Inc.
-## See COPYING.LIB for the License of this software
-
-SUBDIRS=libstoragemgmt
diff --git a/c_binding/include/libstoragemgmt/Makefile.am b/c_binding/include/libstoragemgmt/Makefile.am
deleted file mode 100644
index 2a947f6..0000000
--- a/c_binding/include/libstoragemgmt/Makefile.am
+++ /dev/null
@@ -1,30 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-## Copyright (C) 2005-2011 Red Hat, Inc.
-## See COPYING.LIB for the License of this software
-
-lsmincdir = $(includedir)/libstoragemgmt
-
-lsminc_HEADERS = \
- libstoragemgmt.h \
- libstoragemgmt_accessgroups.h \
- libstoragemgmt_blockrange.h \
- libstoragemgmt_capabilities.h \
- libstoragemgmt_common.h \
- libstoragemgmt_disk.h \
- libstoragemgmt_error.h \
- libstoragemgmt_fs.h \
- libstoragemgmt_nfsexport.h \
- libstoragemgmt_hash.h \
- libstoragemgmt_plug_interface.h \
- libstoragemgmt_pool.h \
- libstoragemgmt_snapshot.h \
- libstoragemgmt_systems.h \
- libstoragemgmt_targetport.h \
- libstoragemgmt_types.h \
- libstoragemgmt_version.h \
- libstoragemgmt_volumes.h
-
-
-install-exec-hook:
- $(mkinstalldirs) $(DESTDIR)$(lsmincdir)
diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt.h b/c_binding/include/libstoragemgmt/libstoragemgmt.h
deleted file mode 100644
index 6e03f78..0000000
--- a/c_binding/include/libstoragemgmt/libstoragemgmt.h
+++ /dev/null
@@ -1,871 +0,0 @@
-/*
- * Copyright (C) 2011-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 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#ifndef LIBSTORAGEMGMT_H
-#define LIBSTORAGEMGMT_H
-
-#include "libstoragemgmt_types.h"
-#include "libstoragemgmt_common.h"
-
-#include "libstoragemgmt_accessgroups.h"
-#include "libstoragemgmt_blockrange.h"
-#include "libstoragemgmt_capabilities.h"
-#include "libstoragemgmt_disk.h"
-#include "libstoragemgmt_error.h"
-#include "libstoragemgmt_fs.h"
-#include "libstoragemgmt_nfsexport.h"
-#include "libstoragemgmt_pool.h"
-#include "libstoragemgmt_snapshot.h"
-#include "libstoragemgmt_systems.h"
-#include "libstoragemgmt_targetport.h"
-#include "libstoragemgmt_volumes.h"
-
-
-/*! \mainpage libStorageMgmt
- *
- * \section Introduction
- *
- * The libStorageMgmt package is a storage array independent Application
- * Programming Interface (API). It provides a stable and consistent API that
- * allows developers the ability to programmatically manage different storage
- * arrays and leverage the hardware accelerated features that they provide.
- *
- * \section additional Additional documentation
- *
- * Full documentation can be found at:
- * http://sourceforge.net/p/libstoragemgmt/wiki/Home/
- *
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
- /**
- * Get a connection to a storage provider.
- * @param[in] uri Uniform Resource Identifier (see URI documentation)
- * @param[in] password Password for the storage array (optional, can be NULL)
- * @param[out] conn The connection to use for all the other library calls
- * @param[in] timeout Time-out in milliseconds, (initial value).
- * @param[out] e Error data if connection failed.
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, else error code @see lsm_error_number
- */
- int LSM_DLL_EXPORT lsm_connect_password(const char* uri, const char *password,
- lsm_connect **conn, uint32_t timeout, lsm_error_ptr *e, lsm_flag flags);
- /**
- * Closes a connection to a storage provider.
- * @param[in] conn Valid connection to close
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, else error code @see lsm_error_number
- */
- int LSM_DLL_EXPORT lsm_connect_close(lsm_connect *conn, lsm_flag flags);
-
- /**
- * Retrieve information about the plug-in
- * NOTE: Caller needs to free desc and version!
- * @param[in] conn Valid connection @see lsm_connect_password
- * @param[out] desc Plug-in description
- * @param[out] version Plug-in version
- * @param [in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, else error code @see lsm_error_number
- */
- int LSM_DLL_EXPORT lsm_plugin_info_get(lsm_connect *conn, char **desc,
- char **version, lsm_flag flags);
-
- /**
- * Retrieve a list of available plug-ins.
- * @param[in] sep Return data separator
- * @param[out] plugins String list of plug-ins with the form
- * desc<sep>version
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, else error code @see lsm_error_number
- */
- int LSM_DLL_EXPORT lsm_available_plugins_list(const char *sep,
- lsm_string_list **plugins,
- lsm_flag flags);
-
- /**
- * Sets the time-out for this connection.
- * @param[in] conn Valid connection @see lsm_connect_password
- * @param[in] timeout Time-out (in ms)
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, else error reason
- */
- int LSM_DLL_EXPORT lsm_connect_timeout_set(lsm_connect *conn,
- uint32_t timeout, lsm_flag flags);
-
- /**
- * Gets the time-out for this connection.
- * @param[in] conn Valid connection @see lsm_connect_password
- * @param[out] timeout Time-out (in ms)
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, else error reason
- */
- int LSM_DLL_EXPORT lsm_connect_timeout_get(lsm_connect *conn,
- uint32_t *timeout, lsm_flag flags);
-
- /**
- * Check on the status of a job, no data to return on completion.
- * @param[in] conn Valid connection
- * @param[in] job_id Job id
- * @param[out] status Job Status
- * @param[out] percent_complete Percent job complete
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, else error reason
- */
- int LSM_DLL_EXPORT lsm_job_status_get(lsm_connect *conn, const char *job_id,
- lsm_job_status *status, uint8_t *percent_complete,
- lsm_flag flags);
-
- /**
- * Check on the status of a job and return the pool information when
- * complete
- * @param[in] conn Valid connection pointer
- * @param[in] job_id Job to check status on
- * @param[out] status What is the job status
- * @param[out] percent_complete Domain 0..100
- * @param[out] pool lsm_pool for completed operation
- * @param[in] flags Reserved for future use, must be zero
- * @return LSM_ERR_OK on success, else error reason.
- */
- int LSM_DLL_EXPORT lsm_job_status_pool_get(lsm_connect *conn,
- const char *job_id, lsm_job_status *status,
- uint8_t *percent_complete, lsm_pool **pool,
- lsm_flag flags);
-
- /**
- * Check on the status of a job and returns the volume information when
- * complete.
- * @param[in] conn Valid connection pointer.
- * @param[in] job_id Job to check status on
- * @param[out] status What is the job status
- * @param[out] percent_complete Domain 0..100
- * @param[out] vol lsm_volume for completed operation.
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, else error reason.
- */
- int LSM_DLL_EXPORT lsm_job_status_volume_get(lsm_connect *conn,
- const char *job_id, lsm_job_status *status,
- uint8_t *percent_complete, lsm_volume **vol,
- lsm_flag flags);
-
-
- /**
- * Check on the status of a job and return the fs information when complete.
- * @param[in] conn Valid connection pointer
- * @param[in] job_id Job to check
- * @param[out] status What is the job status
- * @param[out] percent_complete Percent of job complete
- * @param[out] fs lsm_fs * for the completed operation
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, else error reason.
- */
- int LSM_DLL_EXPORT lsm_job_status_fs_get(lsm_connect *conn, const char *job_id,
- lsm_job_status *status, uint8_t *percent_complete,
- lsm_fs **fs, lsm_flag flags);
-
- /**
- * Check on the status of a job and return the snapshot information when
- * compete.
- * @param[in] c Valid connection pointer
- * @param[in] job Job id to check
- * @param[out] status Job status
- * @param[out] percent_complete Percent complete
- * @param[out] ss Snap shot information
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, else error reason
- */
- int LSM_DLL_EXPORT lsm_job_status_ss_get(lsm_connect *c, const char *job,
- lsm_job_status *status, uint8_t *percent_complete,
- lsm_fs_ss **ss, lsm_flag flags);
-
- /**
- * Frees the resources used by a job.
- * @param[in] conn Valid connection pointer
- * @param[in] job_id Job ID
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK, else error reason.
- */
- int LSM_DLL_EXPORT lsm_job_free(lsm_connect *conn, char **job_id,
- lsm_flag flags);
- /**
- * Storage system query functions
- */
-
- /**
- * Query the capabilities of the storage array.
- * @param[in] conn Valid connection @see lsm_connect_password
- * @param[in] system System of interest
- * @param[out] cap The storage array capabilities
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success else error reason
- */
- int LSM_DLL_EXPORT lsm_capabilities(lsm_connect *conn,
- lsm_system *system,
- lsm_storage_capabilities **cap,
- lsm_flag flags);
-
- /**
- * Query the list of storage pools on the array.
- * @param[in] conn Valid connection @see lsm_connect_password
- * @param[in] search_key Search key (NULL for all)
- * @param[in] search_value Search value
- * @param[out] pool_array Array of storage pools
- * @param[out] count Number of storage pools
- * @param[in] flags Reserved, set to 0
- * @return LSM_ERR_OK on success else error reason
- */
- int LSM_DLL_EXPORT lsm_pool_list(lsm_connect *conn, char *search_key,
- char *search_value, lsm_pool **pool_array[],
- uint32_t *count, lsm_flag flags);
-
- /**
- * Volume management functions
- */
-
- /**
- * Gets a list of logical units for this array.
- * @param[in] conn Valid connection @see lsm_connect_password
- * @param[in] search_key Search key (NULL for all)
- * @param[in] search_value Search value
- * @param[out] volumes An array of lsm_volume
- * @param[out] count Number of elements in the lsm_volume array
- * @param[in] flags Reserved set to 0
- * @return LSM_ERR_OK on success else error reason
- */
- int LSM_DLL_EXPORT lsm_volume_list(lsm_connect *conn,
- const char *search_key,
- const char *search_value,
- lsm_volume **volumes[],
- uint32_t *count, lsm_flag flags);
-
- /**
- * Get a list of disk for this array.
- * @param [in] conn Valid connection @see
- * lsm_connect_password
- * @param[in] search_key Search key (NULL for all)
- * @param[in] search_value Search value
- * @param [out] disks An array of lsm_disk types
- * @param [out] count Number of disks
- * @param [in] flags Reserved set to zero
- * @return LSM_ERR_OK on success else error reason
- */
- int LSM_DLL_EXPORT lsm_disk_list(lsm_connect *conn, const char * search_key,
- const char *search_value,
- lsm_disk **disks[], uint32_t *count,
- lsm_flag flags);
-
- /**
- * Creates a new volume (aka. LUN).
- * @param[in] conn Valid connection @see lsm_connect_password
- * @param[in] pool Valid pool @see lsm_pool (OPTIONAL, use NULL for plug-in choice)
- * @param[in] volume_name Human recognizable name (not all arrays support)
- * @param[in] size Size of new volume in bytes (actual size will
- * be based on array rounding to block size)
- * @param[in] provisioning Type of volume provisioning to use
- * @param[out] new_volume Valid volume @see lsm_volume
- * @param[out] job Indicates job id
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, LSM_ERR_JOB_STARTED if async. , else error code
- */
- int LSM_DLL_EXPORT lsm_volume_create(lsm_connect *conn, lsm_pool *pool,
- const char *volume_name, uint64_t size,
- lsm_volume_provision_type provisioning,
- lsm_volume **new_volume, char **job,
- lsm_flag flags);
-
- /**
- * Resize an existing volume.
- * @param[in] conn Valid connection @see lsm_connect_password
- * @param[in] volume volume to re-size
- * @param[in] new_size New size of volume
- * @param[out] resized_volume Pointer to newly re-sized lun.
- * @param[out] job Indicates job id
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, LSM_ERR_JOB_STARTED if async. , else error code
- */
- int LSM_DLL_EXPORT lsm_volume_resize(lsm_connect *conn, lsm_volume *volume,
- uint64_t new_size, lsm_volume **resized_volume,
- char **job, lsm_flag flags);
-
- /**
- * Replicates a volume
- * @param[in] conn Valid connection @see lsm_connect_password
- * @param[in] pool Valid pool
- * @param[in] rep_type Type of replication lsm_replication_type
- * @param[in] volume_src Which volume to replicate
- * @param[in] name Human recognizable name (not all arrays support)
- * @param[out] new_replicant New replicated volume lsm_volume_t
- * @param[out] job Indicates job id
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, LSM_ERR_JOB_STARTED if async. , else error code
- */
- int LSM_DLL_EXPORT lsm_volume_replicate(lsm_connect *conn, lsm_pool *pool,
- lsm_replication_type rep_type, lsm_volume *volume_src,
- const char *name, lsm_volume **new_replicant,
- char **job, lsm_flag flags);
-
- /**
- * Unit of block size for the replicate range method.
- * @param[in] conn Valid connection
- * @param[in] system Valid lsm_system
- * @param[out] bs Block size
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, else error reason.
- */
- int LSM_DLL_EXPORT lsm_volume_replicate_range_block_size(lsm_connect *conn,
- lsm_system *system,
- uint32_t *bs,
- lsm_flag flags);
-
- /**
- * Replicates a portion of a volume to a volume.
- * @param[in] conn Valid connection
- * @param[in] rep_type Replication type
- * @param[in] source Source volume
- * @param[in] dest Destination volume (can be same as source)
- * @param[in] ranges An array of block ranges
- * @param[in] num_ranges Number of entries in ranges.
- * @param[out] job Indicates job id
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, LSM_ERR_JOB_STARTED if async., else error code
- */
- int LSM_DLL_EXPORT lsm_volume_replicate_range(lsm_connect *conn,
- lsm_replication_type rep_type,
- lsm_volume *source,
- lsm_volume *dest,
- lsm_block_range **ranges,
- uint32_t num_ranges, char **job,
- lsm_flag flags);
-
- /**
- * Deletes a logical unit and data is lost!
- * @param[in] conn Valid connection @see lsm_connect_password
- * @param[in] volume Volume that is to be deleted.
- * @param[out] job Indicates job id
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, LSM_ERR_JOB_STARTED if async. , else error code
- */
- int LSM_DLL_EXPORT lsm_volume_delete(lsm_connect *conn, lsm_volume *volume,
- char **job, lsm_flag flags);
-
- /**
- * Set a Volume to online
- * @param[in] conn Valid connection @see lsm_connect_password
- * @param[in] volume Volume that is to be placed online
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, else error code
- */
- int LSM_DLL_EXPORT lsm_volume_enable(lsm_connect *conn, lsm_volume *volume,
- lsm_flag flags);
-
- /**
- * Set a Volume to offline
- * @param[in] conn Valid connection @see lsm_connect_password
- * @param[in] volume Volume that is to be placed online
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, else error code
- */
- int LSM_DLL_EXPORT lsm_volume_disable(lsm_connect *conn,
- lsm_volume *volume, lsm_flag flags);
-
- /**
- * Set the username password for CHAP authentication, inbound and outbound.
- * @param conn Valid connection pointer
- * @param init_id Initiator ID
- * @param in_user inbound user name
- * @param in_password inbound password
- * @param out_user outbound user name
- * @param out_password outbound password
- * @param flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, else error code.
- */
- int LSM_DLL_EXPORT lsm_iscsi_chap_auth(lsm_connect *conn,
- const char *init_id,
- const char *in_user,
- const char *in_password,
- const char *out_user,
- const char *out_password,
- lsm_flag flags);
-
- /**
- * Retrieves a list of access groups.
- * @param[in] conn Valid connection @see lsm_connect_password
- * @param[in] search_key Search key (NULL for all)
- * @param[in] search_value Search value
- * @param[out] groups Array of access groups
- * @param[out] group_count Size of array
- * @param[in] flags Reserved set to zero
- * @return LSM_ERR_OK on success, else error reason.
- */
- int LSM_DLL_EXPORT lsm_access_group_list(lsm_connect *conn,
- const char *search_key,
- const char *search_value,
- lsm_access_group **groups[],
- uint32_t *group_count,
- lsm_flag flags);
-
- /**
- * Creates a new access group with one initiator in it.
- * @param[in] conn Valid connection @see lsm_connect_password
- * @param[in] name Name of access group
- * @param[in] init_id Initiator id to be added to group
- * @param[in] init_type Initiator type
- * @param[in] system System to create access group for
- * @param[out] access_group Returned access group
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, else error reason
- */
- int LSM_DLL_EXPORT lsm_access_group_create(lsm_connect *conn,
- const char *name,
- const char *init_id,
- lsm_access_group_init_type init_type,
- lsm_system *system,
- lsm_access_group **access_group,
- lsm_flag flags);
-
- /**
- * Deletes an access group.
- * @param[in] conn Valid connection @see lsm_connect_password
- * @param[in] access_group Group to delete
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, else error reason.
- */
- int LSM_DLL_EXPORT lsm_access_group_delete(lsm_connect *conn,
- lsm_access_group *access_group,
- lsm_flag flags);
-
- /**
- * Adds an initiator to the access group
- * @param[in] conn Valid connection @see lsm_connect_password
- * @param[in] access_group Group to modify
- * @param[in] init_id Initiator to add to group
- * @param[in] init_type Type of initiator
- * @param[out] updated_access_group Updated access group
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, else error reason.
- */
- int LSM_DLL_EXPORT lsm_access_group_initiator_add(lsm_connect *conn,
- lsm_access_group *access_group,
- const char *init_id,
- lsm_access_group_init_type init_type,
- lsm_access_group **updated_access_group,
- lsm_flag flags);
-
- /**
- * Removes an initiator from an access group.
- * @param[in] conn Valid connection @see lsm_connect_password
- * @param[in] access_group Group to modify
- * @param[in] initiator_id Initiator to delete from group
- * @param[in] init_type Type of initiator, enumerated type
- * @param[out] updated_access_group Updated access group
- * @param[in] flags Reserved for future use, must be zero.
- * @return[in] LSM_ERR_OK on success, else error reason.
- */
- int LSM_DLL_EXPORT lsm_access_group_initiator_delete(lsm_connect *conn,
- lsm_access_group *access_group,
- const char *initiator_id,
- lsm_access_group_init_type init_type,
- lsm_access_group **updated_access_group,
- lsm_flag flags);
-
- /**
- * Grants access to a volume for the specified group
- * @param[in] conn Valid connection
- * @param[in] access_group Valid group pointer
- * @param[in] volume Valid volume pointer
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, else error reason.
- */
- int LSM_DLL_EXPORT lsm_volume_mask(lsm_connect *conn,
- lsm_access_group *access_group,
- lsm_volume *volume,
- lsm_flag flags);
-
- /**
- * Revokes access to a volume for the specified group
- * @param[in] conn Valid connection
- * @param[in] access_group Valid group pointer
- * @param[in] volume Valid volume pointer
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, else error reason.
- */
- int LSM_DLL_EXPORT lsm_volume_unmask(lsm_connect *conn,
- lsm_access_group *access_group,
- lsm_volume *volume,
- lsm_flag flags);
-
- /**
- * Returns those volumes that the specified group has access to.
- * @param[in] conn Valid connection
- * @param[in] group Valid group
- * @param[out] volumes An array of volumes
- * @param[out] count Number of volumes
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, else error reason.
- */
- int LSM_DLL_EXPORT lsm_volumes_accessible_by_access_group(lsm_connect *conn,
- lsm_access_group *group,
- lsm_volume **volumes[],
- uint32_t *count,
- lsm_flag flags);
-
- /**
- * Retrieves the access groups that have access to the specified volume.
- * @param[in] conn Valid connection
- * @param[in] volume Valid volume
- * @param[out] groups An array of access groups
- * @param[out] group_count Number of access groups
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, else error reason.
- */
- int LSM_DLL_EXPORT lsm_access_groups_granted_to_volume(lsm_connect *conn,
- lsm_volume *volume,
- lsm_access_group **groups[],
- uint32_t *group_count,
- lsm_flag flags);
-
- /**
- * Returns 1 if the specified volume has child dependencies.
- * @param[in] conn Valid connection
- * @param[in] volume Valid volume
- * @param[out] yes 1 == Yes, 0 == No
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, else error reason.
- */
- int LSM_DLL_EXPORT lsm_volume_child_dependency(lsm_connect *conn,
- lsm_volume *volume,
- uint8_t *yes,
- lsm_flag flags);
-
- /**
- * Instructs the array to remove all child dependencies by replicating
- * required storage.
- * @param[in] conn Valid connection
- * @param[in] volume Valid volume
- * @param[out] job Job id
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, else error reason.
- */
- int LSM_DLL_EXPORT lsm_volume_child_dependency_delete(lsm_connect *conn,
- lsm_volume *volume,
- char **job, lsm_flag flags);
-
- /**
- * Retrieves information about the different arrays accessible.
- * NOTE: Free returned systems by calling to lsm
- * @param[in] conn Valid connection
- * @param[out] systems Array of lsm_system
- * @param[out] system_count Number of systems
- * @param[in] flags Reserved set to zero
- * @return LSM_ERR_OK on success, else error reason
- */
- int LSM_DLL_EXPORT lsm_system_list(lsm_connect *conn, lsm_system **systems[],
- uint32_t *system_count, lsm_flag flags);
-
- /**
- * Retrieves information about the available file systems.
- * @param[in] conn Valid connection
- * @param[in] search_key Search key (NULL for all)
- * @param[in] search_value Search value
- * @param[out] fs Array of lsm_fs
- * @param[out] fs_count Number of file systems
- * @param[in] flags Reserved set to zero
- * @return LSM_ERR_OK on success, else error reason
- */
- int LSM_DLL_EXPORT lsm_fs_list(lsm_connect *conn, const char *search_key,
- const char *search_value, lsm_fs **fs[],
- uint32_t *fs_count, lsm_flag flags);
-
- /**
- * Creates a new file system from the specified pool
- * @param[in] conn Valid connection
- * @param[in] pool Valid pool
- * @param[in] name File system name
- * @param[in] size_bytes Size of file system in bytes
- * @param[out] fs Newly created fs
- * @param[out] job Job id if job is async.
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, LSM_ERR_JOB_STARTED if async. ,
- * else error code
- */
- int LSM_DLL_EXPORT lsm_fs_create(lsm_connect *conn, lsm_pool *pool,
- const char *name, uint64_t size_bytes,
- lsm_fs **fs, char **job, lsm_flag flags);
-
- /**
- * Deletes a file system
- * @param[in] conn Valid connection
- * @param fs File system to delete
- * @param job Job id if job is created async.
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, LSM_ERR_JOB_STARTED if async. ,
- * else error code
- */
- int LSM_DLL_EXPORT lsm_fs_delete(lsm_connect *conn, lsm_fs *fs, char **job,
- lsm_flag flags);
-
- /**
- * Clones an existing file system
- * @param conn Valid connection
- * @param src_fs Source file system
- * @param name Name of new file system
- * @param optional_ss Optional snapshot to base clone from
- * @param cloned_fs Newly cloned file system record
- * @param job Job id if operation is async.
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on succees, LSM_ERR_JOB_STARTED if async., else
- * error code.
- */
- int LSM_DLL_EXPORT lsm_fs_clone(lsm_connect *conn, lsm_fs *src_fs,
- const char *name, lsm_fs_ss *optional_ss,
- lsm_fs **cloned_fs,
- char **job, lsm_flag flags);
-
- /**
- * Checks to see if the specified file system has a child dependency.
- * @param[in] conn Valid connection
- * @param[in] fs Specific file system
- * @param[in] files Specific files to check (NULL OK)
- * @param[out] yes Zero indicates no, else yes
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, else error code.
- */
- int LSM_DLL_EXPORT lsm_fs_child_dependency( lsm_connect *conn, lsm_fs *fs,
- lsm_string_list *files,
- uint8_t *yes, lsm_flag flags);
-
- /**
- * Removes child dependencies by duplicating the required storage to remove.
- * Note: This could take a long time to complete based on dependencies.
- * @param[in] conn Valid connection
- * @param[in] fs File system to remove dependencies for
- * @param[in] files Specific files to check (NULL OK)
- * @param[out] job Job id for async. identification
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, LSM_ERR_JOB_STARTED if async. ,
- * else error code
- */
- int LSM_DLL_EXPORT lsm_fs_child_dependency_delete( lsm_connect *conn, lsm_fs *fs,
- lsm_string_list *files,
- char **job, lsm_flag flags);
-
- /**
- * Resizes a file system
- * @param[in] conn Valid connection
- * @param[in] fs File system to re-size
- * @param[in] new_size_bytes New size of fs
- * @param[out] rfs File system information for re-sized fs
- * @param[out] job_id Job id for async. identification
- * @param[in] flags Reserved for future use, must be zero.
- * @return @return LSM_ERR_OK on success, LSM_ERR_JOB_STARTED if async. ,
- * else error code
- */
- int LSM_DLL_EXPORT lsm_fs_resize(lsm_connect *conn, lsm_fs *fs,
- uint64_t new_size_bytes, lsm_fs **rfs,
- char **job_id, lsm_flag flags);
-
- /**
- * Clones a file on a file system.
- * @param[in] conn Valid connection
- * @param[in] fs File system which file resides
- * @param[in] src_file_name Source file relative name & path
- * @param[in] dest_file_name Dest. file relative name & path
- * @param[in] snapshot Optional backing snapshot
- * @param[out] job Job id for async. operation
- * @param[in] flags Reserved for future use, must be zero.
- * @return @return LSM_ERR_OK on success, LSM_ERR_JOB_STARTED if async. ,
- * else error code
- */
- int LSM_DLL_EXPORT lsm_fs_file_clone(lsm_connect *conn, lsm_fs *fs,
- const char *src_file_name,
- const char *dest_file_name,
- lsm_fs_ss *snapshot, char **job,
- lsm_flag flags);
-
- /**
- * Return a list of snapshots
- * @param[in] conn Valid connection
- * @param[in] fs File system to check for snapshots
- * @param[out] ss An array of snapshot pointers
- * @param[out] ss_count Number of elements in the array
- * @param[in] flags Reserved set to zero
- * @return LSM_ERR_OK on success, else error reason
- */
- int LSM_DLL_EXPORT lsm_fs_ss_list(lsm_connect *conn, lsm_fs *fs,
- lsm_fs_ss **ss[], uint32_t *ss_count,
- lsm_flag flags);
-
- /**
- * Creates a snapshot
- * @param[in] c Valid connection
- * @param[in] fs File system to snapshot
- * @param[in] name Name of snap shot
- * @param[out] snapshot Snapshot that was created
- * @param[out] job Job id if the operation is async.
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, LSM_ERR_JOB_STARTED if async.,
- * else error code
- */
- int LSM_DLL_EXPORT lsm_fs_ss_create(lsm_connect *c, lsm_fs *fs,
- const char *name,
- lsm_fs_ss **snapshot, char **job,
- lsm_flag flags);
-
- /**
- * Deletes a snapshot
- * @param[in] c Valid connection
- * @param[in] fs File system
- * @param[in] ss Snapshot to delete
- * @param[out] job Job id if the operation is async.
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, LSM_ERR_JOB_STARTED if async., else error
- * code.
- */
- int LSM_DLL_EXPORT lsm_fs_ss_delete(lsm_connect *c, lsm_fs *fs, lsm_fs_ss *ss,
- char **job, lsm_flag flags);
-
- /**
- * Restores a file system or files to a previous state as specified in the
- * snapshot.
- * @param c Valid connection
- * @param fs File system which contains the snapshot
- * @param ss Snapshot to restore to
- * @param files Optional list of files to restore
- * @param restore_files Optional list of file names to restore to
- * @param all_files 0 = False else True
- * @param job Job id if operation is async.
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, LSM_ERR_JOB_STARTED if async.,
- * else error code
- */
- int LSM_DLL_EXPORT lsm_fs_ss_restore(lsm_connect *c, lsm_fs *fs, lsm_fs_ss *ss,
- lsm_string_list *files,
- lsm_string_list *restore_files,
- int all_files, char **job, lsm_flag flags);
-
- /**
- * Returns the types of NFS client authentication the array supports.
- * @param[in] c Valid connection
- * @param[out] types List of types
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, else error code.
- */
- int LSM_DLL_EXPORT lsm_nfs_auth_types( lsm_connect *c,
- lsm_string_list **types,
- lsm_flag flags);
-
- /**
- * Lists the nfs exports on the specified array.
- * @param[in] c Valid connection
- * @param[in] search_key Search key (NULL for all)
- * @param[in] search_value Search value
- * @param[out] exports An array of lsm_nfs_export
- * @param[out] count Number of items in array
- * @param[in] flags Reserved set to zero
- * @return LSM_ERR_OK on success else error code.
- */
- int LSM_DLL_EXPORT lsm_nfs_list(lsm_connect *c, const char *search_key,
- const char *search_value,
- lsm_nfs_export **exports[],
- uint32_t *count, lsm_flag flags);
-
- /**
- * Creates or modifies an NFS export.
- * @param[in] c Valid connection
- * @param[in] fs_id File system ID to export via NFS
- * @param[in] export_path Export path
- * @param[in] root_list List of hosts that have root access
- * @param[in] rw_list List of hosts that have read/write access
- * @param[in] ro_list List of hosts that have read only access
- * @param[in] anon_uid UID to map to anonymous
- * @param[in] anon_gid GID to map to anonymous
- * @param[in] auth_type Array specific authentication types
- * @param[in] options Array specific options
- * @param[out] exported Export record
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success, else error reason.
- */
- int LSM_DLL_EXPORT lsm_nfs_export_fs( lsm_connect *c,
- const char *fs_id,
- const char *export_path,
- lsm_string_list *root_list,
- lsm_string_list *rw_list,
- lsm_string_list *ro_list,
- uint64_t anon_uid,
- uint64_t anon_gid,
- const char *auth_type,
- const char *options,
- lsm_nfs_export **exported,
- lsm_flag flags
- );
-
- /**
- * Delete the export.
- * @param[in] c Valid connection
- * @param[in] e NFS export to remove
- * @param[in] flags Reserved for future use, must be zero.
- * @return LSM_ERR_OK on success else error code.
- */
- int LSM_DLL_EXPORT lsm_nfs_export_delete( lsm_connect *c, lsm_nfs_export *e,
- lsm_flag flags );
-
-/**
- * Retrieve a list of target ports
- * @param[in] c Valid connection
- * @param[in] search_key Search key (NULL for all)
- * @param[in] search_value Search value
- * @param[out] target_ports Array of target ports
- * @param[out] count Number of target ports
- * @param[in] flags Reserved, set to 0
- * @return LSM_ERR_OK on success else error reason
- */
- int LSM_DLL_EXPORT lsm_target_port_list(lsm_connect *c,
- const char *search_key,
- const char *search_value,
- lsm_target_port **target_ports[],
- uint32_t *count,
- lsm_flag flags);
-
-/**
- * Retrieves the pool id that the volume is derived from. New in version 1.2.
- * @param[in] c Valid connection
- * @param[in] v Volume ptr.
- * @param[out] raid_type Enum of lsm_volume_raid_type
- * @param[out] strip_size Size of the strip on disk or other storage extent.
- * @param[out] disk_count Count of disks of RAID group(s) where this volume
- * allocated from.
- * @param[out] min_io_size Minimum I/O size, also the preferred I/O size
- * of random I/O.
- * @param[out] opt_io_size Optimal I/O size, also the preferred I/O size
- * of sequential I/O.
- * @param[in] flags Reserved, set to 0
- * @return LSM_ERR_OK on success else error reason.
- */
-int LSM_DLL_EXPORT lsm_volume_raid_info(
- lsm_connect *c, lsm_volume *volume, lsm_volume_raid_type *raid_type,
- uint32_t *strip_size, uint32_t *disk_count,
- uint32_t *min_io_size, uint32_t *opt_io_size, lsm_flag flags);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LIBSTORAGEMGMT_H */
diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt_accessgroups.h b/c_binding/include/libstoragemgmt/libstoragemgmt_accessgroups.h
deleted file mode 100644
index d26a2eb..0000000
--- a/c_binding/include/libstoragemgmt/libstoragemgmt_accessgroups.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2011-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 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-
-#ifndef LSM_ACCESS_GROUP_H
-#define LSM_ACCESS_GROUP_H
-
-#include "libstoragemgmt_types.h"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Frees the resources for an access group.
- * @param group Group to free
- * @return LSM_ERR_OK on success, else error reason.
- */
-int LSM_DLL_EXPORT lsm_access_group_record_free( lsm_access_group *group );
-
-/**
- * Frees the resources for an array of access groups.
- * @param ag Array of access groups to free resources for
- * @param size Number of elements in the array.
- * @return LSM_ERR_OK on success, else error reason.
- */
-int LSM_DLL_EXPORT lsm_access_group_record_array_free( lsm_access_group *ag[], uint32_t size );
-
-/**
- * Copies an access group.
- * @param ag Access group to copy
- * @return NULL on error, else copied access group.
- */
-lsm_access_group LSM_DLL_EXPORT *lsm_access_group_record_copy( lsm_access_group *ag );
-
-/**
- * Returns a pointer to the id.
- * Note: Storage is allocated in the access group and will be deleted when
- * the access group gets freed. If you need longer lifespan copy the value.
- * @param group Access group to retrieve id for.
- * @return Null on error (not an access group), else value of group.
- */
-const char LSM_DLL_EXPORT *lsm_access_group_id_get( lsm_access_group *group );
-
-/**
- * Returns a pointer to the name.
- * Note: Storage is allocated in the access group and will be deleted when
- * the access group gets freed. If you need longer lifespan copy the value.
- * @param group Access group to retrieve id for.
- * @return Null on error (not an access group), else value of name.
- */
-const char LSM_DLL_EXPORT *lsm_access_group_name_get( lsm_access_group *group );
-
-/**
- * Returns a pointer to the system id.
- * Note: Storage is allocated in the access group and will be deleted when
- * the access group gets freed. If you need longer lifespan copy the value.
- * @param group Access group to retrieve id for.
- * @return Null on error (not an access group), else value of system id.
- */
-const char LSM_DLL_EXPORT *lsm_access_group_system_id_get( lsm_access_group *group );
-
-/**
- * Returns a pointer to the initiator list.
- * Note: Storage is allocated in the access group and will be deleted when
- * the access group gets freed. If you need longer lifespan copy the value.
- * @param group Access group to retrieve id for.
- * @return Null on error (not an access group), else value of initiator list.
- */
-lsm_string_list LSM_DLL_EXPORT *lsm_access_group_initiator_id_get( lsm_access_group *group );
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt_blockrange.h b/c_binding/include/libstoragemgmt/libstoragemgmt_blockrange.h
deleted file mode 100644
index a45a05e..0000000
--- a/c_binding/include/libstoragemgmt/libstoragemgmt_blockrange.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2011-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 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#ifndef LSM_BLOCKRANGE_H
-#define LSM_BLOCKRANGE_H
-
-#include "libstoragemgmt_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Creates memory for opaque data type to store a block range
- * @param source_start Source block number to replicate from
- * @param dest_start Dest block number to replicate to
- * @param block_count Number of blocks to replicate
- * @return Valid block range ptr, otherwise NULL
- */
-lsm_block_range LSM_DLL_EXPORT *lsm_block_range_record_alloc(uint64_t source_start,
- uint64_t dest_start,
- uint64_t block_count);
-
-/**
- * Frees a block range record.
- * @param br Block range to free
- * @return LSM_ERR_OK on success, else error reason.
- */
-int LSM_DLL_EXPORT lsm_block_range_record_free( lsm_block_range *br);
-
-
-/**
- * Copies a block range.
- * @param source Source of the copy
- * @return copy of source
- */
-lsm_block_range LSM_DLL_EXPORT *lsm_block_range_record_copy( lsm_block_range *source );
-
-
-/**
- * Allocates storage for an array of block ranges.
- * @param size Number of elements to store.
- * @return Pointer to memory for array of block ranges.
- */
-lsm_block_range LSM_DLL_EXPORT **lsm_block_range_record_array_alloc( uint32_t size );
-
-
-/**
- * Frees the memory for the array and all records contained in it.
- * @param br Array of block ranges to free
- * @param size Number of elements in array.
- * @return LSM_ERR_OK on success, else error reason.
- */
-int LSM_DLL_EXPORT lsm_block_range_record_array_free( lsm_block_range *br[],
- uint32_t size );
-
-/**
- * Retrieves the source block address.
- * @param br Valid block range pointer
- * @return value of source start.
- */
-uint64_t LSM_DLL_EXPORT lsm_block_range_source_start_get(lsm_block_range *br);
-
-/**
- * Retrieves the dest block address.
- * @param br Valid block range pointer
- * @return value of dest start.
- */
-uint64_t LSM_DLL_EXPORT lsm_block_range_dest_start_get(lsm_block_range *br);
-
-/**
- * Retrieves the number of blocks to replicate.
- * @param br Valid block range pointer
- * @return value of number of blocks
- */
-uint64_t LSM_DLL_EXPORT lsm_block_range_block_count_get(lsm_block_range *br);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt_capabilities.h b/c_binding/include/libstoragemgmt/libstoragemgmt_capabilities.h
deleted file mode 100644
index 18490f3..0000000
--- a/c_binding/include/libstoragemgmt/libstoragemgmt_capabilities.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2011-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 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#ifndef LSM_CAPABILITIES_H
-#define LSM_CAPABILITIES_H
-
-#include "libstoragemgmt_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** @file libstoragemgmt_capabilities.h*/
-
-/*Note: Domain is 0..255 */
-/** \enum lsm_capability_value_type Possible values for supported feature*/
-typedef enum {
- LSM_CAP_UNSUPPORTED = 0, /**< Feature is not supported */
- LSM_CAP_SUPPORTED = 1 /**< Feature is supported */
-} lsm_capability_value_type;
-
-/** \enum lsm_capability_value_type Capabilities supported by array */
-typedef enum {
-
- LSM_CAP_VOLUMES = 20, /**< List volumes */
- LSM_CAP_VOLUME_CREATE = 21, /**< Create volumes */
- LSM_CAP_VOLUME_RESIZE = 22, /**< Resize volumes */
-
- LSM_CAP_VOLUME_REPLICATE = 23, /**< Replication is supported */
- LSM_CAP_VOLUME_REPLICATE_CLONE = 24, /**< Can make a space efficient copy of volume */
- LSM_CAP_VOLUME_REPLICATE_COPY = 25, /**< Can make a bitwise copy of volume */
- LSM_CAP_VOLUME_REPLICATE_MIRROR_ASYNC = 26, /**< Mirror data with delay */
- LSM_CAP_VOLUME_REPLICATE_MIRROR_SYNC = 27, /**< Mirror data and always in sync */
-
- LSM_CAP_VOLUME_COPY_RANGE_BLOCK_SIZE = 28, /**< Size of a block for range operations */
- LSM_CAP_VOLUME_COPY_RANGE = 29, /**< Sub volume replication support */
- LSM_CAP_VOLUME_COPY_RANGE_CLONE = 30, /**< Can space efficient copy a region(s) of a volume*/
- LSM_CAP_VOLUME_COPY_RANGE_COPY = 31, /**< Can copy a region(s) of a volume */
-
- LSM_CAP_VOLUME_DELETE = 33, /**< Can delete a volume */
-
- LSM_CAP_VOLUME_ENABLE = 34, /**< Enable volume*/
- LSM_CAP_VOLUME_DISABLE = 35, /**< Disable volume*/
-
- LSM_CAP_VOLUME_MASK = 36, /**< Grant an access group to a volume */
- LSM_CAP_VOLUME_UNMASK = 37, /**< Revoke access for an access group */
- LSM_CAP_ACCESS_GROUPS = 38, /**< List access groups */
- LSM_CAP_ACCESS_GROUP_CREATE_WWPN = 39, /**< Create an access group */
- LSM_CAP_ACCESS_GROUP_DELETE = 40, /**< Delete an access group */
- LSM_CAP_ACCESS_GROUP_INITIATOR_ADD_WWPN = 41, /**< Add an initiator to an access group */
- LSM_CAP_ACCESS_GROUP_INITIATOR_DELETE = 42, /**< Remove an initiator from an access group */
-
- LSM_CAP_VOLUMES_ACCESSIBLE_BY_ACCESS_GROUP = 43, /**< Retrieve a list of volumes accessible by an access group */
- LSM_CAP_ACCESS_GROUPS_GRANTED_TO_VOLUME = 44, /**< Retrieve a list of what access groups are accessible for a given volume */
-
- LSM_CAP_VOLUME_CHILD_DEPENDENCY = 45, /**< Used to determine if a volume has any dependencies */
- LSM_CAP_VOLUME_CHILD_DEPENDENCY_RM = 46, /**< Removes dependendies */
-
- LSM_CAP_ACCESS_GROUP_CREATE_ISCSI_IQN = 47, /**< Create iSCSI access group */
- LSM_CAP_ACCESS_GROUP_INITIATOR_ADD_ISCSI_IQN = 48, /**< For empty access group, this indicates it can add iSCSI IQN to it */
-
- LSM_CAP_VOLUME_ISCSI_CHAP_AUTHENTICATION = 53, /**< If you can configure iSCSI chap authentication */
-
- LSM_CAP_VOLUME_RAID_INFO = 54,
- /** ^ If you can query RAID information from volume */
-
- LSM_CAP_VOLUME_THIN = 55, /**< Thin provisioned volumes are supported */
-
- LSM_CAP_FS = 100, /**< List file systems */
- LSM_CAP_FS_DELETE = 101, /**< Delete a file system */
- LSM_CAP_FS_RESIZE = 102, /**< Resize a file system */
- LSM_CAP_FS_CREATE = 103, /**< Create a file system */
- LSM_CAP_FS_CLONE = 104, /**< Clone a file system */
- LSM_CAP_FILE_CLONE = 105, /**< Clone a file on a file system */
- LSM_CAP_FS_SNAPSHOTS = 106, /**< List FS snapshots */
- LSM_CAP_FS_SNAPSHOT_CREATE = 107, /**< Create a snapshot */
- LSM_CAP_FS_SNAPSHOT_DELETE = 109, /**< Delete a snapshot */
- LSM_CAP_FS_SNAPSHOT_RESTORE = 110, /**< Revert the state of a FS to the specified snapshot */
- LSM_CAP_FS_SNAPSHOT_RESTORE_SPECIFIC_FILES = 111, /**< Revert the state of a list of files to a specified snapshot */
- LSM_CAP_FS_CHILD_DEPENDENCY = 112, /**< Determine if a child dependency exists for the specified file */
- LSM_CAP_FS_CHILD_DEPENDENCY_RM = 113, /**< Remove any dependencies the file system may have */
- LSM_CAP_FS_CHILD_DEPENDENCY_RM_SPECIFIC_FILES = 114, /**< Remove any dependencies for specific files */
-
- LSM_CAP_EXPORT_AUTH = 120, /**< Get a list of supported client authentication types */
- LSM_CAP_EXPORTS = 121, /**< List exported file systems */
- LSM_CAP_EXPORT_FS = 122, /**< Export a file system */
- LSM_CAP_EXPORT_REMOVE = 123, /**< Remove an export */
- LSM_CAP_EXPORT_CUSTOM_PATH = 124, /**< Plug-in allows user to define custome export path */
-
- LSM_CAP_POOLS_QUICK_SEARCH = 210, /**< Seach occurs on array */
- LSM_CAP_VOLUMES_QUICK_SEARCH = 211, /**< Seach occurs on array */
- LSM_CAP_DISKS_QUICK_SEARCH = 212, /**< Seach occurs on array */
- LSM_CAP_ACCESS_GROUPS_QUICK_SEARCH = 213, /**< Seach occurs on array */
- LSM_CAP_FS_QUICK_SEARCH = 214, /**< Seach occurs on array */
- LSM_CAP_NFS_EXPORTS_QUICK_SEARCH = 215, /**< Seach occurs on array */
-
- LSM_CAP_TARGET_PORTS = 216, /**< List target ports */
- LSM_CAP_TARGET_PORTS_QUICK_SEARCH = 217, /**< Filtering occurs on array */
-
- LSM_CAP_DISKS = 220 /**< List disk drives */
-
-} lsm_capability_type;
-
-/**
- * Free the memory used by the storage capabilities data structure
- * @param cap Valid storage capability data structure.
- * @return LSM_ERR_OK on success, else error reason.
- */
-int LSM_DLL_EXPORT lsm_capability_record_free(lsm_storage_capabilities *cap);
-
-/**
- * Return the capability for the specified feature.
- * @param cap Valid pointer to capability data structure
- * @param t Which capability you are interested in
- * @return Value of supported enumerated type.
- */
-lsm_capability_value_type LSM_DLL_EXPORT lsm_capability_get(
- lsm_storage_capabilities *cap,
- lsm_capability_type t);
-
-/**
- * Boolean version of capability support
- * @param cap
- * @param t
- * @return Non-zero if supported, 0 if not supported
- */
-int LSM_DLL_EXPORT lsm_capability_supported(lsm_storage_capabilities *cap,
- lsm_capability_type t);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt_common.h b/c_binding/include/libstoragemgmt/libstoragemgmt_common.h
deleted file mode 100644
index 64404bb..0000000
--- a/c_binding/include/libstoragemgmt/libstoragemgmt_common.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2011-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 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#ifndef LSM_COMMON_H
-#define LSM_COMMON_H
-
-#include "libstoragemgmt_types.h"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if defined _WIN32 || defined __CYGWIN__
- #define LSM_DLL_IMPORT __declspec(dllimport)
- #define LSM_DLL_EXPORT __declspec(dllexport)
- #define LSM_DLL_LOCAL
-#else
- #if __GNUC__ >= 4
- #define LSM_DLL_IMPORT __attribute__ ((visibility ("default")))
- #define LSM_DLL_EXPORT __attribute__ ((visibility ("default")))
- #define LSM_DLL_LOCAL __attribute__ ((visibility ("hidden")))
- #else
- #define LSM_DLL_IMPORT
- #define LSM_DLL_EXPORT
- #define LSM_DLL_LOCAL
- #endif
-#endif
-
-/**
- * Allocates storage for string line of specified size.
- * @param size Initial number of strings to allocate
- * @return NULL on error, else valid lsm_string_list record pointer
- */
-lsm_string_list LSM_DLL_EXPORT *lsm_string_list_alloc(uint32_t size);
-
-/**
- * Frees the memory allocated with the lsmStringListFree
- * @param sl Record to free
- * @return LSM_ERR_OK on success, else error reason.
- */
-int LSM_DLL_EXPORT lsm_string_list_free(lsm_string_list *sl);
-
-/**
- * Copies a lsm_string_list record.
- * @param src Source to copy
- * @return NULL on error, else copy of source.
- */
-lsm_string_list LSM_DLL_EXPORT *lsm_string_list_copy(lsm_string_list *src);
-
-/**
- * Set the specified element with the passed value.
- * @param sl Valid string list pointer
- * @param index Element position to set value to
- * @param value Value to use for assignment
- * @return LSM_ERR_OK on success, else error reason
- */
-int LSM_DLL_EXPORT lsm_string_list_elem_set(lsm_string_list *sl, uint32_t index,
- const char* value);
-
-/**
- * Returns the value at the specified elem index
- * @param sl Valid string list pointer
- * @param index Index to retrieve
- * @return Value at that index position.
- */
-const char LSM_DLL_EXPORT *lsm_string_list_elem_get(lsm_string_list *sl,
- uint32_t index);
-
-/**
- * Returns the size of the list
- * @param sl Valid string list pointer
- * @return size of list, note you cannot create a zero sized list, so
- * 0 indicates error with structure
- *
- */
-uint32_t LSM_DLL_EXPORT lsm_string_list_size(lsm_string_list *sl);
-
-/**
- * Appends a char * to the string list, will grow container as needed.
- * @param sl String list to append to
- * @param add Character string to add
- * @return LSM_ERR_OK on success, else error reason
- */
-int LSM_DLL_EXPORT lsm_string_list_append(lsm_string_list *sl, const char* add);
-
-/**
- * Deletes the string at the specified index.
- * NOTE: The elements after this one are moved down, thus if you wanted to
- * iterate over the list deleting each element one by one you need to do so in
- * reverse order.
- * @param sl String list to remove item from
- * @param index Specified index
- * @return LSM_ERR_OK on success, else error reason
- */
-int LSM_DLL_EXPORT lsm_string_list_delete(lsm_string_list *sl, uint32_t index);
-
-/**
- * Checks to see if initiator id is valid
- * @param init_id Initiator value
- * @param init_type Type of initiator id, will get modified
- * to determined if type passed in is UNKNOWN
- * @return LSM_ERR_OK if initiator id is OK, else LSM_INVALID_ARGUMENT
- */
-int LSM_DLL_EXPORT lsm_initiator_id_verify( const char *init_id,
- lsm_access_group_init_type *init_type);
-
-
-/**
- * Checks to see if volume vpd83 is valid
- * @param vpd83 VPD string to check
- * @return LSM_ERR_OK if vpd is OK, else LSM_INVALID_ARGUMENT
- */
-int LSM_DLL_EXPORT lsm_volume_vpd83_verify( const char *vpd83 );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LSM_COMMON_H */
diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt_disk.h b/c_binding/include/libstoragemgmt/libstoragemgmt_disk.h
deleted file mode 100644
index f59c302..0000000
--- a/c_binding/include/libstoragemgmt/libstoragemgmt_disk.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- *
- */
-
-#ifndef LIBSTORAGEMGMT_DISK_H
-#define LIBSTORAGEMGMT_DISK_H
-
-#include "libstoragemgmt_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Free the memory for a disk record
- * @param d Disk memory to free
- * @return LSM_ERR_OK on success, else error reason.
- */
-int LSM_DLL_EXPORT lsm_disk_record_free(lsm_disk *d);
-
-/**
- * Copy a disk record
- * @param d Disk record to copy
- * @return Copy of disk record
- */
-lsm_disk LSM_DLL_EXPORT *lsm_disk_record_copy(lsm_disk *d);
-
-/**
- * Free an array of disk records
- * @param disk Array of disk records
- * @param size Size of disk array
- * @return LSM_ERR_OK on success, else error reason.
- */
-int LSM_DLL_EXPORT lsm_disk_record_array_free( lsm_disk *disk[], uint32_t size);
-
-/**
- * Returns the disk id
- * Note: Return value is valid as long as disk pointer is valid. It gets
- * freed when record is freed.
- * @param d Disk record of interest
- * @return String id
- */
-const char LSM_DLL_EXPORT *lsm_disk_id_get(lsm_disk *d);
-
-/**
- * Returns the disk name
- * Note: Return value is valid as long as disk pointer is valid. It gets
- * freed when record is freed.
- * @param d Disk record of interest
- * @return Disk name
- */
-const char LSM_DLL_EXPORT *lsm_disk_name_get(lsm_disk *d);
-
-/**
- * Returns the disk type (enumeration)
- * Note: Return value is valid as long as disk pointer is valid. It gets
- * freed when record is freed.
- * @param d Disk record of interest
- * @return Disk type
- */
-lsm_disk_type LSM_DLL_EXPORT lsm_disk_type_get(lsm_disk *d);
-
-/**
- * Returns number of blocks for disk
- * Note: Return value is valid as long as disk pointer is valid. It gets
- * freed when record is freed.
- * @param d Disk record of interest
- * @return Number of logical blocks
- */
-uint64_t LSM_DLL_EXPORT lsm_disk_number_of_blocks_get(lsm_disk *d);
-
-/**
- * Returns the block size
- * Note: Return value is valid as long as disk pointer is valid. It gets
- * freed when record is freed.
- * @param d Disk record of interest
- * @return Block size in bytes
- */
-uint64_t LSM_DLL_EXPORT lsm_disk_block_size_get(lsm_disk *d);
-
-/**
- * Returns the disk status
- * Note: Return value is valid as long as disk pointer is valid. It gets
- * freed when record is freed.
- * @param d Disk record of interest
- * @return Status of the disk
- */
-uint64_t LSM_DLL_EXPORT lsm_disk_status_get(lsm_disk *d);
-
-/**
- * Returns the system id
- * Note: Return value is valid as long as disk pointer is valid. It gets
- * freed when record is freed.
- * @param d Disk record of interest
- * @return Which system the disk belongs too.
- */
-const char LSM_DLL_EXPORT *lsm_disk_system_id_get(lsm_disk *d);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LIBSTORAGEMGMT_DISK_H */
diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt_error.h b/c_binding/include/libstoragemgmt/libstoragemgmt_error.h
deleted file mode 100644
index 0b28ddc..0000000
--- a/c_binding/include/libstoragemgmt/libstoragemgmt_error.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (C) 2011-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 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#ifndef LIBSTORAGEMGMTERROR_H
-#define LIBSTORAGEMGMTERROR_H
-
-#include "libstoragemgmt_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** @file libstoragemgmt_error.h */
-
-
-
-/**< \enum lsm_error_number Possible enumerated return codes from library */
-typedef enum {
- LSM_ERR_OK = 0, /**< OK */
- LSM_ERR_LIB_BUG = 1, /**< Library BUG */
- LSM_ERR_PLUGIN_BUG = 2, /**< Plugin BUG */
- LSM_ERR_JOB_STARTED = 7, /**< Operation has started */
- LSM_ERR_TIMEOUT = 11, /**< Plug-in is un-responsive */
- LSM_ERR_DAEMON_NOT_RUNNING = 12, /**< Daemon is not running */
-
- LSM_ERR_NAME_CONFLICT = 50, /**< Name exists */
- LSM_ERR_EXISTS_INITIATOR = 52, /**< Initiator exists in another access group */
-
- LSM_ERR_INVALID_ARGUMENT = 101, /**< Precondition checks failed */
-
- LSM_ERR_NO_STATE_CHANGE = 125, /**< Operation completed with no change in array state */
-
- LSM_ERR_NETWORK_CONNREFUSED = 140, /**< Host on network, but not allowing connection */
- LSM_ERR_NETWORK_HOSTDOWN = 141, /**< Host unreachable on network */
- LSM_ERR_NETWORK_ERROR = 142, /**< Generic network error */
-
- LSM_ERR_NO_MEMORY = 152, /**< Memory allocation failure */
- LSM_ERR_NO_SUPPORT = 153, /**< Feature not supported */
-
- LSM_ERR_IS_MASKED = 160, /**< Volume masked to Access Group*/
-
- LSM_ERR_NOT_FOUND_ACCESS_GROUP = 200, /**< Specified access group not found */
- LSM_ERR_NOT_FOUND_FS = 201, /**< Specified FS not found */
- LSM_ERR_NOT_FOUND_JOB = 202, /**< Specified JOB not found */
- LSM_ERR_NOT_FOUND_POOL = 203, /**< Specified POOL not found */
- LSM_ERR_NOT_FOUND_FS_SS = 204, /**< Specified snap shot not found */
- LSM_ERR_NOT_FOUND_VOLUME = 205, /**< Specified volume not found */
- LSM_ERR_NOT_FOUND_NFS_EXPORT = 206, /**< NFS export not found */
- LSM_ERR_NOT_FOUND_SYSTEM = 208, /**< System not found */
-
- LSM_ERR_NOT_LICENSED = 226, /**< Need license for feature */
-
- LSM_ERR_NO_SUPPORT_ONLINE_CHANGE = 250, /**< Take offline before performing operation */
- LSM_ERR_NO_SUPPORT_OFFLINE_CHANGE = 251, /**< Needs to be online to perform operation */
-
- LSM_ERR_PLUGIN_AUTH_FAILED = 300, /**< Authorization failed */
- LSM_ERR_PLUGIN_IPC_FAIL = 301, /**< Inter-process communication between client &
- out of process plug-in encountered connection
- errors.**/
-
- LSM_ERR_PLUGIN_SOCKET_PERMISSION = 307, /**< Incorrect permission on UNIX domain socket used for IPC */
- LSM_ERR_PLUGIN_NOT_EXIST = 311, /**< Plug-in does not appear to exist */
-
- LSM_ERR_NOT_ENOUGH_SPACE = 350, /**< Insufficient space */
-
- LSM_ERR_TRANSPORT_COMMUNICATION = 400, /**< Error comunicating with plug-in */
- LSM_ERR_TRANSPORT_SERIALIZATION = 401, /**< Transport serialization error */
- LSM_ERR_TRANSPORT_INVALID_ARG = 402, /**< Parameter transported over IPC is invalid */
-
- LSM_ERR_LAST_INIT_IN_ACCESS_GROUP = 502,
-
-
- LSM_ERR_UNSUPPORTED_SEARCH_KEY = 510, /**< Unsupport search key */
-
- LSM_ERR_EMPTY_ACCESS_GROUP = 511,
- LSM_ERR_POOL_NOT_READY = 512,
-
-} lsm_error_number;
-
-typedef struct _lsm_error lsm_error;
-typedef lsm_error *lsm_error_ptr;
-
-/**
- * Gets the last error structure
- * Note: @see lsm_error_free to release memory
- * @param c Connection pointer.
- * @return Error pointer, Null if no error exists!
- */
-lsm_error_ptr LSM_DLL_EXPORT lsm_error_last_get(lsm_connect *c);
-
-/**
- * Frees the error record!
- * @param err The error to free!
- * @return LSM_ERR_OK on success, else error reason.
- */
-int LSM_DLL_EXPORT lsm_error_free(lsm_error_ptr err);
-
-/**
- * Retrieves the error number from the error.
- * @param e The lsm_error_ptr
- * @return -1 if e is not a valid error pointer, else error number.
- */
-lsm_error_number LSM_DLL_EXPORT lsm_error_number_get(lsm_error_ptr e);
-
-/**
- * Retrieves the error message from the error.
- * Note: The returned value is only valid as long as the e is valid, in addition
- * the function will return NULL if e is invalid. To remove the ambiguity call
- * lsm_error_number_get and check return code.
- * @param e The lsm_error_ptr
- * @return NULL if message data does not exist, else error message.
- */
-char LSM_DLL_EXPORT *lsm_error_message_get(lsm_error_ptr e);
-
-/**
- * Retrieves the exception message from the error.
- * Note: The returned value is only valid as long as the e is valid, in addition
- * the function will return NULL if e is invalid. To remove the ambiguity call
- * lsm_error_number_get and check return code.
- * @param e The lsm_error_ptr
- * @return NULL if exception does not exist, else error exception.
- */
-char LSM_DLL_EXPORT *lsm_error_exception_get(lsm_error_ptr e);
-
-/**
- * Retrieves the error message from the error.
- * Note: The returned value is only valid as long as the e is valid, in addition
- * the function will return NULL if e is invalid. To remove the ambiguity call
- * lsm_error_number_get and check return code.
- * @param e The lsm_error_ptr
- * @return NULL if does not exist, else debug message.
- */
-char LSM_DLL_EXPORT *lsm_error_debug_get(lsm_error_ptr e);
-
-/**
- * Retrieves the debug data from the error.
- * Note: The returned value is only valid as long as the e is valid, in addition
- * the function will return NULL if e is invalid. To remove the ambiguity call
- * lsm_error_number_get and check return code.
- * @param e The lsm_error_ptr
- * @param[out] size Number of bytes of data returned.
- * @return NULL if does not exist, else debug message.
- */
-void LSM_DLL_EXPORT *lsm_error_debug_data_get(lsm_error_ptr e, uint32_t *size);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LIBSTORAGEMGMTERROR_H */
diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt_fs.h b/c_binding/include/libstoragemgmt/libstoragemgmt_fs.h
deleted file mode 100644
index b400453..0000000
--- a/c_binding/include/libstoragemgmt/libstoragemgmt_fs.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2011-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 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#ifndef LSM_FS_H
-#define LSM_FS_H
-
-#include "libstoragemgmt_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Frees a File system record
- * @param fs File system to free.
- * @return LSM_ERR_OK on success, else error reason.
- */
-int LSM_DLL_EXPORT lsm_fs_record_free(lsm_fs *fs);
-
-/**
- * Copies a file system record.
- * @param source File system record to copy.
- * @return Pointer to copy of file system record
- */
-lsm_fs LSM_DLL_EXPORT *lsm_fs_record_copy(lsm_fs *source);
-
-/**
- * Frees an array of file system records
- * @param fs Array of file system record pointers
- * @param size Number in array to free
- * @return LSM_ERR_OK on success, else error reason.
- */
-int LSM_DLL_EXPORT lsm_fs_record_array_free(lsm_fs * fs[], uint32_t size);
-
-/**
- * Returns the id of the file system.
- * @param fs File system record pointer
- * @return Pointer to file system id
- */
-const char LSM_DLL_EXPORT *lsm_fs_id_get(lsm_fs *fs);
-
-/**
- * Returns the name associated with the file system.
- * @param fs File system record pointer
- * @return Pointer to file system name
- */
-const char LSM_DLL_EXPORT *lsm_fs_name_get(lsm_fs *fs);
-
-/**
- * Returns the file system system id.
- * @param fs File system record pointer
- * @return Pointer to the system id.
- */
-const char LSM_DLL_EXPORT *lsm_fs_system_id_get(lsm_fs *fs);
-
-/**
- * Returns the pool id associated with the file system
- * @param fs File system record pointer
- * @return Pointer to pool id
- */
-const char LSM_DLL_EXPORT *lsm_fs_pool_id_get(lsm_fs *fs);
-
-/**
- * Returns total space of file system.
- * @param fs File system record pointer
- * @return Total size of file system in bytes
- */
-uint64_t LSM_DLL_EXPORT lsm_fs_total_space_get(lsm_fs *fs);
-
-/**
- * Returns the space available on the file system
- * @param fs File system record pointer
- * @return Total number of bytes that are free.
- */
-uint64_t LSM_DLL_EXPORT lsm_fs_free_space_get(lsm_fs *fs);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
\ No newline at end of file
diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt_hash.h b/c_binding/include/libstoragemgmt/libstoragemgmt_hash.h
deleted file mode 100644
index b9f11bf..0000000
--- a/c_binding/include/libstoragemgmt/libstoragemgmt_hash.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- *
- */
-
-#ifndef LIBSTORAGEMGMT_HASH_H
-#define LIBSTORAGEMGMT_HASH_H
-
-#include "libstoragemgmt_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Simple hash table which only stores character strings.
- */
-
-/**
- * Allocate storage for hash.
- * @return Allocated record or NULL on memory allocation failure
- */
-lsm_hash LSM_DLL_EXPORT *lsm_hash_alloc(void);
-
-/**
- * Free a lsm hash
- * @param op Record to free.
- * @return LSM_ERR_OK on success, else error reason.
- */
-int LSM_DLL_EXPORT lsm_hash_free(lsm_hash *op);
-
-/**
- * Get the list of 'keys' available in the hash
- * @param [in] op Valid optional data pointer
- * @param [out] l String list pointer
- * @return LSM_ERR_OK on success, else error reason
- */
-int LSM_DLL_EXPORT lsm_hash_keys(lsm_hash *op,
- lsm_string_list **l);
-
-/**
- * Get the value of a key (string)
- * @param [in] op Valid optional data pointer
- * @param [in] key Key to retrieve value for
- * @return Pointer to value, pointer valid until optional data memory
- * gets released.
- */
-const char LSM_DLL_EXPORT *lsm_hash_string_get(lsm_hash *op,
- const char *key);
-
-/**
- * Set the value of a key.
- * Note: If key exists, it is replaced with new one.
- * @param [in] op Valid optional data pointer
- * @param [in] key Key to set value for (key is duped)
- * @param [in] value Value of new key (string is duped)
- * @return LSM_ERR_OK on success, else error reason
- */
-int LSM_DLL_EXPORT lsm_hash_string_set(lsm_hash *op,
- const char *key,
- const char *value);
-
-/**
- * Does a copy of an lsm_hash
- * @param src lsm_hash to copy
- * @return NULL on error/memory allocation failure, else copy
- */
-lsm_hash LSM_DLL_EXPORT *lsm_hash_copy(lsm_hash *src);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LIBSTORAGEMGMT_HASH_H */
diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt_nfsexport.h b/c_binding/include/libstoragemgmt/libstoragemgmt_nfsexport.h
deleted file mode 100644
index 5e3076d..0000000
--- a/c_binding/include/libstoragemgmt/libstoragemgmt_nfsexport.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2011-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 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#ifndef LSM_NFS_EXPORT_H
-#define LSM_NFS_EXPORT_H
-
-#include "libstoragemgmt_types.h"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Because the nfs export functions use an unsigned data type these values
- * will be represented as (2**64-1 and 2**64-2 respectively)
- */
-#define ANON_UID_GID_NA -1
-#define ANON_UID_GID_ERROR (ANON_UID_GID_NA - 1)
-
-/**
- * Allocated memory for a NFS export record
- * @param id Export ID (Set to NULL when creating new export)
- * @param fs_id File system ID that is exported
- * @param export_path The desired path for the export (May be NULL)
- * @param auth NFS client authentication type (May be NULL)
- * @param root List of hosts that have root access (May be NULL)
- * @param rw List of hosts that have read/write access (May be NULL)
- * @param ro List of hosts that have read only access (May be NULL)
- * @param anonuid User id that should be mapped to anonymous
- * (Valid or set to ANON_UID_GID_NA).
- * @param anongid Group id that should be mapped to anonymous
- * (Valid or set to ANON_UID_GID_NA)
- * @param options String of options passed to array
- * @param plugin_data Reserved for plug-in use
- * @return Valid export pointer, else NULL on error.
- */
-lsm_nfs_export LSM_DLL_EXPORT * lsm_nfs_export_record_alloc(const char *id,
- const char *fs_id,
- const char *export_path,
- const char *auth,
- lsm_string_list *root,
- lsm_string_list *rw,
- lsm_string_list *ro,
- uint64_t anonuid,
- uint64_t anongid,
- const char *options,
- const char * plugin_data);
-
-/**
- * Allocated the memory for an array of NFS export records.
- * @param size Number of elements
- * @return Allocated memory, NULL on error
- */
-lsm_nfs_export LSM_DLL_EXPORT **lsm_nfs_export_record_array_alloc( uint32_t size );
-
-
-/**
- * Frees the memory for a NFS export record.
- * @param exp
- * @return LSM_ERR_OK on success, else error reason.
- */
-int LSM_DLL_EXPORT lsm_nfs_export_record_free( lsm_nfs_export *exp );
-
-/**
- * Frees the memory for the NFS export array and the memory for each entry
- * @param exps Memory to free
- * @param size Number of entries
- * @return LSM_ERR_OK on success, else error reason.
- * */
-int LSM_DLL_EXPORT lsm_nfs_export_record_array_free( lsm_nfs_export *exps[],
- uint32_t size);
-
-/**
- * Duplicates the source and returns the copy.
- * @param source Source record to copy
- * @return Copy of source, else NULL one error.
- */
-lsm_nfs_export LSM_DLL_EXPORT *lsm_nfs_export_record_copy( lsm_nfs_export *source );
-
-/**
- * Returns the ID
- * @param exp Valid nfs export record
- * @return Pointer to ID
- */
-const char LSM_DLL_EXPORT *lsm_nfs_export_id_get( lsm_nfs_export *exp );
-int LSM_DLL_EXPORT lsm_nfs_export_id_set(lsm_nfs_export *exp, const char *ep );
-
-/**
- * Returns the file system id
- * @param exp Valid nfs export record
- * @return Pointer to file system id
- */
-const char LSM_DLL_EXPORT *lsm_nfs_export_fs_id_get( lsm_nfs_export *exp );
-int LSM_DLL_EXPORT lsm_nfs_export_fs_id_set(lsm_nfs_export *exp, const char *fs_id);
-
-/**
- * Returns the export path
- * @param exp Valid nfs export record
- * @return Pointer to export path
- */
-const char LSM_DLL_EXPORT *lsm_nfs_export_export_path_get( lsm_nfs_export *exp );
-int LSM_DLL_EXPORT lsm_nfs_export_export_path_set( lsm_nfs_export *exp,
- const char *export_path);
-
-/**
- * Returns the client authentication type
- * @param exp Valid nfs export record
- * @return Pointer to authentication type
- */
-const char LSM_DLL_EXPORT *lsm_nfs_export_auth_type_get( lsm_nfs_export * exp );
-int LSM_DLL_EXPORT lsm_nfs_export_auth_type_set( lsm_nfs_export * exp,
- const char *value );
-
-/**
- * Returns the list of hosts that have root access
- * @param exp Valid nfs export record
- * @return list of hosts.
- */
-lsm_string_list LSM_DLL_EXPORT * lsm_nfs_export_root_get( lsm_nfs_export * exp);
-int LSM_DLL_EXPORT lsm_nfs_export_root_set(lsm_nfs_export * exp,
- lsm_string_list * value);
-
-/**
- * Returns the list of hosts that have read/write access to export.
- * @param exp Valid nfs export record
- * @return list of hosts.
- */
-lsm_string_list LSM_DLL_EXPORT *lsm_nfs_export_read_write_get( lsm_nfs_export *exp);
-int LSM_DLL_EXPORT lsm_nfs_export_read_write_set( lsm_nfs_export *exp,
- lsm_string_list *value);
-
-/**
- * Returns the list of hosts that have read only access to export.
- * @param exp Valid nfs export record
- * @return list of hosts
- */
-lsm_string_list LSM_DLL_EXPORT *lsm_nfs_export_read_only_get( lsm_nfs_export *exp );
-int LSM_DLL_EXPORT lsm_nfs_export_read_only_set( lsm_nfs_export *exp,
- lsm_string_list *value);
-
-/**
- * Returns the id which is to be mapped to anonymous id
- * @param exp Valid nfs export record
- * @return ANON_UID_GID_NA value is returned when this isn't set, else value
- * mapped to anonymous group id. For errors ANON_UID_GID_ERROR is returned.
- */
-uint64_t LSM_DLL_EXPORT lsm_nfs_export_anon_uid_get( lsm_nfs_export * exp );
-int LSM_DLL_EXPORT lsm_nfs_export_anon_uid_set( lsm_nfs_export * exp, uint64_t value);
-
-/**
- * Returns the group id which is to be mapped to anonymous group
- * @param exp Valid nfs export record
- * @return ANON_UID_GID_NA value is returned when this isn't set, else value
- * mapped to anonymous group id. For errors ANON_UID_GID_ERROR is returned.
- */
-uint64_t LSM_DLL_EXPORT lsm_nfs_export_anon_gid_get( lsm_nfs_export *exp );
-int LSM_DLL_EXPORT lsm_nfs_export_anon_gid_set( lsm_nfs_export *exp, uint64_t value);
-
-/**
- * Returns the options for this export.
- * @param exp Valid nfs export record
- * @return Options value, NULL if not applicable.
- */
-const char LSM_DLL_EXPORT *lsm_nfs_export_options_get( lsm_nfs_export *exp);
-int LSM_DLL_EXPORT lsm_nfs_export_options_set( lsm_nfs_export *exp,
- const char *value);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
\ No newline at end of file
diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt_plug_interface.h b/c_binding/include/libstoragemgmt/libstoragemgmt_plug_interface.h
deleted file mode 100644
index b36586c..0000000
--- a/c_binding/include/libstoragemgmt/libstoragemgmt_plug_interface.h
+++ /dev/null
@@ -1,1358 +0,0 @@
-/*
- * Copyright (C) 2011-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 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#ifndef LIBSTORAGEMGMT_PLUG_INTERFACE_H
-#define LIBSTORAGEMGMT_PLUG_INTERFACE_H
-
-#include "libstoragemgmt_common.h"
-
-#include "libstoragemgmt_accessgroups.h"
-#include "libstoragemgmt_blockrange.h"
-#include "libstoragemgmt_capabilities.h"
-#include "libstoragemgmt_error.h"
-#include "libstoragemgmt_fs.h"
-#include "libstoragemgmt_nfsexport.h"
-#include "libstoragemgmt_hash.h"
-#include "libstoragemgmt_pool.h"
-#include "libstoragemgmt_snapshot.h"
-#include "libstoragemgmt_systems.h"
-#include "libstoragemgmt_volumes.h"
-#include "libstoragemgmt_disk.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** @file libstoragemgmt_plug_interface.h */
-
-/** \enum lsm_data_type What type of data structure we have */
-typedef enum {
- LSM_DATA_TYPE_UNKNOWN = -1, /**< Unknown */
- LSM_DATA_TYPE_NONE, /**< None */
- LSM_DATA_TYPE_ACCESS_GROUP, /**< Access group */
- LSM_DATA_TYPE_BLOCK_RANGE, /**< Block range */
- LSM_DATA_TYPE_FS, /**< File system */
- LSM_DATA_TYPE_NFS_EXPORT, /**< NFS export */
- LSM_DATA_TYPE_POOL, /**< Pool */
- LSM_DATA_TYPE_SS, /**< Snap shot */
- LSM_DATA_TYPE_STRING_LIST, /**< String list */
- LSM_DATA_TYPE_SYSTEM, /**< System */
- LSM_DATA_TYPE_VOLUME, /**< Volume */
- LSM_DATA_TYPE_DISK /**< Disk */
-} lsm_data_type;
-
-/**
- * Opaque data type for plug-ins
- */
-typedef struct _lsm_plugin lsm_plugin;
-
-/**
- * Typedef for pointer type
- */
-typedef lsm_plugin *lsm_plugin_ptr;
-
-/**
- * Plug-in register callback function signature.
- * @param c Valid lsm plugin pointer
- * @param uri Connection URI
- * @param password Plain text password
- * @param timeout Plug-in timeout to array
- * @param flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plugin_register)( lsm_plugin_ptr c, const char *uri,
- const char *password, uint32_t timeout, lsm_flag flags);
-
-/**
- * Plug-in unregister callback function signature
- * @param c Valid lsm plugin pointer
- * @param flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plugin_unregister)( lsm_plugin_ptr c, lsm_flag flags );
-
-/**
- * Set plug-in time-out value callback function signature
- * @param c Valid lsm plug-in pointer
- * @param timeout timeout value in milliseconds
- * @param flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_tmo_set)( lsm_plugin_ptr c, uint32_t timeout,
- lsm_flag flags );
-
-/**
- * Get the plug-in time-out value callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[out] timeout Time-out value
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_tmo_get)( lsm_plugin_ptr c, uint32_t *timeout,
- lsm_flag flags );
-
-/**
- * Retrieve the plug-in capabilities callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] sys System to interrogate
- * @param[out] cap Capabilities
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_capabilities)(lsm_plugin_ptr c, lsm_system *sys,
- lsm_storage_capabilities **cap,
- lsm_flag flags);
-/**
- * Retrieve the job status callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] job Job identifier
- * @param[out] status Enumerated value representing status
- * @param[out] percent_complete How far completed
- * @param[out] type Type of result
- * @param[out] value Value of result
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-
-typedef int (*lsm_plug_Job_status)(lsm_plugin_ptr c, const char *job,
- lsm_job_status *status,
- uint8_t *percent_complete,
- lsm_data_type *type,
- void **value, lsm_flag flags);
-/**
- * Instructs the plug-in to release the memory for the specified job id,
- * callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] job_id Job ID to free memory for
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_job_free)(lsm_plugin_ptr c, char *job_id, lsm_flag flags);
-
-/**
- * Retrieves a list of pools callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] search_key Search key
- * @param[in] search_value Search value
- * @param[out] pool_array List of pools
- * @param[out] count Number of items in array
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_pool_list)( lsm_plugin_ptr c, const char *search_key,
- const char *search_value,
- lsm_pool **pool_array[],
- uint32_t *count, lsm_flag flags);
-
-/**
- * Retrieve a list of systems, callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[out] systems List of systems
- * @param[out] system_count Number of systems
- * @param[out] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_system_list)(lsm_plugin_ptr c, lsm_system **systems[],
- uint32_t *system_count, lsm_flag flags);
-
-/** \struct lsm_mgmt_ops_v1
- * \brief Callback functions for management operations */
-struct lsm_mgmt_ops_v1 {
- lsm_plug_tmo_set tmo_set; /**< tmo set callback */
- lsm_plug_tmo_get tmo_get; /**< tmo get callback */
- lsm_plug_capabilities capablities; /**< capabilities callback */
- lsm_plug_Job_status job_status; /**< status of job */
- lsm_plug_job_free job_free; /**< Free a job */
- lsm_plug_pool_list pool_list; /**< List of pools */
- lsm_plug_system_list system_list; /**< List of systems */
-};
-
-/**
- * Retrieve a list of volumes.
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] search_key Search key
- * @param[in] search_value Search value
- * @param[out] vol_array Array of volumes
- * @param[out] count Number of volumes
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_volume_list)( lsm_plugin_ptr c, const char *search_key,
- const char *search_val,
- lsm_volume **vol_array[],
- uint32_t *count, lsm_flag flags);
-
-/**
- * Retrieve a list of volumes.
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] search_key Search key
- * @param[in] search_value Search value
- * @param[out] disk_array Array of disk pointers
- * @param[out] count Number of disks
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_disk_list)( lsm_plugin_ptr c, const char *search_key,
- const char *search_value,
- lsm_disk **disk_array[],
- uint32_t *count, lsm_flag flags);
-
-/**
- * Retrieve a list of target ports.
- * @param[in] c Valid lsm plugin-in pointer
- * @param[in] search_key Search key
- * @param[in] search_value Search value
- * @param[out] target_port_array Array of target port pointers
- * @param[out] count Number of target ports
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_target_port_list)( lsm_plugin_ptr c,
- const char *search_key,
- const char *search_value,
- lsm_target_port **target_port_array[],
- uint32_t *count, lsm_flag flags);
-
-/**
- * Creates a volume, callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] pool Pool to allocated storage from
- * @param[in] volume_name Name of new volume
- * @param[in] size Size of volume in bytes
- * @param[in] provisioning How provisioned
- * @param[out] new_volume Information on newly created volume
- * @param[out] job Job ID
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_volume_create)(lsm_plugin_ptr c, lsm_pool *pool,
- const char *volume_name, uint64_t size,
- lsm_volume_provision_type provisioning, lsm_volume **new_volume,
- char **job, lsm_flag flags);
-
-/**
- * Volume replicate, callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] pool Pool to allocated replicant from (optional)
- * @param[in] rep_type Replication type
- * @param[in] volume_src Source of the replication
- * @param[in] name Name of newly replicated volume
- * @param[out] new_replicant Newly replicated volume
- * @param job
- * @param flags
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_volume_replicate)(lsm_plugin_ptr c, lsm_pool *pool,
- lsm_replication_type rep_type, lsm_volume *volume_src,
- const char *name, lsm_volume **new_replicant,
- char **job, lsm_flag flags);
-
-/**
- * Return the block size of a replicated block range.
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] system System to query against
- * @param[out] bs Block size
- * @param[out] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_volume_replicate_range_block_size)(lsm_plugin_ptr c,
- lsm_system *system, uint32_t *bs, lsm_flag flags);
-
-/**
- * Replicate a range of a volume to the same volume or different volume.
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] rep_type What type of replication
- * @param[in] source Source of the replication
- * @param[in] dest Destination of the replication, can be
- * same as source
- * @param[in] ranges An array of ranges
- * @param[in] num_ranges Number of items in array
- * @param[out] job Job ID
- * @param flags
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_volume_replicate_range)(lsm_plugin_ptr c,
- lsm_replication_type rep_type,
- lsm_volume *source,
- lsm_volume *dest,
- lsm_block_range **ranges,
- uint32_t num_ranges, char **job,
- lsm_flag flags);
-
-/**
- * Re-size a volume, callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] volume Volume to be re-sized
- * @param[in] new_size New size of volume in bytes
- * @param[in] resized_volume Information about newly re-sized volume
- * @param[out] job The job ID
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_volume_resize)(lsm_plugin_ptr c, lsm_volume *volume,
- uint64_t new_size, lsm_volume **resized_volume,
- char **job, lsm_flag flags);
-
-/**
- * Delete a volume, callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] volume Volume to be deleted
- * @param[out] job Job ID
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_volume_delete)(lsm_plugin_ptr c, lsm_volume *volume,
- char **job, lsm_flag flags);
-/**
- * Place a volume online, callback function signature.
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] v Volume to place online
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_volume_enable)(lsm_plugin_ptr c, lsm_volume *v,
- lsm_flag flags);
-
-/**
- * Take a volume offline, callback function signature.
- * @param[in] c Valid lsm plug-in pointer
- * @param v
- * @param flags
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_volume_disable)(lsm_plugin_ptr c, lsm_volume *v,
- lsm_flag flags);
-
-/**
- * Setup the cap authentication for the specified initiator, callback
- * function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] init_id Initiator to set chap authentication for
- * @param[in] in_user CHAP inbound username
- * @param[in] in_password CHAP inbound password
- * @param[in] out_user CHAP outbound user name
- * @param[in] out_password CHAP outbound user name
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_iscsi_chap_auth)(lsm_plugin_ptr c,
- const char *init_id,
- const char *in_user,
- const char *in_password,
- const char *out_user,
- const char *out_password,
- lsm_flag flags);
-
-/**
- * Retrieve a list of access groups, callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] search_key Field to search on
- * @param[in] search_value Field value
- * @param[out] groups Array of groups
- * @param[out] group_count Number of groups
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_access_group_list)(lsm_plugin_ptr c,
- const char *search_key,
- const char *search_value,
- lsm_access_group **groups[],
- uint32_t *group_count, lsm_flag flags);
-/**
- * Creates an access group, callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] name Name of access group
- * @param[in] initiator_id Initiator to be added to group
- * @param[in] id_type Initiator type
- * @param[in] system System to create group for
- * @param[out] access_group Newly created access group
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_access_group_create)(lsm_plugin_ptr c,
- const char *name,
- const char *initiator_id,
- lsm_access_group_init_type init_type,
- lsm_system *system,
- lsm_access_group **access_group,
- lsm_flag flags);
-
-/**
- * Deletes an access group, callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] group Access group to be deleted
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_access_group_delete)(lsm_plugin_ptr c,
- lsm_access_group *group, lsm_flag flags);
-
-/**
- * Add an initiator to an access group, callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] access_group Group to add initiator to
- * @param[in] initiator_id Initiator to add to group
- * @param[in] id_type Initiator type
- * @param[out] updated_access_group Updated access group
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_access_group_initiator_add)(lsm_plugin_ptr c,
- lsm_access_group *access_group,
- const char *initiator_id,
- lsm_access_group_init_type id_type,
- lsm_access_group **updated_access_group,
- lsm_flag flags);
-
-/**
- * Remove an initiator from an access group, callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] access_group Group to remove initiator from
- * @param[in] initiator_id Initiator to remove
- * @param[in] id_type Initiator type
- * @param[out] updated_access_group Updated access group
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_access_group_initiator_delete)(lsm_plugin_ptr c,
- lsm_access_group *access_group,
- const char *initiator_id,
- lsm_access_group_init_type id_type,
- lsm_access_group **updated_access_group,
- lsm_flag flags);
-
-/**
- * Grants access to a volume for the specified access group, callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] group Group to be granted access
- * @param[in] volume Volume to be given access too
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_volume_mask)(lsm_plugin_ptr c,
- lsm_access_group *group,
- lsm_volume *volume,
- lsm_flag flags);
-
-/**
- * Revokes access to a volume for a specified access group, callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] group Group to revoke access for
- * @param[in] volume Volume to which will no longer be accessible by group
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_volume_unmask)(lsm_plugin_ptr c,
- lsm_access_group *group,
- lsm_volume *volume, lsm_flag flags);
-
-/**
- * Retrieve an array of volumes which are accessible by access group, callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] group Group to find volumes for
- * @param[out] volumes Array of volumes
- * @param[out] count Number of volumes
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_volumes_accessible_by_access_group)(lsm_plugin_ptr c,
- lsm_access_group *group,
- lsm_volume **volumes[],
- uint32_t *count, lsm_flag flags);
-
-/**
- * Retrieve a list of access groups that have access to the specified volume,
- * callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] volume Volume to query
- * @param[out] groups Array of access groups
- * @param[out] group_count Number of access groups
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
- typedef int (*lsm_plug_access_groups_granted_to_volume)(lsm_plugin_ptr c,
- lsm_volume *volume,
- lsm_access_group **groups[],
- uint32_t *group_count, lsm_flag flags);
-
-/**
- * Determine if a volume has child dependencies, callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] volume Volume to query
- * @param[out] yes Boolean
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_volume_child_dependency)(lsm_plugin_ptr c,
- lsm_volume *volume,
- uint8_t *yes, lsm_flag flags);
-
-/**
- * Remove dependencies from a volume, callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] volume Volume to remove dependency for
- * @param[out] job Job ID
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_volume_child_dependency_delete)(lsm_plugin_ptr c,
- lsm_volume *volume,
- char **job, lsm_flag flags);
-
-/**
- * File system list, callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] search_key Search key
- * @param[in] search_value Search value
- * @param[out] fs An array of file systems
- * @param[out] fs_count Number of file systems
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_fs_list)(lsm_plugin_ptr c, const char *search_key,
- const char *search_value, lsm_fs **fs[],
- uint32_t *fs_count, lsm_flag flags);
-
-/**
- * Create a file system, callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] pool Pool to create file system from
- * @param[in] name Name of file system
- * @param[in] size_bytes Size of the file system in bytes
- * @param[out] fs Newly created file system
- * @param[out] job Job ID
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_fs_create)(lsm_plugin_ptr c, lsm_pool *pool,
- const char *name, uint64_t size_bytes,
- lsm_fs **fs, char **job, lsm_flag flags);
-
-/**
- * Delete a file system, callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] fs File system to delete
- * @param[out] job Job ID
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_fs_delete)(lsm_plugin_ptr c, lsm_fs *fs, char **job, lsm_flag flags);
-
-/**
- * Clone a file system, callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] dest_fs_name Clone fs name
- * @param[out] cloned_fs New clone
- * @param[in] optional_snapshot Basis of clone
- * @param[out] job Job ID
- * @param[in] flags reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_fs_clone)(lsm_plugin_ptr c, lsm_fs *src_fs,
- const char *dest_fs_name,
- lsm_fs **cloned_fs,
- lsm_fs_ss *optional_snapshot,
- char **job, lsm_flag flags);
-/**
- * Determine if a file system has child dependencies, callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] fs File system to check
- * @param[in] files Specific files to check
- * @param[out] yes Boolean
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_fs_child_dependency)(lsm_plugin_ptr c, lsm_fs *fs,
- lsm_string_list *files,
- uint8_t *yes);
-
-/**
- * Remove dependencies from a file system, callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] fs File system to remove dependencies for
- * @param[in] files Specific files to remove dependencies for
- * @param[out] job Job ID
- * @param[out] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_fs_child_dependency_delete)( lsm_plugin_ptr c, lsm_fs *fs,
- lsm_string_list *files,
- char **job, lsm_flag flags);
-
-/**
- * Re-size a file system, callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] fs File system to re-size
- * @param[in] new_size_bytes New size of file system
- * @param[out] rfs Re-sized file system
- * @param[out] job Job ID
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_fs_resize)(lsm_plugin_ptr c, lsm_fs *fs,
- uint64_t new_size_bytes, lsm_fs **rfs,
- char **job, lsm_flag flags);
-
-/**
- * Clone an individual file on a file system, callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] fs File system which contains the file to clone
- * @param[in] src_file_name Source file name and path
- * @param[in] dest_file_name Destination file and path
- * @param[in] snapshot Optional backing snapshot
- * @param[out] job Job ID
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_fs_file_clone)(lsm_plugin_ptr c, lsm_fs *fs,
- const char *src_file_name,
- const char *dest_file_name,
- lsm_fs_ss *snapshot, char **job, lsm_flag flags);
-
-/**
- * Retrieve a list of fs snapshots for a file system, callback function
- * signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] fs File system
- * @param[out] ss Array of snap shots
- * @param[out] ss_count Count of snapshots
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_fs_ss_list)(lsm_plugin_ptr c, lsm_fs *fs, lsm_fs_ss **ss[],
- uint32_t *ss_count, lsm_flag flags);
-
-/**
- * Create a fs snapshot of the specified file system and optionally constrain
- * it to a list of files, callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] fs File system to create snapshot for
- * @param[in] name Snap shot name
- * @param[out] snapshot Newly created snapshot
- * @param[out] job Job ID
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_fs_ss_create)(lsm_plugin_ptr c, lsm_fs *fs,
- const char *name,
- lsm_fs_ss **snapshot, char **job,
- lsm_flag flags);
-/**
- * Delete a fs snapshot, callback function signature, callback function
- * signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] fs File system to delete snapshot for
- * @param[in] ss Snapshot to delete
- * @param[out] job Job ID
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_fs_ss_delete)(lsm_plugin_ptr c, lsm_fs *fs, lsm_fs_ss *ss,
- char **job, lsm_flag flags);
-
-/**
- * Revert the state of a file system or specific files to a previous state,
- * callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] fs File system of interest
- * @param[in] files Optional list of files
- * @param[in] restore_files Optional path and name of restored files
- * @param[in] all_files boolean to indicate all files should be restored
- * @param[out] job Job ID
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_fs_ss_restore)(lsm_plugin_ptr c, lsm_fs *fs, lsm_fs_ss *ss,
- lsm_string_list *files,
- lsm_string_list *restore_files,
- int all_files, char **job, lsm_flag flags);
-
-/**
- * Get a list of NFS client authentication types, callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[out] types List of authtication types
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_nfs_auth_types)( lsm_plugin_ptr c,
- lsm_string_list **types, lsm_flag flags);
-
-/**
- * Retrieve a list of NFS exports, callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] search_key Search key
- * @param[in] search_value Search value
- * @param[out] exports An array of exported file systems
- * @param[out] count Number of exported file systems
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_nfs_list)( lsm_plugin_ptr c, const char *search_key,
- const char *search_value,
- lsm_nfs_export **exports[],
- uint32_t *count, lsm_flag flags);
-/**
- * Exports a file system via NFS, callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] fs_id File system id to export
- * @param[in] export_path NFS export path
- * @param[in] root_list List of servers with root access
- * @param[in] rw_list List of servers with read/write access
- * @param[in] ro_list List of servers with read only access
- * @param[in] anon_uid UID to be mapped to anonymous
- * @param[in] anon_gid GID to be mapped to anonymous
- * @param[in] auth_type Client authentication type
- * @param[in] options Options
- * @param[out] exported Newly created export
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_nfs_export_fs)( lsm_plugin_ptr c,
- const char *fs_id,
- const char *export_path,
- lsm_string_list *root_list,
- lsm_string_list *rw_list,
- lsm_string_list *ro_list,
- uint64_t anon_uid,
- uint64_t anon_gid,
- const char *auth_type,
- const char *options,
- lsm_nfs_export **exported,
- lsm_flag flags
- );
-
-/**
- * Removes a NFS export, callback function signature
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] e Export to remove
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_nfs_export_remove)( lsm_plugin_ptr c, lsm_nfs_export *e,
- lsm_flag flags);
-/** \struct lsm_san_ops_v1
- * \brief Block array oriented functions (callback functions)
- * NOTE: This structure cannot change as we need to maintain backwards
- * compatibility
- */
-struct lsm_san_ops_v1 {
- lsm_plug_volume_list vol_get; /**< retrieving volumes */
- lsm_plug_disk_list disk_get; /**< retrieve disks */
- lsm_plug_volume_create vol_create; /**< creating a lun */
- lsm_plug_volume_replicate vol_replicate; /**< replicating lun */
- lsm_plug_volume_replicate_range_block_size vol_rep_range_bs; /**< volume replication range block size */
- lsm_plug_volume_replicate_range vol_rep_range; /**< volume replication range */
- lsm_plug_volume_resize vol_resize; /**< resizing a volume */
- lsm_plug_volume_delete vol_delete; /**< deleting a volume */
- lsm_plug_volume_enable vol_enable; /**< volume is accessible */
- lsm_plug_volume_disable vol_disable; /**< volume is unaccessible */
- lsm_plug_iscsi_chap_auth iscsi_chap_auth; /**< iscsi chap authentication */
- lsm_plug_access_group_list ag_list; /**< access groups */
- lsm_plug_access_group_create ag_create; /**< access group create */
- lsm_plug_access_group_delete ag_delete; /**< access group delete */
- lsm_plug_access_group_initiator_add ag_add_initiator; /**< adding an initiator to an access group */
- lsm_plug_access_group_initiator_delete ag_del_initiator; /**< deleting an initiator from an access group */
- lsm_plug_volume_mask ag_grant; /**< acess group grant */
- lsm_plug_volume_unmask ag_revoke; /**< access group revoke */
- lsm_plug_volumes_accessible_by_access_group vol_accessible_by_ag; /**< volumes accessible by access group */
- lsm_plug_access_groups_granted_to_volume ag_granted_to_vol; /**< access groups granted to a volume */
- lsm_plug_volume_child_dependency vol_child_depends; /**< volume child dependencies */
- lsm_plug_volume_child_dependency_delete vol_child_depends_rm; /**<Callback to remove volume child dependencies */
- lsm_plug_target_port_list target_port_list; /**< Callback to get list of target ports */
-};
-
-/** \struct lsm_fs_ops_v1
- * \brief File system oriented functionality
- * NOTE: This structure cannot change as we need to maintain backwards
- * compatibility
- */
-struct lsm_fs_ops_v1 {
- lsm_plug_fs_list fs_list; /**< list file systems */
- lsm_plug_fs_create fs_create; /**< create a file system */
- lsm_plug_fs_delete fs_delete; /**< delete a file system */
- lsm_plug_fs_resize fs_resize; /**< resize a file system */
- lsm_plug_fs_clone fs_clone; /**< clone a file system */
- lsm_plug_fs_file_clone fs_file_clone; /**< clone files on a file system */
- lsm_plug_fs_child_dependency fs_child_dependency; /**< check file system child dependencies */
- lsm_plug_fs_child_dependency_delete fs_child_dependency_rm; /**< remove file system child dependencies */
- lsm_plug_fs_ss_list fs_ss_list; /**< list snapshots */
- lsm_plug_fs_ss_create fs_ss_create; /**< create a snapshot */
- lsm_plug_fs_ss_delete fs_ss_delete; /**< delete a snapshot */
- lsm_plug_fs_ss_restore fs_ss_restore; /**< restore a snapshot */
-};
-
-/** \struct lsm_nas_ops_v1
- * \brief NAS system oriented functionality call back functions
- * NOTE: This structure cannot change as we need to maintain backwards
- * compatibility
- */
-struct lsm_nas_ops_v1 {
- lsm_plug_nfs_auth_types nfs_auth_types; /**< List nfs authentication types */
- lsm_plug_nfs_list nfs_list; /**< List nfs exports */
- lsm_plug_nfs_export_fs nfs_export; /**< Export a file system */
- lsm_plug_nfs_export_remove nfs_export_remove; /**< Remove a file export */
-};
-
-/**
- * Query the RAID information of a volume
- * @param[in] c Valid lsm plug-in pointer
- * @param[in] volume Volume to be deleted
- * @param[out] raid_type Enum of lsm_volume_raid_type
- * @param[out] strip_size Size of the strip on each disk or other
- * storage extent.
- * @param[out] disk_count Count of of disks of RAID group(s) where this
- * volume allocated from.
- * @param[out] min_io_size Minimum I/O size, also the preferred I/O size
- * of random I/O.
- * @param[out] opt_io_size Optimal I/O size, also the preferred I/O size
- * of sequential I/O.
- * @param[in] flags Reserved
- * @return LSM_ERR_OK, else error reason
- */
-typedef int (*lsm_plug_volume_raid_info)(lsm_plugin_ptr c, lsm_volume *volume,
- lsm_volume_raid_type *raid_type, uint32_t *strip_size,
- uint32_t *disk_count, uint32_t *min_io_size, uint32_t *opt_io_size,
- lsm_flag flags);
-
-/** \struct lsm_ops_v1_2
- * \brief Functions added in version 1.2
- * NOTE: This structure will change during the developement util version 1.2
- * released.
- */
-struct lsm_ops_v1_2 {
- lsm_plug_volume_raid_info vol_raid_info;
- /**^ Query volume RAID information*/
-};
-
-/**
- * Copies the memory pointed to by item with given type t.
- * @param t Type of item to copy
- * @param item Pointer to src
- * @return Null, else copy of item.
- */
-void LSM_DLL_EXPORT * lsm_data_type_copy(lsm_data_type t, void *item);
-
-/**
- * Initializes the plug-in.
- * @param argc Command line argument count
- * @param argv Command line arguments
- * @param reg Registration function
- * @param unreg Un-Registration function
- * @param desc Plug-in description
- * @param version Plug-in version
- * @return exit code for plug-in
- */
-int LSM_DLL_EXPORT lsm_plugin_init_v1( int argc, char *argv[], lsm_plugin_register reg,
- lsm_plugin_unregister unreg,
- const char *desc, const char *version);
-
-
-/**
- * Used to register all the data needed for the plug-in operation.
- * @param plug Pointer provided by the framework
- * @param private_data Private data to be used for whatever the plug-in needs
- * @param mgm_ops Function pointers for management operations
- * @param san_ops Function pointers for SAN operations
- * @param fs_ops Function pointers for file system operations
- * @param nas_ops Function pointers for NAS operations
- * @return LSM_ERR_OK on success, else error reason.
- */
-int LSM_DLL_EXPORT lsm_register_plugin_v1( lsm_plugin_ptr plug,
- void * private_data, struct lsm_mgmt_ops_v1 *mgm_ops,
- struct lsm_san_ops_v1 *san_ops, struct lsm_fs_ops_v1 *fs_ops,
- struct lsm_nas_ops_v1 *nas_ops );
-
-/**
- * Used to register version 1.2 APIs plug-in operation.
- * @param plug Pointer provided by the framework
- * @param private_data Private data to be used for whatever the plug-in
- * needs
- * @param mgm_ops Function pointers for struct lsm_mgmt_ops_v1
- * @param san_ops Function pointers for struct lsm_san_ops_v1
- * @param fs_ops Function pointers for struct lsm_fs_ops_v1
- * @param nas_ops Function pointers for struct lsm_nas_ops_v1
- * @param ops_v1_2 Function pointers for struct lsm_ops_v1_2
- * @return LSM_ERR_OK on success, else error reason.
- */
-int LSM_DLL_EXPORT lsm_register_plugin_v1_2(
- lsm_plugin_ptr plug,
- void * private_data, struct lsm_mgmt_ops_v1 *mgm_ops,
- struct lsm_san_ops_v1 *san_ops, struct lsm_fs_ops_v1 *fs_ops,
- struct lsm_nas_ops_v1 *nas_ops, struct lsm_ops_v1_2 *ops_v1_2);
-
-/**
- * Used to retrieve private data for plug-in operation.
- * @param plug Opaque plug-in pointer.
- */
-void LSM_DLL_EXPORT *lsm_private_data_get( lsm_plugin_ptr plug );
-
-
-/**
- * Logs an error with the plug-in
- * @param plug Plug-in pointer
- * @param code Error code to return
- * @param msg String message
- * @return returns code
- */
-int LSM_DLL_EXPORT lsm_log_error_basic( lsm_plugin_ptr plug, lsm_error_number code,
- const char* msg );
-
-/**
- * Return an error with the plug-in
- * @param plug Opaque plug-in
- * @param error Error to associate.
- * @return LSM_ERR_OK, else error reason.
- */
-int LSM_DLL_EXPORT lsm_plugin_error_log( lsm_plugin_ptr plug, lsm_error_ptr error);
-
-/**
- * Creates an error record.
- * @param code
- * @param msg
- * @param exception
- * @param debug
- * @param debug_data
- * @param debug_data_size
- * @return Null on error, else valid error error record.
- */
-lsm_error_ptr LSM_DLL_EXPORT lsm_error_create(lsm_error_number code, const char* msg,
- const char *exception, const char *debug,
- const void *debug_data, uint32_t debug_data_size);
-
-
-/**
- * Plug-in macros for creating errors
- */
-#define LSM_ERROR_CREATE_PLUGIN_MSG( code, msg ) \
- lsm_error_create(code, msg, NULL, NULL, NULL, 0)
-
-#define LSM_ERROR_CREATE_PLUGIN_EXCEPTION( code, msg, exception) \
- lsm_error_create((code), (msg), (exception), NULL, NULL, 0)
-
-#define LSM_ERROR_CREATE_PLUGIN_DEBUG( code, msg, exception, debug, debug_data, debug_len) \
- lsm_error_create((code), (msg), (exception), (debug), (debug_data), debug_len))
-
-/**
- * Helper function to create an array of lsm_pool *
- * @param size Number of elements
- * @return Valid pointer or NULL on error.
- */
-lsm_pool LSM_DLL_EXPORT **lsm_pool_record_array_alloc( uint32_t size );
-
-/**
- * Used to set the free space on a pool record
- * @param p Pool to modify
- * @param free_space New free space value
- */
-void LSM_DLL_EXPORT lsm_pool_free_space_set(lsm_pool *p, uint64_t free_space);
-
-/**
- * Helper function to allocate a pool record.
- * @param id System unique identifier
- * @param name Human readable name
- * @param element_type A bit field which states what the pool can be used to
- * create
- * @param unsupported_actions Things you cannot do with this pool
- * @param total_space Total space
- * @param free_space Space available
- * @param status Pool status, bit field (See LSM_POOL_STATUS_XXXX constants)
- * @param status_info Additional textual information on status
- * @param system_id System id
- * @param plugin_data Reserved for plugin writer use
- * @return LSM_ERR_OK on success, else error reason.
- */
-lsm_pool LSM_DLL_EXPORT *lsm_pool_record_alloc(const char *id, const char *name,
- uint64_t element_type,
- uint64_t unsupported_actions,
- uint64_t total_space,
- uint64_t free_space,
- uint64_t status, const char* status_info,
- const char *system_id,
- const char * plugin_data);
-
-/**
- * Used to retrieve the plugin-private data for a specfic pool
- * @param p Pool to retrieve plugin private data for
- * @return NULL if donesn't exists, else data.
- */
-const char LSM_DLL_EXPORT *lsm_pool_plugin_data_get(lsm_pool *p);
-
-/**
- * Allocate the storage needed for and array of Volume records.
- * @param size Number of elements.
- * @return Allocated memory or NULL on error.
- */
-lsm_volume LSM_DLL_EXPORT **lsm_volume_record_array_alloc( uint32_t size);
-
-
-/**
- * Allocate the storage needed for tan array of disk records.
- * @param size Number of elements
- * @return Allocated memory or null on error.
- */
-lsm_disk LSM_DLL_EXPORT **lsm_disk_record_array_alloc( uint32_t size );
-
-
-/**
- * Allocate a disk record.
- * @param id Identification
- * @param name Human readable name
- * @param disk_type Enumerated disk type
- * @param block_size Number of bytes per logical block
- * @param block_count Number of blocks for disk
- * @param disk_status Status
- * @param system_id System id this disk resides in
- * @return Pointer to allocated disk record or NULL on memory error.
- */
-lsm_disk LSM_DLL_EXPORT *lsm_disk_record_alloc(const char *id, const char *name,
- lsm_disk_type disk_type, uint64_t block_size, uint64_t block_count,
- uint64_t disk_status, const char *system_id);
-
-/**
- * Allocated the storage needed for one volume record.
- * @param id ID
- * @param name Name
- * @param vpd83 SCSI vpd 83 id
- * @param block_size Volume block size
- * @param number_of_blocks Volume number of blocks
- * @param status Volume status
- * @param system_id System id
- * @param pool_id Pool id this volume is created from
- * @param plugin_data Private data for plugin use
- * @return Allocated memory or NULL on error.
- */
-lsm_volume LSM_DLL_EXPORT *lsm_volume_record_alloc(const char *id,
- const char *name, const char *vpd83,
- uint64_t block_size,
- uint64_t number_of_blocks,
- uint32_t status,
- const char *system_id,
- const char *pool_id,
- const char* plugin_data);
-
-/**
- * Retrieve the private plug-in data from the volume record.
- * @param v Volume pointer
- * @return Private data, else NULL if it doesn't exist.
- */
-const char LSM_DLL_EXPORT *lsm_volume_plugin_data_get( lsm_volume *v);
-
-/**
- * Allocate the storage needed for and array of System records.
- * @param size Number of elements.
- * @return Allocated memory or NULL on error.
- */
-lsm_system LSM_DLL_EXPORT **lsm_system_record_array_alloc( uint32_t size );
-
-/**
- * Allocates the storage for one system record.
- * @param[in] id Id
- * @param[in] name System name (human readable)
- * @param[in] status Status of the system
- * @param[in] status_info Additional text for status
- * @param[in] plugin_data Private plugin data
- * @return Allocated memory or NULL on error.
- */
-lsm_system LSM_DLL_EXPORT *lsm_system_record_alloc(const char *id,
- const char *name,
- uint32_t status,
- const char *status_info,
- const char* plugin_data);
-
-/**
- * Retrieve plugin private data
- * @param s System
- * @return Optional data, NULL if none exist
- */
-const char LSM_DLL_EXPORT *lsm_system_plugin_data_get( lsm_system *s);
-
-/**
- * Allocates storage for Access_group array
- * @param size Number of elements to store.
- * @return NULL on error, else pointer to array for use.
- */
-lsm_access_group LSM_DLL_EXPORT **lsm_access_group_record_array_alloc( uint32_t size);
-
-
-/**
- * Allocates storage for single Access_group
- * @param id ID of access group
- * @param name Name of access group
- * @param initiators List of initiators, can be NULL
- * @param init_type Initiator group type
- * @param system_id System id
- * @param plugin_data Reserved for plug-in use only
- * @return NULL on error, else valid lsm_access_group pointer.
- */
-lsm_access_group LSM_DLL_EXPORT * lsm_access_group_record_alloc(const char *id,
- const char *name,
- lsm_string_list *initiators,
- lsm_access_group_init_type init_type,
- const char *system_id,
- const char *plugin_data);
-
-
-/**
- * Use to change the list of initiators associated with an access group.
- * @param group Access group to change initiators for
- * @param il String list of initiators.
- */
-void LSM_DLL_EXPORT lsm_access_group_initiator_id_set( lsm_access_group *group,
- lsm_string_list *il);
-
-/**
- * Allocates memory for a file system record
- * @param id ID of file system
- * @param name Name of file system
- * @param total_space Total space
- * @param free_space Free space
- * @param pool_id Pool id
- * @param system_id System id
- * @param plugin_data Reserved for plug-in use only
- * @return lsm_fs, NULL on error
- */
-lsm_fs LSM_DLL_EXPORT *lsm_fs_record_alloc(const char *id, const char *name,
- uint64_t total_space,
- uint64_t free_space,
- const char *pool_id,
- const char *system_id,
- const char* plugin_data);
-
-/**
- * Allocates the memory for the array of file system records.
- * @param size Number of elements
- * @return Allocated memory, NULL on error
- */
-lsm_fs LSM_DLL_EXPORT **lsm_fs_record_array_alloc( uint32_t size );
-
-/**
- * Used to retrieve the plug-in private data for a specific pool
- * @param fs FS to retrieve plug-in private data for
- * @return NULL if doesn't exist, else data.
- */
-const char LSM_DLL_EXPORT *lsm_fs_plugin_data_get(lsm_fs *fs);
-
-/**
- * Allocates the memory for single snap shot record.
- * @param id ID
- * @param name Name
- * @param ts Epoch time stamp when snapshot was created
- * @param plugin_data Private plugin data
- * @return Allocated memory, NULL on error
- */
-lsm_fs_ss LSM_DLL_EXPORT *lsm_fs_ss_record_alloc(const char *id,
- const char *name,
- uint64_t ts,
- const char * plugin_data);
-
-/**
- * Allocates the memory for an array of snapshot records.
- * @param size Number of elements
- * @return Allocated memory, NULL on error
- */
-lsm_fs_ss LSM_DLL_EXPORT **lsm_fs_ss_record_array_alloc( uint32_t size );
-
-/**
- * Retrieve private data from fs_ss.
- * @param fs_ss Valid fs_ss record
- * @return Private data, else NULL
- */
-const char LSM_DLL_EXPORT *lsm_fs_ss_plugin_data_get( lsm_fs_ss *fs_ss );
-
-/**
- * Set a capability
- * @param cap Valid capability pointer
- * @param t Which capability to set
- * @param v Value of the capability
- * @return LSM_ERR_OK on success, else error reason.
- */
-int LSM_DLL_EXPORT lsm_capability_set(lsm_storage_capabilities *cap, lsm_capability_type t,
- lsm_capability_value_type v);
-
-/**
- * Sets 1 or more capabilities with the same value v
- * @param cap Valid capability pointer
- * @param v The value to set capabilities to
- * @param ... Which capabilites to set (Make sure to terminate list
- * with a -1)
- * @return LSM_ERR_OK on success, else error reason
- */
-int LSM_DLL_EXPORT lsm_capability_set_n( lsm_storage_capabilities *cap,
- lsm_capability_value_type v, ... );
-
-/**
- * Allocated storage for capabilities
- * @param value Set to NULL, used during serialization otherwise.
- * @return Allocated record, or NULL on memory allocation failure.
- */
-lsm_storage_capabilities LSM_DLL_EXPORT *lsm_capability_record_alloc(char const *value);
-
-/**
- * Convenience function for plug-in writer.
- * Note: Make sure to free returned items to prevent memory leaks.
- * @param[in] uri URI to parse
- * @param[out] scheme returned scheme
- * @param[out] user returned user
- * @param[out] server returned server
- * @param[out] port returned port
- * @param[out] path returned path
- * @param[out] query_params returned query params
- * @return LSM_ERR_OK on successful parse, else error reason.
- */
-int LSM_DLL_EXPORT lsm_uri_parse(const char *uri, char **scheme, char **user,
- char **server, int *port, char **path,
- lsm_hash **query_params);
-
-/**
- * Provides for volume filtering when an array doesn't support this natively.
- * Note: Filters in place removing and freeing those that don't match.
- * @param search_key Search field
- * @param search_value Search value
- * @param[in,out] vols Array to filter
- * @param[in,out] count Number of volumes to filter, number remain
- */
-void LSM_DLL_EXPORT lsm_plug_volume_search_filter(const char *search_key,
- const char *search_value,
- lsm_volume *vols[],
- uint32_t *count);
-
-/**
- * Provides for pool filtering when an array doesn't support this natively.
- * Note: Filters in place removing and freeing those that don't match.
- * @param search_key Search field
- * @param search_value Search value
- * @param[in,out] pools Array to filter
- * @param[in,out] count Number of pools to filter, number remain
- */
-void LSM_DLL_EXPORT lsm_plug_pool_search_filter( const char *search_key,
- const char *search_value,
- lsm_pool *pools[], uint32_t *count);
-
-/**
- * Provides for disk filtering when an array doesn't support this natively.
- * Note: Filters in place removing and freeing those that don't match.
- * @param search_key Search field
- * @param search_value Search value
- * @param[in,out] disks Array to filter
- * @param[in,out] count Number of disks to filter, number remain
- */
-void LSM_DLL_EXPORT lsm_plug_disk_search_filter(const char *search_key,
- const char *search_value,
- lsm_disk *disks[], uint32_t *count);
-
-/**
- * Provides for access group filtering when an array doesn't support this
- * natively.
- * Note: Filters in place removing and freeing those that don't match.
- * @param search_key Search field
- * @param search_value Search value
- * @param[in,out] ag Array to filter
- * @param[in,out] count Number of access groups to filter, number remain
- */
-void LSM_DLL_EXPORT lsm_plug_access_group_search_filter(const char *search_key,
- const char *search_value,
- lsm_access_group *ag[], uint32_t *count);
-
-/**
- * Provides for fs filtering when an array doesn't support this natively.
- * Note: Filters in place removing and freeing those that don't match.
- * @param search_key Search field
- * @param search_value Search value
- * @param[in,out] fs Array to filter
- * @param[in,out] count Number of file systems to filter, number remain
- */
-void LSM_DLL_EXPORT lsm_plug_fs_search_filter(const char *search_key,
- const char *search_value,
- lsm_fs *fs[], uint32_t *count);
-
-/**
- * Provides for nfs filtering when an array doesn't support this natively.
- * Note: Filters in place removing and freeing those that don't match.
- * @param search_key Search field
- * @param search_value Search value
- * @param[in,out] exports Array to filter
- * @param[in,out] count Number of nfs exports to filter, number remain
- */
-void LSM_DLL_EXPORT lsm_plug_nfs_export_search_filter(const char *search_key,
- const char *search_value,
- lsm_nfs_export *exports[],
- uint32_t *count);
-
-/**
- * Retrieve private data from nfs export record.
- * @param exp Valid nfs export record
- * @return Private data, else NULL
- */
-const char LSM_DLL_EXPORT *lsm_nfs_export_plugin_data_get( lsm_nfs_export *exp);
-
-
-/**
- * Allocate a target port
- * @param id ID of target port
- * @param port_type Port type
- * @param service_address Service address
- * @param network_address Network Address
- * @param physical_address Physical address
- * @param physical_name Physical name
- * @param system_id System ID
- * @param plugin_data Plug-in data
- * @return valid lsm_target_port, else NULL on memory allocation failure
- */
-lsm_target_port LSM_DLL_EXPORT *lsm_target_port_record_alloc(
- const char *id,
- lsm_target_port_type port_type,
- const char *service_address,
- const char *network_address,
- const char *physical_address,
- const char *physical_name,
- const char *system_id,
- const char *plugin_data);
-
-/**
- * Retrieve the plug-in private data pointer
- * @param tp Valid target port pointer
- * @return Character pointer to string, NULL on error
- */
-const char LSM_DLL_EXPORT *lsm_target_port_plugin_data_get(lsm_target_port *tp);
-
-/**
- * Allocated an array of target pointers
- * @param size Number of pointers to store
- * @return Allocated memory, NULL on allocation errors
- */
-lsm_target_port LSM_DLL_EXPORT **lsm_target_port_record_array_alloc(
- uint32_t size );
-
-
-/**
- * Provides for target port filtering when an array doesn't support this
- * natively.
- * Note: Filters in place removing and freeing those that don't match.
- * @param search_key Search field
- * @param search_value Search value
- * @param[in,out] tp Array to filter
- * @param[in,out] count Number of target ports to filter, number remain
- */
-void LSM_DLL_EXPORT lsm_plug_target_port_search_filter(const char *search_key,
- const char *search_value,
- lsm_target_port *tp[],
- uint32_t *count);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LIBSTORAGEMGMT_PLUG_INTERFACE_H */
diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt_pool.h b/c_binding/include/libstoragemgmt/libstoragemgmt_pool.h
deleted file mode 100644
index 6ddfed0..0000000
--- a/c_binding/include/libstoragemgmt/libstoragemgmt_pool.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2011-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 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#ifndef LIBSTORAGEMGMT_POOL_H
-#define LIBSTORAGEMGMT_POOL_H
-
-#include "libstoragemgmt_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Frees the memory for each of the pools and then the pool array itself.
- * @param pa Pool array to free.
- * @param size Size of the pool array.
- * @return LSM_ERR_OK on success, else error reason.
- */
-int LSM_DLL_EXPORT lsm_pool_record_array_free( lsm_pool *pa[], uint32_t size );
-
-/**
- * Frees the memory for an individual pool
- * @param p Valid pool
- * @return LSM_ERR_OK on success, else error reason.
- */
-int LSM_DLL_EXPORT lsm_pool_record_free(lsm_pool *p);
-
-/**
- * Copies a lsm_pool record
- * @param to_be_copied Record to be copied
- * @return NULL on memory exhaustion, else copy.
- */
-lsm_pool LSM_DLL_EXPORT *lsm_pool_record_copy( lsm_pool *to_be_copied);
-
-/**
- * Retrieves the name from the pool.
- * Note: Returned value is only valid as long as p is valid!.
- * @param p Pool
- * @return The name of the pool.
- */
-char LSM_DLL_EXPORT *lsm_pool_name_get( lsm_pool *p );
-
-/**
- * Retrieves the system wide unique identifier for the pool.
- * Note: Returned value is only valid as long as p is valid!.
- * @param p Pool
- * @return The System wide unique identifier.
- */
-char LSM_DLL_EXPORT *lsm_pool_id_get( lsm_pool *p );
-
-/**
- * Retrieves the total space for the pool.
- * @param p Pool
- * @return Total space of the pool.
- */
-uint64_t LSM_DLL_EXPORT lsm_pool_total_space_get( lsm_pool *p );
-
-/**
- * Retrieves the remaining free space in the pool.
- * @param p Pool
- * @return The amount of free space.
- */
-uint64_t LSM_DLL_EXPORT lsm_pool_free_space_get( lsm_pool *p );
-
-/**
- * Retrieve the status for the Pool.
- * @param s Pool to retrieve status for
- * @return Pool status which is a bit sensitive field, returns UINT64_MAX on
- * bad pool pointer.
- */
-uint64_t LSM_DLL_EXPORT lsm_pool_status_get( lsm_pool *s );
-
-/**
- * Retrieve the status info for the Pool.
- * @param s Pool to retrieve status for
- * @return Pool status info which is a character string.
- */
-const char LSM_DLL_EXPORT *lsm_pool_status_info_get( lsm_pool *s );
-
-/**
- * Retrieve the system id for the specified pool.
- * @param p Pool pointer
- * @return System ID
- */
-char LSM_DLL_EXPORT *lsm_pool_system_id_get( lsm_pool *p );
-
-/**
- * Retrieve what the pool can be used to create
- * @param p Pool pointer
- * @return Usage value
- */
-uint64_t LSM_DLL_EXPORT lsm_pool_element_type_get( lsm_pool *p );
-
-/**
- * Retrieve what the pool cannot be used for.
- * @param p Pool pointer
- * @return bitmap of actions not supported.
- */
-uint64_t LSM_DLL_EXPORT lsm_pool_unsupported_actions_get( lsm_pool *p);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LIBSTORAGEMGMT_POOL_H */
diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt_snapshot.h b/c_binding/include/libstoragemgmt/libstoragemgmt_snapshot.h
deleted file mode 100644
index 393596b..0000000
--- a/c_binding/include/libstoragemgmt/libstoragemgmt_snapshot.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2011-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 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#ifndef LSM_SNAPSHOT_H
-#define LSM_SNAPSHOT_H
-
-#include "libstoragemgmt_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Frees a file system snapshot record.
- * @param ss Snapshot record
- * @return LSM_ERR_OK on success, else error reason.
- */
-int LSM_DLL_EXPORT lsm_fs_ss_record_free(lsm_fs_ss *ss);
-
-/**
- * Copies a file system snapshot record.
- * @param source Source to copy
- * @return Copy of source record snapshot
- */
-lsm_fs_ss LSM_DLL_EXPORT *lsm_fs_ss_record_copy(lsm_fs_ss *source);
-
-/**
- * Frees an array of snapshot record.
- * @param ss An array of snapshot record pointers.
- * @param size Number of snapshot records.
- * @return LSM_ERR_OK on success, else error reason.
- */
-int LSM_DLL_EXPORT lsm_fs_ss_record_array_free(lsm_fs_ss *ss[], uint32_t size);
-
-/**
- * Returns the file system snapshot id.
- * @param ss The snapshot record
- * @return Pointer to id.
- */
-const char LSM_DLL_EXPORT *lsm_fs_ss_id_get(lsm_fs_ss *ss);
-
-/**
- * Returns the name.
- * @param ss The file system snapshot record
- * @return The Name
- */
-const char LSM_DLL_EXPORT *lsm_fs_ss_name_get(lsm_fs_ss *ss);
-
-/**
- * Returns the timestamp
- * @param ss The file system snapshot record.
- * @return The timestamp the file system snapshot was taken
- */
-uint64_t LSM_DLL_EXPORT lsm_fs_ss_time_stamp_get(lsm_fs_ss *ss);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
\ No newline at end of file
diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt_systems.h b/c_binding/include/libstoragemgmt/libstoragemgmt_systems.h
deleted file mode 100644
index 9c59062..0000000
--- a/c_binding/include/libstoragemgmt/libstoragemgmt_systems.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2011-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 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-#ifndef LIBSTORAGEMGMT_SYSTEMS_H
-#define LIBSTORAGEMGMT_SYSTEMS_H
-
-#include "libstoragemgmt_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Duplicated a system record.
- * NOTE: Make sure to free resources with a call to lsm_system_record_free
- * @param s Record to duplicate
- * @return NULL on memory allocation failure, else duplicated record.
- */
-lsm_system LSM_DLL_EXPORT *lsm_system_record_copy(lsm_system *s);
-
-
-/**
- * Frees the resources for a lsm_system
- * @param s Record to release
- * @return LSM_ERR_OK on success, else error reason.
- */
-int LSM_DLL_EXPORT lsm_system_record_free(lsm_system *s);
-
-/**
- * Frees the resources for an array for lsm_system
- * @param s Array to release memory for
- * @param size Number of elements.
- * @return LSM_ERR_OK on success, else error reason.
- * */
-int LSM_DLL_EXPORT lsm_system_record_array_free(lsm_system *s[], uint32_t size );
-
-/**
- * Retrieve the Id for the system.
- * Note: Address returned is valid until lsm_system gets freed, copy return
- * value if you need longer scope. Do not free returned string.
- * @param s System to retrieve id for.
- * @return NULL on error, else value.
- */
-const char LSM_DLL_EXPORT *lsm_system_id_get(lsm_system *s);
-
-/**
- * Retrieve the Id for the system.
- * Note: Address returned is valid until lsm_system gets freed, copy return
- * value if you need longer scope. Do not free returned string.
- * @param s System to retrieve id for.
- * @return NULL on error, else value.
- */
-const char LSM_DLL_EXPORT *lsm_system_name_get(lsm_system *s);
-
-/**
- * Retrieve the status for the system.
- * @param s System to retrieve status for
- * @return System status which is a bit sensitive field, returns UINT32_MAX on
- * bad system pointer.
- */
-uint32_t LSM_DLL_EXPORT lsm_system_status_get(lsm_system *s);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
\ No newline at end of file
diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt_targetport.h b/c_binding/include/libstoragemgmt/libstoragemgmt_targetport.h
deleted file mode 100644
index a392ed4..0000000
--- a/c_binding/include/libstoragemgmt/libstoragemgmt_targetport.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2011-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 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#ifndef LIBSTORAGEMGMT_TARGET_PORT_H
-#define LIBSTORAGEMGMT_TARGET_PORT_H
-
-#include "libstoragemgmt_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Duplicated a target port record.
- * NOTE: Make sure to free resources with a call to lsm_target_port_record_free
- * @param tp Record to duplicate
- * @return NULL on memory allocation failure, else duplicated record.
- */
-lsm_target_port LSM_DLL_EXPORT *lsm_target_port_copy(lsm_target_port *tp);
-
-
-/**
- * Frees the resources for a lsm_system
- * @param tp Record to release
- * @return LSM_ERR_OK on success, else error reason.
- */
-int LSM_DLL_EXPORT lsm_target_port_record_free(lsm_target_port *tp);
-
-/**
- * Frees the resources for an array for lsm_target_port
- * @param tp Array to release memory for
- * @param size Number of elements.
- * @return LSM_ERR_OK on success, else error reason.
- * */
-int LSM_DLL_EXPORT lsm_target_port_record_array_free(lsm_target_port *tp[],
- uint32_t size );
-
-/**
- * Returns the ID of the target port
- * @param tp lsm_target_port record
- * @return ID, NULL on error
- */
-const char LSM_DLL_EXPORT *lsm_target_port_id_get(lsm_target_port *tp);
-
-/**
- * Returns the type of target port
- * @param tp lsm_target_port record
- * @return enumerated value
- */
-lsm_target_port_type LSM_DLL_EXPORT lsm_target_port_type_get(lsm_target_port *tp);
-
-/**
- * Returns the service address
- * @param tp lsm_target_port record
- * @return Service address, NULL on error
- */
-const char LSM_DLL_EXPORT *lsm_target_port_service_address_get(lsm_target_port *tp);
-
-/**
- * Returns the network address
- * @param tp lsm_target_port record
- * @return Network address, NULL on error
- */
-const char LSM_DLL_EXPORT *lsm_target_port_network_address_get(lsm_target_port *tp);
-
-/**
- * Returns the physical address
- * @param tp lsm_target_port record
- * @return Physical address, NULL on error
- */
-const char LSM_DLL_EXPORT *lsm_target_port_physical_address_get(lsm_target_port *tp);
-
-/**
- * Returns the physical name
- * @param tp lsm_target_port record
- * @return Physical name, NULL on error
- */
-const char LSM_DLL_EXPORT *lsm_target_port_physical_name_get(lsm_target_port *tp);
-
-/**
- * Returns the system_id
- * @param tp lsm_target_port record
- * @return System id, NULL on error
- */
-const char LSM_DLL_EXPORT *lsm_target_port_system_id_get(lsm_target_port *tp);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
\ No newline at end of file
diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt_types.h b/c_binding/include/libstoragemgmt/libstoragemgmt_types.h
deleted file mode 100644
index c5607c1..0000000
--- a/c_binding/include/libstoragemgmt/libstoragemgmt_types.h
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (C) 2011-2013 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 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#ifndef LIBSTORAGEMGMT_TYPES_H
-#define LIBSTORAGEMGMT_TYPES_H
-
-
-#ifdef __cplusplus
- #define __STDC_FORMAT_MACROS
- #define __STDC_LIMIT_MACROS
-#endif
-#include <inttypes.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** @file libstoragemgmt_types.h */
-
-/* Just incase we want to change the flag to a different type */
-typedef uint64_t lsm_flag;
-
-#define LSM_CLIENT_FLAG_RSVD 0
-
-/**
- * Opaque data type for a connection.
- */
-typedef struct _lsm_connect lsm_connect;
-
-/**
- * Opaque data type for a block based storage unit
- */
-typedef struct _lsm_volume lsm_volume;
-
-/**
- * Opaque data type for a storage pool which is used as a base for Volumes etc.
- * to be created from.
- */
-typedef struct _lsm_pool lsm_pool;
-
-/**
- * Opaque data type for an initiator.
- */
-typedef struct _lsm_initiator lsm_initiator;
-
-/**
- * Opaque data type for storage capabilities.
- */
-typedef struct _lsm_storage_capabilities lsm_storage_capabilities;
-
-/**
- * Access group
- */
-typedef struct _lsm_access_group lsm_access_group;
-
-/**
- * Opaque data type for nfs exports
- */
-typedef struct _lsm_nfs_export lsm_nfs_export;
-
-/**
- * Opaque data type for block ranges (regions to replicate)
- */
-typedef struct _lsm_block_range lsm_block_range;
-
-/**
- * Opaque data type for systems.
- */
-typedef struct _lsm_system lsm_system;
-
-/**
- * Opaque data type for string collection
- */
-typedef struct _lsm_string_list lsm_string_list;
-
-/**
- * Opaque data type for file systems
- */
-typedef struct _lsm_fs lsm_fs;
-
-/**
- * Opaque data type for snapshot
- */
-typedef struct _lsm_fs_ss lsm_fs_ss;
-
-/**
- * Opaque data type for disk
- */
-typedef struct _lsm_disk lsm_disk;
-
-/**
- * Optional data type
- */
-typedef struct _lsm_hash lsm_hash;
-
-/**
- * Opaque data type for Target ports
- */
-typedef struct _lsm_target_port lsm_target_port;
-
-/**< \enum lsm_replication_type Different types of replications that can be created */
-typedef enum {
- LSM_VOLUME_REPLICATE_UNKNOWN = -1, /**< Unknown replicate */
- LSM_VOLUME_REPLICATE_CLONE = 2, /**< Space efficient copy */
- LSM_VOLUME_REPLICATE_COPY = 3, /**< Full bitwise copy */
- LSM_VOLUME_REPLICATE_MIRROR_SYNC = 4, /**< Mirrors always in sync */
- LSM_VOLUME_REPLICATE_MIRROR_ASYNC = 5 /**< Mirror partner updated with delay */
-} lsm_replication_type;
-
-/**< \enum lsm_volume_provision_type Different types of provisioning */
-typedef enum {
- LSM_VOLUME_PROVISION_UNKNOWN = -1, /**< Unknown */
- LSM_VOLUME_PROVISION_THIN = 1, /**< Thin provisioning */
- LSM_VOLUME_PROVISION_FULL = 2, /**< Thick provisioning */
- LSM_VOLUME_PROVISION_DEFAULT = 3 /**< Default provisioning */
-} lsm_volume_provision_type;
-
-/**< \enum lsm_volume_raid_type Different types of RAID */
-typedef enum {
- LSM_VOLUME_RAID_TYPE_UNKNOWN = -1,
- /**^ Unknown */
- LSM_VOLUME_RAID_TYPE_RAID0 = 0,
- /**^ Stripe */
- LSM_VOLUME_RAID_TYPE_RAID1 = 1,
- /**^ Mirror between two disks. For 4 disks or more, they are RAID10.*/
- LSM_VOLUME_RAID_TYPE_RAID3 = 3,
- /**^ Byte-level striping with dedicated parity */
- LSM_VOLUME_RAID_TYPE_RAID4 = 4,
- /**^ Block-level striping with dedicated parity */
- LSM_VOLUME_RAID_TYPE_RAID5 = 5,
- /**^ Block-level striping with distributed parity */
- LSM_VOLUME_RAID_TYPE_RAID6 = 6,
- /**^ Block-level striping with two distributed parities, aka, RAID-DP */
- LSM_VOLUME_RAID_TYPE_RAID10 = 10,
- /**^ Stripe of mirrors */
- LSM_VOLUME_RAID_TYPE_RAID15 = 15,
- /**^ Parity of mirrors */
- LSM_VOLUME_RAID_TYPE_RAID16 = 16,
- /**^ Dual parity of mirrors */
- LSM_VOLUME_RAID_TYPE_RAID50 = 50,
- /**^ Stripe of parities */
- LSM_VOLUME_RAID_TYPE_RAID60 = 60,
- /**^ Stripe of dual parities */
- LSM_VOLUME_RAID_TYPE_RAID51 = 51,
- /**^ Mirror of parities */
- LSM_VOLUME_RAID_TYPE_RAID61 = 61,
- /**^ Mirror of dual parities */
- LSM_VOLUME_RAID_TYPE_JBOD = 20,
- /**^ Just bunch of disks, no parity, no striping. */
- LSM_VOLUME_RAID_TYPE_MIXED = 21,
- /**^ This volume contains multiple RAID settings. */
- LSM_VOLUME_RAID_TYPE_OTHER = 22,
- /**^ Vendor specific RAID type */
-} lsm_volume_raid_type;
-
-#define LSM_VOLUME_STRIP_SIZE_UNKNOWN 0
-#define LSM_VOLUME_DISK_COUNT_UNKNOWN 0
-#define LSM_VOLUME_MIN_IO_SIZE_UNKNOWN 0
-#define LSM_VOLUME_OPT_IO_SIZE_UNKNOWN 0
-
-/**
- * Admin state for volume, enabled or disabled
- */
-#define LSM_VOLUME_ADMIN_STATE_ENABLED 0x1 /**< Volume accessible */
-#define LSM_VOLUME_ADMIN_STATE_DISABLED 0x0 /**< Volume unaccessible */
-
-/**
- * Different states a system status can be in.
- * Bit field, can be in multiple states at the same time.
- */
-#define LSM_SYSTEM_STATUS_UNKNOWN 0x00000001 /**< Unknown */
-#define LSM_SYSTEM_STATUS_OK 0x00000002 /**< OK */
-#define LSM_SYSTEM_STATUS_ERROR 0x00000004 /**< Error(s) exist */
-#define LSM_SYSTEM_STATUS_DEGRADED 0x00000008 /**< Degraded */
-#define LSM_SYSTEM_STATUS_PREDICTIVE_FAILURE 0x00000010 /**< System has predictive failure(s) */
-#define LSM_SYSTEM_STATUS_OTHER 0x00000020 /**< Vendor specific */
-
-
-typedef enum {
- LSM_ACCESS_GROUP_INIT_TYPE_UNKNOWN = 0, /**< Unknown */
- LSM_ACCESS_GROUP_INIT_TYPE_OTHER = 1, /**< Something not seen before */
- LSM_ACCESS_GROUP_INIT_TYPE_WWPN = 2, /**< Port name */
- LSM_ACCESS_GROUP_INIT_TYPE_ISCSI_IQN = 5, /**< ISCSI IQN */
- LSM_ACCESS_GROUP_INIT_TYPE_ISCSI_WWPN_MIXED = 7 /**< More than 1 type */
-} lsm_access_group_init_type;
-
-/**< \enum lsm_job_status Job states */
-typedef enum {
- LSM_JOB_INPROGRESS = 1, /**< Job is in progress */
- LSM_JOB_COMPLETE = 2, /**< Job is complete */
- LSM_JOB_ERROR = 3 /**< Job has errored */
-} lsm_job_status;
-
-typedef enum {
- LSM_DISK_TYPE_UNKNOWN = 0,
- LSM_DISK_TYPE_OTHER = 1,
- LSM_DISK_TYPE_ATA = 3,
- LSM_DISK_TYPE_SATA = 4,
- LSM_DISK_TYPE_SAS = 5,
- LSM_DISK_TYPE_FC = 6,
- LSM_DISK_TYPE_SOP = 7,
- LSM_DISK_TYPE_SCSI = 8,
- LSM_DISK_TYPE_LUN = 9,
- LSM_DISK_TYPE_NL_SAS = 51,
- LSM_DISK_TYPE_HDD = 52,
- LSM_DISK_TYPE_SSD = 53,
- LSM_DISK_TYPE_HYBRID = 54,
-} lsm_disk_type;
-
-
-#define LSM_DISK_STATUS_UNKNOWN 0x0000000000000001
-#define LSM_DISK_STATUS_OK 0x0000000000000002
-#define LSM_DISK_STATUS_OTHER 0x0000000000000004
-#define LSM_DISK_STATUS_PREDICTIVE_FAILURE 0x0000000000000008
-#define LSM_DISK_STATUS_ERROR 0x0000000000000010
-#define LSM_DISK_STATUS_REMOVED 0x0000000000000020
-#define LSM_DISK_STATUS_STARTING 0x0000000000000040
-#define LSM_DISK_STATUS_STOPPING 0x0000000000000080
-#define LSM_DISK_STATUS_STOPPED 0x0000000000000100
-#define LSM_DISK_STATUS_INITIALIZING 0x0000000000000200
-#define LSM_DISK_STATUS_MAINTENANCE_MODE 0x0000000000000400
-#define LSM_DISK_STATUS_SPARE_DISK 0x0000000000000800
-#define LSM_DISK_STATUS_RECONSTRUCT 0x0000000000001000
-#define LSM_DISK_STATUS_FREE 0x0000000000002000
-/**^
- * New in version 1.2, New in version 1.2, indicate the whole disk is not
- * holding any data or acting as a dedicate spare disk.
- * This disk could be assigned as a dedicated spare disk or used for creating
- * pool.
- * If any spare disk(like those on NetApp ONTAP) does not require any explicit
- * action when assigning to pool, it should be treated as free disk and marked
- * as LSM_DISK_STATUS_FREE|LSM_DISK_STATUS_SPARE_DISK.
- * */
-
-#define LSM_DISK_BLOCK_SIZE_NOT_FOUND -1
-#define LSM_DISK_BLOCK_COUNT_NOT_FOUND -1
-
-#define LSM_POOL_STATUS_UNKNOWN 0x0000000000000001
-#define LSM_POOL_STATUS_OK 0x0000000000000002
-#define LSM_POOL_STATUS_OTHER 0x0000000000000004
-#define LSM_POOL_STATUS_DEGRADED 0x0000000000000010
-#define LSM_POOL_STATUS_ERROR 0x0000000000000020
-#define LSM_POOL_STATUS_STOPPED 0x0000000000000200
-#define LSM_POOL_STATUS_RECONSTRUCTING 0x0000000000001000
-#define LSM_POOL_STATUS_VERIFYING 0x0000000000002000
-#define LSM_POOL_STATUS_INITIALIZING 0x0000000000004000
-#define LSM_POOL_STATUS_GROWING 0x0000000000008000
-
-#define LSM_POOL_ELEMENT_TYPE_POOL 0x0000000000000002
-#define LSM_POOL_ELEMENT_TYPE_VOLUME 0x0000000000000004
-#define LSM_POOL_ELEMENT_TYPE_FS 0x0000000000000008
-#define LSM_POOL_ELEMENT_TYPE_DELTA 0x0000000000000010
-#define LSM_POOL_ELEMENT_TYPE_VOLUME_FULL 0x0000000000000020
-#define LSM_POOL_ELEMENT_TYPE_VOLUME_THIN 0x0000000000000040
-#define LSM_POOL_ELEMENT_TYPE_SYS_RESERVED 0x0000000000000400
-
-#define LSM_POOL_UNSUPPORTED_VOLUME_GROW 0x0000000000000001
-#define LSM_POOL_UNSUPPORTED_VOLUME_SHRINK 0x0000000000000002
-
-typedef enum {
- LSM_TARGET_PORT_TYPE_OTHER = 1,
- LSM_TARGET_PORT_TYPE_FC = 2,
- LSM_TARGET_PORT_TYPE_FCOE = 3,
- LSM_TARGET_PORT_TYPE_ISCSI = 4
-} lsm_target_port_type;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LIBSTORAGEMGMT_TYPES_H */
diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt_version.h.in b/c_binding/include/libstoragemgmt/libstoragemgmt_version.h.in
deleted file mode 100644
index 1321ead..0000000
--- a/c_binding/include/libstoragemgmt/libstoragemgmt_version.h.in
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2011-2013 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 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#ifndef LSM_VERSION_H_
-#define LSM_VERSION_H_
-
-#define LSM_MAJOR @LIBSM_MAJOR_VERSION@
-#define LSM_MINOR @LIBSM_MINOR_VERSION@
-#define LSM_MICRO @LIBSM_MICRO_VERSION@
-
-#define LSM_VERSION ((LSM_MAJOR * 10000) + (LSM_MINOR * 100) + LSM_MICRO)
-
-#endif
diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt_volumes.h b/c_binding/include/libstoragemgmt/libstoragemgmt_volumes.h
deleted file mode 100644
index ee03010..0000000
--- a/c_binding/include/libstoragemgmt/libstoragemgmt_volumes.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2011-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 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#ifndef LIBSTORAGEMGMT_VOLUMES_H
-#define LIBSTORAGEMGMT_VOLUMES_H
-
-#include "libstoragemgmt_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Frees the memory fro an individual volume
- * @param v Volume pointer to free.
- * @return LSM_ERR_OK on success, else error reason.
- */
-int LSM_DLL_EXPORT lsm_volume_record_free(lsm_volume *v);
-
-/**
- * Copies a volume record structure.
- * @param vol Volume record to be copied.
- * @return NULL on error, else record copy.
- */
-lsm_volume LSM_DLL_EXPORT *lsm_volume_record_copy(lsm_volume *vol);
-
-/**
- * Frees the memory for each of the volume records and then the array itself.
- * @param init Array to free.
- * @param size Size of array.
- * @return LSM_ERR_OK on success, else error reason.
- */
-int LSM_DLL_EXPORT lsm_volume_record_array_free( lsm_volume *init[], uint32_t size);
-
-/**
- * Retrieves the volume id.
- * Note: returned value only valid when v is valid!
- * @param v Volume ptr.
- * @return Volume id.
- */
-const char LSM_DLL_EXPORT *lsm_volume_id_get(lsm_volume *v);
-
-/**
- * Retrieves the volume name (human recognizable)
- * Note: returned value only valid when v is valid!
- * @param v Volume ptr.
- * @return Volume name
- */
-const char LSM_DLL_EXPORT *lsm_volume_name_get(lsm_volume *v);
-
-/**
- * Retrieves the SCSI page 83 unique ID.
- * Note: returned value only valid when v is valid!
- * @param v Volume ptr.
- * @return SCSI page 83 unique ID.
- */
-const char LSM_DLL_EXPORT *lsm_volume_vpd83_get(lsm_volume *v);
-
-/**
- * Retrieves the volume block size.
- * @param v Volume ptr.
- * @return Volume block size.
- */
-uint64_t LSM_DLL_EXPORT lsm_volume_block_size_get(lsm_volume *v);
-
-/**
- * Retrieves the number of blocks.
- * @param v Volume ptr.
- * @return Number of blocks.
- */
-uint64_t LSM_DLL_EXPORT lsm_volume_number_of_blocks_get(lsm_volume *v);
-
-/**
- * Retrieves the admin state of the volume.
- * @param v Volume ptr.
- * @return Admin state of volume, see LSM_VOLUME_ADMIN_STATE_ENABLED and
- * LSM_VOLUME_ADMIN_STATE_DISABLED
- *
- */
-uint32_t LSM_DLL_EXPORT lsm_volume_admin_state_get(lsm_volume *v);
-
-/**
- * Retrieves the system id of the volume.
- * @param v Volume ptr.
- * @return System id.
- */
-char LSM_DLL_EXPORT *lsm_volume_system_id_get( lsm_volume *v);
-
-/**
- * Retrieves the pool id that the volume is derived from.
- * @param v Volume ptr.
- * @return Pool id.
- */
-char LSM_DLL_EXPORT *lsm_volume_pool_id_get( lsm_volume *v);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LIBSTORAGEMGMT_VOLUMES_H */
diff --git a/c_binding/lsm_convert.cpp b/c_binding/lsm_convert.cpp
deleted file mode 100644
index 7baf2e6..0000000
--- a/c_binding/lsm_convert.cpp
+++ /dev/null
@@ -1,619 +0,0 @@
-/*
- * Copyright (C) 2011-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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#include "lsm_convert.hpp"
-#include "libstoragemgmt/libstoragemgmt_accessgroups.h"
-#include "libstoragemgmt/libstoragemgmt_blockrange.h"
-#include "libstoragemgmt/libstoragemgmt_nfsexport.h"
-
-bool is_expected_object(Value &obj, std::string class_name)
-{
- if (obj.valueType() == Value::object_t) {
- std::map<std::string, Value> i = obj.asObject();
- std::map<std::string, Value>::iterator iter = i.find("class");
- if (iter != i.end() && iter->second.asString() == class_name) {
- return true;
- }
- }
- return false;
-}
-
-lsm_volume *value_to_volume(Value &vol)
-{
- lsm_volume *rc = NULL;
-
- if (is_expected_object(vol, CLASS_NAME_VOLUME)) {
- std::map<std::string, Value> v = vol.asObject();
-
- rc = lsm_volume_record_alloc(v["id"].asString().c_str(),
- v["name"].asString().c_str(),
- v["vpd83"].asString().c_str(),
- v["block_size"].asUint64_t(),
- v["num_of_blocks"].asUint64_t(),
- v["admin_state"].asUint32_t(),
- v["system_id"].asString().c_str(),
- v["pool_id"].asString().c_str(),
- v["plugin_data"].asC_str());
- }
-
- return rc;
-}
-
-Value volume_to_value(lsm_volume *vol)
-{
- if( LSM_IS_VOL(vol) ) {
- std::map<std::string, Value> v;
- v["class"] = Value(CLASS_NAME_VOLUME);
- v["id"] = Value(vol->id);
- v["name"] = Value(vol->name);
- v["vpd83"] = Value(vol->vpd83);
- v["block_size"] = Value(vol->block_size);
- v["num_of_blocks"] = Value(vol->number_of_blocks);
- v["admin_state"] = Value(vol->admin_state);
- v["system_id"] = Value(vol->system_id);
- v["pool_id"] = Value(vol->pool_id);
- v["plugin_data"] = Value(vol->plugin_data);
- return Value(v);
- }
- return Value();
-}
-
-int value_array_to_volumes(Value &volume_values, lsm_volume **volumes[],
- uint32_t *count)
-{
- int rc = LSM_ERR_OK;
- try {
- *count = 0;
-
- if( Value::array_t == volume_values.valueType()) {
- std::vector<Value> vol = volume_values.asArray();
-
- *count = vol.size();
-
- if( vol.size() ) {
- *volumes = lsm_volume_record_array_alloc(vol.size());
-
- if( *volumes ){
- for( size_t i = 0; i < vol.size(); ++i ) {
- (*volumes)[i] = value_to_volume(vol[i]);
- }
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
- }
- }
- } catch( const ValueException &ve) {
- if( *volumes && *count ) {
- lsm_volume_record_array_free(*volumes, *count);
- *volumes = NULL;
- *count = 0;
- }
-
- rc = LSM_ERR_LIB_BUG;
- }
- return rc;
-}
-
-lsm_disk *value_to_disk(Value &disk)
-{
- lsm_disk *rc = NULL;
- if (is_expected_object(disk, CLASS_NAME_DISK)) {
- std::map<std::string, Value> d = disk.asObject();
-
- rc = lsm_disk_record_alloc(d["id"].asString().c_str(),
- d["name"].asString().c_str(),
- (lsm_disk_type)d["disk_type"].asInt32_t(),
- d["block_size"].asUint64_t(),
- d["num_of_blocks"].asUint64_t(),
- d["status"].asUint64_t(),
- d["system_id"].asString().c_str()
- );
- }
- return rc;
-}
-
-
-Value disk_to_value(lsm_disk *disk)
-{
- if ( LSM_IS_DISK(disk) ) {
- std::map<std::string, Value> d;
- d["class"] = Value(CLASS_NAME_DISK);
- d["id"] = Value(disk->id);
- d["name"] = Value(disk->name);
- d["disk_type"] = Value(disk->disk_type);
- d["block_size"] = Value(disk->block_size);
- d["num_of_blocks"] = Value(disk->block_count);
- d["status"] = Value(disk->disk_status);
- d["system_id"] = Value(disk->system_id);
-
- return Value(d);
- }
- return Value();
-}
-
-int value_array_to_disks(Value &disk_values, lsm_disk **disks[], uint32_t *count)
-{
- int rc = LSM_ERR_OK;
- try {
- *count = 0;
-
- if( Value::array_t == disk_values.valueType()) {
- std::vector<Value> d = disk_values.asArray();
-
- *count = d.size();
-
- if( d.size() ) {
- *disks = lsm_disk_record_array_alloc(d.size());
-
- if( *disks ){
- for( size_t i = 0; i < d.size(); ++i ) {
- (*disks)[i] = value_to_disk(d[i]);
- }
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
- }
- }
- } catch( const ValueException &ve ) {
- rc = LSM_ERR_LIB_BUG;
- if( *disks && *count ) {
- lsm_disk_record_array_free(*disks, *count);
- *disks = NULL;
- *count = 0;
- }
- }
- return rc;
-}
-
-lsm_pool *value_to_pool(Value &pool)
-{
- lsm_pool *rc = NULL;
-
- if (is_expected_object(pool, CLASS_NAME_POOL)) {
- std::map<std::string, Value> i = pool.asObject();
-
- rc = lsm_pool_record_alloc(i["id"].asString().c_str(),
- i["name"].asString().c_str(),
- i["element_type"].asUint64_t(),
- i["unsupported_actions"].asUint64_t(),
- i["total_space"].asUint64_t(),
- i["free_space"].asUint64_t(),
- i["status"].asUint64_t(),
- i["status_info"].asString().c_str(),
- i["system_id"].asString().c_str(),
- i["plugin_data"].asC_str());
- }
- return rc;
-}
-
-Value pool_to_value(lsm_pool *pool)
-{
- if( LSM_IS_POOL(pool) ) {
- std::map<std::string, Value> p;
- p["class"] = Value(CLASS_NAME_POOL);
- p["id"] = Value(pool->id);
- p["name"] = Value(pool->name);
- p["element_type"] = Value(pool->element_type);
- p["unsupported_actions"] = Value(pool->unsupported_actions);
- p["total_space"] = Value(pool->total_space);
- p["free_space"] = Value(pool->free_space);
- p["status"] = Value(pool->status);
- p["status_info"] = Value(pool->status_info);
- p["system_id"] = Value(pool->system_id);
- p["plugin_data"] = Value(pool->plugin_data);
- return Value(p);
- }
- return Value();
-}
-
-lsm_system *value_to_system(Value &system)
-{
- lsm_system *rc = NULL;
- if (is_expected_object(system, CLASS_NAME_SYSTEM)) {
- std::map<std::string, Value> i = system.asObject();
-
- rc = lsm_system_record_alloc(i["id"].asString().c_str(),
- i["name"].asString().c_str(),
- i["status"].asUint32_t(),
- i["status_info"].asString().c_str(),
- i["plugin_data"].asC_str());
- }
- return rc;
-}
-
-Value system_to_value(lsm_system *system)
-{
- if( LSM_IS_SYSTEM(system)) {
- std::map<std::string, Value> s;
- s["class"] = Value(CLASS_NAME_SYSTEM);
- s["id"] = Value(system->id);
- s["name"] = Value(system->name);
- s["status"] = Value(system->status);
- s["status_info"] = Value(system->status_info);
- s["plugin_data"] = Value(system->plugin_data);
- return Value(s);
- }
- return Value();
-}
-
-lsm_string_list *value_to_string_list(Value &v)
-{
- lsm_string_list *il = NULL;
-
- if( Value::array_t == v.valueType() ) {
- std::vector<Value> vl = v.asArray();
- uint32_t size = vl.size();
- il = lsm_string_list_alloc(size);
-
- if( il ) {
- for( uint32_t i = 0; i < size; ++i ) {
- if(LSM_ERR_OK != lsm_string_list_elem_set(il, i, vl[i].asC_str())){
- lsm_string_list_free(il);
- il = NULL;
- break;
- }
- }
- }
- }
- return il;
-}
-
-Value string_list_to_value( lsm_string_list *sl)
-{
- std::vector<Value> rc;
- if( LSM_IS_STRING_LIST(sl) ) {
- uint32_t size = lsm_string_list_size(sl);
-
- for(uint32_t i = 0; i < size; ++i ) {
- rc.push_back(Value(lsm_string_list_elem_get(sl, i)));
- }
- }
- return Value(rc);
-}
-
-lsm_access_group *value_to_access_group( Value &group )
-{
- lsm_string_list *il = NULL;
- lsm_access_group *ag = NULL;
-
- if( is_expected_object(group, CLASS_NAME_ACCESS_GROUP)) {
- std::map<std::string, Value> vAg = group.asObject();
- il = value_to_string_list(vAg["init_ids"]);
-
- if( il ) {
- ag = lsm_access_group_record_alloc(vAg["id"].asString().c_str(),
- vAg["name"].asString().c_str(),
- il,
- (lsm_access_group_init_type)vAg["init_type"].asInt32_t(),
- vAg["system_id"].asString().c_str(),
- vAg["plugin_data"].asC_str());
- }
- /* This stuff is copied in lsm_access_group_record_alloc */
- lsm_string_list_free(il);
- }
- return ag;
-}
-
-Value access_group_to_value( lsm_access_group *group )
-{
- if( LSM_IS_ACCESS_GROUP(group) ) {
- std::map<std::string, Value> ag;
- ag["class"] = Value(CLASS_NAME_ACCESS_GROUP);
- ag["id"] = Value(group->id);
- ag["name"] = Value(group->name);
- ag["init_ids"] = Value(string_list_to_value(group->initiators));
- ag["init_type"] = Value(group->init_type);
- ag["system_id"] = Value(group->system_id);
- ag["plugin_data"] = Value(group->plugin_data);
- return Value(ag);
- }
- return Value();
-}
-
-lsm_access_group **value_to_access_group_list( Value &group, uint32_t *count )
-{
- lsm_access_group **rc = NULL;
- std::vector<Value> ag = group.asArray();
-
- *count = ag.size();
-
- if( *count ) {
- rc = lsm_access_group_record_array_alloc(*count);
- if( rc ) {
- uint32_t i;
- for(i = 0; i < *count; ++i ) {
- rc[i] = value_to_access_group(ag[i]);
- if( !rc[i] ) {
- lsm_access_group_record_array_free(rc, i);
- rc = NULL;
- break;
- }
- }
- }
- }
- return rc;
-}
-
-Value access_group_list_to_value( lsm_access_group **group, uint32_t count)
-{
- std::vector<Value> rc;
-
- if( group && count ) {
- uint32_t i;
- for( i = 0; i < count; ++i ) {
- rc.push_back(access_group_to_value(group[i]));
- }
- }
- return Value(rc);
-}
-
-lsm_block_range *value_to_block_range(Value &br)
-{
- lsm_block_range *rc = NULL;
- if( is_expected_object(br, CLASS_NAME_BLOCK_RANGE) ) {
- std::map<std::string, Value> range = br.asObject();
-
- rc = lsm_block_range_record_alloc(range["src_block"].asUint64_t(),
- range["dest_block"].asUint64_t(),
- range["block_count"].asUint64_t());
- }
- return rc;
-}
-
-Value block_range_to_value(lsm_block_range *br)
-{
- if( LSM_IS_BLOCK_RANGE(br) ) {
- std::map<std::string, Value> r;
- r["class"] = Value(CLASS_NAME_BLOCK_RANGE);
- r["src_block"] = Value(br->source_start);
- r["dest_block"] = Value(br->dest_start);
- r["block_count"] = Value(br->block_count);
- return Value(r);
- }
- return Value();
-}
-
-lsm_block_range **value_to_block_range_list(Value &brl, uint32_t *count)
-{
- lsm_block_range **rc = NULL;
- std::vector<Value> r = brl.asArray();
- *count = r.size();
- if( *count ) {
- rc = lsm_block_range_record_array_alloc(*count);
- if( rc ) {
- for( uint32_t i = 0; i < *count; ++i ) {
- rc[i] = value_to_block_range(r[i]);
- if( !rc[i] ) {
- lsm_block_range_record_array_free(rc, i);
- rc = NULL;
- break;
- }
- }
- }
- }
- return rc;
-}
-
-Value block_range_list_to_value( lsm_block_range **brl, uint32_t count )
-{
- std::vector<Value> r;
- if( brl && count) {
- uint32_t i = 0;
- for( i = 0; i < count; ++i ) {
- r.push_back(block_range_to_value(brl[i]));
- }
- }
- return Value(r);
-}
-
-lsm_fs *value_to_fs(Value &fs)
-{
- lsm_fs *rc = NULL;
- if( is_expected_object(fs, CLASS_NAME_FILE_SYSTEM) ) {
- std::map<std::string, Value> f = fs.asObject();
-
- rc = lsm_fs_record_alloc(f["id"].asString().c_str(),
- f["name"].asString().c_str(),
- f["total_space"].asUint64_t(),
- f["free_space"].asUint64_t(),
- f["pool_id"].asString().c_str(),
- f["system_id"].asString().c_str(),
- f["plugin_data"].asC_str());
- }
- return rc;
-}
-
-Value fs_to_value(lsm_fs *fs)
-{
- if( LSM_IS_FS(fs) ) {
- std::map<std::string, Value> f;
- f["class"] = Value(CLASS_NAME_FILE_SYSTEM);
- f["id"] = Value(fs->id);
- f["name"] = Value(fs->name);
- f["total_space"] = Value(fs->total_space);
- f["free_space"] = Value(fs->free_space);
- f["pool_id"] = Value(fs->pool_id);
- f["system_id"] = Value(fs->system_id);
- f["plugin_data"] = Value(fs->plugin_data);
- return Value(f);
- }
- return Value();
-}
-
-
-lsm_fs_ss *value_to_ss(Value &ss)
-{
- lsm_fs_ss *rc = NULL;
- if( is_expected_object(ss, CLASS_NAME_FS_SNAPSHOT) ) {
- std::map<std::string, Value> f = ss.asObject();
-
- rc = lsm_fs_ss_record_alloc(f["id"].asString().c_str(),
- f["name"].asString().c_str(),
- f["ts"].asUint64_t(),
- f["plugin_data"].asC_str());
- }
- return rc;
-}
-
-Value ss_to_value(lsm_fs_ss *ss)
-{
- if( LSM_IS_SS(ss) ) {
- std::map<std::string, Value> f;
- f["class"] = Value(CLASS_NAME_FS_SNAPSHOT);
- f["id"] = Value(ss->id);
- f["name"] = Value(ss->name);
- f["ts"] = Value(ss->ts);
- f["plugin_data"] = Value(ss->plugin_data);
- return Value(f);
- }
- return Value();
-}
-
-lsm_nfs_export *value_to_nfs_export(Value &exp)
-{
- lsm_nfs_export *rc = NULL;
- if( is_expected_object(exp, CLASS_NAME_FS_EXPORT) ) {
- int ok = 0;
- lsm_string_list *root = NULL;
- lsm_string_list *rw = NULL;
- lsm_string_list *ro = NULL;
-
- std::map<std::string, Value> i = exp.asObject();
-
- /* Check all the arrays for successful allocation */
- root = value_to_string_list(i["root"]);
- if( root ) {
- rw = value_to_string_list(i["rw"]);
- if( rw ) {
- ro = value_to_string_list(i["ro"]);
- if( !ro ) {
- lsm_string_list_free(rw);
- lsm_string_list_free(root);
- rw = NULL;
- root = NULL;
- } else {
- ok = 1;
- }
- } else {
- lsm_string_list_free(root);
- root = NULL;
- }
- }
-
- if( ok ) {
- rc = lsm_nfs_export_record_alloc(i["id"].asC_str(),
- i["fs_id"].asC_str(),
- i["export_path"].asC_str(),
- i["auth"].asC_str(),
- root,
- rw,
- ro,
- i["anonuid"].asUint64_t(),
- i["anongid"].asUint64_t(),
- i["options"].asC_str(),
- i["plugin_data"].asC_str());
-
- lsm_string_list_free(root);
- lsm_string_list_free(rw);
- lsm_string_list_free(ro);
- }
- }
- return rc;
-}
-
-Value nfs_export_to_value(lsm_nfs_export *exp)
-{
- if( LSM_IS_NFS_EXPORT(exp) ) {
- std::map<std::string, Value> f;
- f["class"] = Value(CLASS_NAME_FS_EXPORT);
- f["id"] = Value(exp->id);
- f["fs_id"] = Value(exp->fs_id);
- f["export_path"] = Value(exp->export_path);
- f["auth"] = Value(exp->auth_type);
- f["root"] = Value(string_list_to_value(exp->root));
- f["rw"] = Value(string_list_to_value(exp->rw));
- f["ro"] = Value(string_list_to_value(exp->ro));
- f["anonuid"] = Value(exp->anonuid);
- f["anongid"] = Value(exp->anongid);
- f["options"] = Value(exp->options);
- f["plugin_data"] = Value(exp->plugin_data);
- return Value(f);
- }
- return Value();
-
-}
-
-lsm_storage_capabilities *value_to_capabilities(Value &exp)
-{
- lsm_storage_capabilities *rc = NULL;
- if( is_expected_object(exp, CLASS_NAME_CAPABILITIES) ) {
- const char *val = exp["cap"].asC_str();
- rc = lsm_capability_record_alloc(val);
- }
- return rc;
-}
-
-Value capabilities_to_value(lsm_storage_capabilities *cap)
-{
- if( LSM_IS_CAPABILITIY(cap) ) {
- std::map<std::string, Value> c;
- char *t = capability_string(cap);
- c["class"] = Value(CLASS_NAME_CAPABILITIES);
- c["cap"] = Value(t);
- free(t);
- return Value(c);
- }
- return Value();
-}
-
-
-lsm_target_port *value_to_target_port(Value &tp)
-{
- lsm_target_port *rc = NULL;
- if( is_expected_object(tp, CLASS_NAME_TARGET_PORT) ) {
- rc = lsm_target_port_record_alloc(
- tp["id"].asC_str(),
- (lsm_target_port_type)tp["port_type"].asInt32_t(),
- tp["service_address"].asC_str(),
- tp["network_address"].asC_str(),
- tp["physical_address"].asC_str(),
- tp["physical_name"].asC_str(),
- tp["system_id"].asC_str(),
- tp["plugin_data"].asC_str());
- }
- return rc;
-}
-
-Value target_port_to_value(lsm_target_port *tp)
-{
- if( LSM_IS_TARGET_PORT(tp) ) {
- std::map<std::string, Value> p;
- p["class"] = Value(CLASS_NAME_TARGET_PORT);
- p["id"] = Value(tp->id);
- p["port_type"] = Value(tp->port_type);
- p["service_address"] = Value(tp->service_address);
- p["network_address"] = Value(tp->network_address);
- p["physical_address"] = Value(tp->physical_address);
- p["physical_name"] = Value(tp->physical_name);
- p["system_id"] = Value(tp->system_id);
- p["plugin_data"] = Value(tp->plugin_data);
- return Value(p);
- }
- return Value();
-}
diff --git a/c_binding/lsm_convert.hpp b/c_binding/lsm_convert.hpp
deleted file mode 100644
index fe1e91d..0000000
--- a/c_binding/lsm_convert.hpp
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (C) 2011-2013 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#ifndef LSM_CONVERT_HPP
-#define LSM_CONVERT_HPP
-
-#include "lsm_datatypes.hpp"
-#include "lsm_ipc.hpp"
-
-/**
- * Class names for serialized json
- */
-const char CLASS_NAME_SYSTEM[] = "System";
-const char CLASS_NAME_POOL[] = "Pool";
-const char CLASS_NAME_VOLUME[] = "Volume";
-const char CLASS_NAME_BLOCK_RANGE[] = "BlockRange";
-const char CLASS_NAME_ACCESS_GROUP[] = "AccessGroup";
-const char CLASS_NAME_FILE_SYSTEM[] = "FileSystem";
-const char CLASS_NAME_DISK[] = "Disk";
-const char CLASS_NAME_FS_SNAPSHOT[] = "FsSnapshot";
-const char CLASS_NAME_FS_EXPORT[] = "NfsExport";
-const char CLASS_NAME_CAPABILITIES[] = "Capabilities";
-const char CLASS_NAME_TARGET_PORT[] = "TargetPort";
-
-
-#define IS_CLASS(x, name) is_expected_object(x, name)
-
-#define IS_CLASS_SYSTEM(x) IS_CLASS(x, CLASS_NAME_SYSTEM)
-#define IS_CLASS_POOL(x) IS_CLASS(x, CLASS_NAME_POOL)
-#define IS_CLASS_VOLUME(x) IS_CLASS(x, CLASS_NAME_VOLUME)
-#define IS_CLASS_BLOCK_RANGE(x) IS_CLASS(x, CLASS_NAME_BLOCK_RANGE)
-#define IS_CLASS_ACCESS_GROUP(x) IS_CLASS(x, CLASS_NAME_ACCESS_GROUP)
-#define IS_CLASS_FILE_SYSTEM(x) IS_CLASS(x, CLASS_NAME_FILE_SYSTEM)
-
-
-
-/**
- * Checks to see if a value is an expected object instance
- * @param obj Value to check
- * @param class_name Class name to check
- * @return boolean, true if matches
- */
-bool LSM_DLL_LOCAL is_expected_object(Value &obj, std::string class_name);
-
-/**
- * Converts an array of Values to a lsm_string_list
- * @param list List represented as an vector of strings.
- * @return lsm_string_list pointer, NULL on error.
- */
-lsm_string_list LSM_DLL_LOCAL *value_to_string_list( Value &list);
-
-/**
- * Converts a lsm_string_list to a Value
- * @param sl String list to convert
- * @return Value
- */
-Value LSM_DLL_LOCAL string_list_to_value( lsm_string_list *sl);
-
-/**
- * Converts a volume to a volume.
- * @param vol Value to convert.
- * @return lsm_volume *, else NULL on error
- */
-lsm_volume LSM_DLL_LOCAL *value_to_volume(Value &vol);
-
-/**
- * Converts a lsm_volume * to a Value
- * @param vol lsm_volume to convert
- * @return Value
- */
-Value LSM_DLL_LOCAL volume_to_value(lsm_volume *vol);
-
-
-/**
- * Converts a vector of volume values to an array
- * @param volume_values Vector of values that represents volumes
- * @param volumes An array of volume pointers
- * @param count Number of volumes
- * @return LSM_ERR_OK on success, else error reason
- */
-int LSM_DLL_LOCAL value_array_to_volumes(Value &volume_values, lsm_volume **volumes[],
- uint32_t *count);
-
-/**
- * Converts a Value to a lsm_disk
- * @param disk Value representing a disk
- * @return lsm_disk pointer, else NULL on error
- */
-lsm_disk LSM_DLL_LOCAL *value_to_disk(Value &disk);
-
-/**
- * Converts a lsm_disk to a value
- * @param disk lsm_disk to convert to value
- * @return Value
- */
-Value LSM_DLL_LOCAL disk_to_value(lsm_disk *disk);
-
-/**
- * Converts a vector of disk values to an array.
- * @param[in] disk_values Vector of values that represents disks
- * @param[out] disks An array of disk pointers
- * @param[out] count Number of disks
- * @return LSM_ERR_OK on success, else error reason.
- */
-int LSM_DLL_LOCAL value_array_to_disks(Value &disk_values, lsm_disk **disks[],
- uint32_t *count);
-
-/**
- * Converts a value to a pool
- * @param pool To convert to lsm_pool *
- * @return lsm_pool *, else NULL on error.
- */
-lsm_pool LSM_DLL_LOCAL *value_to_pool(Value &pool);
-
-/**
- * Converts a lsm_pool * to Value
- * @param pool Pool pointer to convert
- * @return Value
- */
-Value LSM_DLL_LOCAL pool_to_value(lsm_pool *pool);
-
-/**
- * Converts a value to a system
- * @param system to convert to lsm_system *
- * @return lsm_system pointer, else NULL on error
- */
-lsm_system LSM_DLL_LOCAL *value_to_system(Value &system);
-
-/**
- * Converts a lsm_system * to a Value
- * @param system pointer to convert to Value
- * @return Value
- */
-Value LSM_DLL_LOCAL system_to_value(lsm_system *system);
-
-/**
- * Converts a Value to a lsm_access_group
- * @param group to convert to lsm_access_group*
- * @return lsm_access_group *, NULL on error
- */
-lsm_access_group LSM_DLL_LOCAL *value_to_access_group(Value &group);
-
-/**
- * Converts a lsm_access_group to a Value
- * @param group Group to convert
- * @return Value, null value type on error.
- */
-Value LSM_DLL_LOCAL access_group_to_value(lsm_access_group *group);
-
-/**
- * Converts an access group list to an array of access group pointers
- * @param[in] group Value representing a std::vector of access groups
- * @param[out] count Number of items in the returned array.
- * @return NULL on memory allocation failure, else pointer to access group
- * array.
- */
-lsm_access_group LSM_DLL_LOCAL **value_to_access_group_list( Value &group,
- uint32_t *count );
-
-/**
- * Converts an array of lsm_access_group to Value(s)
- * @param group Pointer to an array of lsm_access_group
- * @param count Number of items in array.
- * @return std::vector of Values representing access groups
- */
-Value LSM_DLL_LOCAL access_group_list_to_value( lsm_access_group **group,
- uint32_t count);
-
-/**
- * Converts a Value to a lsm_block_range
- * @param br Value representing a block range
- * @return lsm_block_range *
- */
-lsm_block_range LSM_DLL_LOCAL *value_to_block_range(Value &br);
-
-/**
- * Converts a lsm_block_range to a Value
- * @param br lsm_block_range to convert
- * @return Value, null value type on error
- */
-Value LSM_DLL_LOCAL block_range_to_value(lsm_block_range *br);
-
-/**
- * Converts a Value to an array of lsm_block_range
- * @param[in] brl Value representing block range(s)
- * @param[out] count Number of items in the resulting array
- * @return NULL on memory allocation failure, else array of lsm_block_range
- */
-lsm_block_range LSM_DLL_LOCAL **value_to_block_range_list(Value &brl,
- uint32_t *count);
-
-/**
- * Converts an array of lsm_block_range to Value
- * @param brl An array of lsm_block_range
- * @param count Number of items in input
- * @return Value
- */
-Value LSM_DLL_LOCAL block_range_list_to_value( lsm_block_range **brl,
- uint32_t count);
-
-/**
- * Converts a value to a lsm_fs *
- * @param fs Value representing a FS to be converted
- * @return lsm_fs pointer or NULL on error.
- */
-lsm_fs LSM_DLL_LOCAL *value_to_fs(Value &fs);
-
-/**
- * Converts a lsm_fs pointer to a Value
- * @param fs File system pointer to convert
- * @return Value
- */
-Value LSM_DLL_LOCAL fs_to_value(lsm_fs *fs);
-
-/**
- * Converts a value to a lsm_ss *
- * @param ss Value representing a snapshot to be converted
- * @return lsm_ss pointer or NULL on error.
- */
-lsm_fs_ss LSM_DLL_LOCAL *value_to_ss(Value &ss);
-
-/**
- * Converts a lsm_ss pointer to a Value
- * @param ss Snapshot pointer to convert
- * @return Value
- */
-Value LSM_DLL_LOCAL ss_to_value(lsm_fs_ss *ss);
-
-/**
- * Converts a value to a lsm_nfs_export *
- * @param exp Value representing a nfs export to be converted
- * @return lsm_nfs_export pointer or NULL on error.
- */
-lsm_nfs_export LSM_DLL_LOCAL *value_to_nfs_export(Value &exp);
-
-/**
- * Converts a lsm_nfs_export pointer to a Value
- * @param exp NFS export pointer to convert
- * @return Value
- */
-Value LSM_DLL_LOCAL nfs_export_to_value(lsm_nfs_export *exp);
-
-/**
- * Converts a Value to a lsm_storage_capabilities
- * @param exp Value representing a storage capabilities
- * @return lsm_storage_capabilities pointer or NULL on error
- */
-lsm_storage_capabilities LSM_DLL_LOCAL *value_to_capabilities(Value &exp);
-
-/**
- * Converts a lsm_storage_capabilities to a value
- * @param cap lsm_storage_capabilities to convert to value
- * @return Value
- */
-Value LSM_DLL_LOCAL capabilities_to_value(lsm_storage_capabilities *cap);
-
-/**
- * Convert a Value representation to lsm_target_port
- * @param tp Value to convert to lsm_target_port
- * @return lsm_target_port pointer or NULL on errors
- */
-lsm_target_port LSM_DLL_LOCAL *value_to_target_port(Value &tp);
-
-/**
- * Converts a lsm_target_port to a value
- * @param tp lsm_target_port to convert to value
- * @return Value
- */
-Value LSM_DLL_LOCAL target_port_to_value(lsm_target_port *tp);
-
-#endif
diff --git a/c_binding/lsm_datatypes.cpp b/c_binding/lsm_datatypes.cpp
deleted file mode 100644
index 4826a6b..0000000
--- a/c_binding/lsm_datatypes.cpp
+++ /dev/null
@@ -1,1977 +0,0 @@
-/*
- * Copyright (C) 2011-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 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#ifndef __cplusplus
-#define _GNU_SOURCE
-#endif
-
-#include <stdio.h>
-
-#include "lsm_datatypes.hpp"
-
-#include "libstoragemgmt/libstoragemgmt_accessgroups.h"
-#include "libstoragemgmt/libstoragemgmt_common.h"
-#include "libstoragemgmt/libstoragemgmt_disk.h"
-#include "libstoragemgmt/libstoragemgmt_error.h"
-#include "libstoragemgmt/libstoragemgmt_fs.h"
-#include "libstoragemgmt/libstoragemgmt_nfsexport.h"
-#include "libstoragemgmt/libstoragemgmt_plug_interface.h"
-#include "libstoragemgmt/libstoragemgmt_pool.h"
-#include "libstoragemgmt/libstoragemgmt_snapshot.h"
-#include "libstoragemgmt/libstoragemgmt_systems.h"
-#include "libstoragemgmt/libstoragemgmt_targetport.h"
-#include "libstoragemgmt/libstoragemgmt_types.h"
-#include "libstoragemgmt/libstoragemgmt_volumes.h"
-
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <dlfcn.h>
-#include <glib.h>
-#include <regex.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define LSM_DEFAULT_PLUGIN_DIR "/var/run/lsm/ipc"
-
-/* We would certainly expand this to encompass the entire function */
-#define MEMBER_GET(x, validation, member, error) \
- if( validation(x) ) { \
- return x->member; \
- } else { \
- return error; \
- }
-
-int lsm_string_list_append(lsm_string_list *sl, const char *value)
-{
- int rc = LSM_ERR_INVALID_ARGUMENT;
-
- if( LSM_IS_STRING_LIST(sl) ) {
- char *d = strdup(value);
- if(d) {
- g_ptr_array_add(sl->values, d);
- rc = LSM_ERR_OK;
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
- }
- return rc;
-}
-
-int lsm_string_list_delete(lsm_string_list *sl, uint32_t index)
-{
- int rc = LSM_ERR_INVALID_ARGUMENT;
-
- if( LSM_IS_STRING_LIST(sl) ) {
- if( index < sl->values->len ) {
- g_ptr_array_remove_index(sl->values, index);
- rc = LSM_ERR_OK;
- }
- }
- return rc;
-}
-
-
-int lsm_string_list_elem_set(lsm_string_list *sl, uint32_t index,
- const char* value)
-{
- int rc = LSM_ERR_OK;
- if( LSM_IS_STRING_LIST(sl) ) {
- if( index < sl->values->len ) {
-
- char *i = (char *)g_ptr_array_index(sl->values, index);
-
- if( i ) {
- free(i);
- }
-
- g_ptr_array_index(sl->values, index) = strdup(value);
-
- if( !g_ptr_array_index(sl->values, index) ) {
- rc = LSM_ERR_NO_MEMORY;
- }
- } else {
- g_ptr_array_set_size(sl->values, index + 1);
- g_ptr_array_index(sl->values, index) = strdup(value);
-
- if( !g_ptr_array_index(sl->values, index) ) {
- rc = LSM_ERR_NO_MEMORY;
- }
- }
- } else {
- rc = LSM_ERR_INVALID_ARGUMENT;
- }
- return rc;
-}
-
-const char *lsm_string_list_elem_get(lsm_string_list *sl, uint32_t index)
-{
- if( LSM_IS_STRING_LIST(sl) ) {
- if( index < sl->values->len ) {
- return (const char*)g_ptr_array_index(sl->values, index);
- }
- }
- return NULL;
-}
-
-lsm_string_list *lsm_string_list_alloc(uint32_t size)
-{
- lsm_string_list *rc = NULL;
-
- rc = (lsm_string_list *)malloc(sizeof(lsm_string_list));
- if( rc ) {
- rc->magic = LSM_STRING_LIST_MAGIC;
- rc->values = g_ptr_array_sized_new(size);
- if( !rc->values ) {
- rc->magic = LSM_DEL_MAGIC(LSM_STRING_LIST_MAGIC);
- free(rc);
- rc = NULL;
- } else {
- g_ptr_array_set_size(rc->values, size);
- g_ptr_array_set_free_func(rc->values, free);
- }
- }
-
- return rc;
-}
-
-int lsm_string_list_free(lsm_string_list *sl)
-{
- if( LSM_IS_STRING_LIST(sl) ) {
- sl->magic = LSM_DEL_MAGIC(LSM_STRING_LIST_MAGIC);
- g_ptr_array_free(sl->values, TRUE);
- sl->values = NULL;
- free(sl);
- return LSM_ERR_OK;
- }
- return LSM_ERR_INVALID_ARGUMENT;
-}
-
-uint32_t lsm_string_list_size(lsm_string_list *sl)
-{
- if( LSM_IS_STRING_LIST(sl) ) {
- return (uint32_t)sl->values->len;
- }
- return 0;
-}
-
-lsm_string_list *lsm_string_list_copy(lsm_string_list *src)
-{
- lsm_string_list *dest = NULL;
-
- if( LSM_IS_STRING_LIST(src) ) {
- uint32_t size = lsm_string_list_size(src);
- dest = lsm_string_list_alloc(size);
-
- if( dest ) {
- uint32_t i;
-
- for( i = 0; i < size ; ++i ) {
- if ( LSM_ERR_OK != lsm_string_list_elem_set(dest, i,
- lsm_string_list_elem_get(src, i))) {
- /** We had an allocation failure setting an element item */
- lsm_string_list_free(dest);
- dest = NULL;
- break;
- }
- }
- }
- }
- return dest;
-}
-
-lsm_connect *connection_get()
-{
- lsm_connect *c = (lsm_connect *)calloc(1, sizeof(lsm_connect));
- if (c) {
- c->magic = LSM_CONNECT_MAGIC;
- }
- return c;
-}
-
-void connection_free(lsm_connect *c)
-{
- if (LSM_IS_CONNECT(c)) {
-
- c->magic = LSM_DEL_MAGIC(LSM_CONNECT_MAGIC);
- c->flags = 0;
-
- if (c->uri) {
- xmlFreeURI(c->uri);
- c->uri = NULL;
- }
-
- if (c->error) {
- lsm_error_free(c->error);
- c->error = NULL;
- }
-
- if( c->tp ) {
- delete(c->tp);
- c->tp = NULL;
- }
-
- if( c->raw_uri ) {
- free(c->raw_uri);
- c->raw_uri = NULL;
- }
-
- free(c);
- }
-}
-
-static int connection_establish( lsm_connect *c, const char * password,
- uint32_t timeout, lsm_error_ptr *e,
- lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- std::map<std::string, Value> params;
-
- try {
- params["uri"] = Value(c->raw_uri);
-
- if( password ) {
- params["password"] = Value(password);
- } else {
- params["password"] = Value();
- }
- params["timeout"] = Value(timeout);
- params["flags"] = Value(flags);
- Value p(params);
-
- c->tp->rpc("plugin_register", p);
- } catch (const ValueException &ve) {
- *e = lsm_error_create(LSM_ERR_TRANSPORT_SERIALIZATION, "Error in serialization",
- ve.what(), NULL, NULL, 0 );
- rc = LSM_ERR_TRANSPORT_SERIALIZATION;
- } catch (const LsmException &le) {
- *e = lsm_error_create(LSM_ERR_TRANSPORT_COMMUNICATION, "Error in communication",
- le.what(), NULL, NULL, 0 );
- rc = LSM_ERR_TRANSPORT_COMMUNICATION;
- } catch (...) {
- *e = lsm_error_create(LSM_ERR_LIB_BUG, "Undefined exception",
- NULL, NULL, NULL, 0 );
- rc = LSM_ERR_LIB_BUG;
- }
- return rc;
-}
-
-const char *uds_path(void)
-{
- const char *plugin_dir = getenv("LSM_UDS_PATH");
-
- if (plugin_dir == NULL) {
- plugin_dir = LSM_DEFAULT_PLUGIN_DIR;
- }
- return plugin_dir;
-}
-
-
-int driver_load(lsm_connect *c, const char *plugin_name, const char *password,
- uint32_t timeout, lsm_error_ptr *e, int startup, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- char *plugin_file = NULL;
- const char *plugin_dir = uds_path();
-
- if (asprintf(&plugin_file, "%s/%s", plugin_dir, plugin_name) == -1) {
- return LSM_ERR_NO_MEMORY;
- }
-
- if (access(plugin_file, F_OK) != 0) {
- rc = LSM_ERR_PLUGIN_NOT_EXIST;
- } else {
- if (access(plugin_file, R_OK|W_OK) == 0) {
- int ec;
- int sd = Transport::socket_get(std::string(plugin_file), ec);
-
- if( sd >= 0 ) {
- c->tp = new Ipc(sd);
- if( startup ) {
- if( connection_establish(c, password, timeout, e, flags)) {
- rc = LSM_ERR_PLUGIN_IPC_FAIL;
- }
- }
- } else {
- *e = lsm_error_create(LSM_ERR_PLUGIN_IPC_FAIL, "Unable to connect to plugin",
- NULL, dlerror(), NULL, 0 );
-
- rc = LSM_ERR_PLUGIN_IPC_FAIL;
- }
- } else {
- *e = lsm_error_create(LSM_ERR_PLUGIN_SOCKET_PERMISSION, "Unable to access plugin",
- NULL, NULL, NULL, 0 );
-
- rc = LSM_ERR_PLUGIN_SOCKET_PERMISSION;
- }
- }
-
- free(plugin_file);
- return rc;
-}
-
-lsm_error_ptr lsm_error_create(lsm_error_number code, const char* msg,
- const char *exception, const char *debug,
- const void *debug_data, uint32_t debug_data_size)
-{
- lsm_error_ptr err = (lsm_error_ptr)calloc(1, sizeof(lsm_error));
-
- if (err) {
- err->magic = LSM_ERROR_MAGIC;
- err->code = code;
-
- /* Any of these strdup calls could fail, but we will continue*/
- if (msg) {
- err->message = strdup(msg);
- }
-
- if (exception) {
- err->exception = strdup(exception);
- }
-
- if (debug) {
- err->debug = strdup(debug);
- }
-
- /* We are not going to fail the creation of the error if we cannot
- * allocate the storage for the debug data.
- */
- if (debug_data && (debug_data_size > 0)) {
- err->debug_data = malloc(debug_data_size);
-
- if (err->debug_data) {
- err->debug_data_size = debug_data_size;
- memcpy(err->debug_data, debug_data, debug_data_size);
- }
- }
- }
- return(lsm_error_ptr) err;
-}
-
-int lsm_error_free(lsm_error_ptr e)
-{
- if (!LSM_IS_ERROR(e)) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- if (e->debug_data) {
- free(e->debug_data);
- e->debug_data = NULL;
- e->debug_data_size = 0;
- }
-
- if (e->debug) {
- free(e->debug);
- e->debug = NULL;
- }
-
- if (e->exception) {
- free(e->exception);
- e->exception = NULL;
- }
-
- if (e->message) {
- free(e->message);
- e->message = NULL;
- }
-
- e->magic = LSM_DEL_MAGIC(LSM_ERROR_MAGIC);
- free(e);
-
- return LSM_ERR_OK;
-}
-
-#define LSM_RETURN_ERR_VAL(type_t, e, x, error) \
- if( LSM_IS_ERROR(e) ) { \
- return e->x; \
- } \
- return (type_t)error; \
-
-
-lsm_error_number lsm_error_number_get(lsm_error_ptr e)
-{
- LSM_RETURN_ERR_VAL(lsm_error_number, e, code, -1);
-}
-
-char* lsm_error_message_get( lsm_error_ptr e)
-{
- LSM_RETURN_ERR_VAL(char*, e, message, NULL);
-}
-
-char* lsm_error_exception_get(lsm_error_ptr e)
-{
- LSM_RETURN_ERR_VAL(char*, e, exception, NULL);
-}
-
-char* lsm_error_debug_get(lsm_error_ptr e)
-{
- LSM_RETURN_ERR_VAL(char*, e, debug, NULL);
-}
-
-void* lsm_error_debug_data_get(lsm_error_ptr e, uint32_t *size)
-{
- if (LSM_IS_ERROR(e) && size != NULL) {
- if (e->debug_data) {
- *size = e->debug_data_size;
- return e->debug_data;
- } else {
- *size = 0;
- }
- }
- return NULL;
-}
-
-/**
- * When creating arrays of the different types the code is the same. This
- * macro is used to create type safe code.
- * @param name Name of the function
- * @param rtype return type
- * @return An array of pointers of rtype
- */
-#define CREATE_ALLOC_ARRAY_FUNC(name, rtype)\
-rtype *name(uint32_t size) \
-{ \
- rtype *rc = NULL; \
- if (size > 0) { \
- rc = (rtype *) calloc(size, sizeof(rtype)); \
- } \
- return rc; \
-}
-
-/**
- * Common macro for freeing the memory associated with one of these
- * data structures.
- * @param name Name of function to create
- * @param free_func Function to call to free one of the elements
- * @param record_type Type to record
- * @param error Value to return on error
- * @return None
- */
-#define CREATE_FREE_ARRAY_FUNC(name, free_func, record_type, error)\
-int name( record_type pa[], uint32_t size) \
-{ \
- if (pa) { \
- uint32_t i = 0; \
- for (i = 0; i < size; ++i) { \
- free_func(pa[i]); \
- } \
- free(pa); \
- return LSM_ERR_OK; \
- } \
- return error; \
-}
-
-
-CREATE_ALLOC_ARRAY_FUNC(lsm_pool_record_array_alloc, lsm_pool *)
-
-lsm_pool *lsm_pool_record_alloc(const char *id, const char *name,
- uint64_t element_type,
- uint64_t unsupported_actions,
- uint64_t totalSpace, uint64_t freeSpace, uint64_t status,
- const char* status_info,
- const char *system_id, const char * plugin_data)
-{
- lsm_pool *rc = (lsm_pool *)calloc(1, sizeof(lsm_pool));
- if (rc) {
- rc->magic = LSM_POOL_MAGIC;
- rc->id = strdup(id);
- rc->name = strdup(name);
- rc->element_type = element_type;
- rc->unsupported_actions = unsupported_actions;
- rc->total_space = totalSpace;
- rc->free_space = freeSpace;
- rc->status = status;
- rc->status_info = strdup(status_info);
- rc->system_id = strdup(system_id);
-
- if( plugin_data ) {
- rc->plugin_data = strdup(plugin_data);
- }
-
- if( !rc->id || !rc->name || !rc->system_id || !rc->status_info ||
- (plugin_data && !rc->plugin_data)) {
- lsm_pool_record_free(rc);
- rc = NULL;
- }
- }
- return rc;
-}
-
-void lsm_pool_free_space_set(lsm_pool *p, uint64_t free_space)
-{
- if( LSM_IS_POOL(p) ) {
- p->free_space = free_space;
- }
-}
-
-lsm_pool * lsm_pool_record_copy( lsm_pool *toBeCopied)
-{
- if( LSM_IS_POOL(toBeCopied) ) {
- return lsm_pool_record_alloc(toBeCopied->id, toBeCopied->name,
- toBeCopied->element_type,
- toBeCopied->unsupported_actions,
- toBeCopied->total_space,
- toBeCopied->free_space,
- toBeCopied->status,
- toBeCopied->status_info,
- toBeCopied->system_id,
- toBeCopied->plugin_data);
- }
- return NULL;
-}
-
-int lsm_pool_record_free(lsm_pool *p)
-{
- if (LSM_IS_POOL(p)) {
- p->magic = LSM_DEL_MAGIC(LSM_POOL_MAGIC);
- if (p->name) {
- free(p->name);
- p->name = NULL;
- }
-
- if( p->status_info ) {
- free(p->status_info);
- p->status_info = NULL;
- }
-
- if (p->id) {
- free(p->id);
- p->id = NULL;
- }
-
- if( p->system_id) {
- free(p->system_id);
- p->system_id = NULL;
- }
-
- free(p->plugin_data);
- p->plugin_data = NULL;
-
- free(p);
- return LSM_ERR_OK;
- }
- return LSM_ERR_INVALID_ARGUMENT;
-}
-
-CREATE_FREE_ARRAY_FUNC(lsm_pool_record_array_free, lsm_pool_record_free, lsm_pool *,
- LSM_ERR_INVALID_ARGUMENT)
-
-char *lsm_pool_name_get(lsm_pool *p)
-{
- if (LSM_IS_POOL(p)) {
- return p->name;
- }
- return NULL;
-}
-
-char *lsm_pool_id_get(lsm_pool *p)
-{
- if (LSM_IS_POOL(p)) {
- return p->id;
- }
- return NULL;
-}
-
-uint64_t lsm_pool_total_space_get(lsm_pool *p)
-{
- if (LSM_IS_POOL(p)) {
- return p->total_space;
- }
- return 0;
-}
-
-uint64_t lsm_pool_free_space_get(lsm_pool *p)
-{
- if (LSM_IS_POOL(p)) {
- return p->free_space;
- }
- return 0;
-}
-
-uint64_t lsm_pool_status_get( lsm_pool *p )
-{
- if (LSM_IS_POOL(p)) {
- return p->status;
- }
- return UINT64_MAX;
-}
-
-const char *lsm_pool_status_info_get( lsm_pool *p )
-{
- if (LSM_IS_POOL(p)) {
- return p->status_info;
- }
- return NULL;
-}
-
-char *lsm_pool_system_id_get( lsm_pool *p )
-{
- if (LSM_IS_POOL(p)) {
- return p->system_id;
- }
- return NULL;
-}
-
-MEMBER_FUNC_GET(const char *, lsm_pool_plugin_data_get, lsm_pool *p,
- p, LSM_IS_POOL, plugin_data, NULL)
-
-MEMBER_FUNC_GET( uint64_t, lsm_pool_element_type_get, lsm_pool *p, p, LSM_IS_POOL,
- element_type, 0)
-
-MEMBER_FUNC_GET( uint64_t, lsm_pool_unsupported_actions_get, lsm_pool *p, p,
- LSM_IS_POOL, element_type, 0)
-
-CREATE_ALLOC_ARRAY_FUNC(lsm_volume_record_array_alloc, lsm_volume *)
-
-lsm_volume * lsm_volume_record_alloc(const char *id, const char *name,
- const char *vpd83, uint64_t blockSize,
- uint64_t numberOfBlocks,
- uint32_t status, const char *system_id, const char *pool_id,
- const char* plugin_data)
-{
- if( vpd83 && (LSM_ERR_OK != lsm_volume_vpd83_verify(vpd83)) ) {
- return NULL;
- }
-
- lsm_volume *rc = (lsm_volume *)calloc(1, sizeof(lsm_volume));
- if (rc) {
- rc->magic = LSM_VOL_MAGIC;
- rc->id = strdup(id);
- rc->name = strdup(name);
-
- if( vpd83 ) {
- rc->vpd83 = strdup(vpd83);
- }
-
- rc->block_size = blockSize;
- rc->number_of_blocks = numberOfBlocks;
- rc->admin_state = status;
- rc->system_id = strdup(system_id);
- rc->pool_id = strdup(pool_id);
-
- if( plugin_data ) {
- rc->plugin_data = strdup(plugin_data);
- }
-
- if( !rc->id || !rc->name || (vpd83 && !rc->vpd83) || !rc->system_id ||
- !rc->pool_id ||
- (plugin_data && !rc->plugin_data)) {
- lsm_volume_record_free(rc);
- rc = NULL;
- }
- }
- return rc;
-}
-
-CREATE_ALLOC_ARRAY_FUNC(lsm_disk_record_array_alloc, lsm_disk *)
-
-lsm_disk *lsm_disk_record_alloc(const char *id, const char *name,
- lsm_disk_type disk_type, uint64_t block_size, uint64_t block_count,
- uint64_t disk_status, const char *system_id)
-{
- lsm_disk *rc = (lsm_disk *)malloc(sizeof(lsm_disk));
- if( rc ) {
- rc->magic = LSM_DISK_MAGIC;
- rc->id = strdup(id);
- rc->name = strdup(name);
- rc->disk_type = disk_type;
- rc->block_size = block_size;
- rc->block_count = block_count;
- rc->disk_status = disk_status;
- rc->system_id = strdup(system_id);
-
- if( !rc->id || !rc->name || !rc->system_id ) {
- lsm_disk_record_free(rc);
- rc = NULL;
- }
- }
- return rc;
-}
-
-CREATE_ALLOC_ARRAY_FUNC(lsm_system_record_array_alloc, lsm_system *)
-
-lsm_system *lsm_system_record_alloc(const char *id, const char *name,
- uint32_t status, const char *status_info,
- const char* plugin_data)
-{
- lsm_system *rc = (lsm_system *)calloc(1, sizeof(lsm_system));
- if (rc) {
- rc->magic = LSM_SYSTEM_MAGIC;
- rc->id = strdup(id);
- rc->name = strdup(name);
- rc->status = status;
- rc->status_info = strdup(status_info);
-
- if( plugin_data ) {
- rc->plugin_data = strdup(plugin_data);
- }
-
- if( !rc->name || !rc->id || !rc->status_info ||
- (plugin_data && !rc->plugin_data)) {
- lsm_system_record_free(rc);
- rc = NULL;
- }
- }
- return rc;
-}
-
-int lsm_system_record_free(lsm_system *s)
-{
- if( LSM_IS_SYSTEM(s) ) {
- s->magic = LSM_DEL_MAGIC(LSM_SYSTEM_MAGIC);
-
- if (s->id) {
- free(s->id);
- s->id = NULL;
- }
-
- if (s->name) {
- free(s->name);
- s->name = NULL;
- }
-
- if (s->status_info) {
- free(s->status_info);
- s->status_info = NULL;
- }
-
- free(s->plugin_data);
-
- free(s);
- return LSM_ERR_OK;
- }
- return LSM_ERR_INVALID_ARGUMENT;
-}
-
-CREATE_FREE_ARRAY_FUNC(lsm_system_record_array_free, lsm_system_record_free,
- lsm_system *, LSM_ERR_INVALID_ARGUMENT)
-
-lsm_system *lsm_system_record_copy(lsm_system *s)
-{
- lsm_system *rc = NULL;
- if( LSM_IS_SYSTEM(s) ) {
- rc = lsm_system_record_alloc(s->id, s->name, s->status, s->status_info, s->plugin_data);
- }
- return rc;
-}
-
-const char *lsm_system_id_get(lsm_system *s)
-{
- if( LSM_IS_SYSTEM(s) ) {
- return s->id;
- }
- return NULL;
-}
-
-const char *lsm_system_name_get(lsm_system *s)
-{
- if( LSM_IS_SYSTEM(s) ) {
- return s->name;
- }
- return NULL;
-}
-
-uint32_t lsm_system_status_get(lsm_system *s)
-{
- if( LSM_IS_SYSTEM(s) ) {
- return s->status;
- }
- return UINT32_MAX;
-}
-
-MEMBER_FUNC_GET(const char *, lsm_system_plugin_data_get, lsm_system *s,
- s, LSM_IS_SYSTEM, plugin_data, NULL)
-
-lsm_volume *lsm_volume_record_copy(lsm_volume *vol)
-{
- lsm_volume *rc = NULL;
- if( LSM_IS_VOL(vol) ) {
- rc = lsm_volume_record_alloc(vol->id, vol->name, vol->vpd83,
- vol->block_size, vol->number_of_blocks,
- vol->admin_state, vol->system_id, vol->pool_id, vol->plugin_data);
- }
- return rc;
-}
-
-int lsm_volume_record_free(lsm_volume *v)
-{
- if ( LSM_IS_VOL(v) ) {
- v->magic = LSM_DEL_MAGIC(LSM_VOL_MAGIC);
-
- if (v->id) {
- free(v->id);
- v->id = NULL;
- }
-
- if (v->name) {
- free(v->name);
- v->name = NULL;
- }
-
- if (v->vpd83) {
- free(v->vpd83);
- v->vpd83 = NULL;
- }
-
- if( v->system_id ) {
- free(v->system_id);
- v->system_id = NULL;
- }
-
- if( v->pool_id ) {
- free(v->pool_id);
- v->pool_id = NULL;
- }
-
- free(v->plugin_data);
- v->plugin_data = NULL;
-
- free(v);
- return LSM_ERR_OK;
- }
- return LSM_ERR_INVALID_ARGUMENT;
-}
-
-CREATE_FREE_ARRAY_FUNC( lsm_volume_record_array_free, lsm_volume_record_free,
- lsm_volume *, LSM_ERR_INVALID_ARGUMENT)
-
-lsm_disk *lsm_disk_record_copy(lsm_disk *disk)
-{
- if( LSM_IS_DISK(disk) ) {
- return lsm_disk_record_alloc(disk->id, disk->name, disk->disk_type,
- disk->block_size, disk->block_count, disk->disk_status, disk->system_id);
- }
- return NULL;
-}
-
-int lsm_disk_record_free(lsm_disk *d)
-{
- if ( LSM_IS_DISK(d) ) {
- d->magic = LSM_DEL_MAGIC(LSM_DISK_MAGIC);
-
- free(d->id);
- d->id = NULL;
-
- free(d->name);
- d->name = NULL;
-
- free(d->system_id);
- d->system_id = NULL;
-
- free(d);
- return LSM_ERR_OK;
- }
- return LSM_ERR_INVALID_ARGUMENT;
-}
-
-CREATE_FREE_ARRAY_FUNC( lsm_disk_record_array_free, lsm_disk_record_free,
- lsm_disk *, LSM_ERR_INVALID_ARGUMENT)
-
-/* We would certainly expand this to encompass the entire function */
-#define MEMBER_SET_REF(x, validation, member, value, alloc_func, free_func, error) \
- if( validation(x) ) { \
- if(x->member) { \
- free_func(x->member); \
- x->member = NULL; \
- } \
- if( value ) { \
- x->member = alloc_func(value); \
- if( !x->member ) { \
- return LSM_ERR_NO_MEMORY; \
- } \
- } \
- return LSM_ERR_OK; \
- } else { \
- return error; \
- }
-
-/* We would certainly expand this to encompass the entire function */
-#define MEMBER_SET_VAL(x, validation, member, value, error) \
- if( validation(x) ) { \
- x->member = value; \
- return LSM_ERR_OK; \
- } else { \
- return error; \
- }
-
-const char* lsm_volume_id_get(lsm_volume *v)
-{
- MEMBER_GET(v, LSM_IS_VOL, id, NULL);
-}
-
-const char* lsm_volume_name_get(lsm_volume *v)
-{
- MEMBER_GET(v, LSM_IS_VOL, name, NULL);
-}
-
-const char* lsm_volume_vpd83_get(lsm_volume *v)
-{
- MEMBER_GET(v, LSM_IS_VOL, vpd83, NULL);
-}
-
-uint64_t lsm_volume_block_size_get(lsm_volume *v)
-{
- MEMBER_GET(v, LSM_IS_VOL, block_size, 0);
-}
-
-uint64_t lsm_volume_number_of_blocks_get(lsm_volume *v)
-{
- MEMBER_GET(v, LSM_IS_VOL, number_of_blocks, 0);
-}
-
-uint32_t lsm_volume_admin_state_get(lsm_volume *v)
-{
- MEMBER_GET(v, LSM_IS_VOL, admin_state, 0);
-}
-
-char *lsm_volume_system_id_get( lsm_volume *v)
-{
- MEMBER_GET(v, LSM_IS_VOL, system_id, NULL);
-}
-
-char *lsm_volume_pool_id_get( lsm_volume *v)
-{
- MEMBER_GET(v, LSM_IS_VOL, pool_id, NULL);
-}
-
-MEMBER_FUNC_GET(const char *, lsm_volume_plugin_data_get, lsm_volume *v, v, LSM_IS_VOL, plugin_data, NULL)
-
-const char *lsm_disk_id_get( lsm_disk *d)
-{
- MEMBER_GET(d, LSM_IS_DISK, id, NULL);
-}
-
-const char *lsm_disk_name_get( lsm_disk *d)
-{
- MEMBER_GET(d, LSM_IS_DISK, name, NULL);
-}
-
-lsm_disk_type lsm_disk_type_get( lsm_disk *d)
-{
- MEMBER_GET(d, LSM_IS_DISK, disk_type, LSM_DISK_TYPE_OTHER);
-}
-
-uint64_t lsm_disk_block_size_get( lsm_disk *d)
-{
- MEMBER_GET(d, LSM_IS_DISK, block_size, 0);
-}
-
-uint64_t lsm_disk_number_of_blocks_get( lsm_disk *d)
-{
- MEMBER_GET(d, LSM_IS_DISK, block_count, 0);
-}
-
-uint64_t lsm_disk_status_get( lsm_disk *d)
-{
- MEMBER_GET(d, LSM_IS_DISK, disk_status, LSM_DISK_STATUS_UNKNOWN);
-}
-
-const char *lsm_disk_system_id_get( lsm_disk *d)
-{
- MEMBER_GET(d, LSM_IS_DISK, system_id, NULL);
-}
-
-CREATE_ALLOC_ARRAY_FUNC(lsm_access_group_record_array_alloc, lsm_access_group *)
-
-static lsm_string_list *standardize_init_list(lsm_string_list *initiators)
-{
- uint32_t i = 0;
- lsm_string_list *rc = lsm_string_list_copy(initiators);
- char *wwpn = NULL;
-
- if( rc ) {
- for( i = 0; i < lsm_string_list_size(rc); ++i ) {
- if( LSM_ERR_OK == wwpn_validate(lsm_string_list_elem_get(rc, i)) ) {
- /* We have a wwpn, switch to internal representation */
- wwpn = wwpn_convert(lsm_string_list_elem_get(rc, i));
- if( !wwpn ||
- LSM_ERR_OK != lsm_string_list_elem_set(rc, i, wwpn) ) {
- free(wwpn);
- lsm_string_list_free(rc);
- rc = NULL;
- break;
- }
- free(wwpn);
- wwpn = NULL;
- }
- }
- }
-
- return rc;
-}
-
-
-lsm_access_group *lsm_access_group_record_alloc(const char *id,
- const char *name,
- lsm_string_list *initiators,
- lsm_access_group_init_type init_type,
- const char *system_id,
- const char *plugin_data)
-{
- lsm_access_group *rc = NULL;
- if( id && name && system_id ) {
- rc = (lsm_access_group *)malloc(sizeof(lsm_access_group));
- if( rc ) {
- rc->magic = LSM_ACCESS_GROUP_MAGIC;
- rc->id = strdup(id);
- rc->name = strdup(name);
- rc->system_id = strdup(system_id);
- rc->initiators = standardize_init_list(initiators);
- rc->init_type = init_type;
-
- if( plugin_data ) {
- rc->plugin_data = strdup(plugin_data);
- } else {
- rc->plugin_data = NULL;
- }
-
- if( !rc->id || !rc->name || !rc->system_id ||
- (plugin_data && !rc->plugin_data) ||
- (initiators && !rc->initiators) ) {
- lsm_access_group_record_free(rc);
- rc = NULL;
- }
- }
- }
- return rc;
-}
-
-lsm_access_group *lsm_access_group_record_copy( lsm_access_group *ag )
-{
- lsm_access_group *rc = NULL;
- if( LSM_IS_ACCESS_GROUP(ag) ) {
- rc = lsm_access_group_record_alloc(ag->id, ag->name,
- ag->initiators, ag->init_type,
- ag->system_id, ag->plugin_data);
- }
- return rc;
-}
-
-int lsm_access_group_record_free(lsm_access_group *ag)
-{
- if( LSM_IS_ACCESS_GROUP(ag) ) {
- ag->magic = LSM_DEL_MAGIC(LSM_ACCESS_GROUP_MAGIC);
- free(ag->id);
- free(ag->name);
- free(ag->system_id);
- lsm_string_list_free(ag->initiators);
- free(ag->plugin_data);
- free(ag);
- return LSM_ERR_OK;
- }
- return LSM_ERR_INVALID_ARGUMENT;
-}
-
-CREATE_FREE_ARRAY_FUNC(lsm_access_group_record_array_free, lsm_access_group_record_free,
- lsm_access_group *, LSM_ERR_INVALID_ARGUMENT)
-
-const char *lsm_access_group_id_get( lsm_access_group *group )
-{
- if( LSM_IS_ACCESS_GROUP(group) ) {
- return group->id;
- }
- return NULL;
-}
-const char *lsm_access_group_name_get( lsm_access_group *group )
-{
- if( LSM_IS_ACCESS_GROUP(group) ) {
- return group->name;
- }
- return NULL;
-}
-const char *lsm_access_group_system_id_get( lsm_access_group *group )
-{
- if( LSM_IS_ACCESS_GROUP(group) ) {
- return group->system_id;
- }
- return NULL;
-}
-
-lsm_string_list * lsm_access_group_initiator_id_get( lsm_access_group *group )
-{
- if( LSM_IS_ACCESS_GROUP(group) ) {
- return group->initiators;
- }
- return NULL;
-}
-
-void lsm_access_group_initiator_id_set( lsm_access_group *group, lsm_string_list *il)
-{
- if( LSM_IS_ACCESS_GROUP(group) ) {
- if( group->initiators && group->initiators != il ) {
- lsm_string_list_free(group->initiators);
- }
-
- group->initiators = lsm_string_list_copy(il);
- }
-}
-
-lsm_error_ptr lsm_error_last_get(lsm_connect *c)
-{
- if( LSM_IS_CONNECT(c) ) {
- lsm_error_ptr e = c->error;
- c->error = NULL;
- return e;
- }
- return NULL;
-}
-
-lsm_block_range *lsm_block_range_record_alloc(uint64_t source_start,
- uint64_t dest_start,
- uint64_t block_count)
-{
- lsm_block_range *rc = NULL;
-
- rc = (lsm_block_range*) malloc(sizeof(lsm_block_range));
- if( rc ) {
- rc->magic = LSM_BLOCK_RANGE_MAGIC;
- rc->source_start = source_start;
- rc->dest_start = dest_start;
- rc->block_count = block_count;
- }
- return rc;
-}
-
-int lsm_block_range_record_free( lsm_block_range *br )
-{
- if( LSM_IS_BLOCK_RANGE(br) ) {
- br->magic = LSM_DEL_MAGIC(LSM_BLOCK_RANGE_MAGIC);
- free(br);
- return LSM_ERR_OK;
- }
- return LSM_ERR_INVALID_ARGUMENT;
-}
-
-lsm_block_range *lsm_block_range_record_copy( lsm_block_range *source )
-{
- lsm_block_range *dest = NULL;
-
- if( LSM_IS_BLOCK_RANGE(source) ) {
- dest = lsm_block_range_record_alloc(source->source_start,
- source->dest_start,
- source->block_count);
- }
- return dest;
-}
-
-CREATE_ALLOC_ARRAY_FUNC(lsm_block_range_record_array_alloc, lsm_block_range *)
-CREATE_FREE_ARRAY_FUNC(lsm_block_range_record_array_free, lsm_block_range_record_free,
- lsm_block_range *, LSM_ERR_INVALID_ARGUMENT)
-
-
-uint64_t lsm_block_range_source_start_get(lsm_block_range *br)
-{
- MEMBER_GET(br, LSM_IS_BLOCK_RANGE, source_start, 0);
-}
-
-uint64_t lsm_block_range_dest_start_get(lsm_block_range *br)
-{
- MEMBER_GET(br, LSM_IS_BLOCK_RANGE, dest_start, 0);
-}
-
-uint64_t lsm_block_range_block_count_get(lsm_block_range *br)
-{
- MEMBER_GET(br, LSM_IS_BLOCK_RANGE, block_count, 0);
-}
-
-lsm_fs * lsm_fs_record_alloc(const char *id, const char *name,
- uint64_t total_space,
- uint64_t free_space,
- const char *pool_id,
- const char *system_id,
- const char* plugin_data)
-{
- lsm_fs *rc = NULL;
- rc = (lsm_fs *)calloc(1, sizeof(lsm_fs));
- if( rc ) {
- rc->magic = LSM_FS_MAGIC;
- rc->id = strdup(id);
- rc->name = strdup(name);
- rc->pool_id = strdup(pool_id);
- rc->system_id = strdup(system_id);
- rc->total_space = total_space;
- rc->free_space = free_space;
-
- if( plugin_data ) {
- rc->plugin_data = strdup(plugin_data);
- }
-
- if( !rc->id || !rc->name || !rc->pool_id || !rc->system_id ||
- (plugin_data && !rc->plugin_data)) {
- lsm_fs_record_free(rc);
- rc = NULL;
- }
- }
- return rc;
-}
-
-int lsm_fs_record_free( lsm_fs *fs)
-{
- if( LSM_IS_FS(fs) ) {
- fs->magic = LSM_DEL_MAGIC(LSM_FS_MAGIC);
- free(fs->id);
- free(fs->name);
- free(fs->pool_id);
- free(fs->system_id);
- free(fs->plugin_data);
- free(fs);
- return LSM_ERR_OK;
- }
- return LSM_ERR_INVALID_ARGUMENT;
-}
-
-lsm_fs *lsm_fs_record_copy(lsm_fs *source)
-{
- lsm_fs *dest = NULL;
-
- if( LSM_IS_FS(source) ) {
- dest = lsm_fs_record_alloc(source->id, source->name,
- source->total_space, source->free_space,
- source->pool_id,
- source->system_id,
- source->plugin_data);
- }
- return dest;
-}
-
-CREATE_ALLOC_ARRAY_FUNC(lsm_fs_record_array_alloc, lsm_fs *)
-CREATE_FREE_ARRAY_FUNC(lsm_fs_record_array_free, lsm_fs_record_free, lsm_fs *,
- LSM_ERR_INVALID_ARGUMENT)
-
-const char *lsm_fs_id_get(lsm_fs *fs)
-{
- MEMBER_GET(fs, LSM_IS_FS, id, NULL);
-}
-
-const char *lsm_fs_name_get(lsm_fs *fs)
-{
- MEMBER_GET(fs, LSM_IS_FS, name, NULL);
-}
-
-const char *lsm_fs_system_id_get(lsm_fs *fs)
-{
- MEMBER_GET(fs, LSM_IS_FS, system_id, NULL);
-}
-
-const char *lsm_fs_pool_id_get(lsm_fs *fs)
-{
- MEMBER_GET(fs, LSM_IS_FS, pool_id, NULL);
-}
-
-uint64_t lsm_fs_total_space_get(lsm_fs *fs)
-{
- MEMBER_GET(fs, LSM_IS_FS, total_space, 0);
-}
-uint64_t lsm_fs_free_space_get(lsm_fs *fs)
-{
- MEMBER_GET(fs, LSM_IS_FS, free_space, 0);
-}
-
-MEMBER_FUNC_GET(const char *, lsm_fs_plugin_data_get, lsm_fs *fs,
- fs, LSM_IS_POOL, plugin_data, NULL)
-
-lsm_fs_ss * lsm_fs_ss_record_alloc(const char *id, const char *name,
- uint64_t ts,
- const char * plugin_data)
-{
- lsm_fs_ss *rc = (lsm_fs_ss *) calloc(1, sizeof(lsm_fs_ss));
- if( rc ) {
- rc->magic = LSM_SS_MAGIC;
- rc->id = strdup(id);
- rc->name = strdup(name);
- rc->ts = ts;
- if( plugin_data ) {
- rc->plugin_data = strdup(plugin_data);
- }
-
- if( !rc->id || ! rc->name ||
- (plugin_data && !rc->plugin_data)) {
- lsm_fs_ss_record_free(rc);
- rc = NULL;
- }
- }
- return rc;
-}
-
-lsm_fs_ss *lsm_fs_ss_record_copy(lsm_fs_ss *source)
-{
- lsm_fs_ss *rc = NULL;
- if( LSM_IS_SS(source) ) {
- rc = lsm_fs_ss_record_alloc(source->id,
- source->name,
- source->ts, source->plugin_data);
- }
- return rc;
-}
-
-int lsm_fs_ss_record_free( lsm_fs_ss *ss)
-{
- if( LSM_IS_SS(ss) ) {
- ss->magic = LSM_DEL_MAGIC(LSM_SS_MAGIC);
- free(ss->id);
- free(ss->name);
- free(ss->plugin_data);
-
- free(ss);
- return LSM_ERR_OK;
- }
- return LSM_ERR_INVALID_ARGUMENT;
-}
-
-CREATE_ALLOC_ARRAY_FUNC(lsm_fs_ss_record_array_alloc, lsm_fs_ss *)
-CREATE_FREE_ARRAY_FUNC(lsm_fs_ss_record_array_free, lsm_fs_ss_record_free, lsm_fs_ss *,
- LSM_ERR_INVALID_ARGUMENT)
-
-const char *lsm_fs_ss_id_get(lsm_fs_ss *ss)
-{
- MEMBER_GET(ss, LSM_IS_SS, id, NULL);
-}
-
-const char *lsm_fs_ss_name_get(lsm_fs_ss *ss)
-{
- MEMBER_GET(ss, LSM_IS_SS, name, NULL);
-}
-
-uint64_t lsm_fs_ss_time_stamp_get(lsm_fs_ss *ss)
-{
- MEMBER_GET(ss, LSM_IS_SS, ts, 0);
-}
-
-MEMBER_FUNC_GET(const char *, lsm_fs_ss_plugin_data_get, lsm_fs_ss *ss,
- ss, LSM_IS_SS, plugin_data, NULL)
-
-lsm_nfs_export *lsm_nfs_export_record_alloc(const char *id,
- const char *fs_id,
- const char *export_path,
- const char *auth,
- lsm_string_list *root,
- lsm_string_list *rw,
- lsm_string_list *ro,
- uint64_t anonuid,
- uint64_t anongid,
- const char *options,
- const char * plugin_data)
-{
- lsm_nfs_export *rc = NULL;
-
- /* This is required */
- if( fs_id ) {
- rc = (lsm_nfs_export *)calloc(1, sizeof(lsm_nfs_export));
- if( rc ) {
- rc->magic = LSM_NFS_EXPORT_MAGIC;
- rc->id = (id) ? strdup(id) : NULL;
- rc->fs_id = strdup(fs_id);
- rc->export_path = (export_path) ? strdup(export_path) : NULL;
- rc->auth_type = (auth) ? strdup(auth) : NULL;
- rc->root = lsm_string_list_copy(root);
- rc->rw = lsm_string_list_copy(rw);
- rc->ro = lsm_string_list_copy(ro);
- rc->anonuid = anonuid;
- rc->anongid = anongid;
- rc->options = (options) ? strdup(options) : NULL;
-
- if( plugin_data ) {
- rc->plugin_data = strdup(plugin_data);
- }
-
- if( !rc->id ||
- !rc->fs_id ||
- (export_path && !rc->export_path) ||
- (auth && !rc->auth_type) ||
- (root && !rc->root) ||
- (rw && !rc->rw) ||
- (ro && !rc->ro) ||
- (options && !rc->options) ||
- (plugin_data && !rc->plugin_data)) {
- lsm_nfs_export_record_free(rc);
- rc = NULL;
- }
- }
- }
-
- return rc;
-}
-
-int lsm_nfs_export_record_free( lsm_nfs_export *exp )
-{
- if( LSM_IS_NFS_EXPORT(exp) ) {
- exp->magic = LSM_DEL_MAGIC(LSM_NFS_EXPORT_MAGIC);
- free(exp->id);
- free(exp->fs_id);
- free(exp->export_path);
- free(exp->auth_type);
- lsm_string_list_free(exp->root);
- lsm_string_list_free(exp->rw);
- lsm_string_list_free(exp->ro);
- free(exp->options);
- free(exp->plugin_data);
-
- free(exp);
- return LSM_ERR_OK;
- }
- return LSM_ERR_INVALID_ARGUMENT;
-}
-
-
-lsm_nfs_export *lsm_nfs_export_record_copy( lsm_nfs_export *s )
-{
- if(LSM_IS_NFS_EXPORT(s)) {
- return lsm_nfs_export_record_alloc(s->id, s->fs_id, s->export_path,
- s->auth_type, s->root, s->rw, s->ro, s->anonuid,
- s->anongid, s->options, s->plugin_data);
- }
- return NULL;
-}
-
-CREATE_ALLOC_ARRAY_FUNC(lsm_nfs_export_record_array_alloc, lsm_nfs_export *)
-CREATE_FREE_ARRAY_FUNC(lsm_nfs_export_record_array_free, lsm_nfs_export_record_free,
- lsm_nfs_export *, LSM_ERR_INVALID_ARGUMENT)
-
-const char *lsm_nfs_export_id_get( lsm_nfs_export *exp )
-{
- MEMBER_GET(exp, LSM_IS_NFS_EXPORT, id, NULL);
-}
-
-int lsm_nfs_export_id_set(lsm_nfs_export *exp, const char *ep )
-{
- MEMBER_SET_REF(exp, LSM_IS_NFS_EXPORT, id, ep, strdup, free,
- LSM_ERR_INVALID_ARGUMENT);
-}
-
-const char *lsm_nfs_export_fs_id_get( lsm_nfs_export *exp )
-{
- MEMBER_GET(exp, LSM_IS_NFS_EXPORT, fs_id, NULL);
-}
-
-int lsm_nfs_export_fs_id_set( lsm_nfs_export *exp, const char *fs_id)
-{
- MEMBER_SET_REF(exp, LSM_IS_NFS_EXPORT, fs_id, fs_id, strdup, free,
- LSM_ERR_INVALID_ARGUMENT);
-}
-
-const char *lsm_nfs_export_export_path_get( lsm_nfs_export *exp )
-{
- MEMBER_GET(exp, LSM_IS_NFS_EXPORT, export_path, NULL);
-}
-
-int lsm_nfs_export_export_path_set( lsm_nfs_export *exp, const char *ep )
-{
- MEMBER_SET_REF(exp, LSM_IS_NFS_EXPORT, export_path, ep, strdup, free,
- LSM_ERR_INVALID_ARGUMENT);
-}
-
-const char *lsm_nfs_export_auth_type_get( lsm_nfs_export *exp )
-{
- MEMBER_GET(exp, LSM_IS_NFS_EXPORT, auth_type, NULL);
-}
-
-int lsm_nfs_export_auth_type_set( lsm_nfs_export *exp, const char *auth )
-{
- MEMBER_SET_REF(exp, LSM_IS_NFS_EXPORT, auth_type, auth, strdup, free,
- LSM_ERR_INVALID_ARGUMENT);
-}
-
-lsm_string_list * lsm_nfs_export_root_get( lsm_nfs_export *exp)
-{
- MEMBER_GET(exp, LSM_IS_NFS_EXPORT, root, NULL);
-}
-
-int lsm_nfs_export_root_set( lsm_nfs_export *exp, lsm_string_list *root)
-{
- MEMBER_SET_REF(exp, LSM_IS_NFS_EXPORT, root, root, lsm_string_list_copy,
- lsm_string_list_free, LSM_ERR_INVALID_ARGUMENT);
-}
-
-lsm_string_list * lsm_nfs_export_read_write_get( lsm_nfs_export *exp)
-{
- MEMBER_GET(exp, LSM_IS_NFS_EXPORT, rw, NULL);
-}
-
-int lsm_nfs_export_read_write_set( lsm_nfs_export *exp, lsm_string_list *rw)
-{
- MEMBER_SET_REF(exp, LSM_IS_NFS_EXPORT, rw, rw, lsm_string_list_copy,
- lsm_string_list_free, LSM_ERR_INVALID_ARGUMENT);
-}
-
-lsm_string_list * lsm_nfs_export_read_only_get( lsm_nfs_export *exp)
-{
- MEMBER_GET(exp, LSM_IS_NFS_EXPORT, ro, NULL);
-}
-
-int lsm_nfs_export_read_only_set(lsm_nfs_export *exp, lsm_string_list *ro)
-{
- MEMBER_SET_REF(exp, LSM_IS_NFS_EXPORT, ro, ro, lsm_string_list_copy,
- lsm_string_list_free, LSM_ERR_INVALID_ARGUMENT);
-}
-
-uint64_t lsm_nfs_export_anon_uid_get( lsm_nfs_export *exp )
-{
- MEMBER_GET(exp, LSM_IS_NFS_EXPORT, anonuid, ANON_UID_GID_ERROR);
-}
-
-int lsm_nfs_export_anon_uid_set( lsm_nfs_export *exp, uint64_t value)
-{
- MEMBER_SET_VAL(exp, LSM_IS_NFS_EXPORT, anonuid, value,
- LSM_ERR_INVALID_ARGUMENT);
-}
-
-uint64_t lsm_nfs_export_anon_gid_get( lsm_nfs_export *exp )
-{
- MEMBER_GET(exp, LSM_IS_NFS_EXPORT, anongid, ANON_UID_GID_ERROR);
-}
-
-int lsm_nfs_export_anon_gid_set( lsm_nfs_export *exp, uint64_t value )
-{
- MEMBER_SET_VAL(exp, LSM_IS_NFS_EXPORT, anongid, value,
- LSM_ERR_INVALID_ARGUMENT);
-}
-
-const char *lsm_nfs_export_options_get( lsm_nfs_export *exp)
-{
- MEMBER_GET(exp, LSM_IS_NFS_EXPORT, options, NULL);
-}
-
-int lsm_nfs_export_options_set( lsm_nfs_export *exp, const char *value )
-{
- MEMBER_SET_REF(exp, LSM_IS_NFS_EXPORT, options, value, strdup, free,
- LSM_ERR_INVALID_ARGUMENT);
-}
-
-MEMBER_FUNC_GET(const char *, lsm_nfs_export_plugin_data_get,
- lsm_nfs_export *exp, exp, LSM_IS_NFS_EXPORT, plugin_data, NULL)
-
-lsm_capability_value_type lsm_capability_get(lsm_storage_capabilities *cap,
- lsm_capability_type t)
-{
- lsm_capability_value_type rc = LSM_CAP_UNSUPPORTED;
-
- if( LSM_IS_CAPABILITIY(cap) && (uint32_t)t < cap->len ) {
- rc = (lsm_capability_value_type)cap->cap[t];
- }
- return rc;
-}
-
-int LSM_DLL_EXPORT lsm_capability_supported(lsm_storage_capabilities *cap,
- lsm_capability_type t)
-{
- if( lsm_capability_get(cap, t) == LSM_CAP_SUPPORTED ) {
- return 1;
- }
- return 0;
-}
-
-int lsm_capability_set(lsm_storage_capabilities *cap, lsm_capability_type t,
- lsm_capability_value_type v)
-{
- int rc = LSM_ERR_INVALID_ARGUMENT;
-
- if( LSM_IS_CAPABILITIY(cap) ) {
- if( (uint32_t)t < cap->len) {
- cap->cap[t] = v;
- rc = LSM_ERR_OK;
- }
- }
-
- return rc;
-}
-
-int lsm_capability_set_n( lsm_storage_capabilities *cap,
- lsm_capability_value_type v,
- ... )
-{
- int rc = LSM_ERR_OK;
- int index = 0;
-
- if( !LSM_IS_CAPABILITIY(cap) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- va_list var_arg;
- va_start(var_arg, v);
-
- while( (index = va_arg(var_arg, int)) != -1 ) {
- if( index < (int)cap->len ) {
- cap->cap[index] = v;
- } else {
- rc = LSM_ERR_INVALID_ARGUMENT;
- break;
- }
- }
-
- va_end(var_arg);
- return rc;
-}
-
-static char* bytes_to_string(uint8_t *a, uint32_t len)
-{
- char *buff = NULL;
-
- if( a && len ) {
- uint32_t i = 0;
- char *tmp = NULL;
- size_t str_len = ((sizeof(char) * 2) * len + 1);
- buff = (char*)malloc(str_len);
-
- if( buff ) {
- tmp = buff;
- for( i = 0; i < len; ++i ) {
- tmp += sprintf(tmp, "%02x", a[i]);
- }
- buff[str_len - 1] = '\0';
- }
- }
- return buff;
-}
-
-static uint8_t *string_to_bytes(const char *hex_string, uint32_t *l)
-{
- uint8_t *rc = NULL;
-
- if( hex_string && l ) {
- size_t len = strlen(hex_string);
- if( len && (len % 2) == 0) {
- len /= 2;
- rc = (uint8_t*)malloc( sizeof(uint8_t) * len);
- if( rc ) {
- size_t i;
- const char *t = hex_string;
- *l = len;
-
- for( i = 0; i < len; ++i ) {
- if( 1 != sscanf(t, "%02hhx", &rc[i])) {
- free(rc);
- rc = NULL;
- *l = 0;
- break;
- }
- t += 2;
- }
- }
- }
- }
- return rc;
-}
-
-
-lsm_storage_capabilities *lsm_capability_record_alloc(const char *value)
-{
- lsm_storage_capabilities *rc = NULL;
- rc = (lsm_storage_capabilities *)malloc(sizeof(struct _lsm_storage_capabilities));
- if(rc) {
- rc->magic = LSM_CAPABILITIES_MAGIC;
-
- if( value ) {
- rc->cap = string_to_bytes(value, &rc->len);
- } else {
- rc->cap = (uint8_t *)calloc(LSM_CAP_MAX, sizeof(uint8_t));
- if( rc->cap ) {
- rc->len = LSM_CAP_MAX;
- }
- }
-
- if( !rc->cap ) {
- lsm_capability_record_free(rc);
- rc = NULL;
- }
- }
- return rc;
-}
-
-int lsm_capability_record_free(lsm_storage_capabilities *cap)
-{
- if( LSM_IS_CAPABILITIY(cap) ) {
- cap->magic = LSM_DEL_MAGIC(LSM_CAPABILITIES_MAGIC);
- free(cap->cap);
- free(cap);
- return LSM_ERR_OK;
- }
- return LSM_ERR_INVALID_ARGUMENT;
-}
-
-char* capability_string(lsm_storage_capabilities *c)
-{
- char *rc = NULL;
- if( LSM_IS_CAPABILITIY(c) ) {
- rc = bytes_to_string(c->cap, c->len);
- }
- return rc;
-}
-
-lsm_hash *lsm_hash_alloc(void)
-{
- lsm_hash *rc = NULL;
-
- rc = (lsm_hash *)malloc(sizeof(lsm_hash));
- if( rc ) {
- rc->magic = LSM_HASH_MAGIC;
- rc->data = g_hash_table_new_full(g_str_hash, g_str_equal, free, free);
- if ( !rc->data ) {
- lsm_hash_free(rc);
- rc = NULL;
- }
- }
- return rc;
-}
-
-lsm_hash *lsm_hash_copy(lsm_hash *src)
-{
- GHashTableIter iter;
- gpointer key;
- gpointer value;
-
- lsm_hash *dest = NULL;
- if( LSM_IS_HASH(src) ) {
- dest = lsm_hash_alloc();
- if( dest ) {
- /* Walk through each from src and duplicate it to dest*/
- g_hash_table_iter_init(&iter, src->data);
- while(g_hash_table_iter_next(&iter, &key, &value)) {
- if( LSM_ERR_OK != lsm_hash_string_set(dest,
- (const char*)key, (const char*)value))
- {
- lsm_hash_free(dest);
- dest = NULL;
- }
- }
- }
- }
- return dest;
-}
-
-int lsm_hash_free(lsm_hash *op)
-{
- if( LSM_IS_HASH(op) ) {
- op->magic = LSM_DEL_MAGIC(LSM_HASH_MAGIC);
-
- if( op->data ) {
- g_hash_table_destroy(op->data);
- }
-
- free(op);
- return LSM_ERR_OK;
- }
- return LSM_ERR_INVALID_ARGUMENT;
-}
-
-int lsm_hash_keys(lsm_hash *op, lsm_string_list **l)
-{
- GHashTableIter iter;
- gpointer key;
- gpointer value;
-
-
- if( LSM_IS_HASH(op) ) {
- int count = g_hash_table_size(op->data);
-
- if( count ) {
- *l = lsm_string_list_alloc(0);
- g_hash_table_iter_init(&iter, op->data);
- while(g_hash_table_iter_next(&iter, &key, &value)) {
- if(LSM_ERR_OK != lsm_string_list_append(*l, (char *)key) ) {
- lsm_string_list_free(*l);
- *l = NULL;
- return LSM_ERR_NO_MEMORY;
- }
- }
- }
- return LSM_ERR_OK;
- }
- return LSM_ERR_INVALID_ARGUMENT;
-}
-
-const char *lsm_hash_string_get(lsm_hash *op,
- const char *key)
-{
- if( LSM_IS_HASH(op) ) {
- return (const char*)g_hash_table_lookup(op->data, key);
- }
- return NULL;
-}
-
-int lsm_hash_string_set(lsm_hash *op,
- const char *key,
- const char *value)
-{
- if( LSM_IS_HASH(op) ) {
- char *k_value = strdup(key);
- char *d_value = strdup(value);
-
- if( k_value && d_value ) {
- g_hash_table_remove(op->data, (gpointer)k_value);
- g_hash_table_insert(op->data, (gpointer)k_value, (gpointer)d_value);
- return LSM_ERR_OK;
- } else {
- free(k_value);
- free(d_value);
- return LSM_ERR_NO_MEMORY;
- }
- }
- return LSM_ERR_INVALID_ARGUMENT;
-}
-
-lsm_target_port *lsm_target_port_record_alloc( const char *id,
- lsm_target_port_type port_type,
- const char *service_address,
- const char *network_address,
- const char *physical_address,
- const char *physical_name,
- const char *system_id,
- const char *plugin_data)
-{
- lsm_target_port *rc = (lsm_target_port *) calloc(1, sizeof(lsm_target_port));
- if( rc ) {
- rc->magic = LSM_TARGET_PORT_MAGIC;
- rc->id = strdup(id);
- rc->port_type = port_type;
- rc->service_address = strdup(service_address);
- rc->network_address = strdup(network_address);
- rc->physical_address = strdup(physical_address);
- rc->physical_name = strdup(physical_name);
- rc->system_id = strdup(system_id);
- rc->plugin_data = (plugin_data) ? strdup(plugin_data) : NULL;
-
- if( !rc->id || !rc->service_address || !rc->network_address ||
- !rc->physical_address || !rc->physical_name ||
- !rc->system_id || (plugin_data && !rc->plugin_data)) {
- lsm_target_port_record_free(rc);
- rc = NULL;
- }
- }
- return rc;
-}
-
-int lsm_target_port_record_free(lsm_target_port *tp)
-{
- if( LSM_IS_TARGET_PORT(tp) ) {
- tp->magic = LSM_DEL_MAGIC(LSM_TARGET_PORT_MAGIC);
- free(tp->id);
- tp->id = NULL;
- free(tp->plugin_data);
- tp->plugin_data = NULL;
- free(tp->system_id);
- tp->system_id = NULL;
- free(tp->physical_name);
- tp->physical_name = NULL;
- free(tp->physical_address);
- tp->physical_address = NULL;
- free(tp->network_address);
- tp->network_address = NULL;
- free(tp->service_address);
- tp->service_address = NULL;
- free(tp);
- return LSM_ERR_OK;
- }
- return LSM_ERR_INVALID_ARGUMENT;
-}
-
-lsm_target_port LSM_DLL_EXPORT *lsm_target_port_copy(lsm_target_port *tp)
-{
- lsm_target_port *rc = NULL;
-
- if( LSM_IS_TARGET_PORT(tp) ) {
- rc = lsm_target_port_record_alloc(tp->id, tp->port_type,
- tp->service_address,
- tp->network_address,
- tp->physical_address,
- tp->physical_name,
- tp->system_id,
- tp->plugin_data);
- }
- return rc;
-}
-
-MEMBER_FUNC_GET(const char *, lsm_target_port_id_get, lsm_target_port *tp, tp, LSM_IS_TARGET_PORT, id, NULL)
-MEMBER_FUNC_GET(lsm_target_port_type, lsm_target_port_type_get, lsm_target_port *tp, tp, LSM_IS_TARGET_PORT, port_type, LSM_TARGET_PORT_TYPE_OTHER)
-MEMBER_FUNC_GET(const char *, lsm_target_port_service_address_get, lsm_target_port *tp, tp, LSM_IS_TARGET_PORT, service_address, NULL)
-MEMBER_FUNC_GET(const char *, lsm_target_port_network_address_get, lsm_target_port *tp, tp, LSM_IS_TARGET_PORT, network_address, NULL)
-MEMBER_FUNC_GET(const char *, lsm_target_port_physical_address_get, lsm_target_port *tp, tp, LSM_IS_TARGET_PORT, physical_address, NULL)
-MEMBER_FUNC_GET(const char *, lsm_target_port_physical_name_get, lsm_target_port *tp, tp, LSM_IS_TARGET_PORT, physical_name, NULL)
-MEMBER_FUNC_GET(const char *, lsm_target_port_system_id_get, lsm_target_port *tp, tp, LSM_IS_TARGET_PORT, system_id, NULL)
-
-CREATE_ALLOC_ARRAY_FUNC(lsm_target_port_record_array_alloc, lsm_target_port *)
-CREATE_FREE_ARRAY_FUNC(lsm_target_port_record_array_free,
- lsm_target_port_record_free, lsm_target_port *,
- LSM_ERR_INVALID_ARGUMENT)
-
-static int reg_ex_match(const char *pattern, const char *str)
-{
- regex_t start_state;
- int status = 0;
- int rc = regcomp(&start_state, pattern, REG_EXTENDED);
-
- if (rc) {
- // Development only when changing regular expression
- //fprintf(stderr, "%s: bad pattern: '%s' %d\n", str, pattern, rc);
- return -1;
- }
-
- status = regexec(&start_state, str, 0, NULL, 0);
- regfree(&start_state);
-
- return status;
-}
-
-int iqn_validate(const char *iqn)
-{
- if( (iqn && strlen(iqn) > 4) && ( 0 == strncmp(iqn, "iqn", 3) ||
- 0 == strncmp(iqn, "naa", 3) || 0 == strncmp(iqn, "eui", 3)) ) {
- return LSM_ERR_OK;
- }
- return LSM_ERR_INVALID_ARGUMENT;
-}
-
-int wwpn_validate(const char *wwpn)
-{
- const char *pattern = "^(0x|0X)?([0-9A-Fa-f]{2})"
- "(([\\.\\:\\-])?[0-9A-Fa-f]{2}){7}$";
- if( 0 == reg_ex_match(pattern, wwpn) ) {
- return LSM_ERR_OK;
- }
- return LSM_ERR_INVALID_ARGUMENT;
-}
-
-char *wwpn_convert(const char *wwpn)
-{
- size_t i = 0;
- size_t out = 0;
- char *rc = NULL;
-
- if( LSM_ERR_OK == wwpn_validate(wwpn) ) {
- rc = (char*)calloc(24,1);
- size_t len = strlen(wwpn);
-
- if (wwpn[1] == 'x' || wwpn[1] == 'X') {
- i = 2;
- }
-
- for( ; i < len; ++i ) {
- if( wwpn[i] != ':' && wwpn[i] != '-' && wwpn[i] != '.') {
- rc[out++] = tolower(wwpn[i]);
- } else {
- rc[out++] = ':';
- }
- }
- }
- return rc;
-}
-#ifdef __cplusplus
-}
-#endif
diff --git a/c_binding/lsm_datatypes.hpp b/c_binding/lsm_datatypes.hpp
deleted file mode 100644
index 6a6271f..0000000
--- a/c_binding/lsm_datatypes.hpp
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * Copyright (C) 2011-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 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#ifndef LSM_DATATYPES_H
-#define LSM_DATATYPES_H
-
-#include "libstoragemgmt/libstoragemgmt_plug_interface.h"
-#include "libstoragemgmt/libstoragemgmt_common.h"
-#include "libxml/uri.h"
-#include <glib.h>
-#include "lsm_ipc.hpp"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Helper macros to ease getter construction */
-
-/* Implementation for generic getter */
-#define MEMBER_FUNC_GET(return_type, name, param_sig, x, validation, member, error) \
-return_type name( param_sig ) {\
- if( validation(x) ) { \
- return x->member; \
- } else { \
- return error; \
- } \
-} \
-
-#define MAGIC_CHECK(obj, m) ((obj) && \
- ((obj)->magic==(m) ))
-#define LSM_DEL_MAGIC(obj) ((obj & 0x0FFFFFFF) | 0xD0000000)
-
-#define LSM_VOL_MAGIC 0xAA7A0000
-#define LSM_IS_VOL(obj) MAGIC_CHECK(obj, LSM_VOL_MAGIC)
-
-#define LSM_FLAG_UNUSED_CHECK(x) ( x != 0 )
-#define LSM_FLAG_GET_VALUE(x) x["flags"].asUint64_t()
-#define LSM_FLAG_EXPECTED_TYPE(x) (Value::numeric_t == x["flags"].valueType())
-
-/**
- * Information about storage volumes.
- */
-struct LSM_DLL_LOCAL _lsm_volume {
- uint32_t magic;
- char *id; /**< System wide unique identifier */
- char *name; /**< Human recognizeable name */
- char *vpd83; /**< SCSI page 83 unique ID */
- uint64_t block_size; /**< Block size */
- uint64_t number_of_blocks; /**< Number of blocks */
- uint32_t admin_state; /**< Status */
- char *system_id; /**< System this volume belongs */
- char *pool_id; /**< Pool this volume is derived from */
- char *plugin_data; /**< Private data for plugin */
-};
-
-#define LSM_POOL_MAGIC 0xAA7A0001
-#define LSM_IS_POOL(obj) MAGIC_CHECK(obj, LSM_POOL_MAGIC)
-
-/**
- * Information about storage pools.
- */
-struct LSM_DLL_LOCAL _lsm_pool {
- uint32_t magic; /**< Used for verfication */
- char *id; /**< System wide unique identifier */
- char *name; /**< Human recognizeable name */
- uint64_t element_type; /**< What the pool can be used for */
- uint64_t unsupported_actions; /**< What pool cannot be used for */
- uint64_t total_space; /**< Total size */
- uint64_t free_space; /**< Free space available */
- uint64_t status; /**< Status of pool */
- char *status_info; /**< Status info for pool */
- char *system_id; /**< system id */
- char *plugin_data; /**< Private data for plugin */
-};
-
-
-#define LSM_ACCESS_GROUP_MAGIC 0xAA7A0003
-#define LSM_IS_ACCESS_GROUP(obj) MAGIC_CHECK(obj, LSM_ACCESS_GROUP_MAGIC)
-
-/**
- * Information pertaining to a storage group.
- */
-struct _lsm_access_group {
- uint32_t magic; /**< Used for verification */
- char *id; /**< Id */
- char *name; /**< Name */
- char *system_id; /**< System id */
- lsm_access_group_init_type init_type; /**< Init type */
- lsm_string_list *initiators; /**< List of initiators */
- char *plugin_data; /**< Reserved for the plugin to use */
-};
-
-#define LSM_NFS_EXPORT_MAGIC 0xAA7A0006
-#define LSM_IS_NFS_EXPORT(obj) MAGIC_CHECK(obj, LSM_NFS_EXPORT_MAGIC)
-
-/**
- * Structure for NFS export information
- */
-struct _lsm_nfs_export {
- uint32_t magic; /**< Used for verfication */
- char *id; /**< Id */
- char *fs_id; /**< File system id */
- char *export_path; /**< Export path */
- char *auth_type; /**< Supported authentication types */
- lsm_string_list *root; /**< List of hosts with root access */
- lsm_string_list *rw; /**< List of hosts with read & write access */
- lsm_string_list *ro; /**< List of hosts with read only access */
- uint64_t anonuid; /**< Uid that should map to anonymous */
- uint64_t anongid; /**< Gid that should map to anonymous */
- char *options; /**< Options */
- char *plugin_data; /**< Reserved for the plugin to use */
-};
-
-#define LSM_BLOCK_RANGE_MAGIC 0xAA7A0007
-#define LSM_IS_BLOCK_RANGE(obj) MAGIC_CHECK(obj, LSM_BLOCK_RANGE_MAGIC)
-
-/**
- * Structure for block range ( a region to be replicated )
- */
-struct _lsm_block_range {
- uint32_t magic; /**< Used for verification */
- uint64_t source_start; /**< Source address */
- uint64_t dest_start; /**< Dest address */
- uint64_t block_count; /**< Number of blocks */
-};
-
-#define LSM_CAPABILITIES_MAGIC 0xAA7A0008
-#define LSM_IS_CAPABILITIY(obj) MAGIC_CHECK(obj, LSM_CAPABILITIES_MAGIC)
-
-#define LSM_CAP_MAX 512
-
-/**
- * Capabilities of the plug-in and storage array.
- */
-struct _lsm_storage_capabilities {
- uint32_t magic; /**< Used for verification */
- uint32_t len; /**< Len of cap field */
- uint8_t *cap; /**< Capacity data */
-};
-
-#define LSM_SYSTEM_MAGIC 0xAA7A0009
-#define LSM_IS_SYSTEM(obj) MAGIC_CHECK(obj, LSM_SYSTEM_MAGIC)
-
-/**
- * Structure for a system
- */
-struct _lsm_system {
- uint32_t magic; /**< Used for verification */
- char *id; /**< Id */
- char *name; /**< Name */
- uint32_t status; /**< Enumerated status value */
- char *status_info; /**< System status text */
- char *plugin_data; /**< Reserved for the plugin to use */
-};
-
-#define LSM_CONNECT_MAGIC 0xAA7A000A
-#define LSM_IS_CONNECT(obj) MAGIC_CHECK(obj, LSM_CONNECT_MAGIC)
-
-
-#define LSM_PLUGIN_MAGIC 0xAA7A000B
-#define LSM_IS_PLUGIN(obj) MAGIC_CHECK(obj, LSM_PLUGIN_MAGIC)
-
-/**
- * Information pertaining to the plug-in specifics.
- */
-struct LSM_DLL_LOCAL _lsm_plugin {
- uint32_t magic; /**< Magic, used for structure validation */
- Ipc *tp; /**< IPC transport */
- char *desc; /**< Description */
- char *version; /**< Version */
- void *private_data; /**< Private data for plug-in */
- lsm_error *error; /**< Error information */
- lsm_plugin_register reg; /**< Plug-in registration */
- lsm_plugin_unregister unreg; /**< Plug-in unregistration */
- struct lsm_mgmt_ops_v1 *mgmt_ops; /**< Callback for management ops */
- struct lsm_san_ops_v1 *san_ops; /**< Callbacks for SAN ops */
- struct lsm_nas_ops_v1 *nas_ops; /**< Callbacks for NAS ops */
- struct lsm_fs_ops_v1 *fs_ops; /**< Callbacks for fs ops */
- struct lsm_ops_v1_2 *ops_v1_2; /**< Callbacks for v1.2 ops */
-};
-
-
-/**
- * Information pertaining to the connection. This is the main structure and
- * opaque data type for the library.
- */
-struct LSM_DLL_LOCAL _lsm_connect {
- uint32_t magic; /**< Magic, used for structure validation */
- uint32_t flags; /**< Flags for the connection */
- xmlURIPtr uri; /**< URI */
- char *raw_uri; /**< Raw URI string */
- lsm_error *error; /**< Error information */
- Ipc *tp; /**< IPC transport */
-};
-
-
-#define LSM_ERROR_MAGIC 0xAA7A000C
-#define LSM_IS_ERROR(obj) MAGIC_CHECK(obj, LSM_ERROR_MAGIC)
-
-/**
- * Used to house error information.
- */
-struct LSM_DLL_LOCAL _lsm_error {
- uint32_t magic; /**< Magic, used for struct validation */
- lsm_error_number code; /**< Error code */
- uint32_t reserved; /**< Reserved */
- char *message; /**< Human readable error message */
- char *exception; /**< Exception message if present */
- char *debug; /**< Debug message */
- void *debug_data; /**< Debug data */
- uint32_t debug_data_size; /**< Size of the data */
-};
-
-/**
- * Used to house string collection.
- */
-#define LSM_STRING_LIST_MAGIC 0xAA7A000D
-#define LSM_IS_STRING_LIST(obj) MAGIC_CHECK(obj, LSM_STRING_LIST_MAGIC)
-struct LSM_DLL_LOCAL _lsm_string_list {
- uint32_t magic; /**< Magic value */
- GPtrArray *values;
-};
-
-/**
- * Structure for File system information.
- */
-#define LSM_FS_MAGIC 0xAA7A000E
-#define LSM_IS_FS(obj) MAGIC_CHECK(obj, LSM_FS_MAGIC)
-struct LSM_DLL_LOCAL _lsm_fs {
- uint32_t magic; /**< Magic, used for struct validation */
- char *id; /**< Id */
- char *name; /**< Name */
- char *pool_id; /**< Pool ID */
- uint64_t total_space; /**< Total space */
- uint64_t free_space; /**< Free space */
- char *system_id; /**< System ID */
- char *plugin_data; /**< Plugin private data */
-};
-
-#define LSM_SS_MAGIC 0xAA7A000F
-#define LSM_IS_SS(obj) MAGIC_CHECK(obj, LSM_SS_MAGIC)
-struct LSM_DLL_LOCAL _lsm_fs_ss {
- uint32_t magic;
- char *id;
- char *name;
- uint64_t ts;
- char *plugin_data; /**< Reserved for the plugin to use */
-};
-
-#define LSM_DISK_MAGIC 0xAA7A0010
-#define LSM_IS_DISK(obj) MAGIC_CHECK(obj, LSM_DISK_MAGIC)
-struct LSM_DLL_LOCAL _lsm_disk {
- uint32_t magic;
- char *id;
- char *name;
- lsm_disk_type disk_type;
- uint64_t block_size;
- uint64_t block_count;
- uint64_t disk_status; /* Bit field */
- char *system_id;
-};
-
-#define LSM_HASH_MAGIC 0xAA7A0011
-#define LSM_IS_HASH(obj) MAGIC_CHECK(obj, LSM_HASH_MAGIC)
-struct LSM_DLL_LOCAL _lsm_hash {
- uint32_t magic;
- GHashTable *data;
-};
-
-
-#define LSM_TARGET_PORT_MAGIC 0xAA7A0012
-#define LSM_IS_TARGET_PORT(obj) MAGIC_CHECK(obj, LSM_TARGET_PORT_MAGIC)
-struct LSM_DLL_LOCAL _lsm_target_port {
- uint32_t magic;
- char *id;
- lsm_target_port_type port_type;
- char *service_address;
- char *network_address;
- char *physical_address;
- char *physical_name;
- char *system_id;
- char *plugin_data;
-};
-
-
-/**
- * Returns a pointer to a newly created connection structure.
- * @return NULL on memory exhaustion, else new connection.
- */
-lsm_connect LSM_DLL_LOCAL *connection_get();
-
-/**
- * De-allocates the connection.
- * @param c Connection to free.
- */
-void LSM_DLL_LOCAL connection_free(lsm_connect *c);
-
-/**
- * Loads the requester driver specified in the uri.
- * @param c Connection
- * @param plugin Short name of plugin
- * @param password Password
- * @param timeout Initial timeout
- * @param e Error data
- * @param startup If non zero call rpc start_up, else skip
- * @param flags Reserved flag for future use
- * @return LSM_ERR_OK on success, else error code.
- */
-int LSM_DLL_LOCAL driver_load(lsm_connect *c, const char *plugin,
- const char *password, uint32_t timeout,
- lsm_error_ptr *e,
- int startup,
- lsm_flag flags);
-
-char LSM_DLL_LOCAL *capability_string(lsm_storage_capabilities *c);
-
-const char LSM_DLL_LOCAL *uds_path(void);
-
-/**
- * Take a character string and tries to convert to a number.
- * Note: Number is defined as what is acceptable for JSON number. The number
- * is represented by int64_t if possible, else uint64_t and then long double.
- * @param str_num Character string containing number
- * @param si Signed 64 bit number
- * @param ui Unsigned 64 bit number
- * @param d Long double
- * @return -1 = Invalid string pointer
- * 0 = Not a number
- * 1 = Number converted to signed integer, value in si
- * 2 = Number converted to unsigned integer, value in ui
- * 3 = Number converted to long double, value in d
- */
-int LSM_DLL_LOCAL number_convert(const char *str_num, int64_t *si, uint64_t *ui,
- long double *d);
-
-
-/**
- * Validates an iSCSI IQN
- * @param iqn iSCSI iqn to check
- * @return LSM_ERR_OK on success, else LSM_ERR_INVALID_ARGUMENT
- */
-int LSM_DLL_LOCAL iqn_validate(const char *iqn);
-
-/**
- * Validates an WWPN
- * @param wwpn wwpn to check
- * @return LSM_ERR_OK on success, else LSM_ERR_INVALID_ARGUMENT
- */
-int LSM_DLL_LOCAL wwpn_validate(const char *wwpn);
-
-/**
- * Given a WWPN validate it and then convert to internal representation.
- * @param wwpn World wide port name to validate
- * @return NULL if not patch, else string with common lsm format
- */
-char LSM_DLL_LOCAL *wwpn_convert(const char *wwpn);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LSM_DATATYPES_H */
diff --git a/c_binding/lsm_ipc.cpp b/c_binding/lsm_ipc.cpp
deleted file mode 100644
index 51c862a..0000000
--- a/c_binding/lsm_ipc.cpp
+++ /dev/null
@@ -1,913 +0,0 @@
-/*
- * Copyright (C) 2011-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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#include "lsm_ipc.hpp"
-
-#include "libstoragemgmt/libstoragemgmt_plug_interface.h"
-
-#include <unistd.h>
-#include <errno.h>
-#include <sys/un.h>
-#include <sys/socket.h>
-#include <string.h>
-#include <iomanip>
-#include <sstream>
-#include <iostream>
-#include <algorithm>
-#include <stdio.h>
-#include <list>
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifdef HAVE_YAJL_YAJL_VERSION_H
-#include <yajl/yajl_version.h>
-#endif
-
-
-#if defined(HAVE_YAJL_YAJL_VERSION_H) && YAJL_MAJOR > 1
- #define LSM_NEW_YAJL
-#endif
-
-static std::string zero_pad_num(unsigned int num)
-{
- std::ostringstream ss;
- ss << std::setw(Transport::HDR_LEN) << std::setfill('0') << num;
- return ss.str();
-}
-
-Transport::Transport() : s(-1)
-{
-}
-
-Transport::Transport(int socket_desc) : s(socket_desc)
-{
-}
-
-int Transport::msg_send(const std::string &msg, int &error_code)
-{
- int rc = -1;
- error_code = 0;
-
- if (msg.size() > 0) {
- ssize_t written = 0;
- //fprintf(stderr, ">>> %s\n", msg.c_str());
- std::string data = zero_pad_num(msg.size()) + msg;
- ssize_t msg_size = data.size();
-
- while (written < msg_size) {
- int wrote = send(s, data.c_str() + written, (msg_size - written),
- MSG_NOSIGNAL); //Prevent SIGPIPE on write
- if (wrote != -1) {
- written += wrote;
- } else {
- error_code = errno;
- break;
- }
- }
-
- if ((written == msg_size) && error_code == 0) {
- rc = 0;
- }
- }
- return rc;
-}
-
-static std::string string_read(int fd, size_t count, int &error_code)
-{
- char buff[4096];
- size_t amount_read = 0;
- std::string rc = "";
-
- error_code = 0;
-
- while (amount_read < count) {
- ssize_t rd = recv(fd, buff, std::min(sizeof(buff),
- (count - amount_read)),
- MSG_WAITALL);
- if (rd > 0) {
- amount_read += rd;
- rc += std::string(buff, rd);
- } else {
- error_code = errno;
- break;
- }
- }
-
- if ((amount_read == count) && (error_code == 0))
- return rc;
- else
- throw EOFException("");
-}
-
-std::string Transport::msg_recv(int &error_code)
-{
- std::string msg;
- error_code = 0;
- unsigned long int payload_len = 0;
- std::string len = string_read(s, HDR_LEN, error_code); //Read the length
- if (len.size() && error_code == 0) {
- payload_len = strtoul(len.c_str(), NULL, 10);
- if( payload_len < 0x80000000 ) { /* Should be big enough */
- msg = string_read(s, payload_len, error_code);
- }
- //fprintf(stderr, "<<< %s\n", msg.c_str());
- }
- return msg;
-}
-
-int Transport::socket_get(const std::string& path, int &error_code)
-{
- int sfd = socket(AF_UNIX, SOCK_STREAM, 0);
- int rc = -1;
- error_code = 0;
-
- if (sfd != -1) {
- struct sockaddr_un addr;
-
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
- strncpy(addr.sun_path, path.c_str(), sizeof(addr.sun_path) - 1);
-
- // Connect
- rc = connect(sfd, (struct sockaddr *) &addr, sizeof(addr));
- if (rc != 0) {
- error_code = errno;
- rc = -1; //Redundant, connect should set to -1 on error
- ::close(sfd);
- } else {
- rc = sfd; //We are good to go.
- }
- }
- return rc;
-}
-
-Transport::~Transport()
-{
- close();
-}
-
-int Transport::close()
-{
- int rc = EBADF;
-
- if (s >= 0) {
- int rc = ::close(s);
- if (rc != 0) {
- rc = errno;
- }
-
- // Regardless, clear out socket
- s = -1;
- }
- return rc;
-}
-
-EOFException::EOFException(std::string m) : std::runtime_error(m)
-{
-}
-
-ValueException::ValueException(std::string m) : std::runtime_error(m)
-{
-}
-
-LsmException::LsmException(int code, std::string &msg) :
-std::runtime_error(msg), error_code(code)
-{
-
-}
-
-LsmException::LsmException(int code, std::string &msg, const std::string &debug_addl):
-std::runtime_error(msg), error_code(code), debug(debug_addl)
-{
-}
-
-LsmException::~LsmException() throw ()
-{
-}
-
-LsmException::LsmException(int code, std::string &msg,
- const std::string &debug_addl,
- const std::string &debug_data_addl) :
-std::runtime_error(msg),
-error_code(code), debug(debug_addl),
-debug_data(debug_data_addl)
-{
-}
-
-Value::Value(void) : t(null_t)
-{
-}
-
-Value::Value(bool v) : t(boolean_t), s((v) ? "true" : "false")
-{
-}
-
-Value::Value(double v) : t(numeric_t), s(to_string(v))
-{
-}
-
-Value::Value(long double v) : t(numeric_t), s(to_string(v))
-{
-}
-
-Value::Value(uint32_t v) : t(numeric_t), s(to_string(v))
-{
-}
-
-Value::Value(int32_t v) : t(numeric_t), s(to_string(v))
-{
-}
-
-Value::Value(uint64_t v) : t(numeric_t), s(to_string(v))
-{
-}
-
-Value::Value(int64_t v) : t(numeric_t), s(to_string(v))
-{
-}
-
-Value::Value(value_type type, const std::string &v) : t(type), s(v)
-{
-}
-
-Value::Value(const std::vector<Value> &v) : t(array_t), array(v)
-{
-}
-
-Value::Value(const char *v)
-{
- if(v) {
- t = string_t;
- s = std::string(v);
- } else {
- t = null_t;
- }
-}
-
-Value::Value(const std::string &v) : t(string_t), s(v)
-{
-}
-
-Value::Value(const std::map<std::string, Value> &v) : t(object_t), obj(v)
-{
-}
-
-std::string Value::serialize(void)
-{
- const unsigned char *buf;
- std::string json;
-
- #ifdef LSM_NEW_YAJL
- size_t len;
- yajl_gen g = yajl_gen_alloc(NULL);
- if( g ) {
- /* These could fail, but we will continue regardless */
- yajl_gen_config(g, yajl_gen_beautify, 1);
- yajl_gen_config(g, yajl_gen_indent_string, " ");
- }
- #else
- unsigned int len;
- yajl_gen_config conf = {1, " "};
- yajl_gen g = yajl_gen_alloc(&conf, NULL);
- #endif
-
- if (g) {
- marshal(g);
-
- if (yajl_gen_status_ok == yajl_gen_get_buf(g, &buf, &len)) {
- json = std::string((const char*) buf);
- }
- yajl_gen_free(g);
- }
- return json;
-}
-
-Value::value_type Value::valueType() const
-{
- return t;
-}
-
-Value& Value::operator[](const std::string &key)
-{
- if( t == object_t ) {
- return obj[key];
- }
- throw ValueException("Value not object");
-}
-
-Value& Value::operator[](uint32_t i)
-{
- if( t == array_t ) {
- return array[i];
- }
- throw ValueException("Value not array");
-}
-
-bool Value::hasKey(const std::string &k)
-{
- if( t == object_t ) {
- std::map<std::string, Value>::iterator iter = obj.find(k);
- if (iter != obj.end() && iter->first == k) {
- return true;
- }
- }
- return false;
-}
-
-bool Value::isValidRequest()
-{
- return (t == Value::object_t && hasKey("method") &&
- hasKey("id") && hasKey("params"));
-}
-
-Value Value::getValue( const char* key )
-{
- if( hasKey(key) ) {
- return obj[key];
- }
- return Value();
-}
-
-const char * Value::asNumString()
-{
- const char *rc = NULL;
-
- if (t == numeric_t) {
- rc = s.c_str();
- }
- return rc;
-}
-
-void * Value::asVoid()
-{
- if (t == null_t) {
- return NULL;
- }
- throw ValueException("Value not null");
-}
-
-bool Value::asBool()
-{
- if (t == boolean_t) {
- return(s == "true");
- }
- throw ValueException("Value not boolean");
-}
-
-double Value::asDouble()
-{
- if (t == numeric_t) {
- double rc;
-
- if (sscanf(s.c_str(), "%lf", &rc) > 0) {
- return rc;
- }
- throw ValueException("Value not a double");
- }
- throw ValueException("Value not numeric");
-}
-
-long double Value::asLongDouble()
-{
- if (t == numeric_t) {
- long double rc;
-
- if (sscanf(s.c_str(), "%Lf", &rc) > 0) {
- return rc;
- }
- throw ValueException("Value not a long double");
- }
- throw ValueException("Value not numeric");
-}
-
-int32_t Value::asInt32_t()
-{
- if (t == numeric_t) {
- int32_t rc;
-
- if (sscanf(s.c_str(), "%d", &rc) > 0) {
- return rc;
- }
- throw ValueException("Value not int32");
- }
- throw ValueException("Value not numeric");
-}
-
-int64_t Value::asInt64_t()
-{
- if (t == numeric_t) {
- int64_t rc;
- if (sscanf(s.c_str(), "%lld", (long long int*) &rc) > 0) {
- return rc;
- }
- throw ValueException("Not an integer");
- }
- throw ValueException("Value not numeric");
-}
-
-uint32_t Value::asUint32_t()
-{
- if (t == numeric_t) {
- uint32_t rc;
- if (sscanf(s.c_str(), "%u", &rc) > 0) {
- return rc;
- }
- throw ValueException("Not an integer");
- }
- throw ValueException("Value not numeric");
-}
-
-uint64_t Value::asUint64_t()
-{
- if (t == numeric_t) {
- uint64_t rc;
- if (sscanf(s.c_str(), "%llu", (long long unsigned int*) &rc) > 0) {
- return rc;
- }
- throw ValueException("Not an integer");
- }
- throw ValueException("Value not numeric");
-}
-
-std::string Value::asString()
-{
- if (t == string_t) {
- return s;
- } else if( t == null_t ) {
- return std::string();
- }
- throw ValueException("Value not string");
-}
-
-const char * Value::asC_str()
-{
- if (t == string_t) {
- return s.c_str();
- } else if( t == null_t ) {
- return NULL;
- }
- throw ValueException("Value not string");
-}
-
-std::map<std::string, Value> Value::asObject()
-{
- if (t == object_t) {
- return obj;
- }
- throw ValueException("Value not object");
-}
-
-std::vector<Value> Value::asArray()
-{
- if (t == array_t) {
- return array;
- }
- throw ValueException("Value not array");
-}
-
-void Value::marshal(yajl_gen g)
-{
- switch (t) {
- case(null_t):
- {
- if (yajl_gen_status_ok != yajl_gen_null(g)) {
- throw ValueException("yajl_gen_null failure");
- }
- break;
- }
- case(boolean_t):
- {
- if (yajl_gen_status_ok != yajl_gen_bool(g, (s == "true") ? 1 : 0)) {
- throw ValueException("yajl_gen_bool failure");
- }
- break;
- }
- case(string_t):
- {
- if (yajl_gen_status_ok !=
- yajl_gen_string(g, (const unsigned char*) s.c_str(), s.size())) {
- throw ValueException("yajl_gen_string failure");
- }
- break;
- }
- case(numeric_t):
- {
- if (yajl_gen_status_ok != yajl_gen_number(g, s.c_str(), s.size())) {
- throw ValueException("yajl_gen_number failure");
- }
- break;
- }
- case(object_t):
- {
-
- if (yajl_gen_status_ok != yajl_gen_map_open(g)) {
- throw ValueException("yajl_gen_map_open failure");
- }
-
- std::map<std::string, Value>::iterator iter;
-
- for (iter = obj.begin(); iter != obj.end(); iter++) {
- if (yajl_gen_status_ok != yajl_gen_string(g,
- (const unsigned char*) iter->first.c_str(),
- iter->first.size())) {
- throw ValueException("yajl_gen_string failure");
- }
- iter->second.marshal(g);
- }
-
- if (yajl_gen_status_ok != yajl_gen_map_close(g)) {
- throw ValueException("yajl_gen_map_close failure");
- }
- break;
- }
- case(array_t):
- {
- if (yajl_gen_status_ok != yajl_gen_array_open(g)) {
- throw ValueException("yajl_gen_array_open failure");
- }
-
- for (unsigned int i = 0; i < array.size(); ++i) {
- array[i].marshal(g);
- }
-
- if (yajl_gen_status_ok != yajl_gen_array_close(g)) {
- throw ValueException("yajl_gen_array_close failure");
- }
- break;
- }
- }
-}
-
-class LSM_DLL_LOCAL ParseElement {
-public:
-
- enum parse_type {
- null, boolean, string, number, begin_map, end_map,
- begin_array, end_array, map_key, unknown
- };
-
- ParseElement() : t(unknown)
- {
- }
-
- ParseElement(parse_type type) : t(type)
- {
- }
-
- ParseElement(parse_type type, std::string value) : t(type), v(value)
- {
- }
- parse_type t;
- std::string v;
-
- std::string to_string()
- {
- return "type " + ::to_string(t) + ": value" + v;
- }
-};
-
-#ifdef LSM_NEW_YAJL
- #define YAJL_SIZE_T size_t
-#else
- #define YAJL_SIZE_T unsigned int
-#endif
-
-static int handle_value(void * ctx, ParseElement::parse_type type)
-{
- std::list<ParseElement> *l = (std::list<ParseElement> *)ctx;
- l->push_back(ParseElement(type));
- return 1;
-}
-
-static int handle_value(void * ctx, ParseElement::parse_type type,
- const char* s, size_t len)
-{
- std::list<ParseElement> *l = (std::list<ParseElement> *)ctx;
- l->push_back(ParseElement(type, std::string(s, len)));
- return 1;
-}
-
-static int handle_null(void * ctx)
-{
- return handle_value(ctx, ParseElement::null);
-}
-
-static int handle_boolean(void * ctx, int boolean)
-{
- std::string b = (boolean) ? "true" : "false";
- return handle_value(ctx, ParseElement::boolean, b.c_str(), b.size());
-}
-
-static int handle_number(void * ctx, const char *s, YAJL_SIZE_T len)
-{
- return handle_value(ctx, ParseElement::number, s, len);
-}
-
-static int handle_string(void * ctx, const unsigned char * stringVal,
- YAJL_SIZE_T len)
-{
- return handle_value(ctx, ParseElement::string, (const char*) stringVal, len);
-}
-
-static int handle_map_key(void * ctx, const unsigned char * stringVal,
- YAJL_SIZE_T len)
-{
- return handle_value(ctx, ParseElement::map_key, (const char*) stringVal, len);
-}
-
-static int handle_start_map(void * ctx)
-{
- return handle_value(ctx, ParseElement::begin_map);
-}
-
-static int handle_end_map(void * ctx)
-{
- return handle_value(ctx, ParseElement::end_map);
-}
-
-static int handle_start_array(void * ctx)
-{
- return handle_value(ctx, ParseElement::begin_array);
-}
-
-static int handle_end_array(void * ctx)
-{
- return handle_value(ctx, ParseElement::end_array);
-}
-
-static yajl_callbacks callbacks = {
- handle_null,
- handle_boolean,
- NULL,
- NULL,
- handle_number,
- handle_string,
- handle_start_map,
- handle_map_key,
- handle_end_map,
- handle_start_array,
- handle_end_array
-};
-
-static ParseElement get_next(std::list<ParseElement> &l)
-{
- ParseElement rc = l.front();
- l.pop_front();
- return rc;
-}
-
-static Value ParseElements(std::list<ParseElement> &l);
-
-static Value HandleArray(std::list<ParseElement> &l)
-{
- std::vector<Value> values;
-
- ParseElement cur;
-
- if (!l.empty()) {
- do {
- cur = l.front();
-
- if (cur.t != ParseElement::end_array) {
- values.push_back(ParseElements(l));
- } else {
- get_next(l);
- }
-
- } while (!l.empty() && cur.t != ParseElement::end_array);
- }
-
- return Value(values);
-}
-
-static Value HandleObject(std::list<ParseElement> &l)
-{
- std::map<std::string, Value> values;
- ParseElement cur;
-
- if (!l.empty()) {
- do {
- cur = get_next(l);
-
- if (cur.t == ParseElement::map_key) {
- values[cur.v] = ParseElements(l);
- } else if (cur.t != ParseElement::end_map) {
- throw ValueException("Unexpected state: " + cur.to_string());
- }
- } while (!l.empty() && cur.t != ParseElement::end_map);
- }
- return Value(values);
-}
-
-static Value ParseElements(std::list<ParseElement> &l)
-{
- if (!l.empty()) {
- ParseElement cur = get_next(l);
-
- switch (cur.t) {
- case (ParseElement::null):
- case (ParseElement::boolean):
- case (ParseElement::string):
- case (ParseElement::number):
- {
- return Value((Value::value_type)cur.t, cur.v);
- break;
- }
- case (ParseElement::begin_map):
- {
- return HandleObject(l);
- break;
- }
- case (ParseElement::end_map):
- {
- throw ValueException("Unexpected end_map");
- break;
- }
- case (ParseElement::begin_array):
- {
- return HandleArray(l);
- break;
- }
- case( ParseElement::end_array):
- {
- throw ValueException("Unexpected end_array");
- break;
- }
- case( ParseElement::map_key):
- {
- throw ValueException("Unexpected map_key");
- break;
- }
- case( ParseElement::unknown):
- {
- throw ValueException("Unexpected unknown");
- break;
- }
- }
- }
- return Value();
-}
-
-std::string Payload::serialize(Value &v)
-{
- return v.serialize();
-}
-
-Value Payload::deserialize(const std::string &json)
-{
- yajl_handle hand;
- yajl_status stat;
- std::list<ParseElement> l;
-
- #ifdef LSM_NEW_YAJL
- hand = yajl_alloc(&callbacks, NULL, (void *) &l);
- yajl_config(hand, yajl_allow_comments, 1);
- #else
- yajl_parser_config cfg = {1, 1};
- hand = yajl_alloc(&callbacks, &cfg, NULL, (void *) &l);
- #endif
-
- if (hand) {
- stat = yajl_parse(hand, (const unsigned char*) json.c_str(), json.size());
- yajl_free(hand);
-
- if (stat == yajl_status_ok) {
- return ParseElements(l);
- } else {
- throw ValueException("In-valid json");
- }
- }
- return Value();
-}
-
-Ipc::Ipc()
-{
-}
-
-Ipc::Ipc(int fd):t(fd)
-{
-}
-
-Ipc::Ipc(std::string socket_path)
-{
- int e = 0;
- int fd = Transport::socket_get(socket_path, e);
- if (fd >= 0) {
- t = Transport(fd);
- }
-}
-
-Ipc::~Ipc()
-{
- t.close();
-}
-
-void Ipc::requestSend(const std::string request, const Value &params, int32_t id)
-{
- int rc = 0;
- int ec = 0;
- std::map<std::string, Value> v;
-
- v["method"] = Value(request);
- v["id"] = Value(id);
- v["params"] = params;
-
- Value req(v);
- rc = t.msg_send(Payload::serialize(req), ec);
-
- if( rc != 0 ) {
- std::string em = std::string("Error sending message: errno ")
- + ::to_string(ec);
- throw LsmException((int)LSM_ERR_TRANSPORT_COMMUNICATION, em);
- }
-}
-
-void Ipc::errorSend(int error_code, std::string msg, std::string debug,
- uint32_t id)
-{
- int ec = 0;
- int rc = 0;
- std::map<std::string, Value> v;
- std::map<std::string, Value> error_data;
-
- error_data["code"] = Value(error_code);
- error_data["message"] = Value(msg);
- error_data["data"] = Value(debug);
-
- v["error"] = Value(error_data);
- v["id"] = Value(id);
-
- Value e(v);
- rc = t.msg_send(Payload::serialize(e), ec);
-
- if( rc != 0 ) {
- std::string em = std::string("Error sending error message: errno ")
- + ::to_string(ec);
- throw LsmException((int)LSM_ERR_TRANSPORT_COMMUNICATION, em);
- }
-}
-
-Value Ipc::readRequest(void)
-{
- int ec;
- std::string resp = t.msg_recv(ec);
- return Payload::deserialize(resp);
-}
-
-void Ipc::responseSend(const Value &response, uint32_t id)
-{
- int rc;
- int ec;
- std::map<std::string, Value> v;
-
- v["id"] = id;
- v["result"] = response;
-
- Value resp(v);
- rc = t.msg_send(Payload::serialize(resp), ec);
-
- if( rc != 0 ) {
- std::string em = std::string("Error sending response: errno ")
- + ::to_string(ec);
- throw LsmException((int)LSM_ERR_TRANSPORT_COMMUNICATION, em);
- }
-}
-
-Value Ipc::responseRead()
-{
- Value r = readRequest();
- if( r.hasKey(std::string("result"))) {
- return r.getValue("result");
- } else {
- std::map<std::string, Value> rp = r.asObject();
- std::map<std::string, Value> error = rp["error"].asObject();
-
- std::string msg = error["message"].asString();
- std::string data = error["data"].asString();
- throw LsmException((int)(error["code"].asInt32_t()), msg, data);
- }
-}
-
-Value Ipc::rpc(const std::string &request, const Value &params, int32_t id)
-{
- requestSend(request, params, id);
- return responseRead();
-}
diff --git a/c_binding/lsm_ipc.hpp b/c_binding/lsm_ipc.hpp
deleted file mode 100644
index 8377386..0000000
--- a/c_binding/lsm_ipc.hpp
+++ /dev/null
@@ -1,481 +0,0 @@
-/*
- * Copyright (C) 2011-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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#ifndef LSM_IPC_H
-#define LSM_IPC_H
-
-#include "libstoragemgmt/libstoragemgmt_common.h"
-#include <yajl/yajl_parse.h>
-#include <yajl/yajl_gen.h>
-#include <stdint.h>
-#include <string>
-#include <map>
-#include <vector>
-#include <sstream>
-#include <stdexcept>
-
-//Common serialization
-
-/**
- * Sends and receives payloads, unaware of the contents.
- * Notes: Not thread safe. i.e. you cannot share the same object with two or
- * more threads.
- */
-class LSM_DLL_LOCAL Transport {
-public:
-
- /**
- * Size of the header which immediately proceeds the payload.
- */
- const static int HDR_LEN = 10;
-
- /**
- * Empty ctor.
- * @return
- */
- Transport();
-
- /**
- * Class ctor
- * @param socket_desc Connected socket descriptor.
- */
- Transport(int socket_desc);
-
- /**
- * Class dtor
- */
- ~Transport();
-
- /**
- * Sends a message over the transport.
- * @param[in] msg The message to be sent.
- * @param[out] error_code Errno (only valid if we return -1)
- * @return 0 on success, else -1
- */
- int msg_send(const std::string &msg, int &error_code);
-
- /**
- * Received a message over the transport.
- * Note: A zero read indicates that the transport was closed by other side,
- * no error code will be set in that case.
- * @param error_code (0 on success, else errno)
- * @return Message on success else 0 size with error_code set (not if EOF)
- */
- std::string msg_recv(int &error_code);
-
- /**
- * Creates a connected socket (AF_UNIX) to the specified path
- * @param path of the AF_UNIX file to be used for IPC
- * @param error_code Error reason for the failure (errno)
- * @return -1 on error, else connected socket.
- */
- static int socket_get(const std::string &path, int &error_code);
-
- /**
- * Closes the transport, called in the destructor if not done in advance.
- * @return 0 on success, else EBADF, EINTR, EIO.
- */
- int close();
-
-private:
- int s; //Socket descriptor
-};
-
-/**
- * Generic function to convert Type v into a string.
- * @param v Template type T
- * @return string representation
- */
-template <class Type> static std::string to_string(Type v) {
- std::stringstream out;
- out << v;
- return out.str();
-}
-
-/**
- * Class that represents an EOF condition
- * @param m Message
- */
-class LSM_DLL_LOCAL EOFException : public std::runtime_error {
-public:
- EOFException(std::string m);
-};
-
-
-/**
- * User defined class for Value errors during serialize / de-serialize.
- */
-class LSM_DLL_LOCAL ValueException : public std::runtime_error {
-public:
- /**
- * Constructor
- * @param m Exception message
- */
- ValueException(std::string m);
-};
-
-/**
- * User defined class for errors
- */
-class LSM_DLL_LOCAL LsmException : public std::runtime_error {
-public:
-
- /**
- * Constructor
- * @param code Error code
- * @param msg Error message
- */
- LsmException(int code, std::string &msg);
-
- /**
- * Constructor
- * @param code Error code
- * @param msg Error message
- * @param debug_addl Additional debug data
- */
- LsmException(int code, std::string &msg, const std::string &debug_addl);
-
- /**
- * Constructor
- * @param code Error code
- * @param msg Error message
- * @param debug_addl Additional debug
- * @param debug_data_addl Additional debug data
- */
- LsmException(int code, std::string &msg, const std::string &debug_addl,
- const std::string &debug_data_addl);
-
- /**
- * Destructor
- */
- ~LsmException() throw ();
-
- int error_code;
- std::string debug;
- std::string debug_data;
-};
-
-/**
- * Represents a value in the serialization.
- */
-class LSM_DLL_LOCAL Value {
-public:
-
- /**
- * Different types this class can hold.
- */
- enum value_type {
- null_t, boolean_t, string_t, numeric_t, object_t, array_t
- };
-
- /**
- * Default constructor creates a "null" type
- */
- Value(void);
-
- /**
- * Boolean constructor
- * @param v value
- */
- Value(bool v);
-
- /**
- * Numeric double constructor.
- * @param v value
- */
- Value(double v);
- Value(long double v);
-
- /**
- * Numeric unsigned 32 constructor
- * @param v value
- */
- Value(uint32_t v);
-
- /**
- * Numeric signed 32 constructor
- * @param v value
- */
- Value(int32_t v);
-
- /**
- * Numeric unsigned 64 constructor.
- * @param v value
- */
- Value(uint64_t v);
-
- /**
- * Numeric signed 64 constructor.
- * @param v value
- */
- Value(int64_t v);
-
- /**
- * Constructor in which you specify type and initial value as string.
- * @param type Type this object will hold.
- * @param v value
- */
- Value(value_type type, const std::string &v);
-
- /**
- * Constructor for char * i.e. string.
- * @param v value
- */
- Value(const char *v);
-
- /**
- * Constructor for std::string
- * @param v value
- */
- Value(const std::string &v);
-
- /**
- * Constructor for object type
- * @param v values
- */
- Value(const std::map<std::string, Value> &v);
-
- /**
- * Constructor for array type
- * @param v array values
- */
- Value(const std::vector<Value> &v);
-
- /**
- * Serialize Value to json
- * @return
- */
- std::string serialize(void);
-
- /**
- * Returns the enumerated type represented by object
- * @return enumerated type
- */
- value_type valueType() const;
-
- /**
- * Overloaded operator for map access
- * @param key
- * @return Value
- */
- Value& operator[](const std::string &key);
-
- /**
- * Overloaded operator for vector(array) access
- * @param i
- * @return Value
- */
- Value& operator[](uint32_t i);
-
- /**
- * Returns true if value has a key in key/value pair
- * @return true if key exists, else false.
- */
- bool hasKey(const std::string &k);
-
- /**
- * Checks to see if a Value contains a valid request
- * @return True if it is a request, else false
- */
- bool isValidRequest(void);
-
- /**
- * Given a key returns the value.
- * @param key
- * @return Value
- */
- Value getValue(const char* key);
-
- /**
- * Returns a numeric as the string holding it.
- */
- const char* asNumString();
-
- /**
- * Returns NULL if void type, else ValueException
- * @return NULL
- */
- void * asVoid();
-
- /**
- * Boolean value represented by object.
- * @return true, false ValueException on error
- */
- bool asBool();
-
- /**
- * Double value represented by object.
- * @return double value else ValueException on error
- */
- double asDouble();
- long double asLongDouble();
-
- /**
- * Signed 32 integer value represented by object.
- * @return integer value else ValueException on error
- */
- int32_t asInt32_t();
-
- /**
- * Signed 64 integer value represented by object.
- * @return integer value else ValueException on error
- */
- int64_t asInt64_t();
-
- /**
- * Unsigned 32 integer value represented by object.
- * @return integer value else ValueException on error
- */
- uint32_t asUint32_t();
-
- /**
- * Unsigned 64 integer value represented by object.
- * @return integer value else ValueException on error
- */
- uint64_t asUint64_t();
-
- /**
- * String value represented by object.
- * @return string value else ValueException on error
- */
- std::string asString();
-
- /**
- * Return string as a pointer to a character array
- * @return
- */
- const char *asC_str();
-
- /**
- * key/value represented by object.
- * @return map of key and values else ValueException on error
- */
- std::map<std::string, Value> asObject();
-
- /**
- * vector of values represented by object.
- * @return vector of array values else ValueException on error
- */
- std::vector<Value> asArray();
-
-private:
- value_type t;
- std::string s;
- std::map<std::string, Value> obj;
- std::vector<Value> array;
-
- void marshal(yajl_gen g);
-};
-
-/**
- * Serialize, de-serialize methods.
- */
-class LSM_DLL_LOCAL Payload {
-public:
- /**
- * Given a Value returns json representation.
- * @param v Value to serialize
- * @return String representation
- */
- static std::string serialize(Value &v);
-
- /**
- * Given a json string return a Value
- * @param json String to de-serialize
- * @return Value
- */
- static Value deserialize(const std::string &json);
-};
-
-class LSM_DLL_LOCAL Ipc {
-public:
- /**
- * Constructor
- */
- Ipc();
-
- /**
- * Constructor that takes a file descriptor
- * @param fd File descriptor to use
- */
- Ipc(int fd);
-
- /**
- * Constructor that takes a socket path
- * @param socket_path Unix domain socket
- */
- Ipc(std::string socket_path);
-
- /**
- * Destructor
- */
- ~Ipc();
-
- /**
- * Send a request over IPC
- * @param request IPC function name
- * @param params Parameters
- * @param id Request ID
- */
- void requestSend(const std::string request, const Value &params,
- int32_t id = 100);
- /**
- * Reads a request
- * @returns Value
- */
- Value readRequest(void);
-
- /**
- * Send a response to a request
- * @param response Response value
- * @param id Id that matches request
- */
- void responseSend(const Value &response, uint32_t id = 100);
-
- /**
- * Read a response
- * @return Value of response
- */
- Value responseRead();
-
- /**
- * Send an error
- * @param error_code Error code
- * @param msg Error message
- * @param debug Debug data
- * @param id Id that matches request
- */
- void errorSend(int error_code, std::string msg, std::string debug,
- uint32_t id = 100);
-
- /**
- * Do a remote procedure call (Request with a returned response
- * @param request Function method
- * @param params Function parameters
- * @param id Id of request
- * @return Result of the operation.
- */
- Value rpc(const std::string &request, const Value &params, int32_t id = 100);
-
-
-private:
- Transport t;
-};
-
-#endif
\ No newline at end of file
diff --git a/c_binding/lsm_mgmt.cpp b/c_binding/lsm_mgmt.cpp
deleted file mode 100644
index e6a254f..0000000
--- a/c_binding/lsm_mgmt.cpp
+++ /dev/null
@@ -1,2210 +0,0 @@
-/*
- * Copyright (C) 2011-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 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#include "libstoragemgmt/libstoragemgmt.h"
-#include "libstoragemgmt/libstoragemgmt_error.h"
-#include "libstoragemgmt/libstoragemgmt_plug_interface.h"
-#include "libstoragemgmt/libstoragemgmt_types.h"
-#include <stdio.h>
-#include <string.h>
-#include <dirent.h>
-#include <libxml/uri.h>
-
-#include "lsm_datatypes.hpp"
-#include "lsm_convert.hpp"
-
-#define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
-
-static const char * const POOL_SEARCH_KEYS[] = { "id", "system_id" };
-#define POOL_SEARCH_KEYS_COUNT COUNT_OF(POOL_SEARCH_KEYS)
-
-static const char * const VOLUME_SEARCH_KEYS[] = {"id", "system_id", "pool_id"};
-#define VOLUME_SEARCH_KEYS_COUNT COUNT_OF(VOLUME_SEARCH_KEYS)
-
-static const char * const DISK_SEARCH_KEYS[] = {"id", "system_id"};
-#define DISK_SEARCH_KEYS_COUNT COUNT_OF(DISK_SEARCH_KEYS)
-
-static const char * const FS_SEARCH_KEYS[] = {"id", "system_id", "pool_id"};
-#define FS_SEARCH_KEYS_COUNT COUNT_OF(FS_SEARCH_KEYS)
-
-static const char * const NFS_EXPORT_SEARCH_KEYS[] = {"id", "fs_id"};
-#define NFS_EXPORT_SEARCH_KEYS_COUNT COUNT_OF(NFS_EXPORT_SEARCH_KEYS)
-
-static const char * const ACCESS_GROUP_SEARCH_KEYS[] = {"id", "system_id"};
-#define ACCESS_GROUP_SEARCH_KEYS_COUNT COUNT_OF(ACCESS_GROUP_SEARCH_KEYS)
-
-static const char * const TARGET_PORT_SEARCH_KEYS[] = {"id", "system_id"};
-#define TARGET_PORT_SEARCH_KEYS_COUNT COUNT_OF(TARGET_PORT_SEARCH_KEYS)
-
-/**
- * Common code to validate and initialize the connection.
- */
-#define CONN_SETUP(c) do { \
- if(!LSM_IS_CONNECT(c)) { \
- return LSM_ERR_INVALID_ARGUMENT;\
- } \
- lsm_error_free(c->error); \
- c->error = NULL; \
- } while (0)
-
-static int check_search_key(const char *search_key,
- const char * const supported_keys[],
- size_t supported_keys_count)
-{
- size_t i = 0;
- for( i = 0; i < supported_keys_count; ++i ) {
- if( 0 == strcmp(search_key, supported_keys[i])) {
- return 1;
- }
- }
- return 0;
-}
-
-int lsm_initiator_id_verify(const char *init_id,
- lsm_access_group_init_type *init_type)
-{
- int rc = LSM_ERR_INVALID_ARGUMENT;
-
- if( init_id != NULL && strlen(init_id) > 3 ) {
-
- switch( *init_type ) {
- case( LSM_ACCESS_GROUP_INIT_TYPE_UNKNOWN ):
- if( 0 == iqn_validate(init_id) ) {
- *init_type = LSM_ACCESS_GROUP_INIT_TYPE_ISCSI_IQN;
- rc = LSM_ERR_OK;
- }
- if( 0 == wwpn_validate(init_id) ) {
- *init_type = LSM_ACCESS_GROUP_INIT_TYPE_WWPN;
- rc = LSM_ERR_OK;
- }
- break;
- case( LSM_ACCESS_GROUP_INIT_TYPE_ISCSI_IQN ):
- if( 0 == iqn_validate(init_id) ) {
- *init_type = LSM_ACCESS_GROUP_INIT_TYPE_ISCSI_IQN;
- rc = LSM_ERR_OK;
- }
- break;
- case( LSM_ACCESS_GROUP_INIT_TYPE_WWPN ):
- if( 0 == wwpn_validate(init_id) ) {
- *init_type = LSM_ACCESS_GROUP_INIT_TYPE_WWPN;
- rc = LSM_ERR_OK;
- }
- break;
- default:
- break;
- }
- }
- return rc;
-}
-
-int lsm_volume_vpd83_verify( const char *vpd83 )
-{
- int rc = LSM_ERR_INVALID_ARGUMENT;
- int i;
-
- if( vpd83 && strlen(vpd83) == 32 ) {
- for(i = 0; i < 32; ++i) {
- char v = vpd83[i];
- // 0-9 || a-f is OK
- if( !((v >= 48 && v <= 57) || (v >= 97 && v <= 102)) ) {
- return rc;
- }
- }
- rc = LSM_ERR_OK;
- }
- return rc;
-}
-
-static int verify_initiator_id(const char *id, lsm_access_group_init_type t,
- Value &initiator)
-{
- initiator = Value(id);
-
- if( t == LSM_ACCESS_GROUP_INIT_TYPE_WWPN ) {
- char *wwpn = wwpn_convert(id);
- if( wwpn ) {
- initiator = Value(wwpn);
- free(wwpn);
- wwpn = NULL;
- } else {
- return LSM_ERR_INVALID_ARGUMENT;
- }
- } else if( t == LSM_ACCESS_GROUP_INIT_TYPE_ISCSI_IQN ) {
- if( iqn_validate(id) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
- }
- return LSM_ERR_OK;
-}
-
-/**
- * Strings are non null with a len >= 1
- */
-#define CHECK_STR(x) ( !(x) || !strlen(x) )
-
-/**
- * When we pass in a pointer for an out value we want to make sure that
- * the pointer isn't null, and that the dereferenced value is != NULL to prevent
- * memory leaks.
- */
-#define CHECK_RP(x) (!(x) || *(x) != NULL)
-
-int lsm_connect_password(const char *uri, const char *password,
- lsm_connect **conn, uint32_t timeout, lsm_error_ptr *e,
- lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- lsm_connect *c = NULL;
-
- /* Password is optional */
- if( CHECK_STR(uri) || CHECK_RP(conn) || !timeout || CHECK_RP(e) ||
- LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- c = connection_get();
- if(c) {
- c->uri = xmlParseURI(uri);
- if( c->uri && c->uri->scheme ) {
- c->raw_uri = strdup(uri);
- if( c->raw_uri ) {
- rc = driver_load(c, c->uri->scheme, password, timeout, e, 1,
- flags);
- if( rc == LSM_ERR_OK ) {
- *conn = (lsm_connect *)c;
- }
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
- } else {
- rc = LSM_ERR_INVALID_ARGUMENT;
- }
-
- /*If we fail for any reason free resources associated with connection*/
- if( rc != LSM_ERR_OK ) {
- connection_free(c);
- }
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
- return rc;
-}
-
-static int lsmErrorLog(lsm_connect *c, lsm_error_ptr error)
-{
- if ( !LSM_IS_CONNECT(c) || !LSM_IS_ERROR(error) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- if (c->error) {
- lsm_error_free(c->error);
- c->error = NULL;
- }
-
- c->error = error;
- return LSM_ERR_OK;
-}
-
-static lsm_error_number logException(lsm_connect *c, lsm_error_number error,
- const char *message, const char *exception_msg)
-{
- lsm_error_ptr err = lsm_error_create(error, message,
- exception_msg, NULL,
- NULL, 0);
- if( err ) {
- lsmErrorLog(c, err);
- }
- return error;
-}
-
-static int rpc(lsm_connect *c, const char *method, const Value &parameters,
- Value &response) throw ()
-{
- try {
- response = c->tp->rpc(method,parameters);
- } catch ( const ValueException &ve ) {
- return logException(c, LSM_ERR_TRANSPORT_SERIALIZATION, "Serialization error",
- ve.what());
- } catch ( const LsmException &le ) {
- return logException(c, (lsm_error_number)le.error_code, le.what(),
- NULL);
- } catch ( const EOFException &eof ) {
- return logException(c, LSM_ERR_TRANSPORT_COMMUNICATION, "Plug-in died",
- "Check syslog");
- } catch (...) {
- return logException(c, LSM_ERR_LIB_BUG, "Unexpected exception",
- "Unknown exception");
- }
- return LSM_ERR_OK;
-}
-
-static int jobCheck( lsm_connect *c, int rc, Value &response, char **job )
-{
- try {
- if( LSM_ERR_OK == rc ) {
- //We get a value back, either null or job id.
- if( Value::string_t == response.valueType() ) {
- *job = strdup(response.asString().c_str());
-
- if( *job ) {
- rc = LSM_ERR_JOB_STARTED;
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
- } else {
- *job = NULL;
- }
- }
- } catch (const ValueException &ve) {
- rc = logException(c, LSM_ERR_LIB_BUG, "Wrong type",
- ve.what());
- }
- return rc;
-}
-
-static int getAccessGroups( lsm_connect *c, int rc, Value &response,
- lsm_access_group **groups[], uint32_t *count)
-{
- try {
- if( LSM_ERR_OK == rc && Value::array_t == response.valueType()) {
- *groups = value_to_access_group_list(response, count);
- }
- } catch( const ValueException &ve ) {
- rc = logException(c, LSM_ERR_LIB_BUG, "Unexpected type",
- ve.what());
- }
- return rc;
-}
-
-static int add_search_params(std::map<std::string, Value> &p, const char *k,
- const char *v, const char * const supported_keys[],
- size_t supported_keys_count)
-{
- if( k ) {
- if( v ) {
- if( !check_search_key(k, supported_keys, supported_keys_count) ) {
- return LSM_ERR_UNSUPPORTED_SEARCH_KEY;
- }
- } else {
- return LSM_ERR_INVALID_ARGUMENT;
- }
- }
- p["search_key"] = Value(k);
- p["search_value"] = Value(v);
- return LSM_ERR_OK;
-}
-
-int lsm_connect_close(lsm_connect *c, lsm_flag flags)
-{
- CONN_SETUP(c);
-
- if( LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- std::map<std::string, Value> p;
- p["flags"] = Value(flags);
- Value parameters(p);
- Value response;
-
- //No response data needed on plugin_unregister
- int rc = rpc(c, "plugin_unregister", parameters, response);
-
- //Free the connection.
- connection_free(c);
- return rc;
-}
-
-static Value _create_flag_param(lsm_flag flags)
-{
- std::map<std::string, Value> p;
- p["flags"] = Value(flags);
- return Value(p);
-}
-
-int lsm_plugin_info_get(lsm_connect *c, char **desc,
- char **version, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- CONN_SETUP(c);
-
- if( LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- if( CHECK_RP(desc) || CHECK_RP(version) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- try {
-
- Value parameters = _create_flag_param(flags);
- Value response;
-
- rc = rpc(c, "plugin_info", parameters, response);
-
- if( rc == LSM_ERR_OK ) {
- std::vector<Value> j = response.asArray();
- *desc = strdup(j[0].asC_str());
- *version = strdup(j[1].asC_str());
-
- if( !*desc || !*version ) {
- rc = LSM_ERR_NO_MEMORY;
- free(*desc);
- free(*version);
- }
- }
- } catch (const ValueException &ve) {
- free(*desc);
- *desc = NULL;
- free(*version);
- *version = NULL;
- rc = logException(c, LSM_ERR_LIB_BUG, "Unexpected type",
- ve.what());
- }
-
- return rc;
-}
-
-int lsm_available_plugins_list(const char *sep,
- lsm_string_list **plugins,
- lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- DIR *dirp = NULL;
- struct dirent *dp = NULL;
- lsm_connect *c = NULL;
- lsm_error_ptr e = NULL;
- char *desc = NULL;
- char *version = NULL;
- char *s = NULL;
- const char *uds_dir = uds_path();
- lsm_string_list *plugin_list = NULL;
-
- if( CHECK_STR(sep) || CHECK_RP(plugins) || LSM_FLAG_UNUSED_CHECK(flags)) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- plugin_list = lsm_string_list_alloc(0);
- if( !plugin_list ) {
- return LSM_ERR_NO_MEMORY;
- }
-
- dirp = opendir(uds_dir);
- if( dirp ) {
- for(;;) {
- dp = readdir(dirp);
- if( NULL == dp ) {
- break;
- }
-
- // Check to see if we have a socket
- if( DT_SOCK == dp->d_type ) {
- c = connection_get();
- if ( c ) {
- rc = driver_load(c, dp->d_name, NULL, 30000, &e, 0, 0);
- if( LSM_ERR_OK == rc) {
- // Get the plugin information
- rc = lsm_plugin_info_get(c, &desc, &version, 0);
- if( LSM_ERR_OK == rc) {
- int format = asprintf(&s, "%s%s%s", desc, sep, version);
- free(desc);
- desc = NULL;
- free(version);
- version = NULL;
-
- if( -1 == format ) {
- rc = LSM_ERR_NO_MEMORY;
- break;
- }
-
- rc = lsm_string_list_append(plugin_list, s);
- free(s);
- s = NULL;
- if( LSM_ERR_OK != rc ) {
- break;
- }
-
- }
- } else {
- break;
- }
-
- connection_free(c);
- c = NULL;
- }
- }
- } /* for(;;) */
-
- if( e ) {
- lsm_error_free(e);
- e = NULL;
- }
-
- if( c ) {
- connection_free(c);
- c = NULL;
- }
-
-
- if( -1 == closedir(dirp)) {
- //log the error
- rc = LSM_ERR_LIB_BUG;
- }
-
- } else { /* If dirp == NULL */
- //Log the error
- rc = LSM_ERR_LIB_BUG;
- }
-
- if (LSM_ERR_OK == rc) {
- *plugins = plugin_list;
- } else {
- lsm_string_list_free(plugin_list);
- plugin_list = NULL;
- }
-
- return rc;
-}
-
-int lsm_connect_timeout_set(lsm_connect *c, uint32_t timeout, lsm_flag flags)
-{
- CONN_SETUP(c);
-
- if( LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- std::map<std::string, Value> p;
- p["ms"] = Value(timeout);
- p["flags"] = Value(flags);
- Value parameters(p);
- Value response;
-
- //No response data needed on set time out.
- return rpc(c, "time_out_set", parameters, response);
-}
-
-int lsm_connect_timeout_get(lsm_connect *c, uint32_t *timeout, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- CONN_SETUP(c);
-
- if( LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- try {
-
- Value parameters = _create_flag_param(flags);
- Value response;
-
- rc = rpc(c, "time_out_get", parameters, response);
- if( rc == LSM_ERR_OK ) {
- *timeout = response.asUint32_t();
- }
- }
- catch( const ValueException &ve ) {
- rc = logException(c, LSM_ERR_LIB_BUG, "Unexpected type",
- ve.what());
- }
- return rc;
-}
-
-static int jobStatus( lsm_connect *c, const char *job,
- lsm_job_status *status, uint8_t *percentComplete,
- Value &returned_value, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- CONN_SETUP(c);
-
- if( !job || !status || !percentComplete ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- try {
- std::map<std::string, Value> p;
- p["job_id"] = Value(job);
- p["flags"] = Value(flags);
- Value parameters(p);
- Value response;
-
- rc = rpc(c, "job_status", parameters, response);
- if( LSM_ERR_OK == rc ) {
- //We get back an array [status, percent, volume]
- std::vector<Value> j = response.asArray();
- *status = (lsm_job_status)j[0].asInt32_t();
- *percentComplete = (uint8_t)j[1].asUint32_t();
-
- returned_value = j[2];
- }
- } catch( const ValueException &ve ) {
- rc = logException(c, LSM_ERR_LIB_BUG, "Unexpected type",
- ve.what());
- }
- return rc;
-}
-
-int lsm_job_status_get(lsm_connect *c, const char *job_id,
- lsm_job_status *status, uint8_t *percentComplete,
- lsm_flag flags)
-{
- CONN_SETUP(c);
-
- if( LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- Value rv;
- return jobStatus(c, job_id, status, percentComplete, rv, flags);
-}
-
-int lsm_job_status_pool_get(lsm_connect *c,
- const char *job, lsm_job_status *status,
- uint8_t *percentComplete, lsm_pool **pool,
- lsm_flag flags)
-{
- Value rv;
- int rc = LSM_ERR_OK;
-
- CONN_SETUP(c);
-
- if( CHECK_RP(pool) || LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- try {
-
- rc = jobStatus(c, job, status, percentComplete, rv, flags);
-
- if( LSM_ERR_OK == rc ) {
- if( Value::object_t == rv.valueType() ) {
- *pool = value_to_pool(rv);
- } else {
- *pool = NULL;
- }
- }
- } catch( const ValueException &ve ) {
- rc = logException(c, LSM_ERR_LIB_BUG, "Unexpected type",
- ve.what());
- }
- return rc;
-}
-
-int lsm_job_status_volume_get( lsm_connect *c, const char *job,
- lsm_job_status *status, uint8_t *percentComplete,
- lsm_volume **vol, lsm_flag flags)
-{
- Value rv;
- int rc = LSM_ERR_OK;
-
- CONN_SETUP(c);
-
- if( CHECK_RP(vol) || LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- try {
-
- rc = jobStatus(c, job, status, percentComplete, rv, flags);
-
- if( LSM_ERR_OK == rc ) {
- if( Value::object_t == rv.valueType() ) {
- *vol = value_to_volume(rv);
- } else {
- *vol = NULL;
- }
- }
- } catch( const ValueException &ve ) {
- rc = logException(c, LSM_ERR_LIB_BUG, "Unexpected type",
- ve.what());
- }
- return rc;
-}
-
-int lsm_job_status_fs_get(lsm_connect *c, const char *job,
- lsm_job_status *status, uint8_t *percentComplete,
- lsm_fs **fs, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- Value rv;
-
- if( CHECK_RP(fs) || LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- try {
-
- rc = jobStatus(c, job, status, percentComplete, rv, flags);
-
- if( LSM_ERR_OK == rc ) {
- if( Value::object_t == rv.valueType() ) {
- *fs = value_to_fs(rv);
- } else {
- *fs = NULL;
- }
- }
- } catch( const ValueException &ve) {
- rc = logException(c, LSM_ERR_LIB_BUG, "Unexpected type",
- ve.what());
- }
- return rc;
-}
-
-int lsm_job_status_ss_get(lsm_connect *c, const char *job,
- lsm_job_status *status, uint8_t *percentComplete,
- lsm_fs_ss **ss, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- Value rv;
-
- if( CHECK_RP(ss) || LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- try {
-
- rc = jobStatus(c, job, status, percentComplete, rv, flags);
-
- if( LSM_ERR_OK == rc ) {
- if( Value::object_t == rv.valueType() ) {
- *ss = value_to_ss(rv);
- } else {
- *ss = NULL;
- }
- }
- } catch( const ValueException &ve ) {
- rc = logException(c, LSM_ERR_LIB_BUG, "Unexpected type",
- ve.what());
- }
- return rc;
-}
-
-int lsm_job_free(lsm_connect *c, char **job, lsm_flag flags)
-{
- CONN_SETUP(c);
-
- if( job == NULL || strlen(*job) < 1 || LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- std::map<std::string, Value> p;
- p["job_id"] = Value(*job);
- p["flags"] = Value(flags);
- Value parameters(p);
- Value response;
-
- int rc = rpc(c, "job_free", parameters, response);
-
- if( LSM_ERR_OK == rc ) {
- /* Free the memory for the job id */
- free(*job);
- *job = NULL;
- }
- return rc;
-}
-
-int lsm_capabilities(lsm_connect *c, lsm_system *system,
- lsm_storage_capabilities **cap, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- CONN_SETUP(c);
-
- if( !LSM_IS_SYSTEM(system) || CHECK_RP(cap) ||
- LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- std::map<std::string, Value> p;
-
- p["system"] = system_to_value(system);
- p["flags"] = Value(flags);
-
- Value parameters(p);
- Value response;
-
- try {
- rc = rpc(c, "capabilities", parameters, response);
-
- if( LSM_ERR_OK == rc && Value::object_t == response.valueType() ) {
- *cap = value_to_capabilities(response);
- }
- } catch( const ValueException &ve ) {
- rc = logException(c, LSM_ERR_LIB_BUG, "Unexpected type",
- ve.what());
- }
-
- return rc;
-}
-
-int lsm_pool_list(lsm_connect *c, char *search_key, char *search_value,
- lsm_pool **poolArray[], uint32_t *count, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- CONN_SETUP(c);
-
- if( !poolArray || !count || CHECK_RP(poolArray) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- try {
- std::map<std::string, Value> p;
-
- rc = add_search_params(p, search_key, search_value, POOL_SEARCH_KEYS,
- POOL_SEARCH_KEYS_COUNT);
- if( LSM_ERR_OK != rc ) {
- return rc;
- }
-
- p["flags"] = Value(flags);
- Value parameters(p);
- Value response;
-
- rc = rpc(c, "pools", parameters, response);
- if( LSM_ERR_OK == rc && Value::array_t == response.valueType()) {
- std::vector<Value> pools = response.asArray();
-
- *count = pools.size();
-
- if( pools.size() ) {
- *poolArray = lsm_pool_record_array_alloc(pools.size());
-
- for( size_t i = 0; i < pools.size(); ++i ) {
- (*poolArray)[i] = value_to_pool(pools[i]);
- }
- }
- }
- } catch( const ValueException &ve ) {
- rc = logException(c, LSM_ERR_LIB_BUG, "Unexpected type",
- ve.what());
- if( *poolArray && *count ) {
- lsm_pool_record_array_free(*poolArray, *count);
- *poolArray = NULL;
- *count = 0;
- }
- }
- return rc;
-}
-
-int lsm_target_port_list(lsm_connect *c, const char *search_key,
- const char *search_value,
- lsm_target_port **target_ports[],
- uint32_t *count,
- lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- CONN_SETUP(c);
-
- if( !target_ports || !count || CHECK_RP(target_ports )) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- try {
- std::map<std::string, Value> p;
-
- rc = add_search_params(p, search_key, search_value,
- TARGET_PORT_SEARCH_KEYS,
- TARGET_PORT_SEARCH_KEYS_COUNT);
- if( LSM_ERR_OK != rc ) {
- return rc;
- }
-
- p["flags"] = Value(flags);
- Value parameters(p);
- Value response;
-
- rc = rpc(c, "target_ports", parameters, response);
- if( LSM_ERR_OK == rc && Value::array_t == response.valueType()) {
- std::vector<Value> tp = response.asArray();
-
- *count = tp.size();
-
- if( tp.size() ) {
- *target_ports = lsm_target_port_record_array_alloc(tp.size());
-
- for( size_t i = 0; i < tp.size(); ++i ) {
- (*target_ports)[i] = value_to_target_port(tp[i]);
- }
- }
- }
- } catch( const ValueException &ve ) {
- rc = logException(c, LSM_ERR_LIB_BUG, "Unexpected type",
- ve.what());
- if( *target_ports && *count ) {
- lsm_target_port_record_array_free(*target_ports, *count);
- *target_ports = NULL;
- *count = 0;
- }
- }
- return rc;
-}
-
-static int get_volume_array(lsm_connect *c, int rc, Value &response,
- lsm_volume **volumes[], uint32_t *count)
-{
- if( LSM_ERR_OK == rc && Value::array_t == response.valueType()) {
- rc = value_array_to_volumes(response, volumes, count);
-
- if( LSM_ERR_OK != rc ) {
- rc = logException(c, LSM_ERR_LIB_BUG, "Unexpected type", NULL);
- }
- }
- return rc;
-}
-
-
-int lsm_volume_list(lsm_connect *c, const char *search_key,
- const char *search_value, lsm_volume **volumes[],
- uint32_t *count, lsm_flag flags)
-{
- CONN_SETUP(c);
-
- if( !volumes || !count || CHECK_RP(volumes)){
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- std::map<std::string, Value> p;
- p["flags"] = Value(flags);
-
- int rc = add_search_params(p, search_key, search_value, VOLUME_SEARCH_KEYS,
- VOLUME_SEARCH_KEYS_COUNT);
- if( LSM_ERR_OK != rc ) {
- return rc;
- }
-
- Value parameters(p);
- Value response;
-
- rc = rpc(c, "volumes", parameters, response);
- return get_volume_array(c, rc, response, volumes, count);
-}
-
-static int get_disk_array(lsm_connect *c, int rc, Value &response,
- lsm_disk **disks[], uint32_t *count)
-{
- if( LSM_ERR_OK == rc && Value::array_t == response.valueType()) {
- rc = value_array_to_disks(response, disks, count);
-
- if( LSM_ERR_OK != rc ) {
- rc = logException(c, LSM_ERR_LIB_BUG, "Unexpected type", NULL);
- }
- }
-
- return rc;
-}
-
-int lsm_disk_list(lsm_connect *c, const char *search_key,
- const char *search_value,
- lsm_disk **disks[], uint32_t *count, lsm_flag flags)
-{
- CONN_SETUP(c);
-
- if (CHECK_RP(disks) || !count ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- std::map<std::string, Value> p;
- p["flags"] = Value(flags);
-
- int rc = add_search_params(p, search_key, search_value, DISK_SEARCH_KEYS,
- DISK_SEARCH_KEYS_COUNT);
- if( LSM_ERR_OK != rc ) {
- return rc;
- }
-
- Value parameters(p);
- Value response;
-
- rc = rpc(c, "disks", parameters, response);
- return get_disk_array(c, rc, response, disks, count);
-}
-
-typedef void* (*convert)(Value &v);
-
-static void* parse_job_response(lsm_connect *c, Value response, int &rc,
- char **job, convert conv)
-{
- void *val = NULL;
-
- try {
- //We get an array back. first value is job, second is data of interest.
- if( Value::array_t == response.valueType() ) {
- std::vector<Value> r = response.asArray();
- if( Value::string_t == r[0].valueType()) {
- *job = strdup((r[0].asString()).c_str());
- if( *job ) {
- rc = LSM_ERR_JOB_STARTED;
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
-
- rc = LSM_ERR_JOB_STARTED;
- }
- if( Value::object_t == r[1].valueType() ) {
- val = conv(r[1]);
- }
- }
- } catch( const ValueException &ve ) {
- rc = logException(c, LSM_ERR_LIB_BUG, "Unexpected type",
- ve.what());
- free(*job);
- *job = NULL;
- }
- return val;
-}
-
-int lsm_volume_create(lsm_connect *c, lsm_pool *pool, const char *volumeName,
- uint64_t size, lsm_volume_provision_type provisioning,
- lsm_volume **newVolume, char **job, lsm_flag flags)
-{
- CONN_SETUP(c);
-
- if( !LSM_IS_POOL(pool)) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- if( CHECK_STR(volumeName) || !size || CHECK_RP(newVolume) ||
- CHECK_RP(job) || LSM_FLAG_UNUSED_CHECK(flags) ){
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- std::map<std::string, Value> p;
- p["pool"] = pool_to_value(pool);
- p["volume_name"] = Value(volumeName);
- p["size_bytes"] = Value(size);
- p["provisioning"] = Value((int32_t)provisioning);
- p["flags"] = Value(flags);
-
- Value parameters(p);
- Value response;
-
- int rc = rpc(c, "volume_create", parameters, response);
- if( LSM_ERR_OK == rc ) {
- *newVolume = (lsm_volume *)parse_job_response(c, response, rc, job,
- (convert)value_to_volume);
- }
- return rc;
-}
-
-int lsm_volume_resize(lsm_connect *c, lsm_volume *volume,
- uint64_t newSize, lsm_volume **resizedVolume,
- char **job, lsm_flag flags )
-{
- CONN_SETUP(c);
-
- if( !LSM_IS_VOL(volume) || !newSize || CHECK_RP(resizedVolume) ||
- CHECK_RP(job) || newSize == 0 || LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- //If you try to resize to same size, we will return error.
- if( ( newSize/volume->block_size) == volume->number_of_blocks ) {
- return LSM_ERR_NO_STATE_CHANGE;
- }
-
- std::map<std::string, Value> p;
- p["volume"] = volume_to_value(volume);
- p["new_size_bytes"] = Value(newSize);
- p["flags"] = Value(flags);
-
- Value parameters(p);
- Value response;
-
- int rc = rpc(c, "volume_resize", parameters, response);
- if( LSM_ERR_OK == rc ) {
- *resizedVolume = (lsm_volume *)parse_job_response(c, response, rc, job,
- (convert)value_to_volume);
- }
- return rc;
-}
-
-int lsm_volume_replicate(lsm_connect *c, lsm_pool *pool,
- lsm_replication_type repType, lsm_volume *volumeSrc,
- const char *name, lsm_volume **newReplicant,
- char **job, lsm_flag flags)
-{
- CONN_SETUP(c);
-
- if( (pool && !LSM_IS_POOL(pool)) || !LSM_IS_VOL(volumeSrc) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- if(CHECK_STR(name) || CHECK_RP(newReplicant) || CHECK_RP(job) ||
- LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- std::map<std::string, Value> p;
- p["pool"] = pool_to_value(pool);
- p["rep_type"] = Value((int32_t)repType);
- p["volume_src"] = volume_to_value(volumeSrc);
- p["name"] = Value(name);
- p["flags"] = Value(flags);
-
- Value parameters(p);
- Value response;
-
- int rc = rpc(c, "volume_replicate", parameters, response);
- if( LSM_ERR_OK == rc ) {
- *newReplicant = (lsm_volume *)parse_job_response(c, response, rc, job,
- (convert)value_to_volume);
- }
- return rc;
-
-}
-
-int lsm_volume_replicate_range_block_size(lsm_connect *c, lsm_system *system,
- uint32_t *bs, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- CONN_SETUP(c);
-
- if( !bs || LSM_FLAG_UNUSED_CHECK(flags) || !LSM_IS_SYSTEM(system) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- try {
- std::map<std::string, Value> p;
- p["system"] = system_to_value(system);
- p["flags"] = Value(flags);
- Value parameters(p);
- Value response;
-
- rc = rpc(c, "volume_replicate_range_block_size", parameters, response);
- if( LSM_ERR_OK == rc ) {
- if( Value::numeric_t == response.valueType() ) {
- *bs = response.asUint32_t();
- }
- }
- } catch( const ValueException &ve ) {
- rc = logException(c, LSM_ERR_LIB_BUG, "Unexpected type",
- ve.what());
- }
- return rc;
-}
-
-
-int lsm_volume_replicate_range(lsm_connect *c,
- lsm_replication_type repType,
- lsm_volume *source,
- lsm_volume *dest,
- lsm_block_range **ranges,
- uint32_t num_ranges,
- char **job, lsm_flag flags)
-{
- CONN_SETUP(c);
-
- if( !LSM_IS_VOL(source) || !LSM_IS_VOL(dest) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- if( !ranges || !num_ranges || CHECK_RP(job) ||
- LSM_FLAG_UNUSED_CHECK(flags)) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- std::map<std::string, Value> p;
- p["rep_type"] = Value((int32_t)repType);
- p["volume_src"] = volume_to_value(source);
- p["volume_dest"] = volume_to_value(dest);
- p["ranges"] = block_range_list_to_value(ranges, num_ranges);
- p["flags"] = Value(flags);
-
- Value parameters(p);
- Value response;
-
- int rc = rpc(c, "volume_replicate_range", parameters, response);
- return jobCheck(c, rc, response, job);
-}
-
-static Value _create_volume_flag_param(lsm_volume *volume, lsm_flag flags)
-{
- std::map<std::string, Value> p;
- p["volume"] = volume_to_value(volume);
- p["flags"] = Value(flags);
-
- return Value(p);
-}
-
-int lsm_volume_delete(lsm_connect *c, lsm_volume *volume, char **job,
- lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- CONN_SETUP(c);
-
- if( !LSM_IS_VOL(volume) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- if( CHECK_RP(job) || LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- try {
-
- Value parameters = _create_volume_flag_param(volume, flags);
- Value response;
-
- rc = rpc(c, "volume_delete", parameters, response);
- rc = jobCheck(c, rc, response, job);
- } catch( const ValueException &ve ) {
- rc = logException(c, LSM_ERR_LIB_BUG, "Unexpected type",
- ve.what());
- }
- return rc;
-
-}
-
-int lsm_volume_raid_info(lsm_connect *c, lsm_volume *volume,
- lsm_volume_raid_type * raid_type,
- uint32_t *strip_size, uint32_t *disk_count,
- uint32_t *min_io_size, uint32_t *opt_io_size,
- lsm_flag flags)
-{
- if( LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- int rc = LSM_ERR_OK;
- CONN_SETUP(c);
-
- if( !LSM_IS_VOL(volume) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- if( !raid_type || !strip_size || !disk_count || !min_io_size ||
- !opt_io_size) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- try {
-
- Value parameters = _create_volume_flag_param(volume, flags);
- Value response;
-
- rc = rpc(c, "volume_raid_info", parameters, response);
- if( LSM_ERR_OK == rc ) {
- //We get a value back, either null or job id.
- std::vector<Value> j = response.asArray();
- *raid_type = (lsm_volume_raid_type) j[0].asInt32_t();
- *strip_size = j[1].asUint32_t();
- *disk_count = j[2].asUint32_t();
- *min_io_size = j[3].asUint32_t();
- *opt_io_size = j[4].asUint32_t();
- }
- } catch( const ValueException &ve ) {
- rc = logException(c, LSM_ERR_LIB_BUG, "Unexpected type",
- ve.what());
- }
- return rc;
-
-}
-
-int lsm_iscsi_chap_auth(lsm_connect *c, const char *init_id,
- const char *username, const char *password,
- const char *out_user, const char *out_password,
- lsm_flag flags)
-{
- CONN_SETUP(c);
-
- if( iqn_validate(init_id) || LSM_FLAG_UNUSED_CHECK(flags)) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- std::map<std::string, Value> p;
- p["init_id"] = Value(init_id);
- p["in_user"] = Value(username);
- p["in_password"] = Value(password);
- p["out_user"] = Value(out_user);
- p["out_password"] = Value(out_password);
- p["flags"] = Value(flags);
-
-
- Value parameters(p);
- Value response;
-
- return rpc(c, "iscsi_chap_auth", parameters, response);
-}
-
-static int online_offline(lsm_connect *c, lsm_volume *v,
- const char* operation, lsm_flag flags)
-{
- CONN_SETUP(c);
-
- if( !LSM_IS_VOL(v)) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- if ( LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- std::map<std::string, Value> p;
- p["volume"] = volume_to_value(v);
- p["flags"] = Value(flags);
-
- Value parameters(p);
- Value response;
- return rpc(c, operation, parameters, response);
-}
-
-int lsm_volume_enable(lsm_connect *c, lsm_volume *volume, lsm_flag flags)
-{
- return online_offline(c, volume, "volume_enable", flags);
-}
-
-int lsm_volume_disable(lsm_connect *c, lsm_volume *volume, lsm_flag flags)
-{
- return online_offline(c, volume, "volume_disable", flags);
-}
-
-int lsm_access_group_list(lsm_connect *c, const char *search_key,
- const char *search_value,
- lsm_access_group **groups[], uint32_t *groupCount,
- lsm_flag flags)
-{
- CONN_SETUP(c);
-
- if( !groups || !groupCount ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- std::map<std::string, Value> p;
-
- int rc = add_search_params(p, search_key, search_value,
- ACCESS_GROUP_SEARCH_KEYS,
- ACCESS_GROUP_SEARCH_KEYS_COUNT);
- if( LSM_ERR_OK != rc ) {
- return rc;
- }
-
- p["flags"] = Value(flags);
- Value parameters(p);
- Value response;
-
- rc = rpc(c, "access_groups", parameters, response);
- return getAccessGroups(c, rc, response, groups, groupCount);
-}
-
-int lsm_access_group_create(lsm_connect *c, const char *name,
- const char *init_id, lsm_access_group_init_type init_type,
- lsm_system *system,
- lsm_access_group **access_group, lsm_flag flags)
-{
- CONN_SETUP(c);
-
- if( !LSM_IS_SYSTEM(system) || CHECK_STR(name) || CHECK_STR(init_id) ||
- CHECK_RP(access_group) || LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- Value id;
-
- if( LSM_ERR_OK != verify_initiator_id(init_id, init_type, id) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- std::map<std::string, Value> p;
- p["name"] = Value(name);
- p["init_id"] = id;
- p["init_type"] = Value((int32_t)init_type);
- p["system"] = system_to_value(system);
- p["flags"] = Value(flags);
-
- Value parameters(p);
- Value response;
-
- *access_group = NULL;
-
- int rc = rpc(c, "access_group_create", parameters, response);
- if( LSM_ERR_OK == rc ) {
- //We should be getting a value back.
- if( Value::object_t == response.valueType() ) {
- *access_group = value_to_access_group(response);
- }
- }
- return rc;
-}
-
-int lsm_access_group_delete(lsm_connect *c, lsm_access_group *access_group,
- lsm_flag flags)
-{
- CONN_SETUP(c);
-
- if( !LSM_IS_ACCESS_GROUP(access_group) || LSM_FLAG_UNUSED_CHECK(flags) ){
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- std::map<std::string, Value> p;
- p["access_group"] = access_group_to_value(access_group);
- p["flags"] = Value(flags);
-
- Value parameters(p);
- Value response;
-
- return rpc(c, "access_group_delete", parameters, response);
-}
-
-static int _lsm_ag_add_delete(lsm_connect *c,
- lsm_access_group *access_group,
- const char *init_id,
- lsm_access_group_init_type init_type,
- lsm_access_group **updated_access_group,
- lsm_flag flags, const char *message)
-{
- CONN_SETUP(c);
-
- if( !LSM_IS_ACCESS_GROUP(access_group) || CHECK_STR(init_id) ||
- LSM_FLAG_UNUSED_CHECK(flags) || CHECK_RP(updated_access_group)) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- Value id;
-
- if( LSM_ERR_OK != verify_initiator_id(init_id, init_type, id) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- std::map<std::string, Value> p;
- p["access_group"] = access_group_to_value(access_group);
- p["init_id"] = id;
- p["init_type"] = Value((int32_t)init_type);
- p["flags"] = Value(flags);
-
- Value parameters(p);
- Value response;
-
- int rc = rpc(c, message, parameters, response);
- if( LSM_ERR_OK == rc ) {
- //We should be getting a value back.
- if( Value::object_t == response.valueType() ) {
- *updated_access_group = value_to_access_group(response);
- }
- }
-
- return rc;
-}
-
-int lsm_access_group_initiator_add(lsm_connect *c,
- lsm_access_group *access_group,
- const char *init_id,
- lsm_access_group_init_type init_type,
- lsm_access_group **updated_access_group,
- lsm_flag flags)
-{
- return _lsm_ag_add_delete(c, access_group, init_id, init_type,
- updated_access_group, flags,
- "access_group_initiator_add");
-}
-
-int lsm_access_group_initiator_delete(lsm_connect *c,
- lsm_access_group *access_group,
- const char* init_id,
- lsm_access_group_init_type init_type,
- lsm_access_group **updated_access_group,
- lsm_flag flags)
-{
- return _lsm_ag_add_delete(c, access_group, init_id, init_type,
- updated_access_group, flags,
- "access_group_initiator_delete");
-}
-
-int lsm_volume_mask(lsm_connect *c, lsm_access_group *access_group,
- lsm_volume *volume,
- lsm_flag flags)
-{
- CONN_SETUP(c);
-
- if( !LSM_IS_ACCESS_GROUP(access_group) || !LSM_IS_VOL(volume) ||
- LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- std::map<std::string, Value> p;
- p["access_group"] = access_group_to_value(access_group);
- p["volume"] = volume_to_value(volume);
- p["flags"] = Value(flags);
-
- Value parameters(p);
- Value response;
-
- return rpc(c, "volume_mask", parameters, response);
-}
-
-
-int lsm_volume_unmask(lsm_connect *c, lsm_access_group *group,
- lsm_volume *volume,
- lsm_flag flags)
-{
- CONN_SETUP(c);
-
- if( !LSM_IS_ACCESS_GROUP(group) || !LSM_IS_VOL(volume) ||
- LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- std::map<std::string, Value> p;
- p["access_group"] = access_group_to_value(group);
- p["volume"] = volume_to_value(volume);
- p["flags"] = Value(flags);
-
- Value parameters(p);
- Value response;
-
- return rpc(c, "volume_unmask", parameters, response);
-}
-
-int lsm_volumes_accessible_by_access_group(lsm_connect *c,
- lsm_access_group *group,
- lsm_volume **volumes[],
- uint32_t *count, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- CONN_SETUP(c);
-
- if( !LSM_IS_ACCESS_GROUP(group) ||
- !volumes || !count || LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- try {
- std::map<std::string, Value> p;
- p["access_group"] = access_group_to_value(group);
- p["flags"] = Value(flags);
-
- Value parameters(p);
- Value response;
-
- rc = rpc(c, "volumes_accessible_by_access_group", parameters, response);
- if( LSM_ERR_OK == rc && Value::array_t == response.valueType()) {
- std::vector<Value> vol = response.asArray();
-
- *count = vol.size();
-
- if( vol.size() ) {
- *volumes = lsm_volume_record_array_alloc(vol.size());
-
- for( size_t i = 0; i < vol.size(); ++i ) {
- (*volumes)[i] = value_to_volume(vol[i]);
- }
- }
- }
- } catch( const ValueException &ve ) {
- rc = logException(c, LSM_ERR_LIB_BUG, "Unexpected type",
- ve.what());
- if( *volumes && *count ) {
- lsm_volume_record_array_free(*volumes, *count);
- *volumes = NULL;
- *count = 0;
- }
- }
- return rc;
-}
-
-int lsm_access_groups_granted_to_volume(lsm_connect *c,
- lsm_volume *volume,
- lsm_access_group **groups[],
- uint32_t *groupCount, lsm_flag flags)
-{
- CONN_SETUP(c);
-
- if( !LSM_IS_VOL(volume)) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- if( !groups || !groupCount || LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- std::map<std::string, Value> p;
- p["volume"] = volume_to_value(volume);
- p["flags"] = Value(flags);
-
- Value parameters(p);
- Value response;
-
- int rc = rpc(c, "access_groups_granted_to_volume", parameters, response);
- return getAccessGroups(c, rc, response, groups, groupCount);
-}
-
-static int _retrieve_bool(int rc, Value &response, uint8_t *yes)
-{
- int rc_out = rc;
-
- *yes = 0;
-
- if( LSM_ERR_OK == rc ) {
- //We should be getting a boolean value back.
- if( Value::boolean_t == response.valueType() ) {
- if( response.asBool() ) {
- *yes = 1;
- }
- } else {
- rc_out = LSM_ERR_LIB_BUG;
- }
- }
- return rc_out;
-}
-
-int lsm_volume_child_dependency(lsm_connect *c, lsm_volume *volume,
- uint8_t *yes, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- CONN_SETUP(c);
-
- if( !LSM_IS_VOL(volume)) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- if( !yes || LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- try {
-
- Value parameters = _create_volume_flag_param(volume, flags);
- Value response;
-
- rc = rpc(c, "volume_child_dependency", parameters, response);
- rc = _retrieve_bool(rc, response, yes);
- } catch( const ValueException &ve ) {
- rc = logException(c, LSM_ERR_LIB_BUG, "Unexpected type",
- ve.what());
- }
- return rc;
-}
-
-int lsm_volume_child_dependency_delete(lsm_connect *c, lsm_volume *volume,
- char **job, lsm_flag flags)
-{
- CONN_SETUP(c);
-
- if( !LSM_IS_VOL(volume) || CHECK_RP(job) || LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- Value parameters = _create_volume_flag_param(volume, flags);
- Value response;
-
- int rc = rpc(c, "volume_child_dependency_rm", parameters, response);
- return jobCheck(c, rc, response, job);
-}
-
-int lsm_system_list(lsm_connect *c, lsm_system **systems[],
- uint32_t *systemCount, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- CONN_SETUP(c);
-
- if( !systems || ! systemCount ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- try {
- std::map<std::string, Value> p;
- p["flags"] = Value(flags);
- Value parameters(p);
- Value response;
-
- rc = rpc(c, "systems", parameters, response);
- if( LSM_ERR_OK == rc && Value::array_t == response.valueType()) {
- std::vector<Value> sys = response.asArray();
-
- *systemCount = sys.size();
-
- if( sys.size() ) {
- *systems = lsm_system_record_array_alloc(sys.size());
-
- if( *systems ) {
- for( size_t i = 0; i < sys.size(); ++i ) {
- (*systems)[i] = value_to_system(sys[i]);
- if( !(*systems)[i] ) {
- lsm_system_record_array_free(*systems, i);
- rc = LSM_ERR_NO_MEMORY;
- break;
- }
- }
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
- }
- }
- } catch( const ValueException &ve ) {
- rc = logException(c, LSM_ERR_LIB_BUG, "Unexpected type",
- ve.what());
- if( *systems ) {
- lsm_system_record_array_free( *systems, *systemCount);
- *systems = NULL;
- *systemCount = 0;
- }
- }
- return rc;
-}
-
-int lsm_fs_list(lsm_connect *c, const char *search_key,
- const char *search_value, lsm_fs **fs[],
- uint32_t *fsCount, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- CONN_SETUP(c);
-
- if( !fs || !fsCount ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- try {
- std::map<std::string, Value> p;
-
- int rc = add_search_params(p, search_key, search_value, FS_SEARCH_KEYS,
- FS_SEARCH_KEYS_COUNT);
- if( LSM_ERR_OK != rc ) {
- return rc;
- }
-
- p["flags"] = Value(flags);
- Value parameters(p);
- Value response;
-
- rc = rpc(c, "fs", parameters, response);
- if( LSM_ERR_OK == rc && Value::array_t == response.valueType()) {
- std::vector<Value> sys = response.asArray();
-
- *fsCount = sys.size();
-
- if( sys.size() ) {
- *fs = lsm_fs_record_array_alloc(sys.size());
-
- if( *fs ) {
- for( size_t i = 0; i < sys.size(); ++i ) {
- (*fs)[i] = value_to_fs(sys[i]);
- }
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
- }
- }
- } catch( const ValueException &ve ) {
- rc = logException(c, LSM_ERR_LIB_BUG, "Unexpected type",
- ve.what());
- if( *fs && *fsCount) {
- lsm_fs_record_array_free(*fs, *fsCount);
- *fs = NULL;
- *fsCount = 0;
- }
- }
- return rc;
-
-}
-
-int lsm_fs_create(lsm_connect *c, lsm_pool *pool, const char *name,
- uint64_t size_bytes, lsm_fs **fs, char **job,
- lsm_flag flags)
-{
- CONN_SETUP(c);
-
- if( !LSM_IS_POOL(pool)) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- if( CHECK_STR(name) || !size_bytes || CHECK_RP(fs) || CHECK_RP(job)
- || LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- std::map<std::string, Value> p;
- p["pool"] = pool_to_value(pool);
- p["name"] = Value(name);
- p["size_bytes"] = Value(size_bytes);
- p["flags"] = Value(flags);
-
- Value parameters(p);
- Value response;
-
- int rc = rpc(c, "fs_create", parameters, response);
- if( LSM_ERR_OK == rc ) {
- *fs = (lsm_fs *)parse_job_response(c, response, rc, job,
- (convert)value_to_fs);
- }
- return rc;
-}
-
-static Value _create_fs_flag_param(lsm_fs *fs, lsm_flag flags)
-{
- std::map<std::string, Value> p;
- p["fs"] = fs_to_value(fs);
- p["flags"] = Value(flags);
- return Value(p);
-}
-
-int lsm_fs_delete(lsm_connect *c, lsm_fs *fs, char **job, lsm_flag flags)
-{
- CONN_SETUP(c);
-
- if( !LSM_IS_FS(fs) || CHECK_RP(job) || LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- Value parameters = _create_fs_flag_param(fs, flags);
- Value response;
-
- int rc = rpc(c, "fs_delete", parameters, response);
- return jobCheck(c, rc, response, job);
-}
-
-
-int lsm_fs_resize(lsm_connect *c, lsm_fs *fs,
- uint64_t new_size_bytes, lsm_fs **rfs,
- char **job, lsm_flag flags)
-{
- CONN_SETUP(c);
-
- if( !LSM_IS_FS(fs) || !new_size_bytes || CHECK_RP(rfs) || CHECK_RP(job) ||
- LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- std::map<std::string, Value> p;
- p["fs"] = fs_to_value(fs);
- p["new_size_bytes"] = Value(new_size_bytes);
- p["flags"] = Value(flags);
-
- Value parameters(p);
- Value response;
-
- int rc = rpc(c, "fs_resize", parameters, response);
- if( LSM_ERR_OK == rc ) {
- *rfs = (lsm_fs *)parse_job_response(c, response, rc, job,
- (convert)value_to_fs);
- }
- return rc;
-}
-
-int lsm_fs_clone(lsm_connect *c, lsm_fs *src_fs,
- const char *name, lsm_fs_ss *optional_ss,
- lsm_fs **cloned_fs,
- char **job, lsm_flag flags)
-{
- CONN_SETUP(c);
-
- if( !LSM_IS_FS(src_fs) || CHECK_STR(name) || CHECK_RP(cloned_fs) ||
- CHECK_RP(job) || LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- std::map<std::string, Value> p;
- p["src_fs"] = fs_to_value(src_fs);
- p["dest_fs_name"] = Value(name);
- p["snapshot"] = ss_to_value(optional_ss);
- p["flags"] = Value(flags);
-
- Value parameters(p);
- Value response;
-
- int rc = rpc(c, "fs_clone", parameters, response);
- if( LSM_ERR_OK == rc ) {
- *cloned_fs = (lsm_fs *)parse_job_response(c, response, rc, job,
- (convert)value_to_fs);
- }
- return rc;
-}
-
-int lsm_fs_file_clone(lsm_connect *c, lsm_fs *fs, const char *src_file_name,
- const char *dest_file_name, lsm_fs_ss *snapshot, char **job,
- lsm_flag flags)
-{
- CONN_SETUP(c);
-
- if( !LSM_IS_FS(fs) || CHECK_STR(src_file_name) || CHECK_STR(dest_file_name)
- || CHECK_RP(job) || LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- std::map<std::string, Value> p;
- p["fs"] = fs_to_value(fs);
- p["src_file_name"] = Value(src_file_name);
- p["dest_file_name"] = Value(dest_file_name);
- p["snapshot"] = ss_to_value(snapshot);
- p["flags"] = Value(flags);
-
- Value parameters(p);
- Value response;
-
- int rc = rpc(c, "fs_file_clone", parameters, response);
- return jobCheck(c, rc, response, job);
-}
-
-static Value _create_fs_file_flag_params(lsm_fs *fs, lsm_string_list *files,
- lsm_flag flags)
-{
- std::map<std::string, Value> p;
- p["fs"] = fs_to_value(fs);
- p["files"] = string_list_to_value(files);
- p["flags"] = Value(flags);
- return Value(p);
-}
-
-int lsm_fs_child_dependency( lsm_connect *c, lsm_fs *fs, lsm_string_list *files,
- uint8_t *yes, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- CONN_SETUP(c);
-
- if( !LSM_IS_FS(fs) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- if( files ) {
- if( !LSM_IS_STRING_LIST(files) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
- }
-
- if( !yes || LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- try {
-
- Value parameters = _create_fs_file_flag_params(fs, files, flags);
- Value response;
-
- rc = rpc(c, "fs_child_dependency", parameters, response);
- rc = _retrieve_bool(rc, response, yes);
- } catch( const ValueException &ve ) {
- rc = logException(c, LSM_ERR_LIB_BUG, "Unexpected type",
- ve.what());
- }
- return rc;
-}
-
-int lsm_fs_child_dependency_delete( lsm_connect *c, lsm_fs *fs, lsm_string_list *files,
- char **job, lsm_flag flags )
-{
- CONN_SETUP(c);
-
- if( !LSM_IS_FS(fs)) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- if( files ) {
- if( !LSM_IS_STRING_LIST(files) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
- }
-
- if( CHECK_RP(job) || LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- Value parameters = _create_fs_file_flag_params(fs, files, flags);
- Value response;
-
- int rc = rpc(c, "fs_child_dependency_rm", parameters, response);
- return jobCheck(c, rc, response, job);
-}
-
-int lsm_fs_ss_list(lsm_connect *c, lsm_fs *fs, lsm_fs_ss **ss[],
- uint32_t *ssCount, lsm_flag flags )
-{
- int rc = LSM_ERR_OK;
- CONN_SETUP(c);
-
- if( !LSM_IS_FS(fs) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- if( CHECK_RP(ss) || !ssCount ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- Value parameters = _create_fs_flag_param(fs, flags);
- Value response;
-
- try {
- rc = rpc(c, "fs_snapshots", parameters, response);
- if( LSM_ERR_OK == rc && Value::array_t == response.valueType()) {
- std::vector<Value> sys = response.asArray();
-
- *ssCount = sys.size();
-
- if( sys.size() ) {
- *ss = lsm_fs_ss_record_array_alloc(sys.size());
-
- if( *ss ) {
- for( size_t i = 0; i < sys.size(); ++i ) {
- (*ss)[i] = value_to_ss(sys[i]);
- }
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
- }
- }
- } catch( const ValueException &ve ) {
- rc = logException(c, LSM_ERR_LIB_BUG, "Unexpected type",
- ve.what());
- if( *ss && *ssCount ) {
- lsm_fs_ss_record_array_free(*ss, *ssCount);
- *ss = NULL;
- *ssCount = 0;
- }
- }
- return rc;
-
-}
-
-int lsm_fs_ss_create(lsm_connect *c, lsm_fs *fs, const char *name, lsm_fs_ss **snapshot, char **job,
- lsm_flag flags)
-{
- CONN_SETUP(c);
-
- if( !LSM_IS_FS(fs)) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- if( CHECK_STR(name) || CHECK_RP(snapshot) || CHECK_RP(job) || LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- std::map<std::string, Value> p;
- p["fs"] = fs_to_value(fs);
- p["snapshot_name"] = Value(name);
- p["flags"] = Value(flags);
-
- Value parameters(p);
- Value response;
-
- int rc = rpc(c, "fs_snapshot_create", parameters, response);
- if( LSM_ERR_OK == rc ) {
- *snapshot = (lsm_fs_ss *)parse_job_response(c, response, rc, job,
- (convert)value_to_ss);
- }
- return rc;
-}
-
-int lsm_fs_ss_delete(lsm_connect *c, lsm_fs *fs, lsm_fs_ss *ss, char **job,
- lsm_flag flags)
-{
- CONN_SETUP(c);
-
- if( !LSM_IS_FS(fs) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- if( !LSM_IS_SS(ss) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- if( CHECK_RP(job) || LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- std::map<std::string, Value> p;
- p["fs"] = fs_to_value(fs);
- p["snapshot"] = ss_to_value(ss);
- p["flags"] = Value(flags);
-
- Value parameters(p);
- Value response;
-
- int rc = rpc(c, "fs_snapshot_delete", parameters, response);
- return jobCheck(c, rc, response, job);
-}
-
-int lsm_fs_ss_restore(lsm_connect *c, lsm_fs *fs, lsm_fs_ss *ss,
- lsm_string_list *files,
- lsm_string_list *restore_files,
- int all_files, char **job, lsm_flag flags)
-{
- CONN_SETUP(c);
-
- if( !LSM_IS_FS(fs) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- if( !LSM_IS_SS(ss) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- if( files ) {
- if( !LSM_IS_STRING_LIST(files) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
- }
-
- if( restore_files ) {
- if( !LSM_IS_STRING_LIST(restore_files) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
- }
-
- if( CHECK_RP(job) || LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- std::map<std::string, Value> p;
- p["fs"] = fs_to_value(fs);
- p["snapshot"] = ss_to_value(ss);
- p["files"] = string_list_to_value(files);
- p["restore_files"] = string_list_to_value(restore_files);
- p["all_files"] = Value((all_files)?true:false);
- p["flags"] = Value(flags);
-
- Value parameters(p);
- Value response;
-
- int rc = rpc(c, "fs_snapshot_restore", parameters, response);
- return jobCheck(c, rc, response, job);
-
-}
-
-int lsm_nfs_list( lsm_connect *c, const char *search_key,
- const char *search_value, lsm_nfs_export **exports[],
- uint32_t *count, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- CONN_SETUP(c);
-
- if( CHECK_RP(exports) || !count ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- try {
- std::map<std::string, Value> p;
-
- rc = add_search_params(p, search_key, search_value,
- NFS_EXPORT_SEARCH_KEYS,
- NFS_EXPORT_SEARCH_KEYS_COUNT);
- if( LSM_ERR_OK != rc ) {
- return rc;
- }
-
- p["flags"] = Value(flags);
- Value parameters(p);
- Value response;
-
- rc = rpc(c, "exports", parameters, response);
- if( LSM_ERR_OK == rc && Value::array_t == response.valueType()) {
- std::vector<Value> exps = response.asArray();
-
- *count = exps.size();
-
- if( *count ) {
- *exports = lsm_nfs_export_record_array_alloc(*count);
-
- if( *exports ) {
- for( size_t i = 0; i < *count; ++i ) {
- (*exports)[i] = value_to_nfs_export(exps[i]);
- }
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
- }
- }
- } catch( const ValueException &ve ) {
- rc = logException(c, LSM_ERR_LIB_BUG, "Unexpected type",
- ve.what());
- if( *exports && *count ) {
- lsm_nfs_export_record_array_free( *exports, *count );
- *exports = NULL;
- *count = 0;
- }
- }
- return rc;
-}
-
-int lsm_nfs_export_fs( lsm_connect *c,
- const char *fs_id,
- const char *export_path,
- lsm_string_list *root_list,
- lsm_string_list *rw_list,
- lsm_string_list *ro_list,
- uint64_t anon_uid,
- uint64_t anon_gid,
- const char *auth_type,
- const char *options,
- lsm_nfs_export **exported,
- lsm_flag flags
- )
-{
- CONN_SETUP(c);
-
- if( root_list ) {
- if( !LSM_IS_STRING_LIST(root_list) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
- }
-
- if( rw_list ) {
- if( !LSM_IS_STRING_LIST(rw_list) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
- }
-
- if( ro_list ) {
- if( !LSM_IS_STRING_LIST(ro_list) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
- }
-
- if( CHECK_STR(fs_id) || CHECK_RP(exported)
- || !(root_list || rw_list || ro_list) || LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- std::map<std::string, Value> p;
-
- p["fs_id"] = Value(fs_id);
- p["export_path"] = Value(export_path);
- p["root_list"] = string_list_to_value(root_list);
- p["rw_list"] = string_list_to_value(rw_list);
- p["ro_list"] = string_list_to_value(ro_list);
- p["anon_uid"] = Value(anon_uid);
- p["anon_gid"] = Value(anon_gid);
- p["auth_type"] = Value(auth_type);
- p["options"] = Value(options);
- p["flags"] = Value(flags);
-
- Value parameters(p);
- Value response;
-
- int rc = rpc(c, "export_fs", parameters, response);
- if( LSM_ERR_OK == rc && Value::object_t == response.valueType()) {
- *exported = value_to_nfs_export(response);
- }
- return rc;
-}
-
-int lsm_nfs_export_delete( lsm_connect *c, lsm_nfs_export *e, lsm_flag flags)
-{
- CONN_SETUP(c);
-
- if( !LSM_IS_NFS_EXPORT(e) || LSM_FLAG_UNUSED_CHECK(flags) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- std::map<std::string, Value> p;
- p["export"] = nfs_export_to_value(e);
- p["flags"] = Value(flags);
-
- Value parameters(p);
- Value response;
-
- int rc = rpc(c, "export_remove", parameters, response);
- return rc;
-}
diff --git a/c_binding/lsm_plugin_ipc.cpp b/c_binding/lsm_plugin_ipc.cpp
deleted file mode 100644
index d2a43d4..0000000
--- a/c_binding/lsm_plugin_ipc.cpp
+++ /dev/null
@@ -1,2629 +0,0 @@
-/*
- * Copyright (C) 2011-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 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#include "lsm_plugin_ipc.hpp"
-#include "lsm_datatypes.hpp"
-#include "lsm_ipc.hpp"
-#include "lsm_convert.hpp"
-#include "libstoragemgmt/libstoragemgmt_systems.h"
-#include "libstoragemgmt/libstoragemgmt_blockrange.h"
-#include "libstoragemgmt/libstoragemgmt_disk.h"
-#include "libstoragemgmt/libstoragemgmt_accessgroups.h"
-#include "libstoragemgmt/libstoragemgmt_fs.h"
-#include "libstoragemgmt/libstoragemgmt_snapshot.h"
-#include "libstoragemgmt/libstoragemgmt_nfsexport.h"
-#include "libstoragemgmt/libstoragemgmt_plug_interface.h"
-#include "libstoragemgmt/libstoragemgmt_targetport.h"
-#include "libstoragemgmt/libstoragemgmt_volumes.h"
-#include "libstoragemgmt/libstoragemgmt_pool.h"
-#include <errno.h>
-#include <string.h>
-#include <libxml/uri.h>
-#include "util/qparams.h"
-#include <syslog.h>
-
-//Forward decl.
-static int lsm_plugin_run(lsm_plugin_ptr plug);
-
-/**
- * Safe string wrapper
- * @param s Character array to convert to std::string
- * @return String representation.
- */
-static std::string ss(char *s)
-{
- if( s ) {
- return std::string(s);
- }
- return std::string();
-}
-
-void * lsm_data_type_copy(lsm_data_type t, void *item)
-{
- void *rc = NULL;
-
- if( item ) {
- switch( t ) {
- case(LSM_DATA_TYPE_ACCESS_GROUP):
- rc = lsm_access_group_record_copy((lsm_access_group *)item);
- break;
- case(LSM_DATA_TYPE_BLOCK_RANGE):
- rc = lsm_block_range_record_copy((lsm_block_range *)item);
- break;
- case(LSM_DATA_TYPE_FS):
- rc = lsm_fs_record_copy((lsm_fs *)item);
- break;
- case(LSM_DATA_TYPE_NFS_EXPORT):
- rc = lsm_nfs_export_record_copy((lsm_nfs_export *)item);
- break;
- case(LSM_DATA_TYPE_POOL):
- rc = lsm_pool_record_copy((lsm_pool *)item);
- break;
- case(LSM_DATA_TYPE_SS):
- rc = lsm_fs_ss_record_copy((lsm_fs_ss *)item);
- break;
- case(LSM_DATA_TYPE_STRING_LIST):
- rc = lsm_string_list_copy((lsm_string_list *)item);
- break;
- case(LSM_DATA_TYPE_SYSTEM):
- rc = lsm_system_record_copy((lsm_system *)item);
- break;
- case(LSM_DATA_TYPE_VOLUME):
- rc = lsm_volume_record_copy((lsm_volume *)item);
- break;
- case(LSM_DATA_TYPE_DISK):
- rc = lsm_disk_record_copy((lsm_disk *)item);
- break;
- default:
- break;
- }
- }
- return rc;
-}
-
-static Value job_handle(const Value &val, char *job)
-{
- std::vector<Value> r;
- r.push_back(Value(job));
- r.push_back(val);
- return Value(r);
-}
-
-int lsm_register_plugin_v1(lsm_plugin_ptr plug,
- void *private_data, struct lsm_mgmt_ops_v1 *mgm_op,
- struct lsm_san_ops_v1 *san_op, struct lsm_fs_ops_v1 *fs_op,
- struct lsm_nas_ops_v1 *nas_op)
-{
- int rc = LSM_ERR_INVALID_ARGUMENT;
-
- if(LSM_IS_PLUGIN(plug)) {
- plug->private_data = private_data;
- plug->mgmt_ops = mgm_op;
- plug->san_ops = san_op;
- plug->fs_ops = fs_op;
- plug->nas_ops = nas_op;
- rc = LSM_ERR_OK;
- }
- return rc;
-}
-
-int lsm_register_plugin_v1_2(
- lsm_plugin_ptr plug, void *private_data, struct lsm_mgmt_ops_v1 *mgm_op,
- struct lsm_san_ops_v1 *san_op, struct lsm_fs_ops_v1 *fs_op,
- struct lsm_nas_ops_v1 *nas_op, struct lsm_ops_v1_2 *ops_v1_2)
-{
- int rc = lsm_register_plugin_v1(
- plug, private_data, mgm_op, san_op, fs_op, nas_op);
-
- if (rc != LSM_ERR_OK){
- return rc;
- }
- plug->ops_v1_2 = ops_v1_2;
- return rc;
-}
-
-void *lsm_private_data_get(lsm_plugin_ptr plug)
-{
- if (!LSM_IS_PLUGIN(plug)) {
- return NULL;
- }
-
- return plug->private_data;
-}
-
-static void lsm_plugin_free(lsm_plugin_ptr p, lsm_flag flags)
-{
- if( LSM_IS_PLUGIN(p) ) {
-
- delete(p->tp);
- p->tp = NULL;
-
- if( p->unreg ) {
- p->unreg(p, flags);
- }
-
- free(p->desc);
- p->desc = NULL;
-
- free(p->version);
- p->version = NULL;
-
- lsm_error_free(p->error);
- p->error = NULL;
-
- p->magic = LSM_DEL_MAGIC(LSM_PLUGIN_MAGIC);
-
- free(p);
- }
-}
-
-static lsm_plugin_ptr lsm_plugin_alloc(lsm_plugin_register reg,
- lsm_plugin_unregister unreg,
- const char* desc, const char *version) {
-
- if( !reg || !unreg ) {
- return NULL;
- }
-
- lsm_plugin_ptr rc = (lsm_plugin_ptr)calloc(1, sizeof(lsm_plugin));
- if( rc ) {
- rc->magic = LSM_PLUGIN_MAGIC;
- rc->reg = reg;
- rc->unreg = unreg;
- rc->desc = strdup(desc);
- rc->version = strdup(version);
-
- if (!rc->desc || !rc->version) {
- lsm_plugin_free(rc, LSM_CLIENT_FLAG_RSVD);
- rc = NULL;
- }
- }
- return rc;
-}
-
-static void error_send(lsm_plugin_ptr p, int error_code)
-{
- if( !LSM_IS_PLUGIN(p) ) {
- return;
- }
-
- if( p->error ) {
- if( p->tp ) {
- p->tp->errorSend(p->error->code, ss(p->error->message),
- ss(p->error->debug));
- lsm_error_free(p->error);
- p->error = NULL;
- }
- } else {
- p->tp->errorSend(error_code, "UNA", "UNA");
- }
-}
-
-static int get_search_params(Value &params, char **k, char **v)
-{
- int rc = LSM_ERR_OK;
- Value key = params["search_key"];
- Value val = params["search_value"];
-
- if( Value::string_t == key.valueType() ) {
- if ( Value::string_t == val.valueType() ) {
- *k = strdup(key.asC_str());
- *v = strdup(val.asC_str());
-
- if( *k == NULL || *v == NULL ) {
- free( *k );
- *k = NULL;
- free( *v );
- *v = NULL;
- rc = LSM_ERR_NO_MEMORY;
- }
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- } else if( Value::null_t != key.valueType() ) {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
-
- return rc;
-}
-
-/**
- * Checks to see if a character string is an integer and returns result
- * @param[in] sn Character array holding the integer
- * @param[out] num The numeric value contained in string
- * @return true if sn is an integer, else false
- */
-static bool get_num( char *sn, int &num)
-{
- errno = 0;
-
- num = strtol(sn, NULL, 10);
- if( !errno ) {
- return true;
- }
- return false;
-}
-
-int lsm_plugin_init_v1( int argc, char *argv[], lsm_plugin_register reg,
- lsm_plugin_unregister unreg,
- const char *desc, const char *version)
-{
- int rc = 1;
- lsm_plugin_ptr plug = NULL;
-
- if (NULL == desc || NULL == version) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- int sd = 0;
- if( argc == 2 && get_num(argv[1], sd) ) {
- plug = lsm_plugin_alloc(reg, unreg, desc, version);
- if( plug ) {
- plug->tp = new Ipc(sd);
- if (plug->tp) {
- rc = lsm_plugin_run(plug);
- } else {
- lsm_plugin_free(plug, LSM_CLIENT_FLAG_RSVD);
- rc = LSM_ERR_NO_MEMORY;
- }
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
- } else {
- //Process command line arguments or display help text.
- rc = 2;
- }
-
- return rc;
-}
-
-typedef int (*handler)(lsm_plugin_ptr p, Value &params, Value &response);
-
-static int handle_unregister(lsm_plugin_ptr p, Value &params, Value &response)
-{
- /* This is handled in the event loop */
- return LSM_ERR_OK;
-}
-
-static int handle_register(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
- std::string uri_string;
- std::string password;
-
- if( p && p->reg ) {
-
- Value uri_v = params["uri"];
- Value passwd_v = params["password"];
- Value tmo_v = params["timeout"];
-
- if( Value::string_t == uri_v.valueType() &&
- (Value::string_t == passwd_v.valueType() ||
- Value::null_t == passwd_v.valueType()) &&
- Value::numeric_t == tmo_v.valueType()) {
- lsm_flag flags = LSM_FLAG_GET_VALUE(params);
-
- uri_string = uri_v.asString();
-
- if( Value::string_t == params["password"].valueType() ) {
- password = params["password"].asString();
- }
-
- //Let the plug-in initialize itself.
- rc = p->reg(p, uri_string.c_str(), password.c_str(),
- tmo_v.asUint32_t(),
- flags);
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- } else {
- rc = LSM_ERR_NO_SUPPORT;
- }
- return rc;
-}
-
-static int handle_set_time_out( lsm_plugin_ptr p, Value &params, Value &response)
-{
- if( p && p->mgmt_ops && p->mgmt_ops->tmo_set ) {
- if( Value::numeric_t == params["ms"].valueType() &&
- LSM_FLAG_EXPECTED_TYPE(params) ) {
- return p->mgmt_ops->tmo_set(p, params["ms"].asUint32_t(),
- LSM_FLAG_GET_VALUE(params));
- } else {
- return LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return LSM_ERR_NO_SUPPORT;
-}
-
-static int handle_get_time_out( lsm_plugin_ptr p, Value &params, Value &response)
-{
- uint32_t tmo = 0;
- int rc = LSM_ERR_NO_SUPPORT;
-
- if( p && p->mgmt_ops && p->mgmt_ops->tmo_get ) {
-
- if( LSM_FLAG_EXPECTED_TYPE(params) ) {
- rc = p->mgmt_ops->tmo_get(p, &tmo, LSM_FLAG_GET_VALUE(params));
- if( LSM_ERR_OK == rc) {
- response = Value(tmo);
- }
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int handle_job_status( lsm_plugin_ptr p, Value &params, Value &response)
-{
- std::string job_id;
- lsm_job_status status;
- uint8_t percent;
- lsm_data_type t = LSM_DATA_TYPE_UNKNOWN;
- void *value = NULL;
- int rc = LSM_ERR_NO_SUPPORT;
-
- if( p && p->mgmt_ops && p->mgmt_ops->job_status ) {
-
- if( Value::string_t != params["job_id"].valueType() &&
- !LSM_FLAG_EXPECTED_TYPE(params) ) {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- } else {
-
- job_id = params["job_id"].asString();
-
- rc = p->mgmt_ops->job_status(p, job_id.c_str(), &status, &percent, &t,
- &value, LSM_FLAG_GET_VALUE(params));
-
- if( LSM_ERR_OK == rc) {
- std::vector<Value> result;
-
- result.push_back(Value((int32_t)status));
- result.push_back(Value(percent));
-
- if( NULL == value ) {
- result.push_back(Value());
- } else {
- if( LSM_DATA_TYPE_VOLUME == t &&
- LSM_IS_VOL((lsm_volume *)value)) {
- result.push_back(volume_to_value((lsm_volume *)value));
- lsm_volume_record_free((lsm_volume *)value);
- } else if( LSM_DATA_TYPE_FS == t &&
- LSM_IS_FS((lsm_fs *)value)) {
- result.push_back(fs_to_value((lsm_fs *)value));
- lsm_fs_record_free((lsm_fs *)value);
- } else if( LSM_DATA_TYPE_SS == t &&
- LSM_IS_SS((lsm_fs_ss *)value)) {
- result.push_back(ss_to_value((lsm_fs_ss *)value));
- lsm_fs_ss_record_free((lsm_fs_ss *)value);
- } else if( LSM_DATA_TYPE_POOL == t &&
- LSM_IS_POOL((lsm_pool *)value)) {
- result.push_back(pool_to_value((lsm_pool *)value));
- lsm_pool_record_free((lsm_pool *)value);
- } else {
- rc = LSM_ERR_PLUGIN_BUG;
- }
- }
- response = Value(result);
- }
- }
- }
- return rc;
-}
-
-static int handle_plugin_info( lsm_plugin_ptr p, Value &params, Value &response )
-{
- int rc = LSM_ERR_NO_SUPPORT;
- if( p ) {
- std::vector<Value> result;
- result.push_back(Value(p->desc));
- result.push_back(Value(p->version));
- response = Value(result);
- rc = LSM_ERR_OK;
- }
- return rc;
-}
-
-static int handle_job_free(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
- if( p && p->mgmt_ops && p->mgmt_ops->job_free ) {
- if( Value::string_t == params["job_id"].valueType() &&
- LSM_FLAG_EXPECTED_TYPE(params) ) {
- std::string job_num = params["job_id"].asString();
- char *j = (char*)job_num.c_str();
- rc = p->mgmt_ops->job_free(p, j, LSM_FLAG_GET_VALUE(params));
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int handle_system_list(lsm_plugin_ptr p, Value &params,
- Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
-
- if( p && p->mgmt_ops && p->mgmt_ops->system_list ) {
- lsm_system **systems;
- uint32_t count = 0;
-
- if( LSM_FLAG_EXPECTED_TYPE(params) ) {
-
- rc = p->mgmt_ops->system_list(p, &systems, &count,
- LSM_FLAG_GET_VALUE(params));
- if( LSM_ERR_OK == rc ) {
- std::vector<Value> result;
-
- for( uint32_t i = 0; i < count; ++i ) {
- result.push_back(system_to_value(systems[i]));
- }
-
- lsm_system_record_array_free(systems, count);
- systems = NULL;
- response = Value(result);
- }
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-static int handle_pools(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
- char *key = NULL;
- char *val = NULL;
-
- if( p && p->mgmt_ops && p->mgmt_ops->pool_list ) {
- lsm_pool **pools = NULL;
- uint32_t count = 0;
-
- if( LSM_FLAG_EXPECTED_TYPE(params) &&
- ((rc = get_search_params(params, &key, &val)) == LSM_ERR_OK )) {
- rc = p->mgmt_ops->pool_list(p, key, val, &pools, &count,
- LSM_FLAG_GET_VALUE(params));
- if( LSM_ERR_OK == rc) {
- std::vector<Value> result;
-
- for( uint32_t i = 0; i < count; ++i ) {
- result.push_back(pool_to_value(pools[i]));
- }
-
- lsm_pool_record_array_free(pools, count);
- pools = NULL;
- response = Value(result);
- }
- free(key);
- free(val);
- } else {
- if( rc == LSM_ERR_NO_SUPPORT ) {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- }
- return rc;
-}
-
-static int handle_target_ports(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
- char *key = NULL;
- char *val = NULL;
-
- if( p && p->san_ops && p->san_ops->target_port_list ) {
- lsm_target_port **target_ports = NULL;
- uint32_t count = 0;
-
- if( LSM_FLAG_EXPECTED_TYPE(params) &&
- ((rc = get_search_params(params, &key, &val)) == LSM_ERR_OK )) {
- rc = p->san_ops->target_port_list(p, key, val, &target_ports, &count,
- LSM_FLAG_GET_VALUE(params));
- if( LSM_ERR_OK == rc) {
- std::vector<Value> result;
-
- for( uint32_t i = 0; i < count; ++i ) {
- result.push_back(target_port_to_value(target_ports[i]));
- }
-
- lsm_target_port_record_array_free(target_ports, count);
- target_ports = NULL;
- response = Value(result);
- }
- free(key);
- free(val);
- } else {
- if( rc == LSM_ERR_NO_SUPPORT ) {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- }
- return rc;
-}
-
-static int capabilities(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
-
- if( p && p->mgmt_ops && p->mgmt_ops->capablities) {
- lsm_storage_capabilities *c = NULL;
-
- Value v_s = params["system"];
-
- if( IS_CLASS_SYSTEM(v_s) &&
- LSM_FLAG_EXPECTED_TYPE(params) ) {
- lsm_system *sys = value_to_system(v_s);
-
- if( sys ) {
- rc = p->mgmt_ops->capablities(p, sys, &c,
- LSM_FLAG_GET_VALUE(params));
- if( LSM_ERR_OK == rc) {
- response = capabilities_to_value(c);
- lsm_capability_record_free(c);
- c = NULL;
- }
- lsm_system_record_free(sys);
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static void get_volumes(int rc, lsm_volume **vols, uint32_t count,
- Value &response)
-{
- if( LSM_ERR_OK == rc ) {
- std::vector<Value> result;
-
- for( uint32_t i = 0; i < count; ++i ) {
- result.push_back(volume_to_value(vols[i]));
- }
-
- lsm_volume_record_array_free(vols, count);
- vols = NULL;
- response = Value(result);
- }
-}
-
-static int handle_volumes(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
- char *key = NULL;
- char *val = NULL;
-
-
- if( p && p->san_ops && p->san_ops->vol_get ) {
- lsm_volume **vols = NULL;
- uint32_t count = 0;
-
- if( LSM_FLAG_EXPECTED_TYPE(params) &&
- (rc = get_search_params(params, &key, &val)) == LSM_ERR_OK ) {
- rc = p->san_ops->vol_get(p, key, val, &vols, &count,
- LSM_FLAG_GET_VALUE(params));
-
- get_volumes(rc, vols, count, response);
- free(key);
- free(val);
- } else {
- if( rc == LSM_ERR_NO_SUPPORT ) {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- }
- return rc;
-}
-
-static void get_disks(int rc, lsm_disk **disks, uint32_t count, Value &response)
-{
- if( LSM_ERR_OK == rc ) {
- std::vector<Value> result;
-
- for( uint32_t i = 0; i < count; ++i ) {
- result.push_back(disk_to_value(disks[i]));
- }
-
- lsm_disk_record_array_free(disks, count);
- disks = NULL;
- response = Value(result);
- }
-}
-
-static int handle_disks(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
- char *key = NULL;
- char *val = NULL;
-
- if( p && p->san_ops && p->san_ops->disk_get ) {
- lsm_disk **disks = NULL;
- uint32_t count = 0;
-
- if( LSM_FLAG_EXPECTED_TYPE(params) &&
- (rc = get_search_params(params, &key, &val)) == LSM_ERR_OK ) {
- rc = p->san_ops->disk_get(p, key, val, &disks, &count,
- LSM_FLAG_GET_VALUE(params));
- get_disks(rc, disks, count, response);
- free(key);
- free(val);
- } else {
- if( rc == LSM_ERR_NO_SUPPORT ) {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- }
- return rc;
-}
-
-static int handle_volume_create(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
- if( p && p->san_ops && p->san_ops->vol_create ) {
-
- Value v_p = params["pool"];
- Value v_name = params["volume_name"];
- Value v_size = params["size_bytes"];
- Value v_prov = params["provisioning"];
-
- if( IS_CLASS_POOL(v_p) &&
- Value::string_t == v_name.valueType() &&
- Value::numeric_t == v_size.valueType() &&
- Value::numeric_t == v_prov.valueType() &&
- LSM_FLAG_EXPECTED_TYPE(params)) {
-
- lsm_pool *pool = value_to_pool(v_p);
- if( pool ) {
- lsm_volume *vol = NULL;
- char *job = NULL;
- const char *name = v_name.asC_str();
- uint64_t size = v_size.asUint64_t();
- lsm_volume_provision_type pro = (lsm_volume_provision_type)v_prov.asInt32_t();
-
- rc = p->san_ops->vol_create(p, pool, name, size, pro, &vol, &job,
- LSM_FLAG_GET_VALUE(params));
-
- Value v = volume_to_value(vol);
- response = job_handle(v, job);
-
- //Free dynamic data.
- lsm_pool_record_free(pool);
- lsm_volume_record_free(vol);
- free(job);
-
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
-
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int handle_volume_resize(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
- if( p && p->san_ops && p->san_ops->vol_resize ) {
- Value v_vol = params["volume"];
- Value v_size = params["new_size_bytes"];
-
- if( IS_CLASS_VOLUME(v_vol) &&
- Value::numeric_t == v_size.valueType() &&
- LSM_FLAG_EXPECTED_TYPE(params) ) {
-
- lsm_volume *vol = value_to_volume(v_vol);
- if( vol ) {
- lsm_volume *resized_vol = NULL;
- uint64_t size = v_size.asUint64_t();
- char *job = NULL;
-
- rc = p->san_ops->vol_resize(p, vol, size, &resized_vol, &job,
- LSM_FLAG_GET_VALUE(params));
-
- Value v = volume_to_value(resized_vol);
- response = job_handle(v, job);
-
- lsm_volume_record_free(vol);
- lsm_volume_record_free(resized_vol);
- free(job);
-
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
-
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int handle_volume_replicate(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
-
- if( p && p->san_ops && p->san_ops->vol_replicate ) {
-
- Value v_pool = params["pool"];
- Value v_vol_src = params["volume_src"];
- Value v_rep = params["rep_type"];
- Value v_name = params["name"];
-
- if( ((Value::object_t == v_pool.valueType() &&
- IS_CLASS_POOL(v_pool)) ||
- Value::null_t == v_pool.valueType()) &&
- IS_CLASS_VOLUME(v_vol_src) &&
- Value::numeric_t == v_rep.valueType() &&
- Value::string_t == v_name.valueType() &&
- LSM_FLAG_EXPECTED_TYPE(params) ) {
-
- lsm_pool *pool = value_to_pool(v_pool);
- lsm_volume *vol = value_to_volume(v_vol_src);
- lsm_volume *newVolume = NULL;
- lsm_replication_type rep = (lsm_replication_type)v_rep.asInt32_t();
- const char *name = v_name.asC_str();
- char *job = NULL;
-
- if( vol ) {
- rc = p->san_ops->vol_replicate(p, pool, rep, vol, name,
- &newVolume, &job,
- LSM_FLAG_GET_VALUE(params));
-
- Value v = volume_to_value(newVolume);
- response = job_handle(v, job);
-
- lsm_volume_record_free(newVolume);
- free(job);
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
-
- lsm_pool_record_free(pool);
- lsm_volume_record_free(vol);
-
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int handle_volume_replicate_range_block_size( lsm_plugin_ptr p,
- Value &params,
- Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
- uint32_t block_size = 0;
-
- if( p && p->san_ops && p->san_ops->vol_rep_range_bs ) {
- Value v_s = params["system"];
-
- if( IS_CLASS_SYSTEM(v_s) &&
- LSM_FLAG_EXPECTED_TYPE(params) ) {
- lsm_system *sys = value_to_system(v_s);
-
- if( sys ) {
- rc = p->san_ops->vol_rep_range_bs(p, sys, &block_size,
- LSM_FLAG_GET_VALUE(params));
-
- if( LSM_ERR_OK == rc ) {
- response = Value(block_size);
- }
-
- lsm_system_record_free(sys);
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int handle_volume_replicate_range(lsm_plugin_ptr p, Value &params,
- Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
- uint32_t range_count = 0;
- char *job = NULL;
- if( p && p->san_ops && p->san_ops->vol_rep_range ) {
- Value v_rep = params["rep_type"];
- Value v_vol_src = params["volume_src"];
- Value v_vol_dest = params["volume_dest"];
- Value v_ranges = params["ranges"];
-
- if( Value::numeric_t == v_rep.valueType() &&
- IS_CLASS_VOLUME(v_vol_src) &&
- IS_CLASS_VOLUME(v_vol_dest) &&
- Value::array_t == v_ranges.valueType() &&
- LSM_FLAG_EXPECTED_TYPE(params) ) {
-
- lsm_replication_type repType = (lsm_replication_type)
- v_rep.asInt32_t();
- lsm_volume *source = value_to_volume(v_vol_src);
- lsm_volume *dest = value_to_volume(v_vol_dest);
- lsm_block_range **ranges = value_to_block_range_list(v_ranges,
- &range_count);
-
- if( source && dest && ranges ) {
-
- rc = p->san_ops->vol_rep_range(p, repType, source, dest, ranges,
- range_count, &job,
- LSM_FLAG_GET_VALUE(params));
-
- if( LSM_ERR_JOB_STARTED == rc ) {
- response = Value(job);
- free(job);
- job = NULL;
- }
-
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
-
- lsm_volume_record_free(source);
- lsm_volume_record_free(dest);
- lsm_block_range_record_array_free(ranges, range_count);
-
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int handle_volume_delete(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
- if( p && p->san_ops && p->san_ops->vol_delete ) {
- Value v_vol = params["volume"];
-
- if(IS_CLASS_VOLUME(v_vol) &&
- LSM_FLAG_EXPECTED_TYPE(params) ) {
- lsm_volume *vol = value_to_volume(v_vol);
-
- if( vol ) {
- char *job = NULL;
-
- rc = p->san_ops->vol_delete(p, vol, &job,
- LSM_FLAG_GET_VALUE(params));
-
- if( LSM_ERR_JOB_STARTED == rc ) {
- response = Value(job);
- }
-
- lsm_volume_record_free(vol);
- free(job);
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
-
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int handle_vol_enable_disable( lsm_plugin_ptr p, Value &params,
- Value &response, int online)
-{
- int rc = LSM_ERR_NO_SUPPORT;
-
- if( p && p->san_ops &&
- ((online)? p->san_ops->vol_enable : p->san_ops->vol_disable)) {
-
- Value v_vol = params["volume"];
-
- if( IS_CLASS_VOLUME(v_vol) &&
- LSM_FLAG_EXPECTED_TYPE(params) ) {
- lsm_volume *vol = value_to_volume(v_vol);
- if( vol ) {
- if( online ) {
- rc = p->san_ops->vol_enable(p, vol,
- LSM_FLAG_GET_VALUE(params));
- } else {
- rc = p->san_ops->vol_disable(p, vol,
- LSM_FLAG_GET_VALUE(params));
- }
-
- lsm_volume_record_free(vol);
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int handle_volume_enable(lsm_plugin_ptr p, Value &params, Value &response)
-{
- return handle_vol_enable_disable(p, params, response, 1);
-}
-
-static int handle_volume_disable(lsm_plugin_ptr p, Value &params, Value &response)
-{
- return handle_vol_enable_disable(p, params, response, 0);
-}
-
-static int handle_volume_raid_info(lsm_plugin_ptr p, Value &params,
- Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
- if( p && p->ops_v1_2 && p->ops_v1_2->vol_raid_info) {
- Value v_vol = params["volume"];
-
- if(IS_CLASS_VOLUME(v_vol) &&
- LSM_FLAG_EXPECTED_TYPE(params) ) {
- lsm_volume *vol = value_to_volume(v_vol);
- std::vector<Value> result;
-
- if( vol ) {
- lsm_volume_raid_type raid_type;
- uint32_t strip_size;
- uint32_t disk_count;
- uint32_t min_io_size;
- uint32_t opt_io_size;
-
- rc = p->ops_v1_2->vol_raid_info(
- p, vol, &raid_type, &strip_size, &disk_count,
- &min_io_size, &opt_io_size, LSM_FLAG_GET_VALUE(params));
-
- if( LSM_ERR_OK == rc ) {
- result.push_back(Value((int32_t)raid_type));
- result.push_back(Value(strip_size));
- result.push_back(Value(disk_count));
- result.push_back(Value(min_io_size));
- result.push_back(Value(opt_io_size));
- response = Value(result);
- }
-
- lsm_volume_record_free(vol);
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
-
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int ag_list(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
- char *key = NULL;
- char *val = NULL;
-
- if( p && p->san_ops && p->san_ops->ag_list ) {
-
- if( LSM_FLAG_EXPECTED_TYPE(params) &&
- (rc = get_search_params(params, &key, &val)) == LSM_ERR_OK ) {
- lsm_access_group **groups = NULL;
- uint32_t count;
-
- rc = p->san_ops->ag_list(p, key, val, &groups, &count,
- LSM_FLAG_GET_VALUE(params));
- if( LSM_ERR_OK == rc ) {
- response = access_group_list_to_value(groups, count);
-
- /* Free the memory */
- lsm_access_group_record_array_free(groups, count);
- }
- free(key);
- free(val);
- } else {
- if( rc == LSM_ERR_NO_SUPPORT ) {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- }
- return rc;
-}
-
-static int ag_create(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
-
- if( p && p->san_ops && p->san_ops->ag_create ) {
- Value v_name = params["name"];
- Value v_init_id = params["init_id"];
- Value v_init_type = params["init_type"];
- Value v_system = params["system"];
-
- if( Value::string_t == v_name.valueType() &&
- Value::string_t == v_init_id.valueType() &&
- Value::numeric_t == v_init_type.valueType() &&
- IS_CLASS_SYSTEM(v_system) &&
- LSM_FLAG_EXPECTED_TYPE(params)) {
-
- lsm_access_group *ag = NULL;
- lsm_system *system = value_to_system(v_system);
-
- if( system ) {
- rc = p->san_ops->ag_create(
- p,
- v_name.asC_str(),
- v_init_id.asC_str(),
- (lsm_access_group_init_type)v_init_type.asInt32_t(),
- system, &ag,
- LSM_FLAG_GET_VALUE(params));
- if( LSM_ERR_OK == rc ) {
- response = access_group_to_value(ag);
- lsm_access_group_record_free(ag);
- }
-
- lsm_system_record_free(system);
- system = NULL;
- }
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int ag_delete(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
-
- if( p && p->san_ops && p->san_ops->ag_delete ) {
- Value v_access_group = params["access_group"];
-
- if( IS_CLASS_ACCESS_GROUP(v_access_group) &&
- LSM_FLAG_EXPECTED_TYPE(params)) {
-
- lsm_access_group *ag = value_to_access_group(v_access_group);
-
- if( ag ) {
- rc = p->san_ops->ag_delete(p, ag, LSM_FLAG_GET_VALUE(params));
- lsm_access_group_record_free(ag);
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
-
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int ag_initiator_add(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
-
- if( p && p->san_ops && p->san_ops->ag_add_initiator ) {
-
- Value v_group = params["access_group"];
- Value v_init_id = params["init_id"];
- Value v_init_type = params["init_type"];
-
-
- if( IS_CLASS_ACCESS_GROUP(v_group) &&
- Value::string_t == v_init_id.valueType() &&
- Value::numeric_t == v_init_type.valueType() &&
- LSM_FLAG_EXPECTED_TYPE(params) ) {
-
- lsm_access_group *ag = value_to_access_group(v_group);
- if( ag ) {
- lsm_access_group *updated_access_group = NULL;
- const char *id = v_init_id.asC_str();
- lsm_access_group_init_type id_type =
- (lsm_access_group_init_type) v_init_type.asInt32_t();
-
- rc = p->san_ops->ag_add_initiator(p, ag, id, id_type,
- &updated_access_group,
- LSM_FLAG_GET_VALUE(params));
-
- if( LSM_ERR_OK == rc ) {
- response = access_group_to_value(updated_access_group);
- lsm_access_group_record_free(updated_access_group);
- }
-
- lsm_access_group_record_free(ag);
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
-
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
-
- return rc;
-}
-
-static int ag_initiator_del(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
-
- if( p && p->san_ops && p->san_ops->ag_del_initiator ) {
-
- Value v_group = params["access_group"];
- Value v_init_id = params["init_id"];
- Value v_init_type = params["init_type"];
-
- if( IS_CLASS_ACCESS_GROUP(v_group) &&
- Value::string_t == v_init_id.valueType() &&
- Value::numeric_t == v_init_type.valueType() &&
- LSM_FLAG_EXPECTED_TYPE(params) ) {
-
- lsm_access_group *ag = value_to_access_group(v_group);
-
- if( ag ) {
- lsm_access_group *updated_access_group = NULL;
- const char *id = v_init_id.asC_str();
- lsm_access_group_init_type id_type =
- (lsm_access_group_init_type) v_init_type.asInt32_t();
- rc = p->san_ops->ag_del_initiator(p, ag, id, id_type,
- &updated_access_group,
- LSM_FLAG_GET_VALUE(params));
-
- if( LSM_ERR_OK == rc ) {
- response = access_group_to_value(updated_access_group);
- lsm_access_group_record_free(updated_access_group);
- }
-
- lsm_access_group_record_free(ag);
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
-
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int volume_mask(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
-
- if( p && p->san_ops && p->san_ops->ag_grant ) {
-
- Value v_group = params["access_group"];
- Value v_vol = params["volume"];
-
- if( IS_CLASS_ACCESS_GROUP(v_group) &&
- IS_CLASS_VOLUME(v_vol) &&
- LSM_FLAG_EXPECTED_TYPE(params) ) {
-
- lsm_access_group *ag = value_to_access_group(v_group);
- lsm_volume *vol = value_to_volume(v_vol);
-
- if( ag && vol ) {
- rc = p->san_ops->ag_grant(p, ag, vol,
- LSM_FLAG_GET_VALUE(params));
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
-
- lsm_access_group_record_free(ag);
- lsm_volume_record_free(vol);
-
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
-
- return rc;
-}
-
-static int volume_unmask(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
-
- if( p && p->san_ops && p->san_ops->ag_revoke ) {
-
- Value v_group = params["access_group"];
- Value v_vol = params["volume"];
-
- if( IS_CLASS_ACCESS_GROUP(v_group) &&
- IS_CLASS_VOLUME(v_vol) &&
- LSM_FLAG_EXPECTED_TYPE(params)) {
-
- lsm_access_group *ag = value_to_access_group(v_group);
- lsm_volume *vol = value_to_volume(v_vol);
-
- if( ag && vol ) {
- rc = p->san_ops->ag_revoke(p, ag, vol,
- LSM_FLAG_GET_VALUE(params));
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
-
- lsm_access_group_record_free(ag);
- lsm_volume_record_free(vol);
-
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
-
- return rc;
-}
-
-static int vol_accessible_by_ag(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
-
- if( p && p->san_ops && p->san_ops->vol_accessible_by_ag ) {
- Value v_access_group = params["access_group"];
-
- if( IS_CLASS_ACCESS_GROUP(v_access_group) &&
- LSM_FLAG_EXPECTED_TYPE(params) ) {
- lsm_access_group *ag = value_to_access_group(v_access_group);
-
- if( ag ) {
- lsm_volume **vols = NULL;
- uint32_t count = 0;
-
- rc = p->san_ops->vol_accessible_by_ag(p, ag, &vols, &count,
- LSM_FLAG_GET_VALUE(params));
-
- if( LSM_ERR_OK == rc ) {
- std::vector<Value> result;
-
- for( uint32_t i = 0; i < count; ++i ) {
- result.push_back(volume_to_value(vols[i]));
- }
- response = Value(result);
- }
-
- lsm_access_group_record_free(ag);
- lsm_volume_record_array_free(vols, count);
- vols = NULL;
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
-
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int ag_granted_to_volume(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
-
- if( p && p->san_ops && p->san_ops->ag_granted_to_vol ) {
-
- Value v_vol = params["volume"];
-
- if( IS_CLASS_VOLUME(v_vol) &&
- LSM_FLAG_EXPECTED_TYPE(params) ) {
- lsm_volume *volume = value_to_volume(v_vol);
-
- if( volume ) {
- lsm_access_group **groups = NULL;
- uint32_t count = 0;
-
- rc = p->san_ops->ag_granted_to_vol(p, volume, &groups, &count,
- LSM_FLAG_GET_VALUE(params));
-
- if( LSM_ERR_OK == rc ) {
- std::vector<Value> result;
-
- for( uint32_t i = 0; i < count; ++i ) {
- result.push_back(access_group_to_value(groups[i]));
- }
- response = Value(result);
- }
-
- lsm_volume_record_free(volume);
- lsm_access_group_record_array_free(groups, count);
- groups = NULL;
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int volume_dependency(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
-
- if( p && p->san_ops && p->san_ops->vol_child_depends ) {
-
- Value v_vol = params["volume"];
-
- if( IS_CLASS_VOLUME(v_vol) &&
- LSM_FLAG_EXPECTED_TYPE(params) ) {
- lsm_volume *volume = value_to_volume(v_vol);
-
- if( volume ) {
- uint8_t yes;
-
- rc = p->san_ops->vol_child_depends(p, volume, &yes,
- LSM_FLAG_GET_VALUE(params));
-
- if( LSM_ERR_OK == rc ) {
- response = Value((bool)(yes));
- }
-
- lsm_volume_record_free(volume);
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
-
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
-
- return rc;
-}
-
-static int volume_dependency_rm(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
-
- if( p && p->san_ops && p->san_ops->vol_child_depends_rm ) {
-
- Value v_vol = params["volume"];
-
- if( IS_CLASS_VOLUME(v_vol) &&
- LSM_FLAG_EXPECTED_TYPE(params)) {
- lsm_volume *volume = value_to_volume(v_vol);
-
- if( volume ) {
-
- char *job = NULL;
-
- rc = p->san_ops->vol_child_depends_rm(p, volume, &job,
- LSM_FLAG_GET_VALUE(params));
-
- if( LSM_ERR_JOB_STARTED == rc ) {
- response = Value(job);
- free(job);
- }
- lsm_volume_record_free(volume);
-
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
-
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int fs(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
- char *key = NULL;
- char *val = NULL;
-
- if( p && p->fs_ops && p->fs_ops->fs_list ) {
- if( LSM_FLAG_EXPECTED_TYPE(params) &&
- ((rc = get_search_params(params, &key, &val)) == LSM_ERR_OK )) {
-
- lsm_fs **fs = NULL;
- uint32_t count = 0;
-
- rc = p->fs_ops->fs_list(p, key, val, &fs, &count,
- LSM_FLAG_GET_VALUE(params));
-
- if( LSM_ERR_OK == rc ) {
- std::vector<Value> result;
-
- for( uint32_t i = 0; i < count; ++i ) {
- result.push_back(fs_to_value(fs[i]));
- }
-
- response = Value(result);
- lsm_fs_record_array_free(fs, count);
- fs = NULL;
- }
- free(key);
- free(val);
- } else {
- if( rc == LSM_ERR_NO_SUPPORT ) {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- }
- return rc;
-}
-
-static int fs_create(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
-
- if( p && p->fs_ops && p->fs_ops->fs_create ) {
-
- Value v_pool = params["pool"];
- Value v_name = params["name"];
- Value v_size = params["size_bytes"];
-
- if( IS_CLASS_POOL(v_pool) &&
- Value::string_t == v_name.valueType() &&
- Value::numeric_t == v_size.valueType() &&
- LSM_FLAG_EXPECTED_TYPE(params) ) {
-
- lsm_pool *pool = value_to_pool(v_pool);
-
- if( pool ) {
- const char *name = params["name"].asC_str();
- uint64_t size_bytes = params["size_bytes"].asUint64_t();
- lsm_fs *fs = NULL;
- char *job = NULL;
-
- rc = p->fs_ops->fs_create(p, pool, name, size_bytes, &fs, &job,
- LSM_FLAG_GET_VALUE(params));
-
- std::vector<Value> r;
-
- if( LSM_ERR_OK == rc ) {
- r.push_back(Value());
- r.push_back(fs_to_value(fs));
- response = Value(r);
- lsm_fs_record_free(fs);
- } else if (LSM_ERR_JOB_STARTED == rc ) {
- r.push_back(Value(job));
- r.push_back(Value());
- response = Value(r);
- free(job);
- }
- lsm_pool_record_free(pool);
-
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
-
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int fs_delete(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
-
- if( p && p->fs_ops && p->fs_ops->fs_delete ) {
-
- Value v_fs = params["fs"];
-
- if( IS_CLASS_FILE_SYSTEM(v_fs) && LSM_FLAG_EXPECTED_TYPE(params)) {
-
- lsm_fs *fs = value_to_fs(v_fs);
-
- if( fs ) {
- char *job = NULL;
-
- rc = p->fs_ops->fs_delete(p, fs, &job,
- LSM_FLAG_GET_VALUE(params));
-
- if( LSM_ERR_JOB_STARTED == rc ) {
- response = Value(job);
- free(job);
- }
- lsm_fs_record_free(fs);
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
-
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int fs_resize(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
-
- if( p && p->fs_ops && p->fs_ops->fs_resize ) {
-
- Value v_fs = params["fs"];
- Value v_size = params["new_size_bytes"];
-
- if( Value::object_t == v_fs.valueType() &&
- Value::numeric_t == v_size.valueType() &&
- LSM_FLAG_EXPECTED_TYPE(params) ) {
-
- lsm_fs *fs = value_to_fs(v_fs);
-
- if( fs ) {
- uint64_t size_bytes = v_size.asUint64_t();
- lsm_fs *rfs = NULL;
- char *job = NULL;
-
- rc = p->fs_ops->fs_resize(p, fs, size_bytes, &rfs, &job,
- LSM_FLAG_GET_VALUE(params));
-
- std::vector<Value> r;
-
- if( LSM_ERR_OK == rc ) {
- r.push_back(Value());
- r.push_back(fs_to_value(rfs));
- response = Value(r);
- lsm_fs_record_free(rfs);
- } else if (LSM_ERR_JOB_STARTED == rc ) {
- r.push_back(Value(job));
- r.push_back(Value());
- response = Value(r);
- free(job);
- }
- lsm_fs_record_free(fs);
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
-
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int fs_clone(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
-
- if( p && p->fs_ops && p->fs_ops->fs_clone ) {
-
- Value v_src_fs = params["src_fs"];
- Value v_name = params["dest_fs_name"];
- Value v_ss = params["snapshot"]; /* This is optional */
-
- if( Value::object_t == v_src_fs.valueType() &&
- Value::string_t == v_name.valueType() &&
- (Value::null_t == v_ss.valueType() ||
- Value::object_t == v_ss.valueType()) &&
- LSM_FLAG_EXPECTED_TYPE(params)) {
-
- lsm_fs *clonedFs = NULL;
- char *job = NULL;
- lsm_fs *fs = value_to_fs(v_src_fs);
- const char* name = v_name.asC_str();
- lsm_fs_ss *ss = value_to_ss(v_ss);
-
- if( fs &&
- (( ss && v_ss.valueType() == Value::object_t) ||
- (!ss && v_ss.valueType() == Value::null_t) )) {
-
- rc = p->fs_ops->fs_clone(p, fs, name, &clonedFs, ss, &job,
- LSM_FLAG_GET_VALUE(params));
-
- std::vector<Value> r;
- if( LSM_ERR_OK == rc ) {
- r.push_back(Value());
- r.push_back(fs_to_value(clonedFs));
- response = Value(r);
- lsm_fs_record_free(clonedFs);
- } else if (LSM_ERR_JOB_STARTED == rc ) {
- r.push_back(Value(job));
- r.push_back(Value());
- response = Value(r);
- free(job);
- }
-
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
-
- lsm_fs_record_free(fs);
- lsm_fs_ss_record_free(ss);
-
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int fs_file_clone(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_OK;
-
- if( p && p->fs_ops && p->fs_ops->fs_file_clone ) {
-
- Value v_fs = params["fs"];
- Value v_src_name = params["src_file_name"];
- Value v_dest_name = params["dest_file_name"];
- Value v_ss = params["snapshot"]; /* This is optional */
-
- if( Value::object_t == v_fs.valueType() &&
- Value::string_t == v_src_name.valueType() &&
- (Value::string_t == v_dest_name.valueType() ||
- Value::object_t == v_ss.valueType()) &&
- LSM_FLAG_EXPECTED_TYPE(params)) {
-
-
- lsm_fs *fs = value_to_fs(v_fs);
- lsm_fs_ss *ss = value_to_ss(v_ss);
-
- if( fs &&
- (( ss && v_ss.valueType() == Value::object_t) ||
- (!ss && v_ss.valueType() == Value::null_t) )) {
-
- const char *src = v_src_name.asC_str();
- const char *dest = v_dest_name.asC_str();
-
- char *job = NULL;
-
- rc = p->fs_ops->fs_file_clone(p, fs, src, dest, ss, &job,
- LSM_FLAG_GET_VALUE(params));
-
- if( LSM_ERR_JOB_STARTED == rc ) {
- response = Value(job);
- free(job);
- }
-
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
-
- lsm_fs_record_free(fs);
- lsm_fs_ss_record_free(ss);
-
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int fs_child_dependency(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
- if( p && p->fs_ops && p->fs_ops->fs_child_dependency ) {
-
- Value v_fs = params["fs"];
- Value v_files = params["files"];
-
- if( Value::object_t == v_fs.valueType() &&
- (Value::array_t == v_files.valueType() ||
- Value::null_t == v_files.valueType()) &&
- LSM_FLAG_EXPECTED_TYPE(params)) {
-
- lsm_fs *fs = value_to_fs(v_fs);
- lsm_string_list *files = value_to_string_list(v_files);
-
- if( fs ) {
- uint8_t yes = 0;
-
- rc = p->fs_ops->fs_child_dependency(p, fs, files, &yes);
-
- if( LSM_ERR_OK == rc ) {
- response = Value((bool)yes);
- }
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
-
- lsm_fs_record_free(fs);
- lsm_string_list_free(files);
-
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int fs_child_dependency_rm(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
- if( p && p->fs_ops && p->fs_ops->fs_child_dependency_rm ) {
-
- Value v_fs = params["fs"];
- Value v_files = params["files"];
-
- if( Value::object_t == v_fs.valueType() &&
- (Value::array_t == v_files.valueType() ||
- Value::null_t == v_files.valueType()) &&
- LSM_FLAG_EXPECTED_TYPE(params) ) {
-
- lsm_fs *fs = value_to_fs(v_fs);
- lsm_string_list *files = value_to_string_list(v_files);
-
- if( fs ) {
- char *job = NULL;
-
- rc = p->fs_ops->fs_child_dependency_rm(p, fs, files, &job,
- LSM_FLAG_GET_VALUE(params));
-
- if( LSM_ERR_JOB_STARTED == rc ) {
- response = Value(job);
- free(job);
- }
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
-
- lsm_fs_record_free(fs);
- lsm_string_list_free(files);
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int ss_list(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
- if( p && p->fs_ops && p->fs_ops->fs_ss_list ) {
-
- Value v_fs = params["fs"];
-
- if( Value::object_t == v_fs.valueType() &&
- LSM_FLAG_EXPECTED_TYPE(params)) {
-
- lsm_fs *fs = value_to_fs(v_fs);
-
- if( fs ) {
- lsm_fs_ss **ss = NULL;
- uint32_t count = 0;
-
- rc = p->fs_ops->fs_ss_list(p, fs, &ss, &count,
- LSM_FLAG_GET_VALUE(params));
-
- if( LSM_ERR_OK == rc ) {
- std::vector<Value> result;
-
- for( uint32_t i = 0; i < count; ++i ) {
- result.push_back(ss_to_value(ss[i]));
- }
- response = Value(result);
-
- lsm_fs_record_free(fs);
- fs = NULL;
- lsm_fs_ss_record_array_free(ss, count);
- ss = NULL;
- }
- }
-
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int ss_create(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
- if( p && p->fs_ops && p->fs_ops->fs_ss_create ) {
-
- Value v_fs = params["fs"];
- Value v_ss_name = params["snapshot_name"];
-
- if( Value::object_t == v_fs.valueType() &&
- Value::string_t == v_ss_name.valueType() &&
- LSM_FLAG_EXPECTED_TYPE(params) ) {
- lsm_fs *fs = value_to_fs(v_fs);
-
- if( fs ) {
- lsm_fs_ss *ss = NULL;
- char *job = NULL;
-
- const char *name = v_ss_name.asC_str();
-
- rc = p->fs_ops->fs_ss_create(p, fs, name, &ss, &job,
- LSM_FLAG_GET_VALUE(params));
-
- std::vector<Value> r;
- if( LSM_ERR_OK == rc ) {
- r.push_back(Value());
- r.push_back(ss_to_value(ss));
- response = Value(r);
- lsm_fs_ss_record_free(ss);
- } else if (LSM_ERR_JOB_STARTED == rc ) {
- r.push_back(Value(job));
- r.push_back(Value());
- response = Value(r);
- free(job);
- }
-
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
-
- lsm_fs_record_free(fs);
-
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int ss_delete(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
- if( p && p->fs_ops && p->fs_ops->fs_ss_delete ) {
-
- Value v_fs = params["fs"];
- Value v_ss = params["snapshot"];
-
- if( Value::object_t == v_fs.valueType() &&
- Value::object_t == v_ss.valueType() &&
- LSM_FLAG_EXPECTED_TYPE(params)) {
-
- lsm_fs *fs = value_to_fs(v_fs);
- lsm_fs_ss *ss = value_to_ss(v_ss);
-
- if( fs && ss ) {
- char *job = NULL;
- rc = p->fs_ops->fs_ss_delete(p, fs, ss, &job,
- LSM_FLAG_GET_VALUE(params));
-
- if( LSM_ERR_JOB_STARTED == rc ) {
- response = Value(job);
- free(job);
- }
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
-
- lsm_fs_record_free(fs);
- lsm_fs_ss_record_free(ss);
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int ss_restore(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
- if( p && p->fs_ops && p->fs_ops->fs_ss_restore ) {
-
- Value v_fs = params["fs"];
- Value v_ss = params["snapshot"];
- Value v_files = params["files"];
- Value v_restore_files = params["restore_files"];
- Value v_all_files = params["all_files"];
-
- if( Value::object_t == v_fs.valueType() &&
- Value::object_t == v_ss.valueType() &&
- (Value::array_t == v_files.valueType() ||
- Value::null_t == v_files.valueType() ) &&
- (Value::array_t == v_restore_files.valueType() ||
- Value::null_t == v_restore_files.valueType()) &&
- Value::boolean_t == v_all_files.valueType() &&
- LSM_FLAG_EXPECTED_TYPE(params) ) {
-
- char *job = NULL;
- lsm_fs *fs = value_to_fs(v_fs);
- lsm_fs_ss *ss = value_to_ss(v_ss);
- lsm_string_list *files = value_to_string_list(v_files);
- lsm_string_list *restore_files =
- value_to_string_list(v_restore_files);
- int all_files = (v_all_files.asBool()) ? 1 : 0;
-
- if( fs && ss ) {
- rc = p->fs_ops->fs_ss_restore(p, fs, ss, files, restore_files,
- all_files, &job,
- LSM_FLAG_GET_VALUE(params));
-
- if( LSM_ERR_JOB_STARTED == rc ) {
- response = Value(job);
- free(job);
- }
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
-
- lsm_fs_record_free(fs);
- lsm_fs_ss_record_free(ss);
- lsm_string_list_free(files);
- lsm_string_list_free(restore_files);
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int export_auth(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
- if( p && p->nas_ops && p->nas_ops->nfs_auth_types ) {
- lsm_string_list *types = NULL;
-
- if( LSM_FLAG_EXPECTED_TYPE(params) ) {
-
- rc = p->nas_ops->nfs_auth_types(p, &types,
- LSM_FLAG_GET_VALUE(params));
- if( LSM_ERR_OK == rc ) {
- response = string_list_to_value(types);
- lsm_string_list_free(types);
- }
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
-
- }
- return rc;
-}
-
-static int exports(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
- char *key = NULL;
- char *val = NULL;
-
- if( p && p->nas_ops && p->nas_ops->nfs_list ) {
- lsm_nfs_export **exports = NULL;
- uint32_t count = 0;
-
- if( LSM_FLAG_EXPECTED_TYPE(params) &&
- (rc = get_search_params(params, &key, &val)) == LSM_ERR_OK ) {
- rc = p->nas_ops->nfs_list(p, key, val, &exports, &count,
- LSM_FLAG_GET_VALUE(params));
-
- if( LSM_ERR_OK == rc ) {
- std::vector<Value> result;
-
- for( uint32_t i = 0; i < count; ++i ) {
- result.push_back(nfs_export_to_value(exports[i]));
- }
- response = Value(result);
-
- lsm_nfs_export_record_array_free(exports, count);
- exports = NULL;
- count = 0;
- }
- free(key);
- free(val);
- } else {
- if( rc == LSM_ERR_NO_SUPPORT ) {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- }
-
- return rc;
-}
-
-static int64_t get_uid_gid(Value &id)
-{
- if( Value::null_t == id.valueType() ) {
- return ANON_UID_GID_NA;
- } else {
- return id.asInt64_t();
- }
-}
-
-static int export_fs(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
-
- if( p && p->nas_ops && p->nas_ops->nfs_export ) {
-
- Value v_fs_id = params["fs_id"];
- Value v_export_path = params["export_path"];
- Value v_root_list = params["root_list"];
- Value v_rw_list = params["rw_list"];
- Value v_ro_list = params["ro_list"];
- Value v_auth_type = params["auth_type"];
- Value v_options = params["options"];
- Value v_anon_uid = params["anon_uid"];
- Value v_anon_gid = params["anon_gid"];
-
- if( Value::string_t == v_fs_id.valueType() &&
- (Value::string_t == v_export_path.valueType() ||
- Value::null_t == v_export_path.valueType()) &&
- Value::array_t == v_root_list.valueType() &&
- Value::array_t == v_rw_list.valueType() &&
- Value::array_t == v_ro_list.valueType() &&
- (Value::string_t == v_auth_type.valueType() ||
- Value::null_t == v_auth_type.valueType()) &&
- (Value::string_t == v_options.valueType() ||
- Value::null_t == v_options.valueType()) &&
- Value::numeric_t == v_anon_uid.valueType() &&
- Value::numeric_t == v_anon_gid.valueType() &&
- LSM_FLAG_EXPECTED_TYPE(params) ) {
-
- lsm_string_list *root_list = value_to_string_list(v_root_list);
- lsm_string_list *rw_list = value_to_string_list(v_rw_list);
- lsm_string_list *ro_list = value_to_string_list(v_ro_list);
-
- if( root_list && rw_list && ro_list ) {
- const char *fs_id = v_fs_id.asC_str();
- const char *export_path = v_export_path.asC_str();
- const char *auth_type = v_auth_type.asC_str();
- const char *options = v_options.asC_str();
- lsm_nfs_export *exported = NULL;
-
- int64_t anon_uid = get_uid_gid(v_anon_uid);
- int64_t anon_gid = get_uid_gid(v_anon_gid);
-
- rc = p->nas_ops->nfs_export(p, fs_id, export_path, root_list,
- rw_list, ro_list, anon_uid,
- anon_gid, auth_type, options,
- &exported,
- LSM_FLAG_GET_VALUE(params));
- if( LSM_ERR_OK == rc ) {
- response = nfs_export_to_value(exported);
- lsm_nfs_export_record_free(exported);
- }
-
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
-
- lsm_string_list_free(root_list);
- lsm_string_list_free(rw_list);
- lsm_string_list_free(ro_list);
-
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int export_remove(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
-
- if( p && p->nas_ops && p->nas_ops->nfs_export_remove ) {
- Value v_export = params["export"];
-
- if( Value::object_t == v_export.valueType() &&
- LSM_FLAG_EXPECTED_TYPE(params)) {
- lsm_nfs_export *exp = value_to_nfs_export(v_export);
-
- if( exp ) {
- rc = p->nas_ops->nfs_export_remove(p, exp,
- LSM_FLAG_GET_VALUE(params));
- lsm_nfs_export_record_free(exp);
- exp = NULL;
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-static int iscsi_chap(lsm_plugin_ptr p, Value &params, Value &response)
-{
- int rc = LSM_ERR_NO_SUPPORT;
-
- if( p && p->san_ops && p->san_ops->iscsi_chap_auth ) {
- Value v_init = params["init_id"];
- Value v_in_user = params["in_user"];
- Value v_in_password = params["in_password"];
- Value v_out_user = params["out_user"];
- Value v_out_password = params["out_password"];
-
- if( Value::string_t == v_init.valueType() &&
- (Value::string_t == v_in_user.valueType() ||
- Value::null_t == v_in_user.valueType()) &&
- (Value::string_t == v_in_password.valueType() ||
- Value::null_t == v_in_password.valueType()) &&
- (Value::string_t == v_out_user.valueType() ||
- Value::null_t == v_out_user.valueType()) &&
- (Value::string_t == v_out_password.valueType() ||
- Value::null_t == v_out_password.valueType()) &&
- LSM_FLAG_EXPECTED_TYPE(params) ) {
-
- rc = p->san_ops->iscsi_chap_auth(p, v_init.asC_str(),
- v_in_user.asC_str(),
- v_in_password.asC_str(),
- v_out_user.asC_str(),
- v_out_password.asC_str(),
- LSM_FLAG_GET_VALUE(params));
-
- } else {
- rc = LSM_ERR_TRANSPORT_INVALID_ARG;
- }
- }
- return rc;
-}
-
-/**
- * map of function pointers
- */
-static std::map<std::string,handler> dispatch = static_map<std::string,handler>
- ("access_group_initiator_add", ag_initiator_add)
- ("access_group_create", ag_create)
- ("access_group_delete", ag_delete)
- ("access_group_initiator_delete", ag_initiator_del)
- ("volume_mask", volume_mask)
- ("access_groups", ag_list)
- ("volume_unmask", volume_unmask)
- ("access_groups_granted_to_volume", ag_granted_to_volume)
- ("capabilities", capabilities)
- ("disks", handle_disks)
- ("export_auth", export_auth)
- ("export_fs", export_fs)
- ("export_remove", export_remove)
- ("exports", exports)
- ("fs_file_clone", fs_file_clone)
- ("fs_child_dependency", fs_child_dependency)
- ("fs_child_dependency_rm", fs_child_dependency_rm)
- ("fs_clone", fs_clone)
- ("fs_create", fs_create)
- ("fs_delete", fs_delete)
- ("fs", fs)
- ("fs_resize", fs_resize)
- ("fs_snapshot_create", ss_create)
- ("fs_snapshot_delete", ss_delete)
- ("fs_snapshot_restore", ss_restore)
- ("fs_snapshots", ss_list)
- ("time_out_get", handle_get_time_out)
- ("iscsi_chap_auth", iscsi_chap)
- ("job_free", handle_job_free)
- ("job_status", handle_job_status)
- ("plugin_info", handle_plugin_info)
- ("pools", handle_pools)
- ("target_ports", handle_target_ports)
- ("time_out_set", handle_set_time_out)
- ("plugin_unregister", handle_unregister)
- ("plugin_register", handle_register)
- ("systems", handle_system_list)
- ("volume_child_dependency_rm", volume_dependency_rm)
- ("volume_child_dependency", volume_dependency)
- ("volume_create", handle_volume_create)
- ("volume_delete", handle_volume_delete)
- ("volume_disable", handle_volume_disable)
- ("volume_enable", handle_volume_enable)
- ("volume_replicate", handle_volume_replicate)
- ("volume_replicate_range_block_size", handle_volume_replicate_range_block_size)
- ("volume_replicate_range", handle_volume_replicate_range)
- ("volume_resize", handle_volume_resize)
- ("volumes_accessible_by_access_group", vol_accessible_by_ag)
- ("volumes", handle_volumes)
- ("volume_raid_info", handle_volume_raid_info);
-
-static int process_request(lsm_plugin_ptr p, const std::string &method, Value &request,
- Value &response)
-{
- int rc = LSM_ERR_LIB_BUG;
-
- response = Value(); //Default response will be null
-
- if( dispatch.find(method) != dispatch.end() ) {
- rc = (dispatch[method])(p, request["params"], response);
- } else {
- rc = LSM_ERR_NO_SUPPORT;
- }
-
- return rc;
-}
-
-static int lsm_plugin_run(lsm_plugin_ptr p)
-{
- int rc = 0;
- lsm_flag flags = 0;
-
- if( LSM_IS_PLUGIN(p) ) {
- while(true) {
- try {
-
- if( !LSM_IS_PLUGIN(p) ) {
- syslog(LOG_USER|LOG_NOTICE, "Someone stepped on "
- "plugin pointer, exiting!");
- break;
- }
-
- Value req = p->tp->readRequest();
- Value resp;
-
- if( req.isValidRequest() ) {
- std::string method = req["method"].asString();
- rc = process_request(p, method, req, resp);
-
- if( LSM_ERR_OK == rc || LSM_ERR_JOB_STARTED == rc ) {
- p->tp->responseSend(resp);
- } else {
- error_send(p, rc);
- }
-
- if( method == "plugin_unregister" ) {
- flags = LSM_FLAG_GET_VALUE(req["params"]);
- break;
- }
- } else {
- syslog(LOG_USER|LOG_NOTICE, "Invalid request");
- break;
- }
- } catch (EOFException &eof) {
- break;
- } catch (ValueException &ve) {
- syslog(LOG_USER|LOG_NOTICE, "Plug-in exception: %s", ve.what());
- rc = 1;
- break;
- } catch (LsmException &le) {
- syslog(LOG_USER|LOG_NOTICE, "Plug-in exception: %s", le.what());
- rc = 2;
- break;
- } catch ( ... ) {
- syslog(LOG_USER|LOG_NOTICE, "Plug-in un-handled exception");
- rc = 3;
- break;
- }
- }
- lsm_plugin_free(p, flags);
- p = NULL;
- } else {
- rc = LSM_ERR_INVALID_ARGUMENT;
- }
-
- return rc;
-}
-
-int lsm_log_error_basic( lsm_plugin_ptr plug, lsm_error_number code, const char* msg )
-{
- if( !LSM_IS_PLUGIN(plug) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- lsm_error_ptr e = LSM_ERROR_CREATE_PLUGIN_MSG(code, msg);
- if( e ) {
- int rc = lsm_plugin_error_log(plug, e);
-
- if( LSM_ERR_OK != rc ) {
- syslog(LOG_USER|LOG_NOTICE,
- "Plug-in error %d while reporting an error, code= %d, msg= %s",
- rc, code, msg);
- }
- }
- return (int)code;
-}
-
-int lsm_plugin_error_log( lsm_plugin_ptr plug, lsm_error_ptr error)
-{
- if( !LSM_IS_PLUGIN(plug) || !LSM_IS_ERROR(error) ) {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-
- if( plug->error ) {
- lsm_error_free(plug->error);
- }
-
- plug->error = error;
-
- return LSM_ERR_OK;
-}
-
-
-#define STR_D(c, s) \
-do { \
- if(s) { \
- (c) = strdup(s); \
- if( !c ) {\
- rc = LSM_ERR_NO_MEMORY; \
- goto bail; \
- } \
- } \
-} while(0)\
-
-int LSM_DLL_EXPORT lsm_uri_parse(const char *uri, char **scheme, char **user,
- char **server, int *port, char **path,
- lsm_hash **query_params)
-{
- int rc = LSM_ERR_INVALID_ARGUMENT;
- xmlURIPtr u = NULL;
-
- if( uri && strlen(uri) > 0 ) {
- *scheme = NULL;
- *user = NULL;
- *server = NULL;
- *port = -1;
- *path = NULL;
- *query_params = NULL;
-
- u = xmlParseURI(uri);
- if( u ) {
- STR_D(*scheme, u->scheme);
- STR_D(*user, u->user);
- STR_D(*server, u->server);
- STR_D(*path, u->path);
- *port = u->port;
-
- *query_params = lsm_hash_alloc();
- if( *query_params ) {
- int i;
- struct qparam_set *qp = NULL;
- qp = qparam_query_parse(u->query_raw);
-
- if( qp ) {
- for( i = 0; i < qp->n; ++i ) {
- rc = lsm_hash_string_set(*query_params,
- qp->p[i].name,
- qp->p[i].value);
- if( LSM_ERR_OK != rc ) {
- free_qparam_set(qp);
- goto bail;
- }
- }
- free_qparam_set(qp);
- }
- } else {
- rc = LSM_ERR_NO_MEMORY;
- goto bail;
- }
-
- rc = LSM_ERR_OK;
- }
-
- bail:
- if( rc != LSM_ERR_OK ){
- free(*scheme);
- *scheme = NULL;
- free(*user);
- *user = NULL;
- free(*server);
- *server = NULL;
- *port = -1;
- free(*path);
- *path = NULL;
- lsm_hash_free(*query_params);
- *query_params = NULL;
- }
-
- if( u ) {
- xmlFreeURI(u);
- u = NULL;
- }
- }
- return rc;
-}
-
-
-typedef int (*array_cmp)(void *item, void *cmp_data);
-typedef void (*free_item)(void *item);
-
-#define CMP_FUNCTION(name, method, method_type) \
-static int name(void *i, void *d) \
-{ \
- method_type *v = (method_type *)i; \
- char *val = (char *)d; \
- \
- if( strcmp(method(v), val) == 0 ) { \
- return 1; \
- } \
- return 0; \
-} \
-
-
-#define CMP_FREE_FUNCTION(name, method, method_type) \
-static void name(void *i) \
-{ \
- method((method_type *)i); \
-} \
-
-static int filter(void *a[], size_t size, array_cmp cmp, void *cmp_data,
- free_item fo)
-{
- int remaining = 0;
- size_t i = 0;
-
- for( i = 0; i < size; ++i ) {
- if( cmp(a[i], cmp_data) ) {
- memmove(&a[remaining], &a[i], sizeof(void *));
- remaining += 1;
- } else {
- fo(a[i]);
- a[i] = NULL;
- }
- }
- return remaining;
-}
-
-CMP_FUNCTION(volume_compare_id, lsm_volume_id_get, lsm_volume)
-CMP_FUNCTION(volume_compare_system, lsm_volume_system_id_get, lsm_volume)
-CMP_FUNCTION(volume_compare_pool, lsm_volume_pool_id_get, lsm_volume)
-CMP_FREE_FUNCTION(volume_free, lsm_volume_record_free, lsm_volume)
-
-void lsm_plug_volume_search_filter(const char *search_key, const char *search_value,
- lsm_volume *vols[], uint32_t *count)
-{
- array_cmp cmp = NULL;
-
- if( search_key ) {
-
- if( 0 == strcmp("id", search_key) ) {
- cmp = volume_compare_id;
- } else if( 0 == strcmp("system_id", search_key) ) {
- cmp = volume_compare_system;
- } else if ( 0 == strcmp("pool_id", search_key) ) {
- cmp = volume_compare_pool;
- }
-
- if( cmp ) {
- *count = filter((void **)vols, *count, cmp, (void*)search_value,
- volume_free);
- }
- }
-}
-
-CMP_FUNCTION(pool_compare_id, lsm_pool_id_get, lsm_pool)
-CMP_FUNCTION(pool_compare_system, lsm_pool_system_id_get, lsm_pool)
-CMP_FREE_FUNCTION(pool_free, lsm_pool_record_free, lsm_pool);
-
-void lsm_plug_pool_search_filter(const char *search_key, const char *search_value,
- lsm_pool *pools[], uint32_t *count)
-{
- array_cmp cmp = NULL;
-
- if( search_key ) {
-
- if( 0 == strcmp("id", search_key) ) {
- cmp = pool_compare_id;
- } else if( 0 == strcmp("system_id", search_key) ) {
- cmp = pool_compare_system;
- }
-
- if( cmp ) {
- *count = filter((void **)pools, *count, cmp, (void*)search_value,
- pool_free);
- }
- }
-}
-
-CMP_FUNCTION(disk_compare_id, lsm_disk_id_get, lsm_disk)
-CMP_FUNCTION(disk_compare_system, lsm_disk_system_id_get, lsm_disk)
-CMP_FREE_FUNCTION(disk_free, lsm_disk_record_free, lsm_disk)
-
-void lsm_plug_disk_search_filter(const char *search_key, const char *search_value,
- lsm_disk *disks[], uint32_t *count)
-{
- array_cmp cmp = NULL;
-
- if( search_key ) {
-
- if( 0 == strcmp("id", search_key) ) {
- cmp = disk_compare_id;
- } else if( 0 == strcmp("system_id", search_key) ) {
- cmp = disk_compare_system;
- }
-
- if( cmp ) {
- *count = filter((void **)disks, *count, cmp, (void*)search_value,
- disk_free);
- }
- }
-}
-
-CMP_FUNCTION(access_group_compare_id, lsm_access_group_id_get, lsm_access_group)
-CMP_FUNCTION(access_group_compare_system, lsm_access_group_system_id_get, lsm_access_group)
-CMP_FREE_FUNCTION(access_group_free, lsm_access_group_record_free,
- lsm_access_group);
-
-void lsm_plug_access_group_search_filter(const char *search_key,
- const char *search_value,
- lsm_access_group *ag[], uint32_t *count)
-{
- array_cmp cmp = NULL;
-
- if( search_key ) {
-
- if( 0 == strcmp("id", search_key) ) {
- cmp = access_group_compare_id;
- } else if( 0 == strcmp("system_id", search_key) ) {
- cmp = access_group_compare_system;
- }
-
- if( cmp ) {
- *count = filter((void **)ag, *count, cmp, (void*)search_value,
- access_group_free);
- }
- }
-}
-
-CMP_FUNCTION(fs_compare_id, lsm_fs_id_get, lsm_fs)
-CMP_FUNCTION(fs_compare_system, lsm_fs_system_id_get, lsm_fs)
-CMP_FREE_FUNCTION(fs_free, lsm_fs_record_free, lsm_fs);
-
-void lsm_plug_fs_search_filter(const char *search_key,
- const char *search_value,
- lsm_fs *fs[], uint32_t *count)
-{
- array_cmp cmp = NULL;
-
- if( search_key ) {
-
- if( 0 == strcmp("id", search_key) ) {
- cmp = fs_compare_id;
- } else if( 0 == strcmp("system_id", search_key) ) {
- cmp = fs_compare_system;
- }
-
- if( cmp ) {
- *count = filter((void **)fs, *count, cmp, (void*)search_value,
- fs_free);
- }
- }
-}
-
-CMP_FUNCTION(nfs_compare_id, lsm_nfs_export_id_get, lsm_nfs_export)
-CMP_FUNCTION(nfs_compare_fs_id, lsm_nfs_export_fs_id_get, lsm_nfs_export)
-CMP_FREE_FUNCTION(nfs_free, lsm_nfs_export_record_free, lsm_nfs_export)
-
-void lsm_plug_nfs_export_search_filter(const char *search_key,
- const char *search_value,
- lsm_nfs_export *exports[], uint32_t *count)
-{
- array_cmp cmp = NULL;
-
- if( search_key ) {
-
- if( 0 == strcmp("id", search_key) ) {
- cmp = nfs_compare_id;
- } else if( 0 == strcmp("fs_id", search_key) ) {
- cmp = nfs_compare_fs_id;
- }
-
- if( cmp ) {
- *count = filter((void **)exports, *count, cmp, (void*)search_value,
- nfs_free);
- }
- }
-}
-
-CMP_FUNCTION(tp_compare_id, lsm_target_port_id_get, lsm_target_port)
-CMP_FUNCTION(tp_compare_system_id, lsm_target_port_system_id_get, lsm_target_port)
-CMP_FREE_FUNCTION(tp_free, lsm_target_port_record_free, lsm_target_port)
-
-void lsm_plug_target_port_search_filter(const char *search_key,
- const char *search_value,
- lsm_target_port *tp[],
- uint32_t *count)
-{
- array_cmp cmp = NULL;
-
- if( search_key ) {
-
- if( 0 == strcmp("id", search_key) ) {
- cmp = tp_compare_id;
- } else if( 0 == strcmp("system_id", search_key) ) {
- cmp = tp_compare_system_id;
- }
-
- if( cmp ) {
- *count = filter((void **)tp, *count, cmp, (void*)search_value,
- tp_free);
- }
- }
-}
diff --git a/c_binding/lsm_plugin_ipc.hpp b/c_binding/lsm_plugin_ipc.hpp
deleted file mode 100644
index 36f3220..0000000
--- a/c_binding/lsm_plugin_ipc.hpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2011-2013 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 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#ifndef LSM_PLUGIN_IPC_HPP
-#define LSM_PLUGIN_IPC_HPP
-
-#include <map>
-#include "libstoragemgmt/libstoragemgmt_common.h"
-
-template <typename K, typename V>
-class LSM_DLL_LOCAL static_map
-{
-private:
- std::map<K, V> _m;
-public:
- static_map(const K& key, const V& val)
- {
- _m[key] = val;
- }
-
- static_map<K, V>& operator()(const K& key, const V& val)
- {
- _m[key] = val;
- return *this;
- }
-
- operator std::map<K, V>()
- {
- return _m;
- }
-};
-
-#endif
\ No newline at end of file
diff --git a/c_binding/test.cpp b/c_binding/test.cpp
deleted file mode 100644
index 9dde0f2..0000000
--- a/c_binding/test.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-#include "lsm_ipc.h"
-
-#include <iostream>
-#include <stdlib.h>
-
-
-std::string gen_random(int len)
-{
- static const char alphanum[] =
- "0123456789"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxyz";
- std::string rc(len, 'x');
-
- for( int i = 0; i < len; ++i ) {
- rc[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
- }
- return rc;
-}
-
-
-void TestIt(int fd)
-{
- int rc = 0;
- int ec = 0;
- Transport t(fd);
-
- for( int i = 1; i < 1024*1024*16; i += 1) {
-
- std::string msg = gen_random(i);
-
- std::cout << "sending msg" << std::endl;
- rc = t.sendMsg(msg, ec);
- std::cout << "message sent: " << rc << std::endl;
- if( rc == 0 ) {
-
- std::cout << "Receiving msg" << std::endl;
- std::string rmsg = t.recvMsg(ec);
- std::cout << "Message received " << rmsg.size() << " Byte(s)" << std::endl;
-
- if( rmsg.size() > 0 ) {
-
- if( msg != rmsg ) {
- std::cout << "Data miss-compare" << std::endl;
- std::cout << "Recv: " << rmsg << std::endl;
- }
- } else {
- std::cout << "Error recv: " << ec << std::endl;
- break;
- }
- } else {
- std::cout << "Error send: " << ec << std::endl;
- break;
- }
- }
-}
-
-
-
-int main(void)
-{
- std::string path("/tmp/testing");
-
- int ec = 0;
- int fd = 0;
-
- fd = Transport::getSocket(path, ec);
-
- if( fd >= 0 ) {
- TestIt(fd);
- } else {
- std::cout << "Error getting connected socket: " << ec << std::endl;
- }
-
- return 0;
-}
diff --git a/c_binding/util/misc.cpp b/c_binding/util/misc.cpp
deleted file mode 100644
index e5e13c5..0000000
--- a/c_binding/util/misc.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2011-2013 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 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#include "misc.h"
-#include "qparams.h"
-#include <string>
-#include <string.h>
-
-namespace LSM {
-
-std::string getValue(std::string uri, std::string key)
-{
- int i;
- std::string rc;
- struct qparam_set *queryParamSet = NULL;
-
- queryParamSet = qparam_query_parse(uri.c_str());
- if( NULL == queryParamSet ) {
- return rc;
- } else {
- for( i = 0; i < queryParamSet->n; ++i ) {
- if(strcmp(queryParamSet->p[i].name, key.c_str()) == 0 ) {
- rc = queryParamSet->p[i].value;
- break;
- }
- }
- free_qparam_set(queryParamSet);
- }
- return rc;
-}
-
-}
\ No newline at end of file
diff --git a/c_binding/util/misc.h b/c_binding/util/misc.h
deleted file mode 100644
index 43f37f3..0000000
--- a/c_binding/util/misc.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2011-2013 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 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#ifndef MISC_H
-#define MISC_H
-#include <string>
-#include <map>
-#include <stdint.h>
-
-#include <libstoragemgmt/libstoragemgmt_common.h>
-
-namespace LSM {
-
-/**
- * Retrieve the first value that matches key from a query string
- * @param query_string Query String to parse.
- * @param key Key to look for
- * @return empty string if key not found, else returns value.
- */
-LSM_DLL_LOCAL std::string getValue(std::string query_string, std::string key);
-
-/**
- * Simple class used to store jobs in an associative array.
- * @param t Type you want to associate with an integer.
- * @return
- */
-template <class Type>
-class LSM_DLL_LOCAL JobControl {
-
-public:
-
- /**
- * Ctor
- */
- JobControl():ticket(0)
- {
- }
-
- /**
- * Adds an item to the collection.
- * @param t Type to add.
- * @return Index it was inserted at.
- */
- int insert( Type t )
- {
- jobs[++ticket] = t;
- return ticket;
- }
-
- /**
- * Returns item at index num.
- * @param num Key
- * @return Item
- */
- Type get(uint32_t num)
- {
- return getInt(num)->second;
- }
-
- /**
- * Checks to see if an item is present.
- * @param num Key
- * @return true if key exists, else false.
- */
- bool present(uint32_t num)
- {
- return ( getInt(num) != jobs.end());
- }
-
- /**
- * Removes an item.
- * @param num Key
- */
- void remove(uint32_t num)
- {
- jobs.erase(getInt(num));
- }
-
-private:
- typename std::map<uint32_t, Type>::iterator getInt(uint32_t num )
- {
- typename std::map<uint32_t, Type>::iterator i = jobs.find(num);
- return i;
- }
- uint32_t ticket;
- std::map<uint32_t , Type> jobs;
-};
-
-} //End namespace
-
-
-#endif /* MISC_H */
diff --git a/c_binding/util/qparams.c b/c_binding/util/qparams.c
deleted file mode 100644
index dc42dae..0000000
--- a/c_binding/util/qparams.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/* Copyright (C) 2007, 2009-2011 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors:
- * Richard W.M. Jones <***@redhat.com>
- *
- * Utility functions to help parse and assemble query strings.
- *
- *
- *
- * !!!NOTE!!!: Taken from libvirt and modified to remove libvirt coupling.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-
-#include <libxml/uri.h>
-#include "qparams.h"
-#include <string.h>
-
-struct qparam_set *
-new_qparam_set (int init_alloc, ...)
-{
- va_list args;
- struct qparam_set *ps;
- const char *pname, *pvalue;
-
- if (init_alloc <= 0) init_alloc = 1;
-
-
- ps = (struct qparam_set *)calloc( 1, sizeof(*(ps)));
- if( !ps ) {
- return NULL;
- }
-
- ps->n = 0;
- ps->alloc = init_alloc;
-
- ps->p = (struct qparam *) calloc( ps->alloc, sizeof(*(ps->p)));
-
- if (!ps->p) {
- free(ps);
- return NULL;
- }
-
- va_start (args, init_alloc);
- while ((pname = va_arg (args, char *)) != NULL) {
- pvalue = va_arg (args, char *);
-
- if (append_qparam (ps, pname, pvalue) == -1) {
- free_qparam_set (ps);
- ps = NULL;
- break;
- }
- }
- va_end (args);
-
- return ps;
-}
-
-int
-append_qparams (struct qparam_set *ps, ...)
-{
- va_list args;
- const char *pname, *pvalue;
- int ret = 0;
-
- va_start (args, ps);
- while ((pname = va_arg (args, char *)) != NULL) {
- pvalue = va_arg (args, char *);
-
- if (append_qparam (ps, pname, pvalue) == -1) {
- ret = -1;
- break;
- }
- }
- va_end (args);
-
- return ret;
-}
-
-/* Ensure there is space to store at least one more parameter
- * at the end of the set.
- */
-static int
-grow_qparam_set (struct qparam_set *ps)
-{
- if (ps->n >= ps->alloc) {
-
- void *tmp = realloc( ps->p, ps->alloc * 2);
- if( !tmp ) {
- return -1;
- }
- ps->p = (struct qparam *)tmp;
- ps->alloc *= 2;
- }
-
- return 0;
-}
-
-int
-append_qparam (struct qparam_set *ps,
- const char *name, const char *value)
-{
- char *pname, *pvalue;
-
- pname = strdup (name);
- if (!pname) {
- return -1;
- }
-
- pvalue = strdup (value);
- if (!pvalue) {
- free(pname);
- return -1;
- }
-
- if (grow_qparam_set (ps) == -1) {
- free(pname);
- free(pvalue);
- return -1;
- }
-
- ps->p[ps->n].name = pname;
- ps->p[ps->n].value = pvalue;
- ps->p[ps->n].ignore = 0;
- ps->n++;
-
- return 0;
-}
-
-void
-free_qparam_set (struct qparam_set *ps)
-{
- int i;
-
- for (i = 0; i < ps->n; ++i) {
- free(ps->p[i].name);
- free(ps->p[i].value);
- }
- free(ps->p);
- ps->p = NULL;
- free(ps);
-}
-
-struct qparam_set *
-qparam_query_parse (const char *query)
-{
- struct qparam_set *ps;
- const char *end, *eq;
-
- ps = new_qparam_set (0, NULL);
- if (!ps) {
- return NULL;
- }
-
- if (!query || query[0] == '\0') return ps;
-
- while (*query) {
- char *name = NULL, *value = NULL;
-
- /* Find the next separator, or end of the string. */
- end = strchr (query, '&');
- if (!end)
- end = strchr (query, ';');
- if (!end)
- end = query + strlen (query);
-
- /* Find the first '=' character between here and end. */
- eq = strchr (query, '=');
- if (eq && eq >= end) eq = NULL;
-
- /* Empty section (eg. "&&"). */
- if (end == query)
- goto next;
-
- /* If there is no '=' character, then we have just "name"
- * and consistent with CGI.pm we assume value is "".
- */
- else if (!eq) {
- name = xmlURIUnescapeString (query, end - query, NULL);
- if (!name) goto out_of_memory;
- }
- /* Or if we have "name=" here (works around annoying
- * problem when calling xmlURIUnescapeString with len = 0).
- */
- else if (eq+1 == end) {
- name = xmlURIUnescapeString (query, eq - query, NULL);
- if (!name) goto out_of_memory;
- }
- /* If the '=' character is at the beginning then we have
- * "=value" and consistent with CGI.pm we _ignore_ this.
- */
- else if (query == eq)
- goto next;
-
- /* Otherwise it's "name=value". */
- else {
- name = xmlURIUnescapeString (query, eq - query, NULL);
- if (!name)
- goto out_of_memory;
- value = xmlURIUnescapeString (eq+1, end - (eq+1), NULL);
- if (!value) {
- free(name);
- goto out_of_memory;
- }
- }
-
- /* Append to the parameter set. */
- if (append_qparam (ps, name, value ? value : "") == -1) {
- free(name);
- free(value);
- goto out_of_memory;
- }
- free(name);
- free(value);
-
- next:
- query = end;
- if (*query) query ++; /* skip '&' separator */
- }
-
- return ps;
-
- out_of_memory:
- free_qparam_set (ps);
- return NULL;
-}
diff --git a/c_binding/util/qparams.h b/c_binding/util/qparams.h
deleted file mode 100644
index ca5ddb4..0000000
--- a/c_binding/util/qparams.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2010-2011 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors:
- * Richard W.M. Jones <***@redhat.com>
- *
- * Utility functions to help parse and assemble query strings.
- *
- *
- * !!!NOTE!!!: Taken from libvirt and modified to remove libvirt coupling.
- */
-
-#ifndef _QPARAMS_H_
-# define _QPARAMS_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "libstoragemgmt/libstoragemgmt_common.h"
-
-/**
- * * ATTRIBUTE_SENTINEL:
- * *
- * * Macro to check for NULL-terminated varargs lists
- * */
-# ifndef ATTRIBUTE_SENTINEL
-# if __GNUC_PREREQ (4, 0)
-# define ATTRIBUTE_SENTINEL __attribute__((__sentinel__))
-# else
-# define ATTRIBUTE_SENTINEL
-# endif
-# endif
-
-
-/**
- * Single web service query parameter 'name=value'.
- */
-struct qparam {
- char *name; /**< Name (unescaped). */
- char *value; /**< Value (unescaped). */
- int ignore; /**< Ignore this field in qparam_get_query */
-};
-
-/**
- * Set of parameters.
- */
-struct qparam_set {
- int n; /**< number of parameters used */
- int alloc; /**< allocated space */
- struct qparam *p; /**< array of parameters */
-};
-
-/* New parameter set. */
-LSM_DLL_LOCAL struct qparam_set *new_qparam_set (int init_alloc, ...)
- ATTRIBUTE_SENTINEL;
-
-/* Appending parameters. */
-LSM_DLL_LOCAL int append_qparams (struct qparam_set *ps, ...)
- ATTRIBUTE_SENTINEL;
-LSM_DLL_LOCAL int append_qparam (struct qparam_set *ps,
- const char *name, const char *value);
-
-
-/* Parse a query string into a parameter set. */
-LSM_DLL_LOCAL struct qparam_set *qparam_query_parse (const char *query);
-
-LSM_DLL_LOCAL void free_qparam_set (struct qparam_set *ps);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _QPARAMS_H_ */
diff --git a/config/Makefile.am b/config/Makefile.am
deleted file mode 100644
index 39fb224..0000000
--- a/config/Makefile.am
+++ /dev/null
@@ -1,18 +0,0 @@
-lsmconfdir=$(sysconfdir)/lsm
-lsmconf_DATA=lsmd.conf
-
-EXTRA_DIST= lsmd.conf pluginconf.d/sim.conf
-
-pluginconfdir=$(sysconfdir)/lsm/pluginconf.d
-
-pluginconf_DATA=pluginconf.d/sim.conf
-
-if WITH_MEGARAID
-pluginconf_DATA += pluginconf.d/megaraid.conf
-EXTRA_DIST += pluginconf.d/megaraid.conf
-endif
-
-if WITH_HPSA
-pluginconf_DATA += pluginconf.d/hpsa.conf
-EXTRA_DIST += pluginconf.d/hpsa.conf
-endif
diff --git a/config/lsmd.conf b/config/lsmd.conf
deleted file mode 100644
index 7eb4335..0000000
--- a/config/lsmd.conf
+++ /dev/null
@@ -1 +0,0 @@
-allow-plugin-root-privilege = true;
diff --git a/config/pluginconf.d/hpsa.conf b/config/pluginconf.d/hpsa.conf
deleted file mode 100644
index 35b52d4..0000000
--- a/config/pluginconf.d/hpsa.conf
+++ /dev/null
@@ -1 +0,0 @@
-require-root-privilege = true;
diff --git a/config/pluginconf.d/megaraid.conf b/config/pluginconf.d/megaraid.conf
deleted file mode 100644
index 35b52d4..0000000
--- a/config/pluginconf.d/megaraid.conf
+++ /dev/null
@@ -1 +0,0 @@
-require-root-privilege = true;
diff --git a/config/pluginconf.d/sim.conf b/config/pluginconf.d/sim.conf
deleted file mode 100644
index da915bf..0000000
--- a/config/pluginconf.d/sim.conf
+++ /dev/null
@@ -1 +0,0 @@
-require-root-privilege = false;
diff --git a/configure.ac b/configure.ac
deleted file mode 100644
index 9ad73a3..0000000
--- a/configure.ac
+++ /dev/null
@@ -1,290 +0,0 @@
-dnl Process this file with autoconf to produce a configure script.
-dnl Copyright (C) 2011 Red Hat, Inc.
-dnl See COPYING.LIB for the License of this software
-
-AC_INIT([libstoragemgmt], [1.2.0], [libstoragemgmt-***@lists.sourceforge.net], [], [http://sourceforge.net/projects/libstoragemgmt/])
-AC_CONFIG_SRCDIR([configure.ac])
-AC_CONFIG_AUX_DIR([build-aux])
-AC_CONFIG_HEADERS([config.h])
-AC_CONFIG_MACRO_DIR([m4])
-dnl Make automake keep quiet about wildcards & other GNUmake-isms
-AM_INIT_AUTOMAKE([-Wno-portability subdir-objects])
-AM_MAINTAINER_MODE([enable])
-# Enable silent build when available (Automake 1.11)
-m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
-PKG_PROG_PKG_CONFIG
-
-AC_CANONICAL_HOST
-
-LIBSM_MAJOR_VERSION=`echo $VERSION | awk -F. '{print $1}'`
-LIBSM_MINOR_VERSION=`echo $VERSION | awk -F. '{print $2}'`
-LIBSM_MICRO_VERSION=`echo $VERSION | awk -F. '{print $3}'`
-LIBSM_VERSION=$LIBSM_MAJOR_VERSION.$LIBSM_MINOR_VERSION.$LIBSM_MICRO_VERSION$LIBSM_MICRO_VERSION_SUFFIX
-LIBSM_VERSION_INFO=`expr $LIBSM_MAJOR_VERSION + $LIBSM_MINOR_VERSION`:$LIBSM_MICRO_VERSION:$LIBSM_MINOR_VERSION
-LIBSM_VERSION_NUMBER=`expr $LIBSM_MAJOR_VERSION \* 1000000 + $LIBSM_MINOR_VERSION \* 1000 + $LIBSM_MICRO_VERSION`
-
-# Our intention is that we will always be backward compatible. Thus we will
-# set the library version in such a way so that we will always be
-# libstoragemgmt.so.1.n.n once we officially release our ver 1.0.0.
-#
-# To make this happen we will use the minor version as the libtool current and
-# age set to minor - 1 and the micro used for revision. Basically this will get
-# us what we expect while utilizing the libtool revision system.
-#
-# For this to work we need to make sure that when we add to the interface we
-# increment minor and set micro to 0. If we make a code change which doesn't
-# change the API we can just bump micro.
-#
-# 0.1.0 -> libstoragemgmt.so.0.1.0
-# 1.0.0 -> libstoragemgmt.so.1.0.0
-# 1.1.0 -> libstoragemgmt.so.1.1.0
-# 1.1.1 -> libstoragemgmt.so.1.1.1
-
-CURRENT=`expr $LIBSM_MAJOR_VERSION '*' 1 + $LIBSM_MINOR_VERSION`
-AGE=$LIBSM_MINOR_VERSION
-REVISION=$LIBSM_MICRO_VERSION
-
-LIBSM_LIBTOOL_VERSION=$CURRENT:$REVISION:$AGE
-
-AC_SUBST([LIBSM_MAJOR_VERSION])
-AC_SUBST([LIBSM_MINOR_VERSION])
-AC_SUBST([LIBSM_MICRO_VERSION])
-AC_SUBST([LIBSM_VERSION])
-AC_SUBST([LIBSM_VERSION_INFO])
-AC_SUBST([LIBSM_VERSION_NUMBER])
-AC_SUBST([LIBSM_LIBTOOL_VERSION])
-
-dnl Required minimum versions of all libs we depend on
-LIBXML_REQUIRED="2.5.0"
-
-dnl Checks for C compiler.
-AC_PROG_CC
-AC_PROG_CXX
-AC_PROG_AWK
-AC_PROG_INSTALL
-AC_PROG_LN_S
-AC_PROG_MAKE_SET
-AC_PROG_CPP
-AM_PROG_CC_STDC
-
-AM_PROG_LIBTOOL
-AM_PROG_CC_C_O
-AM_PROG_LD
-
-AC_CHECK_HEADERS([stdint.h stdlib.h string.h sys/socket.h syslog.h unistd.h])
-
-AC_LANG_PUSH([C++])
-AC_COMPILE_IFELSE([AC_LANG_SOURCE([int i;])],
- [], [AC_MSG_ERROR([C++ compiler missing or inoperational])])
-AC_LANG_POP([C++])
-
-#Make sure all types are covered
-AC_HEADER_STDBOOL
-AC_TYPE_INT32_T
-AC_TYPE_INT64_T
-AC_TYPE_SIZE_T
-AC_TYPE_SSIZE_T
-AC_TYPE_UINT32_T
-AC_TYPE_UINT64_T
-AC_TYPE_UINT8_T
-
-AC_FUNC_ERROR_AT_LINE
-AC_FUNC_MALLOC
-AC_FUNC_REALLOC
-AC_CHECK_FUNCS([getpass memset socket strchr strdup strtol strtoul])
-
-dnl Availability of various common headers (non-fatal if missing).
-AC_CHECK_HEADERS([dlfcn.h])
-
-#Check for openssl development libs, we are using in simc_lsmplugin
-AC_CHECK_LIB([crypto], [MD5_Final], [SSL_LIBS=-lcrypto], AC_MSG_ERROR([Missing openssl-devel libraries]))
-AC_SUBST([SSL_LIBS])
-
-#Check for json parser yajl
-AC_CHECK_HEADERS([yajl/yajl_gen.h yajl/yajl_parse.h], [] , AC_MSG_ERROR([Missing yajl development headers]) )
-AC_CHECK_HEADERS([yajl/yajl_version.h])
-AC_CHECK_LIB([yajl], [yajl_parse], [YAJL_LIBS=-lyajl], AC_MSG_ERROR([Missing yajl library]))
-AC_SUBST([YAJL_LIBS])
-
-dnl if --prefix is /usr, don't use /usr/var for localstatedir
-dnl or /usr/etc for sysconfdir
-dnl as this makes a lot of things break in testing situations
-
-if test "$prefix" = "/usr" && test "$localstatedir" = '${prefix}/var' ; then
- localstatedir='/var'
-fi
-if test "$prefix" = "/usr" && test "$sysconfdir" = '${prefix}/etc' ; then
- sysconfdir='/etc'
-fi
-
-dnl ==========================================================================
-dnl find libxml2 library, borrowed from xmlsec
-dnl ==========================================================================
-
-PKG_CHECK_MODULES([LIBXML], [libxml-2.0])
-PKG_CHECK_MODULES([LIBGLIB], [glib-2.0 >= 2.22.5])
-
-want_c_unit="yes"
-AC_ARG_ENABLE([build-c-unit],
- [AC_HELP_STRING([--disable-build-c-unit], [disable building C unit test case.])],
- [want_c_unit=${enableval}], [])
-
-if test "x${want_c_unit}" = "xyes"; then
- PKG_CHECK_MODULES([LIBCHECK], [check >= 0.9.8 ])
-fi
-
-AM_CONDITIONAL([BUILD_C_UNIT], [test "x${want_c_unit}" = "xyes"])
-
-dnl =========================================================================
-dnl Check for perl, used for code constants checking
-dnl =========================================================================
-AC_PATH_PROGS(PERL, perl)
-
-dnl ==========================================================================
-dnl Check for python2 as it is needed for the base cmd line function
-dnl ==========================================================================
-
-AC_PATH_PROGS(PYTHON, python2.7 python2.6 python, [Python is required])
-AC_MSG_CHECKING([Check for Python major version])
-PYTHON_MAJOR_VERSION=`$PYTHON -c "import sys; print(sys.version_info[[0]])"`
-case "$PYTHON_MAJOR_VERSION" in
- 2)
- ;;
- *)
- AC_MSG_ERROR(
- [we need Python version 2.x but found $PYTHON_MAJOR_VERSION.x]) ;;
-esac
-AC_MSG_RESULT([$PYTHON_MAJOR_VERSION])
-AM_PATH_PYTHON([2.6], [], AC_MSG_ERROR([Python interpreter 2.6 or 2.7 required]) )
-
-AC_PYTHON_MODULE([pywbem], [Required])
-AC_PYTHON_MODULE([M2Crypto], [Required])
-AC_PYTHON_MODULE([argparse], [Required])
-
-dnl ==========================================================================
-dnl Check for libmicrohttpd and json-c as it is needed for REST API daemon
-dnl ==========================================================================
-
-AC_ARG_WITH([rest-api],
- [AS_HELP_STRING([--without-rest-api],
- [Do not build the REST API daemon])],
- [],
- [with_rest_api=yes])
-if test "x$with_rest_api" = "xyes"; then
- PKG_CHECK_MODULES([LIBMICROHTTPD], [libmicrohttpd >= 0.9])
- PKG_CHECK_MODULES([JSON], [json >= 0.10], [], [
- PKG_CHECK_MODULES([JSON], [json-c], [], [
- AC_MSG_ERROR([json-c development libraries 0.10 or later required])
- ])
- ])
-fi
-AM_CONDITIONAL([WITH_REST_API], [test "x$with_rest_api" = "xyes"])
-
-dnl ==========================================================================
-dnl Add option '--without-megaraid' to exclude megaraid plugin.
-dnl ==========================================================================
-
-AC_ARG_WITH([megaraid],
- [AS_HELP_STRING([--without-megaraid],
- [Do not build the MegaRAID plugin])],
- [],
- [with_megaraid=yes])
-
-AM_CONDITIONAL([WITH_MEGARAID], [test "x$with_megaraid" = "xyes"])
-
-dnl ==========================================================================
-dnl Add option '--without-hpsa' to exclude hpsa plugin.
-dnl ==========================================================================
-
-AC_ARG_WITH([hpsa],
- [AS_HELP_STRING([--without-hpsa],
- [Do not build the HP SmartArray plugin])],
- [],
- [with_hpsa=yes])
-
-AM_CONDITIONAL([WITH_HPSA], [test "x$with_hpsa" = "xyes"])
-
-dnl ==========================================================================
-dnl Check for libconfig as it is needed for lsmd daemon
-dnl ==========================================================================
-PKG_CHECK_MODULES(
- [LIBCONFIG], [libconfig >= 1.3.2],,
- AC_MSG_ERROR([libconfig 1.3.2 or newer not found.])
-)
-
-dnl ==========================================================================
-dnl Add option '--without-bash-completion' to exclude bash completion script.
-dnl ==========================================================================
-
-AC_ARG_WITH([bash-completion],
- [AS_HELP_STRING([--without-bash-completion],
- [Do not install the bash auto-completion script])],
- [],
- [with_bash_completion=yes])
-
-AM_CONDITIONAL(
- [WITH_BASH_COMPLETION], [test "x$with_bash_completion" = "xyes"])
-
-dnl ==========================================================================
-dnl Add option '--with-bash-completion-dir' to specific bash completion dir,
-dnl if not defined, if pkg-config file for bash-completion found, use its
-dnl 'completionsdir', else use /etc/bash_completion.d
-dnl ==========================================================================
-AC_ARG_WITH([bash-completion-dir],
- AS_HELP_STRING(
- [--with-bash-completion-dir=DIR],
- [Bash completions directory]),
- [],
- [AS_IF(
- [$($PKG_CONFIG --exists bash-completion)],
- [with_bash_completion_dir=$(
- $PKG_CONFIG --variable=completionsdir bash-completion)],
- # EPEL 6 is still shipping bash-completion version 1.x
- # which does not provide pkg-config support.
- # So, for EPEL 6 or anyone not installed bash-compeltion, we
- # use fallback folder '/etc/bash_completion.d'
- [with_bash_completion_dir=$sysconfdir/bash_completion.d])])
-
-AC_SUBST([bashcompletiondir], [$with_bash_completion_dir])
-
-#Setup the unit directory for systemd stuff
-PKG_PROG_PKG_CONFIG
-AC_ARG_WITH([systemdsystemunitdir],
- AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
- [], [with_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)])
-if test "x$with_systemdsystemunitdir" != xno; then
- AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])
-fi
-AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ])
-
-AC_OUTPUT(libstoragemgmt.pc \
- Makefile \
- c_binding/Makefile \
- c_binding/include/Makefile \
- c_binding/include/libstoragemgmt/Makefile \
- c_binding/include/libstoragemgmt/libstoragemgmt_version.h \
- python_binding/Makefile \
- python_binding/lsm/version.py \
- plugin/Makefile \
- plugin/simc/Makefile \
- plugin/megaraid/Makefile \
- plugin/hpsa/Makefile \
- daemon/Makefile \
- config/Makefile \
- doc/Makefile \
- doc/man/lsmcli.1 \
- doc/man/lsmd.1 \
- doc/doxygen.conf \
- doc/man/lsmd.conf.5 \
- doc/man/megaraid_lsmplugin.1 \
- doc/man/hpsa_lsmplugin.1 \
- tools/Makefile \
- tools/udev/Makefile \
- tools/lsmcli/Makefile \
- tools/utility/Makefile \
- tools/bash_completion/Makefile \
- packaging/Makefile \
- packaging/daemon/Makefile \
- packaging/libstoragemgmt.spec \
- doc/man/Makefile \
- test/Makefile)
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
deleted file mode 100644
index a9ef569..0000000
--- a/daemon/Makefile.am
+++ /dev/null
@@ -1,15 +0,0 @@
-bin_PROGRAMS = lsmd
-
-EXTRA_DIST=lsm_rest.c lsm_rest.h
-
-lsmd_LDFLAGS=-Wl,-z,relro,-z,now -pie $(LIBCONFIG_LIBS)
-lsmd_CFLAGS=-fPIE -DPIE $(LIBCONFIG_CFLAGS)
-
-lsmd_SOURCES = lsm_daemon.c
-
-if WITH_REST_API
-bin_PROGRAMS += lsm_restd
-lsm_restd_LDFLAGS=$(LIBMICROHTTPD_LIBS) $(JSON_LIBS) $(LIBXML_LIBS)
-lsm_restd_CFLAGS=-fPIE -DPIE $(LIBMICROHTTPD_CFLAGS) $(JSON_CFLAGS) $(LIBXML_CFLAGS)
-lsm_restd_SOURCES= lsm_rest.c
-endif
diff --git a/daemon/lsm_daemon.c b/daemon/lsm_daemon.c
deleted file mode 100644
index e21cb16..0000000
--- a/daemon/lsm_daemon.c
+++ /dev/null
@@ -1,914 +0,0 @@
-/*
- * Copyright (C) 2011-2015 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <string.h>
-#include <ctype.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <pwd.h>
-#include <errno.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <syslog.h>
-#include <stdarg.h>
-#include <dirent.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/queue.h>
-#include <sys/wait.h>
-#include <sys/time.h>
-#include <libgen.h>
-#include <assert.h>
-#include <grp.h>
-#include <limits.h>
-#include <libconfig.h>
-
-#define BASE_DIR "/var/run/lsm"
-#define SOCKET_DIR BASE_DIR"/ipc"
-#define PLUGIN_DIR "/usr/bin"
-#define LSM_USER "libstoragemgmt"
-#define LSM_CONF_DIR "/etc/lsm/"
-#define LSM_PLUGIN_CONF_DIR_NAME "pluginconf.d"
-#define LSMD_CONF_FILE "lsmd.conf"
-#define LSM_CONF_ALLOW_ROOT_OPT_NAME "allow-plugin-root-privilege"
-#define LSM_CONF_REQUIRE_ROOT_OPT_NAME "require-root-privilege"
-
-#define min(a,b) \
- ({ __typeof__ (a) _a = (a); \
- __typeof__ (b) _b = (b); \
- _a < _b ? _a : _b; })
-
-#define max(a,b) \
- ({ __typeof__ (a) _a = (a); \
- __typeof__ (b) _b = (b); \
- _a > _b ? _a : _b; })
-
-int verbose_flag = 0;
-int systemd = 0;
-
-char *socket_dir = SOCKET_DIR;
-char *plugin_dir = PLUGIN_DIR;
-char *conf_dir = LSM_CONF_DIR;
-
-char plugin_extension[] = "_lsmplugin";
-
-char plugin_conf_extension[] = ".conf";
-
-typedef enum { RUNNING, RESTART, EXIT } serve_type;
-serve_type serve_state = RUNNING;
-
-int plugin_mem_debug = 0;
-
-int allow_root_plugin = 0;
-int has_root_plugin = 0;
-
-/**
- * Each item in plugin list contains this information
- */
-struct plugin {
- char *file_path;
- int require_root;
- int fd;
- LIST_ENTRY(plugin) pointers;
-};
-
-/**
- * Linked list of plug-ins
- */
-LIST_HEAD(plugin_list, plugin) head;
-
-/**
- * Logs messages to the appropriate place
- * @param severity Severity of message, LOG_ERR causes daemon to exit
- * @param fmt String with format
- * @param ... Format parameters
- */
-void logger(int severity, const char *fmt, ...)
-{
- char buf[2048];
-
- if( verbose_flag || LOG_WARNING == severity || LOG_ERR == severity) {
- va_list arg;
- va_start(arg, fmt);
- vsnprintf(buf, sizeof(buf), fmt, arg);
- va_end(arg);
-
- if( !systemd ) {
- if( verbose_flag ) {
- syslog(LOG_ERR, "%s", buf);
- } else {
- syslog(severity, "%s", buf);
- }
- } else {
- fprintf(stdout, "%s", buf);
- fflush(stdout);
- }
-
- if( LOG_ERR == severity) {
- exit(1);
- }
- }
-}
-#define log_and_exit(fmt, ...) logger(LOG_ERR, fmt, ##__VA_ARGS__)
-#define warn(fmt, ...) logger(LOG_WARNING, fmt, ##__VA_ARGS__)
-#define info(fmt, ...) logger(LOG_INFO, fmt, ##__VA_ARGS__)
-
-/**
- * Our signal handler.
- * @param s Received signal
- */
-void signal_handler(int s)
-{
- if( SIGTERM == s) {
- serve_state = EXIT;
- } else if( SIGHUP == s ) {
- serve_state = RESTART;
- }
-}
-
-/**
- * Installs our signal handler
- */
-void install_sh(void)
-{
- if(signal(SIGTERM, signal_handler) == SIG_ERR) {
- log_and_exit("Can't catch signal SIGTERM\n");
- }
-
- if(signal(SIGHUP, signal_handler) == SIG_ERR) {
- log_and_exit("Can't catch signal SIGHUP\n");
- }
-}
-
-/**
- * If we are running as root, we will try to drop our privs. to our default
- * user.
- */
-void drop_privileges(void)
-{
- int err = 0;
- struct passwd *pw = NULL;
-
- pw = getpwnam(LSM_USER);
- if( pw ) {
- if ( !geteuid() ) {
-
- if( -1 == setgid(pw->pw_gid) ) {
- err = errno;
- log_and_exit(
- "Unexpected error on setgid(errno %d)\n", err);
- }
-
- if( -1 == setgroups(1, &pw->pw_gid) ) {
- err = errno;
- log_and_exit(
- "Unexpected error on setgroups(errno %d)\n", err);
- }
-
- if( -1 == setuid(pw->pw_uid) ) {
- err = errno;
- log_and_exit(
- "Unexpected error on setuid(errno %d)\n", err);
- }
- } else if ( pw->pw_uid != getuid() ) {
- warn("Daemon not running as correct user\n");
- }
- } else {
- info("Warn: Missing %s user, running as existing user!\n",
- LSM_USER);
- }
-}
-
-/**
- * Check to make sure we have access to the directories of interest
- */
-void flight_check(void)
-{
- int err = 0;
- if( -1 == access(socket_dir, R_OK|W_OK )) {
- err = errno;
- log_and_exit("Unable to access socket directory %s, errno= %d\n",
- socket_dir, err);
- }
-
- if( -1 == access(plugin_dir, R_OK|X_OK)) {
- err = errno;
- log_and_exit("Unable to access plug-in directory %s, errno= %d\n",
- plugin_dir, err);
- }
-}
-
-/**
- * Print help.
- */
-void usage(void)
-{
- printf("libStorageMgmt plug-in daemon.\n");
- printf("lsmd [--plugindir <directory>] [--socketdir <dir>] [-v] [-d]\n");
- printf(" --plugindir = The directory where the plugins are located\n");
- printf(" --socketdir = The directory where the Unix domain sockets will "
- "be created\n");
- printf(" --confdir = The directory where the config files are "
- "located\n");
- printf(" -v = Verbose logging\n");
- printf(" -d = new style daemon (systemd)\n");
-}
-
-/**
- * Concatenates a path and a file name.
- * @param path Fully qualified path
- * @param name File name
- * @return Concatenated string, caller must call free when done
- */
-char *path_form(const char* path, const char *name)
-{
- size_t s = strlen(path) + strlen(name) + 2;
- char *full = calloc(1, s);
- if( full ) {
- snprintf(full, s, "%s/%s", path, name);
- } else {
- log_and_exit("malloc failure while trying to allocate %d bytes\n", s);
- }
- return full;
-}
-
-/* Call back signature */
-typedef int (*file_op)(void *p, char *full_file_path);
-
-/**
- * For a given directory iterate through each directory item and exec the
- * callback, recursively process nested directories too.
- * @param dir Directory to transverse
- * @param p Pointer to user data (Optional)
- * @param call_back Function to call against file
- * @return
- */
-void process_directory( char *dir, void *p, file_op call_back)
-{
- int err = 0;
-
- if( call_back && dir && strlen(dir) ) {
- DIR *dp = NULL;
- struct dirent *entry = NULL;
- char *full_name = NULL;
- dp = opendir(dir);
-
- if( dp ) {
- while(( entry = readdir(dp)) != NULL) {
- struct stat entry_st;
- free(full_name);
- full_name = path_form(dir, entry->d_name);
-
- if( stat(full_name, &entry_st ) != 0 ) {
- continue;
- }
-
- if( S_ISDIR(entry_st.st_mode) ) {
- if (strncmp(entry->d_name, ".", 1) == 0){
- continue;
- }
- process_directory(full_name, p, call_back);
- } else {
- if( call_back(p, full_name) ) {
- break;
- }
- }
- }
-
- free(full_name);
-
- if( closedir(dp) ) {
- err = errno;
- log_and_exit("Error on closing dir %s: %s\n", dir,
- strerror(err));
- }
- } else {
- err = errno;
- log_and_exit("Error on processing directory %s: %s\n", dir,
- strerror(err));
- }
- }
-}
-
-/**
- * Callback to remove a unix domain socket by deleting it.
- * @param p Call back data
- * @param full_name Full path an and file name
- * @return 0 to continue processing, anything else to stop.
- */
-int delete_socket(void *p, char *full_name)
-{
- struct stat statbuf;
- int err;
-
- assert(p==NULL);
-
- if( !lstat(full_name, &statbuf) ) {
- if( S_ISSOCK(statbuf.st_mode)) {
- if( unlink(full_name) ) {
- err = errno;
- log_and_exit("Error on unlinking file %s: %s\n",
- full_name, strerror(err));
- }
- }
- }
- return 0;
-}
-
-/**
- * Walk the IPC socket directory and remove the socket files.
- */
-void clean_sockets()
-{
- process_directory(socket_dir, NULL, delete_socket);
-}
-
-
-/**
- * Given a fully qualified path and name to a plug-in, create the IPC socket.
- * @param full_name Full name and path for plug-in
- * @return listening socket descriptor for IPC
- */
-int setup_socket(char *full_name)
-{
- int err = 0;
- char name[128];
-
- /* Strip off _lsmplugin from the file name, not sure
- * why I chose to do this */
- memset(name, 0, sizeof(name));
-
- char *base_nm = basename(full_name);
- strncpy(name, base_nm, min(abs(strlen(base_nm) - strlen(plugin_extension)), (sizeof(name)-1)));
-
- char *socket_file = path_form(socket_dir, name);
- delete_socket(NULL, socket_file);
-
- int fd = socket(AF_UNIX, SOCK_STREAM, 0);
- if( -1 != fd ) {
- struct sockaddr_un addr;
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
-
- strncpy(addr.sun_path, socket_file, sizeof(addr.sun_path) - 1);
-
- if( -1 == bind(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un))) {
- err = errno;
- log_and_exit("Error on binding socket %s: %s\n", socket_file, strerror(err));
- }
-
- if( -1 == chmod(socket_file, S_IREAD|S_IWRITE|S_IRGRP|S_IWGRP
- |S_IROTH|S_IWOTH)) {
- err = errno;
- log_and_exit("Error on chmod socket file %s: %s\n", socket_file, strerror(err));
- }
-
- if( -1 == listen(fd, 5)) {
- err = errno;
- log_and_exit("Error on listening %s: %s\n", socket_file, strerror(err));
- }
-
- } else {
- err = errno;
- log_and_exit("Error on socket create %s: %s\n",
- socket_file, strerror(err));
- }
-
- free(socket_file);
- return fd;
-}
-
-/**
- * Closes all the listening sockets and re-claims memory in linked list.
- * @param list
- */
-void empty_plugin_list(struct plugin_list *list)
-{
- int err;
- struct plugin *item = NULL;
-
- while(!LIST_EMPTY(list))
- {
- item = LIST_FIRST(list);
- LIST_REMOVE(item, pointers);
-
- if( -1 == close(item->fd) ) {
- err = errno;
- info("Error on closing fd %d for file %s: %s\n", item->fd,
- item->file_path, strerror(err));
- }
-
- free(item->file_path);
- item->file_path = NULL;
- item->fd = INT_MAX;
- free(item);
- }
-}
-
-/**
- * Parse config and seeking provided key name bool
- * 1. Keep value untouched if file not exist
- * 2. If file is not readable, abort via log_and_exit()
- * 3. Keep value untouched if provided key not found
- * 4. Abort via log_and_exit() if no enough memory.
- * @param conf_path config file path
- * @param key_name string, searching key
- * @param value int, output, value of this config key
- */
-
-void parse_conf_bool(char * conf_path, char *key_name, int *value)
-{
- if( access(conf_path, F_OK) == -1 ) {
- /* file not exist. */
- return;
- }
- config_t *cfg = (config_t *)malloc(sizeof(config_t));
- if (cfg){
- config_init(cfg);
- if (CONFIG_TRUE == config_read_file(cfg, conf_path)){
- config_lookup_bool(cfg, key_name, value);
- }else{
- log_and_exit(
- "configure %s parsing failed: %s at line %d\n",
- conf_path, config_error_text(cfg), config_error_line(cfg));
- }
- } else{
- log_and_exit(
- "malloc failure while trying to allocate memory for config_t\n");
- }
-
- config_destroy(cfg);
- free(cfg);
-}
-
-/**
- * Load plugin config for root privilege setting.
- * If config not found, return 0 for no root privilege required.
- * @param plugin_path Full path of plugin
- * @return 1 for require root privilege, 0 or not.
- */
-
-int chk_pconf_root_pri(char *plugin_path)
-{
- int require_root = 0;
- char *base_name = basename(plugin_path);
- ssize_t plugin_name_len =
- strlen(base_name) - strlen(plugin_extension);
- if ( plugin_name_len <= 0 ){
- log_and_exit(
- "Got invalid plugin full path %s\n", plugin_path);
- }
- ssize_t conf_file_name_len = plugin_name_len +
- strlen(plugin_conf_extension) + 1;
- char *plugin_conf_filename =
- (char *)malloc(conf_file_name_len);
- if (plugin_conf_filename){
- strncpy(
- plugin_conf_filename, base_name, plugin_name_len);
- strncpy(
- plugin_conf_filename+plugin_name_len,
- plugin_conf_extension, strlen(plugin_conf_extension));
- plugin_conf_filename[conf_file_name_len-1] = '\0';
- }else{
- log_and_exit(
- "malloc failure while trying to allocate %d "
- "bytes\n", conf_file_name_len);
- }
- char *plugin_conf_dir_path =
- path_form(conf_dir, LSM_PLUGIN_CONF_DIR_NAME);
-
- char *plugin_conf_path = path_form(
- plugin_conf_dir_path, plugin_conf_filename);
- parse_conf_bool(
- plugin_conf_path, LSM_CONF_REQUIRE_ROOT_OPT_NAME,
- &require_root);
-
- if (require_root == 1 && allow_root_plugin == 0){
- warn(
- "Plugin %s require root privilege while %s disable globally\n",
- base_name, LSMD_CONF_FILE);
- }
- free(plugin_conf_dir_path);
- free(plugin_conf_filename);
- free(plugin_conf_path);
- return require_root;
-}
-
-/**
- * Call back for plug-in processing.
- * @param p Private data
- * @param full_name Full path and file name
- * @return 0 to continue, else abort directory processing
- */
-int process_plugin(void *p, char *full_name)
-{
- if( full_name ) {
- size_t ext_len = strlen(plugin_extension);
- size_t full_len = strlen(full_name);
-
- if( full_len > ext_len) {
- if( strncmp(full_name + full_len - ext_len, plugin_extension, ext_len) == 0) {
- struct plugin *item = calloc(1, sizeof(struct plugin));
- if( item ) {
- item->file_path = strdup(full_name);
- item->fd = setup_socket(full_name);
- item->require_root = chk_pconf_root_pri(full_name);
- has_root_plugin |= item->require_root;
-
- if( item->file_path && item->fd >= 0 ) {
- LIST_INSERT_HEAD((struct plugin_list*)p, item, pointers);
- info("Plugin %s added\n", full_name);
- } else {
- /* The only real way to get here is failed strdup as
- setup_socket will exit on error. */
- free(item);
- item = NULL;
- log_and_exit("strdup failed %s\n", full_name);
- }
- } else {
- log_and_exit("Memory allocation failure!\n");
- }
- }
- }
- }
- return 0;
-}
-
-/**
- * Cleans up any children that have exited.
- */
-void child_cleanup(void)
-{
- int rc;
- int err;
-
- do {
- siginfo_t si;
- memset(&si, 0, sizeof(siginfo_t));
-
- rc = waitid(P_ALL, 0, &si, WNOHANG|WEXITED);
-
- if( -1 == rc ) {
- err = errno;
- if (err != ECHILD){
- info("waitid %d - %s\n", err, strerror(err));
- }
- break;
- } else {
- if( 0 == rc && si.si_pid == 0 ) {
- break;
- } else {
- if( si.si_code == CLD_EXITED && si.si_status != 0 ) {
- info("Plug-in process %d exited with %d\n", si.si_pid,
- si.si_status);
- }
- }
- }
- } while(1);
-}
-
-/**
- * Closes and frees memory and removes Unix domain sockets.
- */
-void clean_up(void )
-{
- empty_plugin_list(&head);
- clean_sockets();
-}
-
-/**
- * Walks the plugin directory creating IPC sockets for each one.
- * @return
- */
-int process_plugins(void)
-{
- clean_up();
- info("Scanning plug-in directory %s\n", plugin_dir);
- process_directory(plugin_dir, &head, process_plugin);
- if ( allow_root_plugin == 1 && has_root_plugin == 0 ){
- info("No plugin requires root privilege, dropping root privilege\n");
- flight_check();
- drop_privileges();
- }
- return 0;
-}
-
-/**
- * Given a socket descriptor looks it up and returns the plug-in
- * @param fd Socket descriptor to lookup
- * @return struct plugin
- */
-struct plugin *plugin_lookup(int fd)
-{
- struct plugin *plug = NULL;
- LIST_FOREACH(plug, &head, pointers) {
- if( plug->fd == fd ) {
- return plug;
- }
- }
- return NULL;
-}
-
-/**
- * Does the actual fork and exec of the plug-in
- * @param plugin Full filename and path of plug-in to exec.
- * @param client_fd Client connected file descriptor
- * @param require_root int, indicate whether this plugin require root
- * privilege or not
- */
-void exec_plugin( char *plugin, int client_fd, int require_root)
-{
- int err = 0;
-
- info("Exec'ing plug-in = %s\n", plugin);
-
- pid_t process = fork();
- if( process ) {
- /* Parent */
- int rc = close(client_fd);
- if( -1 == rc ) {
- err = errno;
- info("Error on closing accepted socket in parent: %s\n",
- strerror(err));
- }
-
- } else {
- /* Child */
- int exec_rc = 0;
- char fd_str[12];
- char *plugin_argv[7];
- extern char **environ;
- struct ucred cli_user_cred;
- socklen_t cli_user_cred_len = sizeof(cli_user_cred);
-
- /*
- * The plugin will still run no matter with root privilege or not.
- * so that client could get detailed error message.
- */
- if ( require_root == 0 ){
- drop_privileges();
- }else{
- if (getuid()){
- warn("Plugin %s require root privilege, but lsmd daemon "
- "is not run as root user\n", plugin);
- }else if(allow_root_plugin == 0){
- warn("Plugin %s require root privilege, but %s disabled "
- "it globally\n", LSMD_CONF_FILE);
- drop_privileges();
- }else{
- /* Check socket client uid */
- int rc_get_cli_uid = getsockopt(
- client_fd, SOL_SOCKET, SO_PEERCRED,
- &cli_user_cred, &cli_user_cred_len);
- if( 0 == rc_get_cli_uid){
- if (cli_user_cred.uid != 0){
- warn("Plugin %s require root privilege, but "
- "client is not run as root user\n", plugin);
- drop_privileges();
- }else{
- info("Plugin %s is running as root privilege\n",
- plugin);
- }
- }else{
- warn("Failed to get client socket uid, getsockopt() "
- "error: %d\n", errno);
- drop_privileges();
- }
- }
-
- }
-
- /* Make copy of plug-in string as once we call empty_plugin_list it
- * will be deleted :-) */
- char *p_copy = strdup(plugin);
-
- empty_plugin_list(&head);
- sprintf(fd_str, "%d", client_fd);
-
- if( plugin_mem_debug ) {
- char debug_out[64];
- snprintf(debug_out, (sizeof(debug_out) - 1),
- "--log-file=/tmp/leaking_%d-%d", getppid(), getpid());
-
- plugin_argv[0] = "valgrind";
- plugin_argv[1] = "--leak-check=full";
- plugin_argv[2] = "--show-reachable=no";
- plugin_argv[3] = debug_out;
- plugin_argv[4] = p_copy;
- plugin_argv[5] = fd_str;
- plugin_argv[6] = NULL;
-
- exec_rc = execve("/usr/bin/valgrind", plugin_argv, environ);
- } else {
- plugin_argv[0] = basename(p_copy);
- plugin_argv[1] = fd_str;
- plugin_argv[2] = NULL;
- exec_rc = execve(p_copy, plugin_argv, environ);
- }
-
- if( -1 == exec_rc ) {
- int err = errno;
- log_and_exit("Error on exec'ing Plugin %s: %s\n",
- p_copy, strerror(err));
- }
- }
-}
-
-/**
- * Main event loop
- */
-void _serving(void)
-{
- struct plugin *plug = NULL;
- struct timeval tmo;
- fd_set readfds;
- int nfds = 0;
- int err = 0;
-
- process_plugins();
-
- while( serve_state == RUNNING ) {
- FD_ZERO(&readfds);
- nfds = 0;
-
- tmo.tv_sec = 15;
- tmo.tv_usec = 0;
-
- LIST_FOREACH(plug, &head, pointers) {
- nfds = max(plug->fd, nfds);
- FD_SET(plug->fd, &readfds);
- }
-
- if( !nfds ) {
- log_and_exit("No plugins found in directory %s\n", plugin_dir);
- }
-
- nfds += 1;
- int ready = select(nfds, &readfds, NULL, NULL, &tmo);
-
- if( -1 == ready ) {
- if( serve_state != RUNNING ) {
- return;
- } else {
- err = errno;
- log_and_exit("Error on selecting Plugin: %s", strerror(err));
- }
- } else if( ready > 0 ) {
- int fd = 0;
- for( fd = 0; fd < nfds; fd++ ) {
- if( FD_ISSET(fd, &readfds) ) {
- int cfd = accept(fd, NULL, NULL);
- if( -1 != cfd ) {
- struct plugin *p = plugin_lookup(fd);
- exec_plugin(p->file_path, cfd, p->require_root);
- } else {
- err = errno;
- info("Error on accepting request: %s", strerror(err));
- }
- }
- }
- }
- child_cleanup();
- }
- clean_up();
-}
-
-/**
- * Main entry for daemon to work
- */
-void serve(void)
-{
- while( serve_state != EXIT ) {
- if( serve_state == RESTART ) {
- info("Reloading plug-ins\n");
- serve_state = RUNNING;
- }
- _serving();
- }
- clean_up();
-}
-
-int main(int argc, char *argv[])
-{
- int c = 0;
-
- LIST_INIT(&head);
-
- /* Process command line arguments */
- while(1) {
- static struct option l_options[] =
- {
- {"help", no_argument, 0, 'h'}, //Index 0
- {"plugindir", required_argument, 0, 0}, //Index 1
- {"socketdir", required_argument, 0, 0}, //Index 2
- {"confdir", required_argument, 0, 0}, //Index 3
- {0, 0, 0, 0}
- };
-
- int option_index = 0;
- c = getopt_long(argc, argv, "hvd", l_options, &option_index);
-
- if ( c == -1 ) {
- break;
- }
-
- switch (c) {
- case 0:
- switch (option_index) {
- case 1:
- plugin_dir = optarg;
- break;
- case 2:
- socket_dir = optarg;
- break;
- case 3:
- conf_dir = optarg;
- break;
- }
- break;
-
- case 'h':
- usage();
- break;
-
- case 'v':
- verbose_flag = 1;
- break;
-
- case 'd':
- systemd = 1;
- break;
-
- case '?':
- break;
-
- default:
- abort ();
- }
- }
-
- /* Print any remaining command line arguments (not options). */
- if (optind < argc) {
- printf ("non-option ARGV-elements: ");
- while (optind < argc) {
- printf ("%s \n", argv[optind++]);
- }
- printf("\n");
- exit(1);
- }
-
- /* Setup syslog if needed */
- if( !systemd ) {
- openlog("lsmd", LOG_ODELAY, LOG_USER);
- }
-
- /* Check lsmd.conf */
- char *lsmd_conf_path = path_form(conf_dir, LSMD_CONF_FILE);
- parse_conf_bool(
- lsmd_conf_path, LSM_CONF_ALLOW_ROOT_OPT_NAME, &allow_root_plugin);
- free(lsmd_conf_path);
-
- /* Check to see if we want to check plugin for memory errors */
- if( getenv("LSM_VALGRIND") ) {
- plugin_mem_debug = 1;
- }
-
- install_sh();
- if (allow_root_plugin == 0){
- drop_privileges();
- }
- flight_check();
-
- /* Become a daemon if told we are not using systemd */
- if( !systemd ) {
- if ( -1 == daemon(0, 0) ) {
- int err = errno;
- log_and_exit("Error on calling daemon: %s\n", strerror(err));
- }
- }
-
- serve();
- return EXIT_SUCCESS;
-}
diff --git a/daemon/lsm_rest.c b/daemon/lsm_rest.c
deleted file mode 100644
index d1e0a00..0000000
--- a/daemon/lsm_rest.c
+++ /dev/null
@@ -1,517 +0,0 @@
-/*
- * Copyright (C) 2011-2013 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301 USA
- *
- * Author: Gris Ge <***@redhat.com>
- */
-
-#define _GNU_SOURCE
-#include <sys/types.h>
-#include <sys/select.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <string.h>
-#include <microhttpd.h>
-#include <json.h>
-#include <libxml/uri.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/param.h>
-#include <stdlib.h>
-
-#include "lsm_rest.h"
-
-/*
- TODO: MHD_get_connection_values() with MHD_GET_ARGUMENT_KIND to
- get all query argument
- TODO: Check malloc() return code
-*/
-
-void para_list_init(ParaList_t *para_list)
-{
- para_list->head = NULL;
-}
-
-int para_list_add(ParaList_t *para_list, const char *key_name,
- const void *value, const enum lsm_json_type value_type,
- const ssize_t array_len)
-{
- if (para_list == NULL) return -1;
- Parameter_t *new_para_node =
- (Parameter_t *)malloc(sizeof(Parameter_t));
- new_para_node->key_name = key_name;
- new_para_node->value = value;
- new_para_node->value_type = value_type;
- new_para_node->array_len = array_len;
- new_para_node->next = NULL;
- if (para_list->head == NULL){
- para_list->head = new_para_node;
- }else{
- Parameter_t *current = para_list->head;
- while (current->next != NULL){
- current = current->next;
- }
- current->next = new_para_node;
- }
- return 0;
-}
-
-void para_list_free(ParaList_t *para_list)
-{
- if (para_list == NULL) return;
- if (para_list->head == NULL){
- free(para_list);
- }else{
- Parameter_t *current = para_list->head;
- Parameter_t *next = current->next;
- free(current);
- while (next != NULL){
- current = next;
- next = current->next;
- free(current);
- }
- free(para_list);
- }
- return;
-}
-
-json_object *para_to_json(const enum lsm_json_type value_type,
- const void *para_value, ssize_t array_len)
-{
- json_object *para_val_obj = NULL;
- switch (value_type) {
- case lsm_json_type_null:
- break;
- case lsm_json_type_int:
- para_val_obj = json_object_new_int64(
- *(int64_t *) para_value);
- break;
- case lsm_json_type_float:
- para_val_obj = json_object_new_double(
- *(double *) para_value);
- break;
- case lsm_json_type_string:
- para_val_obj = json_object_new_string(
- (const char *) para_value);
- break;
- case lsm_json_type_bool:
- para_val_obj = json_object_new_boolean(
- *(json_bool *) para_value);
- break;
- case lsm_json_type_array_str:
- para_val_obj = json_object_new_array();
- ssize_t i;
- for (i=0; i < array_len; i++) {
- json_object *array_member = para_to_json(
- lsm_json_type_string,
- (void *)((char **)para_value)[i], 0);
- json_object_array_add(para_val_obj, array_member);
- }
- break;
- default:
- break;
- }
- return para_val_obj;
-}
-
-
-json_object *para_list_to_json(ParaList_t *para_list)
-{
- Parameter_t *cur_node = para_list->head;
- if (cur_node == NULL){
- return NULL;
- }
- json_object * jobj = json_object_new_object();
- while(cur_node !=NULL){
- json_object_object_add(
- jobj,
- cur_node->key_name,
- para_to_json(
- cur_node->value_type,
- cur_node->value,
- cur_node->array_len));
- cur_node = cur_node->next;
- }
- return jobj;
-}
-
-static int connect_socket(const char *uri_str, const char *plugin_dir,
- int *error_no)
-{
- int socket_fd = -1;
- xmlURIPtr uri_obj;
- uri_obj = xmlParseURI(uri_str);
- char *uri_scheme = NULL;
- if (uri_obj != NULL){
- uri_scheme = strdup(uri_obj->scheme);
- xmlFreeURI(uri_obj);
- uri_obj = NULL;
- }else{
- *error_no = errno;
- return socket_fd;
- }
- char *plugin_file = NULL;
- if (asprintf(&plugin_file, "%s/%s", plugin_dir, uri_scheme) == -1){
- free(uri_scheme);
- *error_no = ENOMEM;
- return socket_fd;
- }
- free(uri_scheme);
-
- socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
- if (socket_fd != -1){
- struct sockaddr_un addr;
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
- if (strlen(plugin_file) > (sizeof(addr.sun_path) - 1)){
- socket_fd = -1;
- fprintf(stderr, "Plugin file path too long: %s, "
- "max is %zu", plugin_file,
- sizeof(addr.sun_path) - 1);
- }
- strcpy(addr.sun_path, plugin_file);
- free(plugin_file);
- if (connect(socket_fd, (struct sockaddr *) &addr,
- sizeof(addr)) != 0){
- *error_no = errno;
- socket_fd = -1;
- }
- }else{
- *error_no = errno;
- }
- return socket_fd;
-}
-
-
-static int send_msg(int socket_fd, const char *msg, int *error_no)
-{
- int rc = -1;
- size_t len = strlen(msg);
- size_t new_msg_len = strlen(msg) + LSM_HEADER_LEN + 1;
- char *msg_with_header = (char *)malloc(new_msg_len);
- sprintf(msg_with_header, "%0*zu%s", LSM_HEADER_LEN, len, msg);
- ssize_t written = 0;
- new_msg_len -= 1;
- while (written < new_msg_len) {
- ssize_t wrote = send(
- socket_fd, msg_with_header + written,
- (new_msg_len - written),
- MSG_NOSIGNAL);
- if (wrote != -1){
- written += wrote;
- }else{
- *error_no = errno;
- break;
- }
- }
- if ((written == new_msg_len) && *error_no == 0){
- rc = 0;
- }
- free(msg_with_header);
- return rc;
-}
-
-static char *_recv_msg(int socket_fd, size_t count, int *error_no)
-{
- char buff[LSM_SOCK_BUFF_LEN];
- size_t amount_read = 0;
- *error_no = 0;
- char *msg = malloc(count + 1);
- memset(msg, 0, count + 1);
- while (amount_read < count) {
- ssize_t rd = (ssize_t)recv(socket_fd, buff,
- MIN(sizeof(buff), count - amount_read), MSG_WAITALL);
- if (rd > 0) {
- memcpy(msg + amount_read, buff, rd);
- amount_read += rd;
- }
- else if(errno == EAGAIN){
- printf("retry\n");
- errno = 0;
- continue; // TODO: don't know why recv() don't block.
- }
- else {
- *error_no = errno;
- break;
- }
- }
- if (*error_no == 0){
- msg[count] = '\0';
- return msg;
- }
- else{
- fprintf(stderr, "recv() got error_no, : %d\n", *error_no);
- free(msg);
- return NULL;
- }
-}
-
-static char *recv_msg(int socket_fd, int *error_no)
-{
- *error_no = 0;
- char *msg_len_str = _recv_msg(socket_fd, LSM_HEADER_LEN, error_no);
- if (msg_len_str == NULL){
- fprintf(stderr, "Failed to read the JSON length "
- "with error_no%d\n", *error_no);
- return NULL;
- }
- errno = 0;
- size_t msg_len = (size_t)strtoul(msg_len_str, NULL, 10);
- free(msg_len_str);
- if ((errno == ERANGE && (msg_len == LONG_MAX || msg_len == LONG_MIN))
- || (errno != 0 && msg_len == 0))
- {
- perror("strtol");
- return NULL;
- }
- if (msg_len == 0){
- fprintf(stderr, "No data needed to retrieve\n");
- return NULL;
- }
- char *msg = _recv_msg(socket_fd, msg_len, error_no);
- if (msg == NULL){
- fprintf(stderr, "Failed to retrieve data from socket "
- "with error_no %d\n", *error_no);
- return NULL;
- }
- return msg;
-}
-
-static char *rpc(int socket_fd, const char *method, ParaList_t *para_list,
- int *error_no)
-{
- *error_no = 0;
- json_object *jobj = json_object_new_object();
- json_object_object_add(jobj,"method", json_object_new_string(method));
- json_object *js_params = para_list_to_json(para_list);
- if (js_params != NULL){
- json_object_object_add(jobj,"params", js_params);
- }
- json_object_object_add(jobj,"id", json_object_new_int(LSM_DEFAULT_ID));
- const char *json_string = json_object_to_json_string_ext(
- jobj, JSON_C_TO_STRING_PRETTY);
- printf ("Sending JSON to plugin:\n%s\n", json_string); // code_debug
- *error_no = 0;
- int rc = send_msg(socket_fd, json_string, error_no);
- json_object_put(jobj);
- if (rc != 0){
- fprintf(stderr, "Got error when sending message to socket, "
- "rc=%d, error_no=%d\n", rc, *error_no);
- return NULL;
- }
- char *recv_json_string = NULL;
- recv_json_string = recv_msg(socket_fd, error_no);
- if (*error_no != 0){
- printf("Got error when receiving message to socket,"
- "error_no=%d\n", *error_no);
- free(recv_json_string);
- return NULL;
- }
- if (recv_json_string == NULL){
- printf("No data retrieved\n");
- return NULL;
- }
- json_object *recv_json = json_tokener_parse(recv_json_string);
- free(recv_json_string);
- json_object *result_json;
- if (!json_object_object_get_ex(recv_json, "result", &result_json)){
- printf("No 'result' node in received JSON data");
- json_object_put(recv_json);
- return NULL;
- }
- char *result_str;
- result_str = (char*) json_object_to_json_string_ext(
- result_json,
- JSON_C_TO_STRING_PRETTY);
- char *rc_msg = strdup(result_str);
- json_object_put(recv_json);
- return rc_msg;
-}
-
-static int plugin_startup(int socket_fd, const char *uri, const char *pass,
- int tmo)
-{
- printf("Starting the plugin\n");
- int error_no = 0;
- enum lsm_json_type pass_type = lsm_json_type_string;
- if (pass == NULL){
- pass_type = lsm_json_type_null;
- }
- ParaList_t *para_list = (ParaList_t *)malloc(sizeof(ParaList_t));
- para_list_init(para_list);
- para_list_add(para_list, "uri", uri, lsm_json_type_string, 0);
- para_list_add(para_list, "password", pass, pass_type, 0);
- para_list_add(para_list, "timeout", &tmo, lsm_json_type_int, 0);
- char *msg = rpc(socket_fd, "plugin_register", para_list, &error_no);
- free(msg);
- para_list_free(para_list);
- return error_no;
-}
-
-static int plugin_shutdown(int socket_fd)
-{
- printf("Shutting down the plugin\n");
- int error_no = 0;
- ParaList_t *para_list = (ParaList_t *)malloc(sizeof(ParaList_t));
- para_list_init(para_list);
- static int lsm_flags = 0;
- para_list_add(para_list, "flags", &lsm_flags, lsm_json_type_int, 0);
- char *msg = rpc(socket_fd, "plugin_unregister", para_list, &error_no);
- free(msg);
- para_list_free(para_list);
- return error_no;
-}
-
-static char *v01_query(int socket_fd, const char* method,
- ParaList_t *para_list, int *error_no)
-{
- *error_no = 0;
- if (para_list == NULL){
- para_list = (ParaList_t *)malloc(sizeof(ParaList_t));
- para_list_init(para_list);
- }
- int lsm_flags = 0;
- para_list_add(para_list, "flags", &lsm_flags, lsm_json_type_int, 0);
- char *json_str = rpc(socket_fd, method, para_list, error_no);
- para_list_free(para_list);
- return json_str;
-}
-
-static char *lsm_api_0_1(struct MHD_Connection *connection,
- const char *uri, const char * pass,
- const char *url, const char *method,
- const char *upload_data)
-{
- const char *plugin_dir = getenv("LSM_UDS_PATH");
- if (plugin_dir == NULL){
- plugin_dir = LSM_UDS_PATH_DEFAULT;
- fprintf(stdout, "Using default LSM_UDS_PATH: %s\n",
- plugin_dir);
- }
- int error_no = 0;
- int socket_fd = connect_socket(uri, plugin_dir, &error_no);
- if (socket_fd == -1){
- fprintf(stderr, "Failed to connecting to the socket for URI "
- "%s with error_no %d\n", uri, error_no);
- return NULL;
- }
- error_no = plugin_startup(socket_fd, uri, pass, LSM_REST_TMO);
- if (error_no != 0){
- fprintf(stderr, "Failed to register plugin, "
- "error_no %d", error_no);
- plugin_shutdown(socket_fd);
- shutdown(socket_fd, 0);
- return NULL;
- }
- error_no = 0;
- char *json_msg = NULL;
- int i;
- int flag_found=0;
- for(i=0; i < sizeof(lsm_query_strs)/sizeof(char*); i++){
- if (0 == strcmp(url, lsm_query_strs[i])){
- flag_found = 1;
- json_msg = v01_query(
- socket_fd, lsm_query_strs[i], NULL,
- &error_no);
- break;
- }
- }
- if (flag_found == 0){
- fprintf(stderr, "Not supported: %s\n", url);
- }
- if (error_no != 0){
- fprintf(stderr, "Failed to call method %s(), error_no: %d\n",
- url, error_no);
- }
- error_no = plugin_shutdown(socket_fd);
- if (error_no != 0){
- fprintf(stderr, "Failed to unregister plugin, "
- "error_no %d", error_no);
- }
- shutdown(socket_fd, 0);
- return json_msg;
-}
-
-static int answer_to_connection(void *cls, struct MHD_Connection *connection,
- const char *url,
- const char *method, const char *version,
- const char *upload_data,
- size_t *upload_data_size, void **con_cls)
-{
- printf ("New '%s' request, URL: '%s'\n", method, url); // code_debug
- struct MHD_Response *response;
-
- if (0 != strcmp (method, "GET")){
- return MHD_NO;
- }
-
- if (strlen(url) == 1){
- return MHD_NO;
- }
-
- const char *uri = MHD_lookup_connection_value(connection,
- MHD_GET_ARGUMENT_KIND, "uri");
-
- const char *pass= MHD_lookup_connection_value(connection,
- MHD_GET_ARGUMENT_KIND, "pass");
-
- int ret;
- char api_version[LSM_API_VER_LEN + 1];
- memcpy(api_version, url + 1 , LSM_API_VER_LEN);
- // url + 1 is used to get rid of leading '/'
- api_version[LSM_API_VER_LEN] = '\0';
- char *json_str = NULL;
- size_t url_no_api_ver_len = strlen(url) - strlen(api_version) - 1 - 1;
- // -1 -1 means remove two leading /
- // example: /v0.1/systems --change to--> systems
- char *url_no_api_ver = malloc(url_no_api_ver_len + 1);
- strcpy(url_no_api_ver, url+strlen(api_version) + 1 + 1);
- if ( 0 == strcmp(api_version, "v0.1" )){
- printf("v0.1 API request found\n"); // code_debug
- json_str = lsm_api_0_1(connection, uri, pass, url_no_api_ver,
- method, upload_data);
- free(url_no_api_ver);
- if(json_str == NULL){
- return MHD_NO;
- }
- }else{
- free(url_no_api_ver);
- return MHD_NO;
- }
- response = MHD_create_response_from_buffer(
- strlen(json_str),
- (void*) json_str, MHD_RESPMEM_MUST_FREE);
-
- MHD_add_response_header(response, "Content-Type", LSM_JSON_MIME);
-
- ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
- MHD_destroy_response(response);
- return ret;
-}
-
-int main (int argc, char **argv)
-{
- struct MHD_Daemon *daemon;
- daemon = MHD_start_daemon(
- MHD_USE_SELECT_INTERNALLY, LSM_REST_PORT, NULL, NULL,
- &answer_to_connection, NULL, MHD_OPTION_END);
- while(1){
- sleep(60);
- }
- MHD_stop_daemon(daemon);
- return EXIT_SUCCESS;
-}
diff --git a/daemon/lsm_rest.h b/daemon/lsm_rest.h
deleted file mode 100644
index 2291273..0000000
--- a/daemon/lsm_rest.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2011-2013 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301 USA
- *
- * Author: Gris Ge <***@redhat.com>
- */
-
-#ifndef LIBSTORAGEMGMT_REST_H
-#define LIBSTORAGEMGMT_REST_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define LSM_REST_PORT 8888
-#define LSM_REST_TMO 60000
-#define LSM_SOCK_BUFF_LEN 4096
-#define LSM_DEFAULT_ID 100
-#define LSM_JSON_MIME "application/json"
-#define LSM_HEADER_LEN 10
-#define LSM_API_VER_LEN 4
-#define LSM_UDS_PATH_DEFAULT "/var/run/lsm/ipc"
-
-enum lsm_json_type {
- lsm_json_type_null,
- lsm_json_type_int,
- lsm_json_type_float,
- lsm_json_type_string,
- lsm_json_type_bool,
- lsm_json_type_array_str,
-};
-
-static const char *lsm_query_strs[] = {
- "systems", "volumes", "pools", "disks", "fs", "access_groups",
- "initiators",
-};
-
-typedef struct Parameter {
- const char *key_name;
- const void *value;
- enum lsm_json_type value_type;
- ssize_t array_len; // only useful for ARRAY_STR type.
- struct Parameter *next;
-} Parameter_t;
-
-typedef struct ParaList {
- Parameter_t *head;
-} ParaList_t;
-
-void para_list_init(ParaList_t *);
-
-int para_list_add(ParaList_t *, const char *, const void *,
- const enum lsm_json_type, const ssize_t);
-
-void para_list_free(ParaList_t *);
-
-json_object *para_to_json(const enum lsm_json_type, const void *,
- const ssize_t);
-
-json_object *para_list_to_json(ParaList_t *);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LIBSTORAGEMGMT_REST_H */
diff --git a/doc/Makefile.am b/doc/Makefile.am
deleted file mode 100644
index 2642856..0000000
--- a/doc/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-EXTRA_DIST=doxygen.conf REST_API_Doc
-
-SUBDIRS = man
diff --git a/doc/REST_API_Doc b/doc/REST_API_Doc
deleted file mode 100644
index c923a75..0000000
--- a/doc/REST_API_Doc
+++ /dev/null
@@ -1,36 +0,0 @@
-RESTful API for LibStorageMgmt(LSM) Version 0.1
-
-Currently, lsm_restd is still in inital stage. You could try:
-
- $ cd libstoragemgmt-git/src
- $ make lsm_restd
- $ ./lsm_restd
- # Open another shell
- $ curl http://localhost:8888/v0.1/systems?uri=sim:
- $ curl http://localhost:8888/v0.1/pools?uri=sim:
- $ curl http://localhost:8888/v0.1/volumes?uri=sim:
- $ curl http://localhost:8888/v0.1/disks?uri=sim:
-
-################### Plan #######################
-# 1. HTTP Methods
- GET List certain resource
- PUT Replace existing resource
- POST Create new resource
- DELETE Delete existing resource
- OPTIONS Response the support HTTP methods and document URL for certain URI
-
-# 2. Resources
-
- Resouce Method URI
- System GET, OPTIONS /v0.1/systems
- Pool GET, PUT, POST, DELETE, OPTIONS /v0.1/pools
- Volume GET, PUT, POST, DELETE, OPTIONS /v0.1/volumes
-
-Please refer to [[DataStucture]]
-
-# 3. Links
-## 3.1 System
-### 3.1.1 GET /v0.1/system
-Query all the storage systems
-### 3.1.2 OPTIONS /v0.1/system
-## 3.2 Pool
diff --git a/doc/doxygen.conf.in b/doc/doxygen.conf.in
deleted file mode 100644
index fbbd0c1..0000000
--- a/doc/doxygen.conf.in
+++ /dev/null
@@ -1,1562 +0,0 @@
-# Doxyfile 1.6.1
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project
-#
-# All text after a hash (#) is considered a comment and will be ignored
-# The format is:
-# TAG = value [value, ...]
-# For lists items can also be appended using:
-# TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ")
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# This tag specifies the encoding used for all characters in the config file
-# that follow. The default is UTF-8 which is also the encoding used for all
-# text before the first occurrence of this tag. Doxygen uses libiconv (or the
-# iconv built into libc) for the transcoding. See
-# http://www.gnu.org/software/libiconv for the list of possible encodings.
-
-DOXYFILE_ENCODING = UTF-8
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
-# by quotes) that should identify the project.
-
-PROJECT_NAME = libStorageMgmt
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number.
-# This could be handy for archiving the generated documentation or
-# if some version control system is used.
-
-PROJECT_NUMBER = @VERSION@
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
-# base path where the generated documentation will be put.
-# If a relative path is entered, it will be relative to the location
-# where doxygen was started. If left blank the current directory will be used.
-
-OUTPUT_DIRECTORY = ./doc/srcdoc/
-
-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
-# 4096 sub-directories (in 2 levels) under the output directory of each output
-# format and will distribute the generated files over these directories.
-# Enabling this option can be useful when feeding doxygen a huge amount of
-# source files, where putting all generated files in the same directory would
-# otherwise cause performance problems for the file system.
-
-CREATE_SUBDIRS = NO
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all constant output in the proper language.
-# The default language is English, other supported languages are:
-# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
-# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
-# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
-# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
-# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak,
-# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
-
-OUTPUT_LANGUAGE = English
-
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
-# include brief member descriptions after the members that are listed in
-# the file and class documentation (similar to JavaDoc).
-# Set to NO to disable this.
-
-BRIEF_MEMBER_DESC = YES
-
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
-# the brief description of a member or function before the detailed description.
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
-# brief descriptions will be completely suppressed.
-
-REPEAT_BRIEF = YES
-
-# This tag implements a quasi-intelligent brief description abbreviator
-# that is used to form the text in various listings. Each string
-# in this list, if found as the leading text of the brief description, will be
-# stripped from the text and the result after processing the whole list, is
-# used as the annotated text. Otherwise, the brief description is used as-is.
-# If left blank, the following values are used ("$name" is automatically
-# replaced with the name of the entity): "The $name class" "The $name widget"
-# "The $name file" "is" "provides" "specifies" "contains"
-# "represents" "a" "an" "the"
-
-ABBREVIATE_BRIEF = "The $name class" \
- "The $name widget" \
- "The $name file" \
- is \
- provides \
- specifies \
- contains \
- represents \
- a \
- an \
- the
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
-# Doxygen will generate a detailed section even if there is only a brief
-# description.
-
-ALWAYS_DETAILED_SEC = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
-# inherited members of a class in the documentation of that class as if those
-# members were ordinary class members. Constructors, destructors and assignment
-# operators of the base classes will not be shown.
-
-INLINE_INHERITED_MEMB = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
-# path before files name in the file list and in the header files. If set
-# to NO the shortest path that makes the file name unique will be used.
-
-FULL_PATH_NAMES = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
-# can be used to strip a user-defined part of the path. Stripping is
-# only done if one of the specified strings matches the left-hand part of
-# the path. The tag can be used to show relative paths in the file list.
-# If left blank the directory from which doxygen is run is used as the
-# path to strip.
-
-STRIP_FROM_PATH = /Users/dimitri/doxygen/mail/1.5.7/doxywizard/
-
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
-# the path mentioned in the documentation of a class, which tells
-# the reader which header file to include in order to use a class.
-# If left blank only the name of the header file containing the class
-# definition is used. Otherwise one should specify the include paths that
-# are normally passed to the compiler using the -I flag.
-
-STRIP_FROM_INC_PATH =
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
-# (but less readable) file names. This can be useful is your file systems
-# doesn't support long names like on DOS, Mac, or CD-ROM.
-
-SHORT_NAMES = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
-# will interpret the first line (until the first dot) of a JavaDoc-style
-# comment as the brief description. If set to NO, the JavaDoc
-# comments will behave just like regular Qt-style comments
-# (thus requiring an explicit @brief command for a brief description.)
-
-JAVADOC_AUTOBRIEF = NO
-
-# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
-# interpret the first line (until the first dot) of a Qt-style
-# comment as the brief description. If set to NO, the comments
-# will behave just like regular Qt-style comments (thus requiring
-# an explicit \brief command for a brief description.)
-
-QT_AUTOBRIEF = NO
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
-# treat a multi-line C++ special comment block (i.e. a block of //! or ///
-# comments) as a brief description. This used to be the default behaviour.
-# The new default is to treat a multi-line C++ comment block as a detailed
-# description. Set this tag to YES if you prefer the old behaviour instead.
-
-MULTILINE_CPP_IS_BRIEF = NO
-
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
-# member inherits the documentation from any documented member that it
-# re-implements.
-
-INHERIT_DOCS = YES
-
-# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
-# a new page for each member. If set to NO, the documentation of a member will
-# be part of the file/class/namespace that contains it.
-
-SEPARATE_MEMBER_PAGES = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab.
-# Doxygen uses this value to replace tabs by spaces in code fragments.
-
-TAB_SIZE = 4
-
-# This tag can be used to specify a number of aliases that acts
-# as commands in the documentation. An alias has the form "name=value".
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to
-# put the command \sideeffect (or @sideeffect) in the documentation, which
-# will result in a user-defined paragraph with heading "Side Effects:".
-# You can put \n's in the value part of an alias to insert newlines.
-
-ALIASES =
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
-# sources only. Doxygen will then generate output that is more tailored for C.
-# For instance, some of the names that are used will be different. The list
-# of all members will be omitted, etc.
-
-OPTIMIZE_OUTPUT_FOR_C = YES
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
-# sources only. Doxygen will then generate output that is more tailored for
-# Java. For instance, namespaces will be presented as packages, qualified
-# scopes will look different, etc.
-
-OPTIMIZE_OUTPUT_JAVA = NO
-
-# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
-# sources only. Doxygen will then generate output that is more tailored for
-# Fortran.
-
-OPTIMIZE_FOR_FORTRAN = NO
-
-# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
-# sources. Doxygen will then generate output that is tailored for
-# VHDL.
-
-OPTIMIZE_OUTPUT_VHDL = NO
-
-# Doxygen selects the parser to use depending on the extension of the files it parses.
-# With this tag you can assign which parser to use for a given extension.
-# Doxygen has a built-in mapping, but you can override or extend it using this tag.
-# The format is ext=language, where ext is a file extension, and language is one of
-# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP,
-# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat
-# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran),
-# use: inc=Fortran f=C. Note that for custom extensions you also need to set
-# FILE_PATTERNS otherwise the files are not read by doxygen.
-
-EXTENSION_MAPPING =
-
-# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
-# to include (a tag file for) the STL sources as input, then you should
-# set this tag to YES in order to let doxygen match functions declarations and
-# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
-# func(std::string) {}). This also make the inheritance and collaboration
-# diagrams that involve STL classes more complete and accurate.
-
-BUILTIN_STL_SUPPORT = NO
-
-# If you use Microsoft's C++/CLI language, you should set this option to YES to
-# enable parsing support.
-
-CPP_CLI_SUPPORT = NO
-
-# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
-# Doxygen will parse them like normal C++ but will assume all classes use public
-# instead of private inheritance when no explicit protection keyword is present.
-
-SIP_SUPPORT = NO
-
-# For Microsoft's IDL there are propget and propput attributes to indicate getter
-# and setter methods for a property. Setting this option to YES (the default)
-# will make doxygen to replace the get and set methods by a property in the
-# documentation. This will only work if the methods are indeed getting or
-# setting a simple type. If this is not the case, or you want to show the
-# methods anyway, you should set this option to NO.
-
-IDL_PROPERTY_SUPPORT = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES, then doxygen will reuse the documentation of the first
-# member in the group (if any) for the other members of the group. By default
-# all members of a group must be documented explicitly.
-
-DISTRIBUTE_GROUP_DOC = NO
-
-# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
-# the same type (for instance a group of public functions) to be put as a
-# subgroup of that type (e.g. under the Public Functions section). Set it to
-# NO to prevent subgrouping. Alternatively, this can be done per class using
-# the \nosubgrouping command.
-
-SUBGROUPING = YES
-
-# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
-# is documented as struct, union, or enum with the name of the typedef. So
-# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
-# with name TypeT. When disabled the typedef will appear as a member of a file,
-# namespace, or class. And the struct will be named TypeS. This can typically
-# be useful for C code in case the coding convention dictates that all compound
-# types are typedef'ed and only the typedef is referenced, never the tag name.
-
-TYPEDEF_HIDES_STRUCT = NO
-
-# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
-# determine which symbols to keep in memory and which to flush to disk.
-# When the cache is full, less often used symbols will be written to disk.
-# For small to medium size projects (<1000 input files) the default value is
-# probably good enough. For larger projects a too small cache size can cause
-# doxygen to be busy swapping symbols to and from disk most of the time
-# causing a significant performance penality.
-# If the system has enough physical memory increasing the cache will improve the
-# performance by keeping more symbols in memory. Note that the value works on
-# a logarithmic scale so increasing the size by one will rougly double the
-# memory usage. The cache size is given by this formula:
-# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
-# corresponding to a cache size of 2^16 = 65536 symbols
-
-SYMBOL_CACHE_SIZE = 0
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
-# documentation are documented, even if no documentation was available.
-# Private class members and static file members will be hidden unless
-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
-
-EXTRACT_ALL = YES
-
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
-# will be included in the documentation.
-
-EXTRACT_PRIVATE = NO
-
-# If the EXTRACT_STATIC tag is set to YES all static members of a file
-# will be included in the documentation.
-
-EXTRACT_STATIC = NO
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
-# defined locally in source files will be included in the documentation.
-# If set to NO only classes defined in header files are included.
-
-EXTRACT_LOCAL_CLASSES = YES
-
-# This flag is only useful for Objective-C code. When set to YES local
-# methods, which are defined in the implementation section but not in
-# the interface are included in the documentation.
-# If set to NO (the default) only methods in the interface are included.
-
-EXTRACT_LOCAL_METHODS = NO
-
-# If this flag is set to YES, the members of anonymous namespaces will be
-# extracted and appear in the documentation as a namespace called
-# 'anonymous_namespace{file}', where file will be replaced with the base
-# name of the file that contains the anonymous namespace. By default
-# anonymous namespace are hidden.
-
-EXTRACT_ANON_NSPACES = NO
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
-# undocumented members of documented classes, files or namespaces.
-# If set to NO (the default) these members will be included in the
-# various overviews, but no documentation section is generated.
-# This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_MEMBERS = NO
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
-# undocumented classes that are normally visible in the class hierarchy.
-# If set to NO (the default) these classes will be included in the various
-# overviews. This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_CLASSES = NO
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
-# friend (class|struct|union) declarations.
-# If set to NO (the default) these declarations will be included in the
-# documentation.
-
-HIDE_FRIEND_COMPOUNDS = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
-# documentation blocks found inside the body of a function.
-# If set to NO (the default) these blocks will be appended to the
-# function's detailed documentation block.
-
-HIDE_IN_BODY_DOCS = NO
-
-# The INTERNAL_DOCS tag determines if documentation
-# that is typed after a \internal command is included. If the tag is set
-# to NO (the default) then the documentation will be excluded.
-# Set it to YES to include the internal documentation.
-
-INTERNAL_DOCS = NO
-
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
-# file names in lower-case letters. If set to YES upper-case letters are also
-# allowed. This is useful if you have classes or files whose names only differ
-# in case and if your file system supports case sensitive file names. Windows
-# and Mac users are advised to set this option to NO.
-
-CASE_SENSE_NAMES = NO
-
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
-# will show members with their full class and namespace scopes in the
-# documentation. If set to YES the scope will be hidden.
-
-HIDE_SCOPE_NAMES = YES
-
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
-# will put a list of the files that are included by a file in the documentation
-# of that file.
-
-SHOW_INCLUDE_FILES = YES
-
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
-# is inserted in the documentation for inline members.
-
-INLINE_INFO = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
-# will sort the (detailed) documentation of file and class members
-# alphabetically by member name. If set to NO the members will appear in
-# declaration order.
-
-SORT_MEMBER_DOCS = YES
-
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
-# brief documentation of file, namespace and class members alphabetically
-# by member name. If set to NO (the default) the members will appear in
-# declaration order.
-
-SORT_BRIEF_DOCS = NO
-
-# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
-# will sort the (brief and detailed) documentation of class members so that
-# constructors and destructors are listed first. If set to NO (the default)
-# the constructors will appear in the respective orders defined by
-# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
-# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
-# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
-
-SORT_MEMBERS_CTORS_1ST = NO
-
-# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
-# hierarchy of group names into alphabetical order. If set to NO (the default)
-# the group names will appear in their defined order.
-
-SORT_GROUP_NAMES = NO
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
-# sorted by fully-qualified names, including namespaces. If set to
-# NO (the default), the class list will be sorted only by class name,
-# not including the namespace part.
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the
-# alphabetical list.
-
-SORT_BY_SCOPE_NAME = NO
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or
-# disable (NO) the todo list. This list is created by putting \todo
-# commands in the documentation.
-
-GENERATE_TODOLIST = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or
-# disable (NO) the test list. This list is created by putting \test
-# commands in the documentation.
-
-GENERATE_TESTLIST = YES
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or
-# disable (NO) the bug list. This list is created by putting \bug
-# commands in the documentation.
-
-GENERATE_BUGLIST = YES
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
-# disable (NO) the deprecated list. This list is created by putting
-# \deprecated commands in the documentation.
-
-GENERATE_DEPRECATEDLIST= YES
-
-# The ENABLED_SECTIONS tag can be used to enable conditional
-# documentation sections, marked by \if sectionname ... \endif.
-
-ENABLED_SECTIONS =
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
-# the initial value of a variable or define consists of for it to appear in
-# the documentation. If the initializer consists of more lines than specified
-# here it will be hidden. Use a value of 0 to hide initializers completely.
-# The appearance of the initializer of individual variables and defines in the
-# documentation can be controlled using \showinitializer or \hideinitializer
-# command in the documentation regardless of this setting.
-
-MAX_INITIALIZER_LINES = 30
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
-# at the bottom of the documentation of classes and structs. If set to YES the
-# list will mention the files that were used to generate the documentation.
-
-SHOW_USED_FILES = YES
-
-# If the sources in your project are distributed over multiple directories
-# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
-# in the documentation. The default is NO.
-
-SHOW_DIRECTORIES = NO
-
-# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
-# This will remove the Files entry from the Quick Index and from the
-# Folder Tree View (if specified). The default is YES.
-
-SHOW_FILES = YES
-
-# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
-# Namespaces page. This will remove the Namespaces entry from the Quick Index
-# and from the Folder Tree View (if specified). The default is YES.
-
-SHOW_NAMESPACES = YES
-
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that
-# doxygen should invoke to get the current version for each file (typically from
-# the version control system). Doxygen will invoke the program by executing (via
-# popen()) the command <command> <input-file>, where <command> is the value of
-# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
-# provided by doxygen. Whatever the program writes to standard output
-# is used as the file version. See the manual for examples.
-
-FILE_VERSION_FILTER =
-
-# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by
-# doxygen. The layout file controls the global structure of the generated output files
-# in an output format independent way. The create the layout file that represents
-# doxygen's defaults, run doxygen with the -l option. You can optionally specify a
-# file name after the option, if omitted DoxygenLayout.xml will be used as the name
-# of the layout file.
-
-LAYOUT_FILE =
-
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated
-# by doxygen. Possible values are YES and NO. If left blank NO is used.
-
-QUIET = NO
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated by doxygen. Possible values are YES and NO. If left blank
-# NO is used.
-
-WARNINGS = YES
-
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
-# automatically be disabled.
-
-WARN_IF_UNDOCUMENTED = YES
-
-# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
-# potential errors in the documentation, such as not documenting some
-# parameters in a documented function, or documenting parameters that
-# don't exist or using markup commands wrongly.
-
-WARN_IF_DOC_ERROR = YES
-
-# This WARN_NO_PARAMDOC option can be abled to get warnings for
-# functions that are documented, but have no documentation for their parameters
-# or return value. If set to NO (the default) doxygen will only warn about
-# wrong or incomplete parameter documentation, but not about the absence of
-# documentation.
-
-WARN_NO_PARAMDOC = NO
-
-# The WARN_FORMAT tag determines the format of the warning messages that
-# doxygen can produce. The string should contain the $file, $line, and $text
-# tags, which will be replaced by the file and line number from which the
-# warning originated and the warning text. Optionally the format may contain
-# $version, which will be replaced by the version of the file (if it could
-# be obtained via FILE_VERSION_FILTER)
-
-WARN_FORMAT = "$file:$line: $text"
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning
-# and error messages should be written. If left blank the output is written
-# to stderr.
-
-WARN_LOGFILE =
-
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag can be used to specify the files and/or directories that contain
-# documented source files. You may enter file names like "myfile.cpp" or
-# directories like "/usr/src/myproject". Separate the files or directories
-# with spaces.
-
-INPUT = . tools/lsmcli
-
-# This tag can be used to specify the character encoding of the source files
-# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
-# also the default input encoding. Doxygen uses libiconv (or the iconv built
-# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
-# the list of possible encodings.
-
-INPUT_ENCODING = UTF-8
-
-# If the value of the INPUT tag contains directories, you can use the
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank the following patterns are tested:
-# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
-# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
-
-FILE_PATTERNS = *.c \
- *.cc \
- *.cxx \
- *.cpp \
- *.c++ \
- *.d \
- *.java \
- *.ii \
- *.ixx \
- *.ipp \
- *.i++ \
- *.inl \
- *.h \
- *.hh \
- *.hxx \
- *.hpp \
- *.h++ \
- *.idl \
- *.odl \
- *.cs \
- *.php \
- *.php3 \
- *.inc \
- *.m \
- *.mm \
- *.dox \
- *.py \
- *.f90 \
- *.f \
- *.vhd \
- *.vhdl
-
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories
-# should be searched for input files as well. Possible values are YES and NO.
-# If left blank NO is used.
-
-RECURSIVE = YES
-
-# The EXCLUDE tag can be used to specify files and/or directories that should
-# excluded from the INPUT source files. This way you can easily exclude a
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-
-EXCLUDE =
-
-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
-# directories that are symbolic links (a Unix filesystem feature) are excluded
-# from the input.
-
-EXCLUDE_SYMLINKS = NO
-
-# If the value of the INPUT tag contains directories, you can use the
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
-# certain files from those directories. Note that the wildcards are matched
-# against the file with absolute path, so to exclude all test directories
-# for example use the pattern */test/*
-
-EXCLUDE_PATTERNS = */test/*
-
-# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
-# (namespaces, classes, functions, etc.) that should be excluded from the
-# output. The symbol name can be a fully qualified name, a word, or if the
-# wildcard * is used, a substring. Examples: ANamespace, AClass,
-# AClass::ANamespace, ANamespace::*Test
-
-EXCLUDE_SYMBOLS =
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or
-# directories that contain example code fragments that are included (see
-# the \include command).
-
-EXAMPLE_PATH =
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank all files are included.
-
-EXAMPLE_PATTERNS = *
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
-# searched for input files to be used with the \include or \dontinclude
-# commands irrespective of the value of the RECURSIVE tag.
-# Possible values are YES and NO. If left blank NO is used.
-
-EXAMPLE_RECURSIVE = NO
-
-# The IMAGE_PATH tag can be used to specify one or more files or
-# directories that contain image that are included in the documentation (see
-# the \image command).
-
-IMAGE_PATH =
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should
-# invoke to filter for each input file. Doxygen will invoke the filter program
-# by executing (via popen()) the command <filter> <input-file>, where <filter>
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
-# input file. Doxygen will then use the output that the filter program writes
-# to standard output. If FILTER_PATTERNS is specified, this tag will be
-# ignored.
-
-INPUT_FILTER =
-
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
-# basis. Doxygen will compare the file name with each pattern and apply the
-# filter if there is a match. The filters are a list of the form:
-# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
-# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
-# is applied to all files.
-
-FILTER_PATTERNS =
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER) will be used to filter the input files when producing source
-# files to browse (i.e. when SOURCE_BROWSER is set to YES).
-
-FILTER_SOURCE_FILES = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will
-# be generated. Documented entities will be cross-referenced with these sources.
-# Note: To get rid of all source code in the generated output, make sure also
-# VERBATIM_HEADERS is set to NO.
-
-SOURCE_BROWSER = YES
-
-# Setting the INLINE_SOURCES tag to YES will include the body
-# of functions and classes directly in the documentation.
-
-INLINE_SOURCES = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
-# doxygen to hide any special comment blocks from generated source code
-# fragments. Normal C and C++ comments will always remain visible.
-
-STRIP_CODE_COMMENTS = YES
-
-# If the REFERENCED_BY_RELATION tag is set to YES
-# then for each documented function all documented
-# functions referencing it will be listed.
-
-REFERENCED_BY_RELATION = NO
-
-# If the REFERENCES_RELATION tag is set to YES
-# then for each documented function all documented entities
-# called/used by that function will be listed.
-
-REFERENCES_RELATION = NO
-
-# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
-# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
-# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
-# link to the source code. Otherwise they will link to the documentation.
-
-REFERENCES_LINK_SOURCE = YES
-
-# If the USE_HTAGS tag is set to YES then the references to source code
-# will point to the HTML generated by the htags(1) tool instead of doxygen
-# built-in source browser. The htags tool is part of GNU's global source
-# tagging system (see http://www.gnu.org/software/global/global.html). You
-# will need version 4.8.6 or higher.
-
-USE_HTAGS = NO
-
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
-# will generate a verbatim copy of the header file for each class for
-# which an include is specified. Set to NO to disable this.
-
-VERBATIM_HEADERS = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
-# of all compounds will be generated. Enable this if the project
-# contains a lot of classes, structs, unions or interfaces.
-
-ALPHABETICAL_INDEX = YES
-
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
-# in which this list will be split (can be a number in the range [1..20])
-
-COLS_IN_ALPHA_INDEX = 5
-
-# In case all classes in a project start with a common prefix, all
-# classes will be put under the same header in the alphabetical index.
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
-# should be ignored while generating the index headers.
-
-IGNORE_PREFIX =
-
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
-# generate HTML output.
-
-GENERATE_HTML = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `html' will be used as the default path.
-
-HTML_OUTPUT = html
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
-# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
-# doxygen will generate files with .html extension.
-
-HTML_FILE_EXTENSION = .html
-
-# The HTML_HEADER tag can be used to specify a personal HTML header for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard header.
-
-HTML_HEADER =
-
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard footer.
-
-HTML_FOOTER =
-
-# If the HTML_TIMESTAMP tag is set to YES then the generated HTML
-# documentation will contain the timesstamp.
-
-HTML_TIMESTAMP = NO
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
-# style sheet that is used by each HTML page. It can be used to
-# fine-tune the look of the HTML output. If the tag is left blank doxygen
-# will generate a default style sheet. Note that doxygen will try to copy
-# the style sheet file to the HTML output directory, so don't put your own
-# stylesheet in the HTML output directory as well, or it will be erased!
-
-HTML_STYLESHEET =
-
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
-# files or namespaces will be aligned in HTML using tables. If set to
-# NO a bullet list will be used.
-
-HTML_ALIGN_MEMBERS = YES
-
-# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
-# documentation will contain sections that can be hidden and shown after the
-# page has loaded. For this to work a browser that supports
-# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
-# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
-
-HTML_DYNAMIC_SECTIONS = NO
-
-# If the GENERATE_DOCSET tag is set to YES, additional index files
-# will be generated that can be used as input for Apple's Xcode 3
-# integrated development environment, introduced with OSX 10.5 (Leopard).
-# To create a documentation set, doxygen will generate a Makefile in the
-# HTML output directory. Running make will produce the docset in that
-# directory and running "make install" will install the docset in
-# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
-# it at startup.
-# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information.
-
-GENERATE_DOCSET = NO
-
-# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
-# feed. A documentation feed provides an umbrella under which multiple
-# documentation sets from a single provider (such as a company or product suite)
-# can be grouped.
-
-DOCSET_FEEDNAME = "Doxygen generated docs"
-
-# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
-# should uniquely identify the documentation set bundle. This should be a
-# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
-# will append .docset to the name.
-
-DOCSET_BUNDLE_ID = org.doxygen.Project
-
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files
-# will be generated that can be used as input for tools like the
-# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
-# of the generated HTML documentation.
-
-GENERATE_HTMLHELP = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
-# be used to specify the file name of the resulting .chm file. You
-# can add a path in front of the file if the result should not be
-# written to the html output directory.
-
-CHM_FILE =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
-# be used to specify the location (absolute path including file name) of
-# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
-# the HTML help compiler on the generated index.hhp.
-
-HHC_LOCATION =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
-# controls if a separate .chi index file is generated (YES) or that
-# it should be included in the master .chm file (NO).
-
-GENERATE_CHI = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
-# is used to encode HtmlHelp index (hhk), content (hhc) and project file
-# content.
-
-CHM_INDEX_ENCODING =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
-# controls whether a binary table of contents is generated (YES) or a
-# normal table of contents (NO) in the .chm file.
-
-BINARY_TOC = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members
-# to the contents of the HTML help documentation and to the tree view.
-
-TOC_EXPAND = NO
-
-# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER
-# are set, an additional index file will be generated that can be used as input for
-# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated
-# HTML documentation.
-
-GENERATE_QHP = NO
-
-# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
-# be used to specify the file name of the resulting .qch file.
-# The path specified is relative to the HTML output folder.
-
-QCH_FILE =
-
-# The QHP_NAMESPACE tag specifies the namespace to use when generating
-# Qt Help Project output. For more information please see
-# http://doc.trolltech.com/qthelpproject.html#namespace
-
-QHP_NAMESPACE =
-
-# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
-# Qt Help Project output. For more information please see
-# http://doc.trolltech.com/qthelpproject.html#virtual-folders
-
-QHP_VIRTUAL_FOLDER = doc
-
-# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add.
-# For more information please see
-# http://doc.trolltech.com/qthelpproject.html#custom-filters
-
-QHP_CUST_FILTER_NAME =
-
-# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see
-# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
-
-QHP_CUST_FILTER_ATTRS =
-
-# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's
-# filter section matches.
-# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
-
-QHP_SECT_FILTER_ATTRS =
-
-# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
-# be used to specify the location of Qt's qhelpgenerator.
-# If non-empty doxygen will try to run qhelpgenerator on the generated
-# .qhp file.
-
-QHG_LOCATION =
-
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
-# top of each HTML page. The value NO (the default) enables the index and
-# the value YES disables it.
-
-DISABLE_INDEX = NO
-
-# This tag can be used to set the number of enum values (range [1..20])
-# that doxygen will group on one line in the generated HTML documentation.
-
-ENUM_VALUES_PER_LINE = 4
-
-# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
-# structure should be generated to display hierarchical information.
-# If the tag value is set to YES, a side panel will be generated
-# containing a tree-like index structure (just like the one that
-# is generated for HTML Help). For this to work a browser that supports
-# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
-# Windows users are probably better off using the HTML help feature.
-
-GENERATE_TREEVIEW = YES
-
-# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
-# and Class Hierarchy pages using a tree view instead of an ordered list.
-
-USE_INLINE_TREES = NO
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
-# used to set the initial width (in pixels) of the frame in which the tree
-# is shown.
-
-TREEVIEW_WIDTH = 250
-
-# Use this tag to change the font size of Latex formulas included
-# as images in the HTML documentation. The default is 10. Note that
-# when you change the font size after a successful doxygen run you need
-# to manually remove any form_*.png images from the HTML output directory
-# to force them to be regenerated.
-
-FORMULA_FONTSIZE = 10
-
-# When the SEARCHENGINE tag is enable doxygen will generate a search box
-# for the HTML output. The underlying search engine uses javascript
-# and DHTML and should work on any modern browser. Note that when using
-# HTML help (GENERATE_HTMLHELP) or Qt help (GENERATE_QHP)
-# there is already a search function so this one should typically
-# be disabled.
-
-SEARCHENGINE = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
-# generate Latex output.
-
-GENERATE_LATEX = NO
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `latex' will be used as the default path.
-
-LATEX_OUTPUT = latex
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
-# invoked. If left blank `latex' will be used as the default command name.
-
-LATEX_CMD_NAME = latex
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
-# generate index for LaTeX. If left blank `makeindex' will be used as the
-# default command name.
-
-MAKEINDEX_CMD_NAME = makeindex
-
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
-# LaTeX documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_LATEX = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used
-# by the printer. Possible values are: a4, a4wide, letter, legal and
-# executive. If left blank a4wide will be used.
-
-PAPER_TYPE = a4wide
-
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
-# packages that should be included in the LaTeX output.
-
-EXTRA_PACKAGES =
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
-# the generated latex document. The header should contain everything until
-# the first chapter. If it is left blank doxygen will generate a
-# standard header. Notice: only use this tag if you know what you are doing!
-
-LATEX_HEADER =
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will
-# contain links (just like the HTML output) instead of page references
-# This makes the output suitable for online browsing using a pdf viewer.
-
-PDF_HYPERLINKS = YES
-
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
-# plain latex in the generated Makefile. Set this option to YES to get a
-# higher quality PDF documentation.
-
-USE_PDFLATEX = YES
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
-# command to the generated LaTeX files. This will instruct LaTeX to keep
-# running if errors occur, instead of asking the user for help.
-# This option is also used when generating formulas in HTML.
-
-LATEX_BATCHMODE = NO
-
-# If LATEX_HIDE_INDICES is set to YES then doxygen will not
-# include the index chapters (such as File Index, Compound Index, etc.)
-# in the output.
-
-LATEX_HIDE_INDICES = NO
-
-# If LATEX_SOURCE_CODE is set to YES then doxygen will include
-# source code with syntax highlighting in the LaTeX output.
-# Note that which sources are shown also depends on other settings
-# such as SOURCE_BROWSER.
-
-LATEX_SOURCE_CODE = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
-# The RTF output is optimized for Word 97 and may not look very pretty with
-# other RTF readers or editors.
-
-GENERATE_RTF = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `rtf' will be used as the default path.
-
-RTF_OUTPUT = rtf
-
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
-# RTF documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_RTF = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
-# will contain hyperlink fields. The RTF file will
-# contain links (just like the HTML output) instead of page references.
-# This makes the output suitable for online browsing using WORD or other
-# programs which support those fields.
-# Note: wordpad (write) and others do not support links.
-
-RTF_HYPERLINKS = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's
-# config file, i.e. a series of assignments. You only have to provide
-# replacements, missing definitions are set to their default value.
-
-RTF_STYLESHEET_FILE =
-
-# Set optional variables used in the generation of an rtf document.
-# Syntax is similar to doxygen's config file.
-
-RTF_EXTENSIONS_FILE =
-
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
-# generate man pages
-
-GENERATE_MAN = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `man' will be used as the default path.
-
-MAN_OUTPUT = man
-
-# The MAN_EXTENSION tag determines the extension that is added to
-# the generated man pages (default is the subroutine's section .3)
-
-MAN_EXTENSION = .3
-
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
-# then it will generate one additional man file for each entity
-# documented in the real man page(s). These additional files
-# only source the real man page, but without them the man command
-# would be unable to find the correct page. The default is NO.
-
-MAN_LINKS = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES Doxygen will
-# generate an XML file that captures the structure of
-# the code including all documentation.
-
-GENERATE_XML = NO
-
-# The XML_OUTPUT tag is used to specify where the XML pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `xml' will be used as the default path.
-
-XML_OUTPUT = xml
-
-# The XML_SCHEMA tag can be used to specify an XML schema,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_SCHEMA =
-
-# The XML_DTD tag can be used to specify an XML DTD,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_DTD =
-
-# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
-# dump the program listings (including syntax highlighting
-# and cross-referencing information) to the XML output. Note that
-# enabling this will significantly increase the size of the XML output.
-
-XML_PROGRAMLISTING = YES
-
-#---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
-# generate an AutoGen Definitions (see autogen.sf.net) file
-# that captures the structure of the code including all
-# documentation. Note that this feature is still experimental
-# and incomplete at the moment.
-
-GENERATE_AUTOGEN_DEF = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES Doxygen will
-# generate a Perl module file that captures the structure of
-# the code including all documentation. Note that this
-# feature is still experimental and incomplete at the
-# moment.
-
-GENERATE_PERLMOD = NO
-
-# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
-# the necessary Makefile rules, Perl scripts and LaTeX code to be able
-# to generate PDF and DVI output from the Perl module output.
-
-PERLMOD_LATEX = NO
-
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
-# nicely formatted so it can be parsed by a human reader. This is useful
-# if you want to understand what is going on. On the other hand, if this
-# tag is set to NO the size of the Perl module output will be much smaller
-# and Perl will parse it just the same.
-
-PERLMOD_PRETTY = YES
-
-# The names of the make variables in the generated doxyrules.make file
-# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
-# This is useful so different doxyrules.make files included by the same
-# Makefile don't overwrite each other's variables.
-
-PERLMOD_MAKEVAR_PREFIX =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
-# evaluate all C-preprocessor directives found in the sources and include
-# files.
-
-ENABLE_PREPROCESSING = YES
-
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
-# names in the source code. If set to NO (the default) only conditional
-# compilation will be performed. Macro expansion can be done in a controlled
-# way by setting EXPAND_ONLY_PREDEF to YES.
-
-MACRO_EXPANSION = NO
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
-# then the macro expansion is limited to the macros specified with the
-# PREDEFINED and EXPAND_AS_DEFINED tags.
-
-EXPAND_ONLY_PREDEF = NO
-
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
-# in the INCLUDE_PATH (see below) will be search if a #include is found.
-
-SEARCH_INCLUDES = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that
-# contain include files that are not input files but should be processed by
-# the preprocessor.
-
-INCLUDE_PATH =
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
-# patterns (like *.h and *.hpp) to filter out the header-files in the
-# directories. If left blank, the patterns specified with FILE_PATTERNS will
-# be used.
-
-INCLUDE_FILE_PATTERNS =
-
-# The PREDEFINED tag can be used to specify one or more macro names that
-# are defined before the preprocessor is started (similar to the -D option of
-# gcc). The argument of the tag is a list of macros of the form: name
-# or name=definition (no spaces). If the definition and the = are
-# omitted =1 is assumed. To prevent a macro definition from being
-# undefined via #undef or recursively expanded use the := operator
-# instead of the = operator.
-
-PREDEFINED =
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
-# this tag can be used to specify a list of macro names that should be expanded.
-# The macro definition that is found in the sources will be used.
-# Use the PREDEFINED tag if you want to use a different macro definition.
-
-EXPAND_AS_DEFINED =
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
-# doxygen's preprocessor will remove all function-like macros that are alone
-# on a line, have an all uppercase name, and do not end with a semicolon. Such
-# function macros are typically used for boiler-plate code, and will confuse
-# the parser if not removed.
-
-SKIP_FUNCTION_MACROS = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to external references
-#---------------------------------------------------------------------------
-
-# The TAGFILES option can be used to specify one or more tagfiles.
-# Optionally an initial location of the external documentation
-# can be added for each tagfile. The format of a tag file without
-# this location is as follows:
-# TAGFILES = file1 file2 ...
-# Adding location for the tag files is done as follows:
-# TAGFILES = file1=loc1 "file2 = loc2" ...
-# where "loc1" and "loc2" can be relative or absolute paths or
-# URLs. If a location is present for each tag, the installdox tool
-# does not have to be run to correct the links.
-# Note that each tag file must have a unique name
-# (where the name does NOT include the path)
-# If a tag file is not located in the directory in which doxygen
-# is run, you must also specify the path to the tagfile here.
-
-TAGFILES =
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create
-# a tag file that is based on the input files it reads.
-
-GENERATE_TAGFILE =
-
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed
-# in the class index. If set to NO only the inherited external classes
-# will be listed.
-
-ALLEXTERNALS = NO
-
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
-# in the modules index. If set to NO, only the current project's groups will
-# be listed.
-
-EXTERNAL_GROUPS = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script
-# interpreter (i.e. the result of `which perl').
-
-PERL_PATH = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
-# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
-# or super classes. Setting the tag to NO turns the diagrams off. Note that
-# this option is superseded by the HAVE_DOT option below. This is only a
-# fallback. It is recommended to install and use dot, since it yields more
-# powerful graphs.
-
-CLASS_DIAGRAMS = NO
-
-# You can define message sequence charts within doxygen comments using the \msc
-# command. Doxygen will then run the mscgen tool (see
-# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
-# documentation. The MSCGEN_PATH tag allows you to specify the directory where
-# the mscgen tool resides. If left empty the tool is assumed to be found in the
-# default search path.
-
-MSCGEN_PATH =
-
-# If set to YES, the inheritance and collaboration graphs will hide
-# inheritance and usage relations if the target is undocumented
-# or is not a class.
-
-HIDE_UNDOC_RELATIONS = YES
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
-# available from the path. This tool is part of Graphviz, a graph visualization
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section
-# have no effect if this option is set to NO (the default)
-
-HAVE_DOT = YES
-
-# By default doxygen will write a font called FreeSans.ttf to the output
-# directory and reference it in all dot files that doxygen generates. This
-# font does not include all possible unicode characters however, so when you need
-# these (or just want a differently looking font) you can specify the font name
-# using DOT_FONTNAME. You need need to make sure dot is able to find the font,
-# which can be done by putting it in a standard location or by setting the
-# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
-# containing the font.
-
-DOT_FONTNAME = FreeSans
-
-# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
-# The default size is 10pt.
-
-DOT_FONTSIZE = 10
-
-# By default doxygen will tell dot to use the output directory to look for the
-# FreeSans.ttf font (which doxygen will put there itself). If you specify a
-# different font using DOT_FONTNAME you can set the path where dot
-# can find it using this tag.
-
-DOT_FONTPATH =
-
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect inheritance relations. Setting this tag to YES will force the
-# the CLASS_DIAGRAMS tag to NO.
-
-CLASS_GRAPH = YES
-
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect implementation dependencies (inheritance, containment, and
-# class references variables) of the class with other documented classes.
-
-COLLABORATION_GRAPH = YES
-
-# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for groups, showing the direct groups dependencies
-
-GROUP_GRAPHS = YES
-
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
-# collaboration diagrams in a style similar to the OMG's Unified Modeling
-# Language.
-
-UML_LOOK = NO
-
-# If set to YES, the inheritance and collaboration graphs will show the
-# relations between templates and their instances.
-
-TEMPLATE_RELATIONS = NO
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
-# tags are set to YES then doxygen will generate a graph for each documented
-# file showing the direct and indirect include dependencies of the file with
-# other documented files.
-
-INCLUDE_GRAPH = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
-# documented header file showing the documented files that directly or
-# indirectly include this file.
-
-INCLUDED_BY_GRAPH = YES
-
-# If the CALL_GRAPH and HAVE_DOT options are set to YES then
-# doxygen will generate a call dependency graph for every global function
-# or class method. Note that enabling this option will significantly increase
-# the time of a run. So in most cases it will be better to enable call graphs
-# for selected functions only using the \callgraph command.
-
-CALL_GRAPH = YES
-
-# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
-# doxygen will generate a caller dependency graph for every global function
-# or class method. Note that enabling this option will significantly increase
-# the time of a run. So in most cases it will be better to enable caller
-# graphs for selected functions only using the \callergraph command.
-
-CALLER_GRAPH = YES
-
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
-# will graphical hierarchy of all classes instead of a textual one.
-
-GRAPHICAL_HIERARCHY = YES
-
-# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
-# then doxygen will show the dependencies a directory has on other directories
-# in a graphical way. The dependency relations are determined by the #include
-# relations between the files in the directories.
-
-DIRECTORY_GRAPH = YES
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
-# generated by dot. Possible values are png, jpg, or gif
-# If left blank png will be used.
-
-DOT_IMAGE_FORMAT = png
-
-# The tag DOT_PATH can be used to specify the path where the dot tool can be
-# found. If left blank, it is assumed the dot tool can be found in the path.
-
-DOT_PATH =
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that
-# contain dot files that are included in the documentation (see the
-# \dotfile command).
-
-DOTFILE_DIRS =
-
-# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
-# nodes that will be shown in the graph. If the number of nodes in a graph
-# becomes larger than this value, doxygen will truncate the graph, which is
-# visualized by representing a node as a red box. Note that doxygen if the
-# number of direct children of the root node in a graph is already larger than
-# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
-# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
-
-DOT_GRAPH_MAX_NODES = 50
-
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
-# graphs generated by dot. A depth value of 3 means that only nodes reachable
-# from the root by following a path via at most 3 edges will be shown. Nodes
-# that lay further from the root node will be omitted. Note that setting this
-# option to 1 or 2 may greatly reduce the computation time needed for large
-# code bases. Also note that the size of a graph can be further restricted by
-# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
-
-MAX_DOT_GRAPH_DEPTH = 0
-
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
-# background. This is disabled by default, because dot on Windows does not
-# seem to support this out of the box. Warning: Depending on the platform used,
-# enabling this option may lead to badly anti-aliased labels on the edges of
-# a graph (i.e. they become hard to read).
-
-DOT_TRANSPARENT = NO
-
-# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
-# files in one run (i.e. multiple -o and -T options on the command line). This
-# makes dot run faster, but since only newer versions of dot (>1.8.10)
-# support this, this feature is disabled by default.
-
-DOT_MULTI_TARGETS = NO
-
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
-# generate a legend page explaining the meaning of the various boxes and
-# arrows in the dot generated graphs.
-
-GENERATE_LEGEND = YES
-
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
-# remove the intermediate dot files that are used to generate
-# the various graphs.
-
-DOT_CLEANUP = YES
diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am
deleted file mode 100644
index 19b536c..0000000
--- a/doc/man/Makefile.am
+++ /dev/null
@@ -1,11 +0,0 @@
-notrans_dist_man1_MANS = lsmcli.1 lsmd.1
-
-if WITH_MEGARAID
-notrans_dist_man1_MANS += megaraid_lsmplugin.1
-endif
-
-if WITH_HPSA
-notrans_dist_man1_MANS += hpsa_lsmplugin.1
-endif
-
-notrans_dist_man5_MANS = lsmd.conf.5.in
diff --git a/doc/man/hpsa_lsmplugin.1.in b/doc/man/hpsa_lsmplugin.1.in
deleted file mode 100644
index 79ff565..0000000
--- a/doc/man/hpsa_lsmplugin.1.in
+++ /dev/null
@@ -1,50 +0,0 @@
-.TH hpsa_lsmplugin "1" "March 2015" "hpsa_lsmplugin @VERSION@" "libStorageMgmt"
-.SH NAME
-hpsa_lsmplugin -- LibstorageMgmt HP SmartArray plugin
-
-.SH DESCRIPTION
-LibstorageMgmt hpsa plugin allows user to manage HP SmartArray via vendor
-tool \fBhpssacli\fR[1].
-The 'hpsa_lsmplugin' executable file is for libStorageMgmt
-daemon to execute when client user specifies hpsa plugin in the URI.
-
-.SH URI
-To use this plugin, users should set their URI to this format:
-.nf
-
- \fBhpsa://\fR
- or
- \fBhpsa://?hpssacli=<path_of_hpssacli>\fR
-
-.fi
-
-.TP hpssacli
-The 'hpssacli' URI parameter is used to specified the path of hpssacli tool.
-By default, this plugin will try these paths used by hpssacli rpm:
-\fB/usr/sbin/hpssacli\fR and \fB/opt/hp/hpssacli/bld/hpssacli\fR.
-
-.SH ROOT PRIVILEGE
-This plugin requires both \fBlsmd\fR daemon and API client running as root
-user. Please check manpage \fIlsmd.conf (5)\fR for detail.
-
-.SH SUPPORTED HARDWARES
-Please refer to HP website for hardware support status of hpssacli.
-Detailed support status can be queried via:
-
- * \fBlsm.Client.capabilities()\fR (Python API)
- * \fBlsm_capabilities()\fR (C API)
- * \fBlsmcli capabilities\fR (lsmcli command line).
-
-.SH FIREWALL RULES
-This plugin only execute \fBhpssacli\fR on localhost. No network connection
-required.
-
-.SH SEE ALSO
-\fIlsmcli\fR(1), \fIlsmd\fR(1), [1]http://downloads.linux.hp.com/SDR/project/spp/
-
-.SH BUGS
-Please report bugs to
-\fI<libstoragemgmt-***@lists.sourceforge.net>\fR
-
-.SH AUTHOR
-Gris Ge \fI<***@redhat.com>\fR
diff --git a/doc/man/lsmcli.1.in b/doc/man/lsmcli.1.in
deleted file mode 100644
index e2af14f..0000000
--- a/doc/man/lsmcli.1.in
+++ /dev/null
@@ -1,727 +0,0 @@
-.TH LSMCLI "1" "September 2014" "lsmcli @VERSION@" "libStorageMgmt"
-.SH NAME
-lsmcli - libStorageMgmt command line interface
-
-.SH SYNOPSIS
-.B lsmcli \fIcommand\fR [\fIGLOBAL OPTIONS\fR]...[\fICOMMAND OPTIONS\fR]...
-
-.SH DESCRIPTION
-lsmcli is the command line tool for the libStorageMgmt library. This tool
-allows users to do one off storage related management operations or to script
-management of their storage.
-
-.SH PREREQUISITES
-.TP 8
-* libStorageMgmt daemon.
-The daemon '\fBlsmd\fR' is required by lsmcli.
-.TP 8
-* URI(Uniform Resource Identifier)
-URI is used to identify which plugin to use and how the plugin should
-communicate with the storage array. The valid URI format is:
-.RS 12
-.nf
-\fBplugin://<username>@host:<port>?<query_string_parameters>\fR
-.br
-\fBplugin+ssl://<username>@host:<port>?<query_string_parameters>\fR
-.fi
-.RE 1
-.RS 8
-Examples, please refer to "LibStorageMgmt User Guide" for more details:
-.RE 1
-.RS 12
-* Simulator:
-.RS 4
-\fBsim://\fR
-.br
-\fBsimc://\fR
-.RE 1
-.RS 12
-* NetApp ONTAP:
-.RS 4
-\fBontap://***@host\fR
-.br
-\fBontap+ssl://***@host\fR
-.RE 1
-.RS 12
-* SMI-S supported arrays (eg. EMC CX/VNX, HDS AMS, IBM SVC/DS, LSI
-MegaRAID and others):
-.RS 4
-\fBsmis://***@host:<port>?namespace=<namespace>\fR
-.br
-\fBsmis+ssl://***@host:<port>?namespace=<namespace>\fR
-.RE 1
-.RS 8
-You can pass URI to lsmcli via one of these methods:
-.RS 4
-* Using '\fB-u\fR, \fB--uri\fR' argument.
-.br
-* Using '\fBLSMCLI_URI\fR' environment variable.
-.br
-* Add this line into \fB$HOME/.lsmcli\fR:
-.RS 4
-uri=\fI<URI>\fR
-.RE 1
-.TP 8
-* Password
-For storage array password authentication you can pass it to
-lsmcli via one of the following methods:
-.RS 12
-* '\fB-P\fR, \fB--prompt\fR' argument to prompt for password.
-.br
-* '\fBLSMCLI_PASSWORD\fR' environment variable.
-.RE 1
-.SH "GLOBAL OPTIONS"
-.TP 15
-\fB--version\fR
-Show program's version number and exit
-.TP 15
-\fB-h\fR, \fB--help\fR
-Show this help message and exit. Will show help message of specific command
-if specified.
-.TP 15
-\fB-u\fR \fI<URI>\fR, \fB--uri\fR \fI<URI>\fR
-Uniform Resource Identifier (env LSMCLI_URI)
-.TP 15
-\fB-P\fR, \fB--prompt\fR
-Prompt for password (env LSMCLI_PASSWORD)
-.TP 15
-\fB-H\fR, \fB--human\fR
-Print sizes in human readable format
-(e.g., KiB, MiB, GiB, TiB, PiB, EiB)
-.TP 15
-\fB-t\fR \fI<SEP>\fR, \fB--terse\fR \fI<SEP>\fR
-Print output in terse form with "SEP" as a record separator without header
-unless '--header' defined.
-.TP 15
-\fB--header\fR
-Include the header with terse
-.TP 15
-\fB-e\fR, \fB--enum\fR
-Display enumerated types as numbers instead of text
-.TP 15
-\fB-f\fR, \fB--force\fR
-Bypass confirmation prompt for data loss operations
-.TP 15
-\fB-w\fR \fI<WAIT>\fR, \fB--wait\fR=\fI<WAIT>\fR
-Command timeout value in ms (default = 30s)
-.TP 15
-\fB-b\fR
-Run the command asynchronously instead of waiting for completion. The lsmcli
-command will exit with exit code(7) and job id will be written to STDOUT when
-a command is still executing on the storage array.
-Use 'job-status --id \fI<job id>\fR' to inquire on the progress of the command.
-Some arrays or plugins might not support asynchronous operations, in those
-circumstances, \fb-b\fR will be ineffective. Command will wait until finished.
-.TP 15
-\fB-s\fR, \fB--script\fR
-Displaying data in script friendly way.
-.br
-Without this option, data is displayed in this manner (default):
-
- ID | Name | Element Type ...
- ------------------------------------------ ...
- aggr0 | aggr0 | FS,SYSTEM_RESERVED,POOL ...
- iscsi | iscsi | FS,POOL ...
-
-
-With this option, data is displayed in this manner.
-
- -----------------------------------------------
- ID | aggr0
- Name | aggr0
- Element Type | FS,SYSTEM_RESERVED,POOL
- ...
- -----------------------------------------------
- ID | iscsi
- Name | iscsi
- Element Type | FS,POOL
- ...
-
-Please note:
-.br
-To reduce the width of output, NOT all properties will be displayed in default
-column display.
-
-.SH COMMANDS
-.SS list
-List information on LSM objects
-.TP 15
-\fB--type\fR \fI<TYPE>\fR
-Required. Valid values are (case insensitive):
-.br
-\fBVOLUMES\fR, \fBPOOLS\fR, \fBFS\fR, \fBSNAPSHOTS\fR,
-\fBEXPORTS\fR, \fBNFS_CLIENT_AUTH\fR,
-.br
-\fBACCESS_GROUPS\fR, \fBSYSTEMS\fR, \fBDISKS\fR, \fBPLUGINS\fR,
-\fBTARGET_PORTS\fR.
-
-.TP
-\fB--fs\fR \fI<FS_ID>\fR
-Required for \fB--type\fR=\fBSNAPSHOTS\fR. List the snapshots of certain
-filesystem.
-PLUGINS will list all supported plugins of LSM, not only the current one.
-.TP
-\fB--sys\fR \fI<SYS_ID>\fR
-Search resources from system with SYS_ID. Only supported when querying these
-types of resources: \fBVOLUMES\fR, \fBPOOLS\fR, \fBFS\fR,
-\fBSNAPSHOTS\fR, \fBDISKS\fR, \fBACCESS_GROUPS\fR.
-.TP
-\fB--pool\fR \fI<POOL_ID>\fR
-Search resources from pool with POOL_ID. Only supported by these types of
-resources: \fBVOLUMES\fR, \fBPOOLS\fR, \fBFS\fR.
-.TP
-\fB--vol\fR \fI<VOL_ID>\fR
-Search resources from volume with VOL_ID. Only supported by these types of
-resources: \fBVOLUMES\fR, \fBACCESS_GROUPS\fR.
-.br
-To query volume masking status, please use this command:
- lsmcli list --type ACCESS_GROUPS --vol <VOL_ID>
-.TP
-\fB--disk\fR \fI<DISK_ID>\fR
-Search resources from disk with DISK_ID. Only supported by these types of
-resources: \fBDISK\fR.
-.TP
-\fB--ag\fR \fI<AG_ID>\fR
-Search resources from access group with AG_ID. Only supported by these types
-of resources: \fBACCESS_GROUPS\fR, \fBVOLUMES\fR.
-.br
-To query volume masking status, please use this command:
- lsmcli list --type VOLUMES --ag <AG_ID>
-.TP
-\fB--fs\fR \fI<FS_ID>\fR
-Search resources from file system with FS_ID. Only supported by these types
-of resources: \fBFS\fR.
-.TP
-\fB--nfs-export\fR \fI<NFS_EXPORT_ID>\fR
-Search resources from NFS export with NFS_EXPORT_ID. Only supported by these
-types of resources: \fBEXPORTS\fR.
-.TP
-\fB--tgt\fR \fI<TGT_ID>\fR
-Search resources from target port with target port ID. Only supported by these
-types of resources: \fBTARGET_PORTS\fR.
-
-.SS job-status
-Retrieve information about a job. Please see user guide on how to use.
-.TP 15
-\fB--job\fR \fI<JOB_ID>\fR
-
-.SS capabilities
-Retrieves array capabilities.
-.TP 15
-\fB--sys\fR \fI<SYS_ID>\fR
-Required. ID of the system to query for capabilities.
-
-.SS plugin-info
-Retrieves plugin description and version for current URI.
-
-.SS volume-create
-Creates a volume (AKA., logical volume, virtual disk, LUN).
-.TP 15
-\fB--name\fR \fI<NAME>\fR
-Required. Volume name.
-.TP
-\fB--size\fR \fI<SIZE>\fR
-Required. Volume size (See \fBSIZE OPTION\fR for allowed formats).
-.TP
-\fB--pool\fR \fI<POOL_ID>\fR
-Required. ID of pool.
-.TP
-\fB--provisioning\fR \fI<THINP_TYPE>\fR
-Optional. Provisioning type. Valid values are: DEFAULT, THIN, FULL.
-\fBDEFAULT\fR means let plugin choose. \fBTHIN\fR means requiring a Thin
-Provisioning enabled volume. \fBFULL\fR means requiring a fully allocated
-volume.
-
-.SS volume-delete
-.TP 15
-Delete a volume given its ID
-.TP
-\fB--vol\fR \fI<VOL_ID>\fR
-Required. The ID of volume to delete.
-
-.SS volume-resize
-.TP 15
-Re-sizes a volume, requires:
-.TP
-\fB--vol\fR \fI<VOL_ID>\fR
-Required. The ID of volume to resize.
-.TP
-\fB--size\fR \fI<NEW_SIZE>\fR
-Required. The new size of volume.(See \fBSIZE OPTION\fR for allowed formats).
-Due to boundary alignment concern, array might return a volume with slightly
-bigger size than requested.
-
-.SS volume-replicate
-Creates a new volume and replicates provided volume to it.
-.TP 15
-\fB--vol\fR \fI<VOL_ID>\fR
-Required. The ID of volume to replicate.
-.TP
-\fB--name\fR \fI<NAME>\fR
-Required. The name for new volume to hold replicated data.
-.TP
-\fB--rep-type\fR \fI<REPL_TYPE>\fR (see \fBVOLUME REPLICATION TYPES)\fR
-Required. Valid types of replication are:
-.br
-\fBCLONE\fR, \fBCOPY\fR, \fBMIRROR_ASYNC\fR,
-\fBMIRROR_SYNC\fR.
-.TP
-\fB--pool\fR \fI<POOL_ID>\fR
-Optional. The ID of pool where the new volume should be created from. If not specified,
-plugin or array will choose appropriate pool.
-
-.SS volume-replicate-range
-Replicates a portion of a volume to the same volume or to a different volume.
-.TP 15
-\fB--src-vol\fR \fI<SRC_VOL_ID>\fR
-Required. The ID of replication source volume.
-.TP
-\fB--dst-vol\fR \fI<DST_VOL_ID>\fR
-Required. The ID of replication destination volume.
-.TP
-\fB--rep-type\fR \fI<REPL_TYPE>\fR (see \fBVOLUME REPLICATION TYPES)\fR
-Required. Appropriate types of replication are:
-.br
-\fBCLONE\fR, \fBCOPY\fR.
-.TP
-\fB--src-start\fR \fI<SRC_START_BLK>\fR
-Required. Replication source volume start block number. Must in pair with
-\fB--count\fR and \fB--dst-start\fR.
-If you have several non-continuous block ranges, you can define repeatly
-define this arugument, like '\fB--src-start 0 --dst-start 0 --count 1024
---src-start 2048 --dst-start 2048 --count 2048\fR'
-.TP
-\fB--dst-start\fR \fI<DST_START_BLK>\fR
-Required. Replication destination volume start block number. Must in pair with
-\fB--count\fR and \fB--src-start\fR.
-.TP
-\fB--count\fR \fI<BLK_COUNT>\fR
-Required. The count of replicated block startting from \fB--src-start\R block.
-Must in pair with \fB--src-start\fR and \fB--dst-start\fR.
-
-.SS volume-replicate-range-block-size
-Size of each replicated block on a system in bytes.
-.TP 15
-\fB--sys\fR \fI<SYS_ID>\fR
-Required. ID of the system to query for replicated block size.
-
-.SS volume-dependants
-Returns True if volume has a dependant child, like replication.
-.TP 15
-\fB--vol\fR \fI<VOL_ID>\fR
-Required. The ID of volume to query dependency.
-
-.SS volume-dependants-rm
-Removes volume dependencies(like replication).
-.TP 15
-\fB--vol\fR \fI<VOL_ID>\fR
-Required. The ID of volume to remove dependency.
-
-.SS volume-access-group
-Lists the access group(s) that have access to the provided volume.
-.TP 15
-\fB--vol\fR \fI<VOL_ID>\fR
-Required. The ID of volume to query access.
-
-.SS volume-mask
-.TP 15
-Grant access group RW access to certain volume. Like LUN masking
-or NFS export.
-.TP
-\fB--vol\fR \fI<VOL_ID>\fR
-Required. The ID of volume to access.
-.TP
-\fB--ag\fR \fI<AG_ID>\fR
-Required. The ID of access group to grant.
-
-.SS volume-unmask
-.TP 15
-Revoke access group RW access to specified volume.
-.TP
-\fB--vol\fR \fI<VOL_ID>\fR
-Required. The ID of volume to revoke.
-.TP
-\fB--ag\fR \fI<AG_ID>\fR
-Required. The ID of access group to revoke.
-
-.SS volume-raid-info
-.TP 15
-Query RAID information for given volume.
-.TP
-\fB--vol\fR \fI<VOL_ID>\fR
-Required. The ID of volume to query.
-
-.SS access-group-create
-.TP 15
-Create an access group.
-.TP
-\fB--name\fR \fI<AG_NAME>\fR
-Required. The human friendly name for new access group.
-.TP
-\fB--init\fR \fI<INIT_ID>\fR
-Required. The first initiator ID of new access group. WWPN or iSCSI IQN.
-.TP
-\fB--sys\fR \fI<SYS_ID>\fR
-Required. The ID of system where this access group should reside on.
-
-.SS access-group-add
-Adds an initiator to an access group.
-.TP 15
-\fB--ag\fR \fI<AG_ID>\fR
-Required. ID of access group.
-.TP
-\fB--init\fR \fI<INIT_ID>\fR
-Required. ID of initiator to add. WWPN or iSCSI IQN.
-
-.SS access-group-remove
-Removes an initiator from an access group.
-.TP 15
-\fB--ag\fR \fI<AG_ID>\fR
-Required. ID of access group.
-.TP
-\fB--init\fR \fI<INIT_ID>\fR
-Required. ID of initiator to remove.
-
-.SS access-group-delete
-Delete an access group.
-.TP 15
-\fB--ag\fR \fI<AG_ID>\fR
-Required. ID of access group to delete.
-
-.SS access-group-volumes
-Lists the volumes that the access group has been granted access to.
-.TP 15
-\fB--ag\fR \fI<AG_ID>\fR
-Required. The ID of access group to query.
-
-.SS iscsi-chap
-Configures ISCSI inbound/outbound CHAP authentication.
-.TP 15
-\fB--init\fR \fI<INIT_ID>\fR
-Required. The ID of iSCSI initiator to configure.
-.TP
-\fB--in-user\fR \fI<IN_USER>\fR
-Optional. Inbound CHAP user name.
-.TP
-\fB--in-pass\fR \fI<IN_PASS>\fR
-Optional. Inbound CHAP password.
-.TP
-\fB--out-user\fR \fI<OUT_USER>\fR
-Optional. Outbound CHAP user name.
-.TP
-\fB--out-pass\fR \fI<OUT_PASS>\fR
-Optional. Outbound CHAP password.
-
-.SS fs-create
-Creates a filesystem.
-.TP 15
-\fB--name\fR \fI<NAME>\fR
-Required. Human friendly name for new filesystem.
-.TP
-\fB--size\fR \fI<SIZE>\fR
-Required. Volume size(See \fBSIZE OPTION\fR for allowed formats).
-.TP
-\fB--pool\fR \fI<POOL_ID>\fR
-Required. ID of pool to hold the new filesystem.
-
-.SS fs-delete
-Delete a filesystem.
-.TP 15
-\fB--fs\fR \fI<FS_ID>\fR
-Required. ID of the filesystem to delete.
-
-.SS fs-resize
-Resizes a filesystem.
-.TP 15
-\fB--fs\fR \fI<FS_ID>\fR
-Required. ID of the filesystem to resize.
-.TP
-\fB--size\fR \fI<NEW_SIZE>\fR
-Required. New size of filesystem. See \fBSIZE OPTION\fR for allowed
-formats.
-
-.SS fs-export
-Export a filesystem via NFS.
-.TP 15
-\fB--fs\fR \fI<FS_ID>\fR
-Required. ID of the filesystem to export.
-.TP
-\fB--exportpath\fR \fI<EXPORT_PATH>\fR
-Optional. NFS server export path. e.g. '/foo/bar'.
-.TP
-\fB--anonuid\fR \fI<ANONY_UID>\fR
-Optional. The UID(User ID) to map to anonymous user.
-.TP
-\fB--anongid\fR \fI<ANONY_GID>\fR
-Optional. The GID(Group ID) to map to anonymous user.
-.TP
-\fB--auth-type\fR \fI<AUTH_TYPE>\fR
-Optional. NFS client authentication type. This is just a place holder, not
-supported yet.
-.TP
-\fB--root-host\fR \fI<ROOT_HOST>\fR
-Optional. Repeatable. The host/IP has root access. For two or more hosts/IPs:
-'\fB--root-host hostA --root-host hostB\fR'.
-.TP
-\fB--ro-host\fR \fI<RO_HOST>\fR
-Optional. Repeatable. The host/IP has read only access. For two or more
-hosts/IPs: '\fB--ro-host hostA --ro-host hostB\fR'.
-.TP
-\fB--rw-host\fR \fI<RW_HOST>\fR
-Optional. The host/IP has read/write access. For two or more hosts/IPs:
-'\fB--rw-host hostA --rw-host hostB\fR'.
-
-.SS fs-unexport
-Remove an NFS export.
-.TP 15
-\fB--fs\fR \fI<FS_ID>\fR
-Required. ID of the filesystem to unexport.
-
-.SS fs-clone
-Creates a file system clone. The 'clone' means point in time read writeable
-space efficient copy of data, AKA. read-writable snapshot.
-.TP 15
-\fB--src-fs\fR \fI<SRC_FS_ID>\fR
-Required. The ID of the filesystem to clone.
-.TP
-\fB--dst-name\fR \fI<DST_FS_NAME>\fR
-Required. The name for newly created destination file system.
-.TP
-\fB--backing-snapshot\fR \fI<BE_SS_ID>\fR
-Optional. Make a FS clone using a previously created snapshot.
-
-.SS fs-snap-create
-Creates a snapshot of specified filesystem. A snapshot is defined as a read only
-space efficient point in time copy (PIT) of a filesystem. The source filesystem
-remains modifiable.
-.TP 15
-\fB--name\fR \fI<SNAP_NAME>\fR
-Required. The human friendly name of new snapshot.
-.TP
-\fB--fs\fR \fI<FS_ID>\fR
-Required. The ID of filesystem to create snapshot against.
-
-.SS fs-snap-delete
-Deletes a snapshot.
-.TP 15
-\fB--snap\fR \fI<SNAP_ID>\fR
-Required. The ID of snapshot to delete.
-.TP
-\fB--fs\fR \fI<FS_ID>\fR
-Required. The ID of filesystem.
-
-.SS fs-snap-restore
-Restores a FS or specified files to previous snapshot state. This will discard
-all the changes to filesystem since snapshot if specific files are not specified in restore.
-.TP 15
-\fB--fs\fR \fI<FS_ID>\fR
-Required. The ID of filesystem to restore.
-.TP
-\fB--snap\fR \fI<SNAP_ID>\fR
-Required. The ID of snapshot to restore.
-.TP
-\fB--file\fR \fI<FILE_PATH>\fR
-Optional. Repeatable. With this option defined, will only restore the defined
-file(s).
-'\fB--file fileA --file pathB\fR'.
-.TP
-\fB--fileas\fR \fI<NEW_FILE_PATH>\fR
-Optional. Repeatable. With this option defined, the restored file will be
-saved to specified path and filename, eg. '\fB--file fileA --fileas old_fileA \fR'.
-
-.SS fs-dependants
-Returns True if a child dependency (snapshot or clone) exists.
-.TP 15
-\fB--fs\fR \fI<FS_ID>\fR
-Required. The ID of filesystem to query.
-.TP
-\fB--file\fR \fI<FILE_PATH>\fR
-Optional. Repeatable. Only check for dependencies on specific file(s), eg. '\fB--file fileA --file pathB\fR'.
-
-.SS fs-dependants-rm
-Removes filesystem dependencies(snapshot or clone).
-.TP 15
-\fB--fs\fR \fI<FS_ID>\fR
-Required. The ID of filesystem to remove dependency.
-.TP
-\fB--file\fR \fI<FILE_PATH>\fR
-Optional. Repeatable. Only remove dependencies on specific file(s), eg. '\fB--file fileA --file pathB\fR'.
-
-.SS file-clone
-Creates a clone of a file (thin provisioned). Note: --src and --dst need to be paired
- eg. '\fB--src fileA --src fileB --dst fileA_clone --dst fileB_clone\fR'.
-.TP 15
-\fB--src\fR \fI<SRC_FILE_PATH>\fR
-Required. Repeatable. Source file to clone (relative path).
-.TP
-\fB--dst\fR \fI<DST_FILE_PATH>\fR
-Required. Repeatable. Destination file for clone (relative path).
-
-.IP
-.SH ALIAS
-.SS ls
-Alias of 'list --type systems'
-.SS lp
-Alias of 'list --type pools'
-.SS lv
-Alias of 'list --type volumes'
-.SS ld
-Alias of 'list --type disks'
-.SS la
-Alias of 'list --type access_groups'
-.SS lf
-Alias of 'list --type fs'
-.SS lt
-Alias of 'list --type target_ports'
-.SS c
- Alias of 'capabilities'
-.SS p
- Alias of 'plugin-info'
-.SS vc
-Alias of 'volume-create'
-.SS vd
-Alias of 'volume-delete'
-.SS vr
-Alias of 'volume-resize'
-.SS vm
-Alias of 'volume-mask'
-.SS vu
-Alias of 'volume-unmask'
-.SS vri
-Alias of 'volume-raid-info'
-.SS ac
-Alias of 'access-group-create'
-.SS aa
-Alias of 'access-group-add'
-.SS ar
-Alias of 'access-group-remove'
-.SS ad
-Alias of 'access-group-delete'
-
-.IP
-.SH SIZE OPTION
-.SS \fB--size\fR \fI\fI<SIZE>\fR\fR
-Storage space size. Format is '\fI<number>\fR' + '\fI<prefix>\fR'. Example:
-"10GiB", "20.5MB". No postfix indicates bytes. Valid prefixes are:
- KiB, # 2^10 Bytes
- MiB, # 2^20 Bytes
- GiB, # 2^30 Bytes
- TiB, # 2^40 Bytes
- PiB, # 2^50 Bytes
- EiB, # 2^60 Bytes
- KB, # 10^3 Bytes
- MB, # 10^6 Bytes
- GB, # 10^9 Bytes
- TB, # 10^12 Bytes
- PB, # 10^15 Bytes
- EB, # 10^17 Bytes
-
-These prefixes are supported also, but not recommended:
- K, M, G, T, P, E, # equal to KiB, MiB, and etc
- k, m, g, t, p, e, # equal to KiB, MiB, and etc
-
-.SH FILES
-.TP 15
-~/.lsmcli
-lsmcli configuration file, containing name-value pairs separated
-by '='. The only currently supported configuration option is 'uri',
-such as 'uri=ontap://***@filer.example.com'.
-
-Configuration options in .lsmcli are only used if not overridden by
-command-line option or environment variable.
-
-.SH EXAMPLES (command output omitted for brevity)
-.TP 15
-Simulator, list pools (no password required)
-$ lsmcli -u sim:// -l POOLS
-.TP 15
-NetApp, list volumes (prompting for password)
-$ lsmcli -u ontap://***@host/ -l VOLUMES -P
-.TP 15
-SMI-S, list systems (prompting for password)
-.nf
-$ lsmcli -u smispy://***@host:5988/?namespace=root/interop \\
- -l SYSTEMS -P
-.fi
-.TP 15
-Targetd, list pools (using env variables for URI and password)
-$ export LSMCLI_URI=targetd://***@host:18700
-.br
-$ export LSMCLI_PASSWORD=\fI<password>\fR
-.br
-$ lsmcli -l POOLS
-.TP 15
-NexentaStor, create volume (using environment variables for URI and password)
-.nf
-$ export LSMCLI_URI='nstor://***@host'
-$ export LSMCLI_PASSWORD=\fI<password>\fR
-$ lsmcli volume-create --name volume_name --size 1TiB --pool default
-.fi
-.TP 15
-SMI-S, create volume (using environment variables for URI and password)
-.nf
-$ export LSMCLI_URI='smispy+ssl://***@host:5989?namespace=root/emc'
-$ export LSMCLI_PASSWORD=\fI<password>\fR
-$ lsmcli volume-create --name volume_name --size 1TiB --pool default
-.fi
-
-.SH ENVIRONMENT
-.TP 17
-LSMCLI_URI
-The URI for the storage array in question.
-.TP 17
-LSMCLI_PASSWORD
-The password to use for the array.
-
-.SH VOLUME REPLICATION TYPES
-.TP 17
-CLONE
-A point in time, read writeable, space efficent copy of data.
-.TP 17
-COPY
-A full bitwise copy of the data. It occupies the full space.
-.TP 17
-MIRROR_SYNC
-Continously updated, realtime with both copies having identical data.
-.TP 17
-MIRROR_ASYNC
-Continously updated, with a varying amount of delay and data delta
-between the source and target.
-
-
-.SH NOTES
-.TP 8
-Plugin installation
-Plugins are installed individually except for the simulators which are always
-included.
-
-.TP 8
-Secure sockets layer (SSL)
-All of the plugins (except the simulator) support SSL when communicating from
-the plugin to the array. This is accomplished by adding "+ssl" to the plugin
-and usually by selecting a different port number from non-SSL communications.
-.br
-.nf
-$ lsmcli -u smispy+ssl://***@host:5989/?namespace=interop \\
- list --type SYSTEMS -P
-.fi
-
-.TP 8
-SSL error: certificate verify failed
-When using SMI-S plugin with SSL against self-signed SMI-S provider, lsmcli
-normally quit with '\fBSSL error: certificate verify failed\fR'. Please
-contact SMI-S provider support to setup the self-signed certificate in your
-system. If you prefer to bypass the certificate check, add 'no_ssl_verify=yes'
-at the end of URI, for example:
-.RS 12
-.nf
-\fBsmispy+ssl://***@emc-smi:5989?namespace=root/emc&no_ssl_verify=yes\fR
-.fi
-
-.SH BUGS
-Please report bugs to
-\fI<libstoragemgmt-***@lists.sourceforge.net>\fR
-.SH AUTHOR
-Tony Asleson \fI<***@redhat.com>\fR
-.br
-Gris Ge \fI<***@redhat.com>\fR
diff --git a/doc/man/lsmd.1.in b/doc/man/lsmd.1.in
deleted file mode 100644
index a215ad0..0000000
--- a/doc/man/lsmd.1.in
+++ /dev/null
@@ -1,26 +0,0 @@
-.TH LSMD "1" "March 2013" "lsmd @VERSION@" "libStorageMgmt plug-in daemon"
-.SH NAME
-Daemon \- lsmd
-.SH DESCRIPTION
-libStorageMgmt plug\-in daemon. Plug-ins execute in their own process space
-for fault isolation and to accommodate different plug\-in licensing
-requirements. Runs as an unprivileged user.
-
-.SH OPTIONS
-\fB\-\-plugindir\fR = The directory where the plugins are located
-.HP
-\fB\-\-socketdir\fR = The directory for IPC sockets
-.HP
-\fB\-v\fR
-= Verbose logging
-.TP
-\fB\-d\fR
-= New style daemon (systemd) non-forking
-
-
-.SH BUGS
-Please report bugs to
-<libstoragemgmt\-***@lists.sourceforge.net>
-.SH AUTHOR
-Tony Asleson <***@redhat.com>
-
diff --git a/doc/man/lsmd.conf.5.in b/doc/man/lsmd.conf.5.in
deleted file mode 100644
index 894789b..0000000
--- a/doc/man/lsmd.conf.5.in
+++ /dev/null
@@ -1,56 +0,0 @@
-.TH lsmd.conf "5" "January 2015" "lsmd.conf @VERSION@" "libStorageMgmt daemon config"
-.SH NAME
-lsmd.conf - libStorageMgmt daemon lsmd configuration file.
-
-.SH DESCRIPTION
-The libStorageMgmt plugin daemon (\fBlsmd\fR) will read the \fBlsmd.conf\fR
-file in the folder defined via \fB--confdir\fR (default is \fB/etc/lsm/\fR).
-
-The daemon reads the plugin configuration files from the sub-folder
-\fBpluginconf.d\fR. The plugin configuration file should be named as
-<uri_scheme>.conf, for example:
-
- * MegaRAID plugin (\fBmegaraid\fR://): \fBmegaraid.conf\fR
-
-The \fBlsmd.conf\fR file controls the global settings for \fBlsmd\fR while
-the plugin configuration file for each plugin controls individual plugin behavior.
-
-Each option line of the configuration file should contain a trailing
-semicolon(\fB;\fR).
-
-.SH lsmd.conf OPTIONS
-.TP
-\fBallow-plugin-root-privilege = true;\fR
-
-Indicates whether the \fBlsmd\fR daemon should keep running as root mode and invoke
-plugin as root user when needed.
-
-Without this option or with option set as \fBfalse\fR means that the daemon and
-the plugins will never run as root.
-
-Only when all the following requirements are met, will \fBlsmd\fR run specified
-plugins as root user:
-
- 1. "allow-plugin-root-privilege = true;" in lsmd.conf
- 2. "require-root-privilege = true;" in plugin config
- 3. API connection (or lsmcli) has root privileges
-
-.SH Plugin OPTIONS
-.TP
-\fBrequire-root-privilege = true;\fR
-
-Indicates plugin requires root privilege.
-Without this line or set as \fBfalse\fR, the plugin will never be invoked as root
-user by \fBlsmd\fR.
-
-Please check \fBlsmd.conf\fR option \fBallow-plugin-root-privilege\fR for
-detail.
-
-.SH SEE ALSO
-\fIlsmd (1)\fR
-
-.SH BUGS
-Please report bugs to
-<libstoragemgmt\-***@lists.sourceforge.net>
-.SH AUTHOR
-Gris Ge <***@redhat.com>
diff --git a/doc/man/megaraid_lsmplugin.1.in b/doc/man/megaraid_lsmplugin.1.in
deleted file mode 100644
index 27749b6..0000000
--- a/doc/man/megaraid_lsmplugin.1.in
+++ /dev/null
@@ -1,52 +0,0 @@
-.TH megaraid_lsmplugin "1" "Januray 2015" "megaraid_lsmplugin @VERSION@" "libStorageMgmt"
-.SH NAME
-megaraid_lsmplugin -- LibstorageMgmt MegaRAID plugin
-
-.SH DESCRIPTION
-LibstorageMgmt megaraid plugin allows user to manage LSI MegaRAID via vendor
-tool \fBstorcli\fR[1].
-The 'megaraid_lsmplugin' executable file is for libStorageMgmt
-daemon to execute when client user specifies megaraid plugin in the URI.
-
-Extra SELinux actions are required to allowing plugin access the hardware.
-
-.SH URI
-To use this plugin, users should set their URI to this format:
-.nf
-
- \fBmegaraid://\fR
- or
- \fBmegaraid://?storcli=<path_of_storcli>\fR
-
-.fi
-
-.TP storcli
-The 'storcli' URI parameter is used to specified the path of storcli tool.
-By default, this plugin will try these paths used by storcli rpm:
-\fB/opt/MegaRAID/storcli/storcli64\fR and \fB/opt/MegaRAID/storcli/storcli\fR.
-
-.SH ROOT PRIVILEGE
-This plugin requires both \fBlsmd\fR daemon and API client running as root
-user. Please check manpage \fIlsmd.conf (5)\fR for detail.
-
-.SH SUPPORTED HARDWARES
-Please refer to LSI website for hardware support status of storcli.
-Detailed support status can be queried via:
-
- * \fBlsm.Client.capabilities()\fR (Python API)
- * \fBlsm_capabilities()\fR (C API)
- * \fBlsmcli capabilities\fR (lsmcli command line).
-
-.SH FIREWALL RULES
-This plugin only execute \fBstorcli\fR on localhost. No network connection
-required.
-
-.SH SEE ALSO
-\fIlsmcli\fR(1), \fIlsmd\fR(1), [1] http://www.lsi.com
-
-.SH BUGS
-Please report bugs to
-\fI<libstoragemgmt-***@lists.sourceforge.net>\fR
-
-.SH AUTHOR
-Gris Ge \fI<***@redhat.com>\fR
diff --git a/examples/client_example.c b/examples/client_example.c
deleted file mode 100644
index 219e91a..0000000
--- a/examples/client_example.c
+++ /dev/null
@@ -1,75 +0,0 @@
-#include <stdio.h>
-#include <libstoragemgmt/libstoragemgmt.h>
-
-/*
- * If you have the development library package installed
- *
- * $ gcc -Wall client_example.c -lstoragemgmt -o client_example
- *
- *
- * If building out of source tree
- *
- * $ gcc -Wall -g -O0 client_example.c -I../c_binding/include/ \
- * -L../c_binding/.libs -lstoragemgmt -o client_example
- */
-
-void error(char *msg, int rc, lsm_error *e)
-{
- if( rc ) {
- printf("%s: error: %d\n", msg, rc);
-
- if( e && lsm_error_message_get(e) ) {
- printf("Msg: %s\n", lsm_error_message_get(e));
- lsm_error_free(e);
- }
- }
-}
-
-void list_pools(lsm_connect *c)
-{
- lsm_pool **pools = NULL;
- int rc = 0;
- uint32_t count = 0;
-
- rc = lsm_pool_list(c, NULL, NULL, &pools, &count, LSM_FLAG_RSVD);
- if( LSM_ERR_OK == rc ) {
- uint32_t i;
- for( i = 0; i < count; ++i) {
- printf("pool name: %s freespace: %"PRIu64"\n",
- lsm_pool_name_get(pools[i]),
- lsm_pool_free_space_get(pools[i]));
- }
-
- lsm_pool_record_array_free(pools, count);
- } else {
- error("Volume list", rc, lsm_error_last_get(c));
- }
-}
-
-int main()
-{
- lsm_connect *c = NULL;
- lsm_error *e = NULL;
- int rc = 0;
-
- const char *uri = "sim://";
-
- rc = lsm_connect_password(uri, NULL, &c, 30000, &e, LSM_FLAG_RSVD);
-
- if( LSM_ERR_OK == rc ) {
- printf("We connected...\n");
-
- list_pools(c);
-
- rc = lsm_connect_close(c, LSM_FLAG_RSVD);
- if( LSM_ERR_OK != rc ) {
- error("Close", rc, lsm_error_last_get(c));
- } else {
- printf("We closed\n");
- }
- } else {
- error("Connect", rc, e);
- }
-
- return rc;
-}
diff --git a/examples/plugin_example.c b/examples/plugin_example.c
deleted file mode 100644
index f516901..0000000
--- a/examples/plugin_example.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Web example.
- * https://sourceforge.net/p/libstoragemgmt/wiki/WritingPlugins/
- *
- *
- gcc -Wall -g -O0 plugin_example.c -I../include/ -L../src/.libs \
- -lstoragemgmt -o c_example_lsmplugin
- */
-
- #include <libstoragemgmt/libstoragemgmt_plug_interface.h>
- #include <stdlib.h>
- #include <stdint.h>
-
- static char name[] = "Simple limited plug-in example";
- static char version [] = "0.01";
-
- struct plugin_data {
- uint32_t tmo;
- /* All your other variables as needed */
- };
-
- /* Create the functions you plan on implementing that
- match the callback signatures */
- static int tmoSet(lsm_plugin_ptr c, uint32_t timeout, lsm_flag flags )
- {
- int rc = LSM_ERR_OK;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
- /* Do something with state to set timeout */
- pd->tmo = timeout;
- return rc;
- }
-
- static int tmoGet(lsm_plugin_ptr c, uint32_t *timeout, lsm_flag flags )
- {
- int rc = LSM_ERR_OK;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
- /* Do something with state to get timeout */
- *timeout = pd->tmo;
- return rc;
- }
-
- /* Setup the function addresses in the appropriate
- required callback structure */
- static struct lsm_mgmt_ops_v1 mgmOps = {
- tmoSet,
- tmoGet,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
- };
-
- int load( lsm_plugin_ptr c, const char *uri, const char *password,
- uint32_t timeout, lsm_flag flags )
- {
- /* Do plug-in specific init. and setup callback structures */
- struct plugin_data *data = (struct plugin_data *)
- malloc(sizeof(struct plugin_data));
-
- if (!data) {
- return LSM_ERR_NO_MEMORY;
- }
-
- /* Call back into the framework */
- int rc = lsm_register_plugin_v1( c, data, &mgmOps, NULL, NULL, NULL);
- return rc;
- }
-
- int unload( lsm_plugin_ptr c, lsm_flag flags)
- {
- /* Get a handle to your private data and do clean-up */
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
- free(pd);
- return LSM_ERR_OK;
- }
-
- int main(int argc, char *argv[] )
- {
- return lsm_plugin_init_v1(argc, argv, load, unload, name, version);
- }
diff --git a/libstoragemgmt.pc.in b/libstoragemgmt.pc.in
deleted file mode 100644
index 453d6d0..0000000
--- a/libstoragemgmt.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@/libstoragemgmt
-
-Name: libstoragemgmt
-Version: @VERSION@
-Description: Storage array management library
-Requires:
-Libs: -L${libdir} -lstoragemgmt @LIBS@
-Cflags: -I${includedir}
diff --git a/m4/README b/m4/README
deleted file mode 100644
index fefb9a1..0000000
--- a/m4/README
+++ /dev/null
@@ -1 +0,0 @@
-Directory for m4 macros.
diff --git a/m4/ax_python_module.m4 b/m4/ax_python_module.m4
deleted file mode 100644
index bd70a06..0000000
--- a/m4/ax_python_module.m4
+++ /dev/null
@@ -1,49 +0,0 @@
-# ===========================================================================
-# http://www.gnu.org/software/autoconf-archive/ax_python_module.html
-# ===========================================================================
-#
-# SYNOPSIS
-#
-# AX_PYTHON_MODULE(modname[, fatal])
-#
-# DESCRIPTION
-#
-# Checks for Python module.
-#
-# If fatal is non-empty then absence of a module will trigger an error.
-#
-# LICENSE
-#
-# Copyright (c) 2008 Andrew Collier <***@ukzn.ac.za>
-#
-# Copying and distribution of this file, with or without modification, are
-# permitted in any medium without royalty provided the copyright notice
-# and this notice are preserved. This file is offered as-is, without any
-# warranty.
-
-#serial 5
-
-AU_ALIAS([AC_PYTHON_MODULE], [AX_PYTHON_MODULE])
-AC_DEFUN([AX_PYTHON_MODULE],[
- if test -z $PYTHON;
- then
- PYTHON="python"
- fi
- PYTHON_NAME=`basename $PYTHON`
- AC_MSG_CHECKING($PYTHON_NAME module: $1)
- $PYTHON -c "import $1" 2>/dev/null
- if test $? -eq 0;
- then
- AC_MSG_RESULT(yes)
- eval AS_TR_CPP(HAVE_PYMOD_$1)=yes
- else
- AC_MSG_RESULT(no)
- eval AS_TR_CPP(HAVE_PYMOD_$1)=no
- #
- if test -n "$2"
- then
- AC_MSG_ERROR(failed to find required module $1)
- exit 1
- fi
- fi
-])
diff --git a/packaging/Makefile.am b/packaging/Makefile.am
deleted file mode 100644
index b44e6ca..0000000
--- a/packaging/Makefile.am
+++ /dev/null
@@ -1,5 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-EXTRA_DIST = libstoragemgmt.spec.in libstoragemgmt.spec
-
-SUBDIRS = daemon
diff --git a/packaging/daemon/Makefile.am b/packaging/daemon/Makefile.am
deleted file mode 100644
index 8f74349..0000000
--- a/packaging/daemon/Makefile.am
+++ /dev/null
@@ -1,13 +0,0 @@
-
-if HAVE_SYSTEMD
-
-systemdsystemunit_DATA = libstoragemgmt.service
-
-if WITH_REST_API
-systemdsystemunit_DATA += libstoragemgmt-rest.service
-endif
-
-endif
-
-EXTRA_DIST = libstoragemgmt.service lsm-tmpfiles.conf libstoragemgmtd
-EXTRA_DIST += libstoragemgmt-rest.service
diff --git a/packaging/daemon/libstoragemgmt-rest.service b/packaging/daemon/libstoragemgmt-rest.service
deleted file mode 100644
index fdd18bf..0000000
--- a/packaging/daemon/libstoragemgmt-rest.service
+++ /dev/null
@@ -1,13 +0,0 @@
-[Unit]
-Description=libstoragemgmt plug-in server daemon
-Requires=libstoragemgmt.service
-After=syslog.target
-
-[Service]
-ExecStart=/usr/bin/lsm_restd
-ExecReload=/bin/kill -HUP $MAINPID
-StandardError=syslog
-User=libstoragemgmt
-
-[Install]
-WantedBy=multi-user.target
diff --git a/packaging/daemon/libstoragemgmt.service b/packaging/daemon/libstoragemgmt.service
deleted file mode 100644
index 81a69ae..0000000
--- a/packaging/daemon/libstoragemgmt.service
+++ /dev/null
@@ -1,12 +0,0 @@
-[Unit]
-Description=libstoragemgmt plug-in server daemon
-After=syslog.target
-
-[Service]
-ExecStart=/usr/bin/lsmd -d
-ExecReload=/bin/kill -HUP $MAINPID
-StandardError=syslog
-User=root
-
-[Install]
-WantedBy=multi-user.target
diff --git a/packaging/daemon/libstoragemgmtd b/packaging/daemon/libstoragemgmtd
deleted file mode 100755
index c145789..0000000
--- a/packaging/daemon/libstoragemgmtd
+++ /dev/null
@@ -1,124 +0,0 @@
-#!/bin/bash
-#
-# chkconfig: 2345 99 1
-### BEGIN INIT INFO
-# Provides: libstoragemgmtd
-# Required-Start: $remote_fs $local_fs
-# Required-Stop: $remote_fs $local_fs
-# Default-Start: 2 3 4 5
-# Default-Stop: 0 1 6
-# Short-Description: libStorageMgmt plug-in daemon
-# Description: libStorageMgmt plug-in daemon
-### END INIT INFO
-
-. /etc/init.d/functions
-
-NAME=lsmd
-PROG=/usr/bin/$NAME
-PID=/var/run/lsm/lsmd.pid
-LOCK=/var/lock/subsys/libstoragemgmtd
-
-RETVAL=0
-STATUS=0
-
-if [ "`id -u`" != 0 ] ; then
- echo "Not root"
- exit 4
-fi
-
-check_dirs() {
- test -d /var/run/lsm || mkdir -p /var/run/lsm/ipc
- test -d /var/run/lsm/ipc || mkdir -p /var/run/lsm/ipc
-}
-
-status_lsm() {
- status -p $PID $NAME > /dev/null 2>&1
- STATUS=$?
-}
-
-result() {
- if [ $RETVAL -eq 0 ]; then
- success
- else
- failure
- fi
- echo
-}
-
-int_start() {
- $PROG
- RETVAL=$?
- [ $RETVAL -eq 0 ] && touch $LOCK && pidof $NAME > $PID
-}
-
-# See how we were called.
-case "$1" in
- start)
- status_lsm
- check_dirs
-
- echo -n "Starting $NAME daemon: "
-
- if [ $STATUS != 0 ] ; then
- int_start
- else
- RETVAL=$STATUS
- fi
-
- result
- ;;
- force-stop|stop)
- echo -n $"Stopping $NAME daemon: "
- status_lsm
- if [ $STATUS == 0 ] ; then
- killproc -p $PID $NAME -TERM
- RETVAL=$?
-
- if [ $RETVAL -eq 0 ]; then
- rm -f $LOCK
- rm -f $PID
- fi
- else
- RETVAL=0
- fi
-
- result
- ;;
- force-reload | reload)
- status_lsm
- check_dirs
- echo -n $"Reloading $NAME daemon: "
- if [ $STATUS == 0 ] ; then
- killproc -p $PID $NAME -HUP
- RETVAL=$?
- else
- int_start
- fi
-
- result
- ;;
- restart)
- status_lsm
- check_dirs
- echo -n $"Restarting $NAME daemon: "
- if [ $STATUS == 0 ] ; then
- killproc -p $PID $NAME -HUP
- else
- int_start
- fi
-
- result
- ;;
-
- status)
- status -p $PID $NAME
- RETVAL=$?
- ;;
-
- *)
- echo $"Usage: $0 {start|stop|restart|reload|status|force-stop}"
- ;;
-esac
-
-exit $RETVAL
-
diff --git a/packaging/daemon/lsm-tmpfiles.conf b/packaging/daemon/lsm-tmpfiles.conf
deleted file mode 100644
index 18d3b9b..0000000
--- a/packaging/daemon/lsm-tmpfiles.conf
+++ /dev/null
@@ -1,2 +0,0 @@
-D /var/run/lsm 0755 libstoragemgmt libstoragemgmt -
-D /var/run/lsm/ipc 0755 libstoragemgmt libstoragemgmt -
diff --git a/packaging/libstoragemgmt.spec.in b/packaging/libstoragemgmt.spec.in
deleted file mode 100644
index 72b81e8..0000000
--- a/packaging/libstoragemgmt.spec.in
+++ /dev/null
@@ -1,912 +0,0 @@
-%bcond_with rest_api
-%bcond_without megaraid
-%bcond_without hpsa
-%bcond_without test
-
-# Use one-line macro for OBS workaround:
-# https://bugzilla.novell.com/show_bug.cgi?id=864323
-%{?_with_rest_api: %global with_rest_api 1 }
-%{?_without_rest_api: %global with_rest_api 0 }
-
-%{?_with_megaraid: %global with_megaraid 1 }
-%{?_without_megaraid: %global with_megaraid 0 }
-
-%{?_with_hpsa: %global with_hpsa 1 }
-%{?_without_hpsa: %global with_hpsa 0 }
-
-%{?_with_test: %global with_test 1 }
-%{?_without_test: %global with_test 0 }
-
-%define libsoname libstoragemgmt
-
-%if 0%{?suse_version} || 0%{?fedora} >= 15 || 0%{?rhel} >= 7
-%define with_systemd 1
-%endif
-
-%global libstoragemgmt libstoragemgmt
-
-%if 0%{?suse_version}
-%global libstoragemgmt libstoragemgmt1
-%endif
-
-%define udev_dir /lib
-# Later versions moved /lib to /usr/lib
-%if 0%{?fedora} >= 18 || 0%{?rhel} >= 7 || 0%{?suse_version}
-%define udev_dir /usr/lib
-%endif
-
-%if 0%{?suse_version}
-# Use fdupes on openSuSE.
-# For Fedora, it will conflict with brp-python-bytecompile
-# For RHEL, fdupes is in EPEL repo.
-%define do_fdupes 1
-%endif
-
-Name: libstoragemgmt
-Version: @VERSION@
-Release: 1%{?dist}
-Summary: Storage array management library
-Group: System Environment/Libraries
-%if 0%{?suse_version}
-License: LGPL-2.1+
-%else
-License: LGPLv2+
-%endif
-URL: http://sourceforge.net/projects/libstoragemgmt/
-Source0: http://sourceforge.net/projects/libstoragemgmt/files/libstoragemgmt-%{version}.tar.gz
-BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
-Requires: %{libstoragemgmt}-python
-BuildRequires: autoconf automake libtool libxml2-devel check-devel perl
-BuildRequires: openssl-devel
-BuildRequires: python-argparse
-BuildRequires: glib2-devel
-# Explicitly require gcc-c++ is for OBS
-BuildRequires: gcc-c++
-BuildRequires: libconfig-devel
-%if 0%{?suse_version}
-BuildRequires: libyajl-devel
-%else
-# Fedora RHEL
-BuildRequires: yajl-devel
-%endif
-
-%if 0%{?do_fdupes}
-BuildRequires: fdupes
-%endif
-
-%if 0%{?rhel} == 6
-BuildRequires: python-ordereddict
-%else
-# Require bash-completion > 2.0
-BuildRequires: bash-completion >= 2.0
-%endif
-
-%if 0%{?with_systemd}
-BuildRequires: systemd
-Requires(post): systemd
-Requires(preun): systemd
-Requires(postun): systemd
-%endif
-
-%description
-The libStorageMgmt library will provide a vendor agnostic open source storage
-application programming interface (API) that will allow management of storage
-arrays. The library includes a command line interface for interactive use and
-scripting (command lsmcli). The library also has a daemon that is used for
-executing plug-ins in a separate process (lsmd).
-
-%if %{libstoragemgmt} != %{name}
-%package -n %{libstoragemgmt}
-Summary: Storage array management library
-Group: System Environment/Libraries
-Requires: %{libstoragemgmt}-python
-
-%description -n %{libstoragemgmt}
-The libStorageMgmt library will provide a vendor agnostic open source storage
-application programming interface (API) that will allow management of storage
-arrays. The library includes a command line interface for interactive use and
-scripting (command lsmcli). The library also has a daemon that is used for
-executing plug-ins in a separate process (lsmd).
-%endif
-
-%package devel
-Summary: Development files for %{name}
-Group: Development/Libraries
-Requires: %{name}%{?_isa} = %{version}-%{release}
-
-%description devel
-The %{name}-devel package contains libraries and header files for
-developing applications that use %{name}.
-
-%package -n %{libstoragemgmt}-python
-Summary: Python client libraries and plug-in support for %{libstoragemgmt}
-Group: System Environment/Libraries
-Requires: %{libstoragemgmt} = %{version}-%{release}
-BuildArch: noarch
-Requires: python-argparse
-%if 0%{?rhel} == 6
-# No way to detect 6.2 yet. Just forcing all RHEL 6 to install
-# python-ordereddict just in case.
-Requires: python-ordereddict
-%endif
-
-%description -n %{libstoragemgmt}-python
-The %{libstoragemgmt}-python package contains python client libraries as
-well as python framework support and open source plug-ins written in python.
-
-
-%package -n %{libstoragemgmt}-smis-plugin
-Summary: Files for SMI-S generic array support for %{libstoragemgmt}
-Group: System Environment/Libraries
-%if 0%{?suse_version}
-BuildRequires: python-pywbem
-Requires: python-pywbem
-%else
-BuildRequires: pywbem
-Requires: pywbem
-%endif
-Requires: %{libstoragemgmt}-python = %{version}-%{release}
-BuildArch: noarch
-
-%description -n %{libstoragemgmt}-smis-plugin
-The %{libstoragemgmt}-smis-plugin package contains plug-in for generic SMI-S
-array support.
-
-
-%package -n %{libstoragemgmt}-netapp-plugin
-Summary: Files for NetApp array support for %{libstoragemgmt}
-Group: System Environment/Libraries
-%if 0%{?suse_version}
-BuildRequires: python-M2Crypto
-Requires: python-M2Crypto
-%else
-BuildRequires: m2crypto
-Requires: m2crypto
-%endif
-Requires: %{libstoragemgmt}-python = %{version}-%{release}
-BuildArch: noarch
-
-%description -n %{libstoragemgmt}-netapp-plugin
-The %{libstoragemgmt}-netapp-plugin package contains plug-in for NetApp array
-support.
-
-
-%package -n %{libstoragemgmt}-targetd-plugin
-Summary: Files for targetd array support for %{libstoragemgmt}
-Group: System Environment/Libraries
-Requires: %{libstoragemgmt}-python = %{version}-%{release}
-BuildArch: noarch
-
-%description -n %{libstoragemgmt}-targetd-plugin
-The %{libstoragemgmt}-targetd-plugin package contains plug-in for targetd
-array support.
-
-
-%package -n %{libstoragemgmt}-nstor-plugin
-Summary: Files for NexentaStor array support for %{libstoragemgmt}
-Group: System Environment/Libraries
-Requires: %{libstoragemgmt}-python = %{version}-%{release}
-BuildArch: noarch
-
-%description -n %{libstoragemgmt}-nstor-plugin
-The %{libstoragemgmt}-nstor-plugin package contains plug-in for NexentaStor
-array support.
-
-%package udev
-Summary: Udev files for %{name}
-Group: System Environment/Base
-
-%description udev
-The %{name}-udev package contains udev rules and helper utilities for
-uevents generated by the kernel.
-
-%if 0%{?with_rest_api}
-%package -n %{libstoragemgmt}-rest
-Summary: REST API daemon for %{libstoragemgmt}
-Group: System Environment/Daemons
-Requires: %{libstoragemgmt}%{?_isa} = %{version}-%{release}
-BuildRequires: libmicrohttpd-devel
-%if 0%{?suse_version}
-BuildRequires: libjson-devel procps
-Requires: libjson0
-Requires: libmicrohttpd10
-%else
-# Fedora RHEL
-BuildRequires: json-c-devel
-Requires: json-c
-Requires: libmicrohttpd
-%endif
-
-%description -n %{libstoragemgmt}-rest
-the %{libstoragemgmt}-rest package contains the http daemon for
-%{libstoragemgmt} rest api.
-%endif
-
-
-%if 0%{?with_megaraid}
-%package -n %{libstoragemgmt}-megaraid-plugin
-Summary: Files for LSI MegaRAID support for %{libstoragemgmt}
-Group: System Environment/Libraries
-Requires: %{libstoragemgmt}%{?_isa} = %{version}-%{release}
-BuildArch: noarch
-
-%description -n %{libstoragemgmt}-megaraid-plugin
-The %{libstoragemgmt}-megaraid-plugin package contains the plugin for LSI
-MegaRAID storage management via storcli.
-%endif
-
-%if 0%{?with_hpsa}
-%package -n %{libstoragemgmt}-hpsa-plugin
-Summary: Files for HP SmartArray support for %{libstoragemgmt}
-Group: System Environment/Libraries
-Requires: %{libstoragemgmt}%{?_isa} = %{version}-%{release}
-BuildArch: noarch
-
-%description -n %{libstoragemgmt}-hpsa-plugin
-The %{libstoragemgmt}-hpsa-plugin package contains the plugin for HP
-SmartArray storage management via hpssacli.
-%endif
-
-%prep
-%setup -q
-
-%build
-./autogen.sh
-
-%configure \
-%if 0%{?with_rest_api} != 1
- --without-rest-api \
-%endif
-%if 0%{?with_megaraid} != 1
- --without-megaraid \
-%endif
-%if 0%{?with_hpsa} != 1
- --without-hpsa \
-%endif
- --disable-static
-
-V=1 make %{?_smp_mflags}
-
-%install
-rm -rf %{buildroot}
-make install DESTDIR=%{buildroot}
-find %{buildroot} -name '*.la' -exec rm -f {} ';'
-
-%if 0%{?with_systemd}
-install -d -m755 %{buildroot}/%{_unitdir}
-install -m644 packaging/daemon/libstoragemgmt.service \
- %{buildroot}/%{_unitdir}/libstoragemgmt.service
-
-#tempfiles.d configuration for /var/run
-mkdir -p %{buildroot}/%{_tmpfilesdir}
-install -m 0644 packaging/daemon/lsm-tmpfiles.conf \
- %{buildroot}/%{_tmpfilesdir}/%{name}.conf
-%else
-#Need these to exist at install so we can start the daemon
-mkdir -p %{buildroot}/etc/rc.d/init.d
-install packaging/daemon/libstoragemgmtd \
- %{buildroot}/etc/rc.d/init.d/libstoragemgmtd
-%endif
-
-#Files for udev handling
-mkdir -p %{buildroot}/%{udev_dir}/udev/rules.d
-install -m 644 tools/udev/90-scsi-ua.rules \
- %{buildroot}/%{udev_dir}/udev/rules.d/90-scsi-ua.rules
-install -m 755 tools/udev/scan-scsi-target \
- %{buildroot}/%{udev_dir}/udev/scan-scsi-target
-
-%if 0%{?with_rest_api}
-%if 0%{?with_systemd}
-%{__install} -m 0644 packaging/daemon/libstoragemgmt-rest.service \
- %{buildroot}/%{_unitdir}/libstoragemgmt-rest.service
-%endif
-%endif
-
-# Deduplication
-%if 0%{?do_fdupes}
-%fdupes -s %{buildroot}/%{python_sitelib}/lsm
-%endif
-
-%clean
-rm -rf %{buildroot}
-
-%if 0%{?with_test}
-%check
-if ! make check
-then
- cat test/test-suite.log || true
- exit 1
-fi
-%endif
-
-%pre -n %{libstoragemgmt}
-if [ $1 -eq 1 ]; then
- #New install.
- getent group libstoragemgmt >/dev/null || groupadd -r libstoragemgmt
- getent passwd libstoragemgmt >/dev/null || \
- useradd -r -g libstoragemgmt -d %{_localstatedir}/run/lsm \
- -s /sbin/nologin \
- -c "daemon account for libstoragemgmt" libstoragemgmt
- #Need these to exist at install so we can start the daemon
- mkdir -p %{_localstatedir}/run/lsm/ipc
- chmod 0755 %{_localstatedir}/run/lsm
- chmod 0755 %{_localstatedir}/run/lsm/ipc
- chown libstoragemgmt:libstoragemgmt %{_localstatedir}/run/lsm
- chown libstoragemgmt:libstoragemgmt %{_localstatedir}/run/lsm/ipc
-fi
-
-%post -n %{libstoragemgmt}
-/sbin/ldconfig
-%if 0%{?with_systemd}
-%if 0%{?suse_version}
- %service_add_post libstoragemgmt.service
-%else
- %systemd_post libstoragemgmt.service
-%endif
-%else
- /sbin/chkconfig --add libstoragemgmtd
-%endif
-
-%preun -n %{libstoragemgmt}
-%if 0%{?with_systemd}
-%if 0%{?suse_version}
- %service_del_preun libstoragemgmt.service
-%else
- %systemd_preun libstoragemgmt.service
-%endif
-%else
- /etc/rc.d/init.d/libstoragemgmtd stop > /dev/null 2>&1 || :
- /sbin/chkconfig --del libstoragemgmtd
-%endif
-
-%postun -n %{libstoragemgmt}
-/sbin/ldconfig
-%if 0%{?with_systemd}
-%if 0%{?suse_version}
- %service_del_postun libstoragemgmt.service
-%else
- %systemd_postun libstoragemgmt.service
-%endif
-%else
- #Restart the daemond
- /etc/rc.d/init.d/libstoragemgmtd restart >/dev/null 2>&1 || :
-%endif
-
-%if 0%{?with_rest_api}
-%post -n %{libstoragemgmt}-rest
-%if 0%{?with_systemd}
-%if 0%{?suse_version}
- %service_add_post libstoragemgmt-rest.service
-%else
- %systemd_post libstoragemgmt-rest.service
-%endif
-%endif
-
-%preun -n %{libstoragemgmt}-rest
-%if 0%{?with_systemd}
-%if 0%{?suse_version}
- %service_del_preun libstoragemgmt-rest.service
-%else
- %systemd_preun libstoragemgmt-rest.service
-%endif
-%endif
-
-%postun -n %{libstoragemgmt}-rest
-%if 0%{?with_systemd}
-%if 0%{?suse_version}
- %service_del_postun libstoragemgmt-rest.service
-%else
- %systemd_postun libstoragemgmt-rest.service
-%endif
-%endif
-%endif
-
-# Need to restart lsmd if plugin is new installed or removed.
-%post -n %{libstoragemgmt}-smis-plugin
-if [ $1 -eq 1 ]; then
- # New install.
- /usr/bin/systemctl try-restart libstoragemgmt.service \
- >/dev/null 2>&1 || :
-fi
-
-%postun -n %{libstoragemgmt}-smis-plugin
-if [ $1 -eq 0 ]; then
- # Remove
- /usr/bin/systemctl try-restart libstoragemgmt.service \
- >/dev/null 2>&1 || :
-fi
-
-# Need to restart lsmd if plugin is new installed or removed.
-%post -n %{libstoragemgmt}-netapp-plugin
-if [ $1 -eq 1 ]; then
- # New install.
- /usr/bin/systemctl try-restart libstoragemgmt.service \
- >/dev/null 2>&1 || :
-fi
-
-%postun -n %{libstoragemgmt}-netapp-plugin
-if [ $1 -eq 0 ]; then
- # Remove
- /usr/bin/systemctl try-restart libstoragemgmt.service \
- >/dev/null 2>&1 || :
-fi
-
-# Need to restart lsmd if plugin is new installed or removed.
-%post -n %{libstoragemgmt}-targetd-plugin
-if [ $1 -eq 1 ]; then
- # New install.
- /usr/bin/systemctl try-restart libstoragemgmt.service \
- >/dev/null 2>&1 || :
-fi
-
-%postun -n %{libstoragemgmt}-targetd-plugin
-if [ $1 -eq 0 ]; then
- # Remove
- /usr/bin/systemctl try-restart libstoragemgmt.service \
- >/dev/null 2>&1 || :
-fi
-
-# Need to restart lsmd if plugin is new installed or removed.
-%post -n %{libstoragemgmt}-nstor-plugin
-if [ $1 -eq 1 ]; then
- # New install.
- /usr/bin/systemctl try-restart libstoragemgmt.service \
- >/dev/null 2>&1 || :
-fi
-
-%postun -n %{libstoragemgmt}-nstor-plugin
-if [ $1 -eq 0 ]; then
- # Remove
- /usr/bin/systemctl try-restart libstoragemgmt.service \
- >/dev/null 2>&1 || :
-fi
-
-%if 0%{?with_megaraid}
-# Need to restart lsmd if plugin is new installed or removed.
-%post -n %{libstoragemgmt}-megaraid-plugin
-if [ $1 -eq 1 ]; then
- # New install.
- /usr/bin/systemctl try-restart libstoragemgmt.service \
- >/dev/null 2>&1 || :
-fi
-%postun -n %{libstoragemgmt}-megaraid-plugin
-if [ $1 -eq 0 ]; then
- # Remove
- /usr/bin/systemctl try-restart libstoragemgmt.service \
- >/dev/null 2>&1 || :
-fi
-%endif
-
-%if 0%{?with_hpsa}
-# Need to restart lsmd if plugin is new installed or removed.
-%post -n %{libstoragemgmt}-hpsa-plugin
-if [ $1 -eq 1 ]; then
- # New install.
- /usr/bin/systemctl try-restart libstoragemgmt.service \
- >/dev/null 2>&1 || :
-fi
-%postun -n %{libstoragemgmt}-hpsa-plugin
-if [ $1 -eq 0 ]; then
- # Remove
- /usr/bin/systemctl try-restart libstoragemgmt.service \
- >/dev/null 2>&1 || :
-fi
-%endif
-
-%files -n %{libstoragemgmt}
-%defattr(-,root,root,-)
-%doc README COPYING.LIB
-%{_mandir}/man1/lsmcli.1*
-%{_mandir}/man1/lsmd.1*
-%{_mandir}/man5/lsmd.conf.5*
-%{_libdir}/*.so.*
-%{_bindir}/lsmcli
-%{_bindir}/lsmd
-%{_bindir}/simc_lsmplugin
-%{_sysconfdir}/lsm/lsmd.conf
-%dir %{_sysconfdir}/lsm
-%dir %{_sysconfdir}/lsm/pluginconf.d
-
-%if 0%{?rhel} == 6
-%{_sysconfdir}/bash_completion.d/lsmcli
-%else
-%{_datadir}/bash-completion/completions/lsmcli
-%endif
-
-
-%if 0%{?with_systemd}
-%{_unitdir}/libstoragemgmt.service
-%endif
-
-%if 0%{?with_systemd}
-%attr(0644, root, root) %{_tmpfilesdir}/%{name}.conf
-%else
-%attr(0755, root, root) /etc/rc.d/init.d/libstoragemgmtd
-%endif
-
-%files devel
-%defattr(-,root,root,-)
-%{_includedir}/*
-%{_libdir}/*.so
-%{_libdir}/pkgconfig/libstoragemgmt.pc
-
-%files -n %{libstoragemgmt}-python
-%defattr(-,root,root,-)
-#Python library files
-%dir %{python_sitelib}/lsm
-%{python_sitelib}/lsm/__init__.*
-%dir %{python_sitelib}/lsm/external
-%{python_sitelib}/lsm/external/*
-%{python_sitelib}/lsm/_client.*
-%{python_sitelib}/lsm/_common.*
-%{python_sitelib}/lsm/_data.*
-%{python_sitelib}/lsm/_iplugin.*
-%{python_sitelib}/lsm/_pluginrunner.*
-%{python_sitelib}/lsm/_transport.*
-%{python_sitelib}/lsm/version.*
-%dir %{python_sitelib}/lsm/plugin
-%{python_sitelib}/lsm/plugin/__init__.*
-%dir %{python_sitelib}/lsm/plugin/sim
-%{python_sitelib}/lsm/plugin/sim/__init__.*
-%{python_sitelib}/lsm/plugin/sim/simulator.*
-%{python_sitelib}/lsm/plugin/sim/simarray.*
-%dir %{python_sitelib}/lsm/lsmcli
-%{python_sitelib}/lsm/lsmcli/__init__.*
-%{python_sitelib}/lsm/lsmcli/data_display.*
-%{python_sitelib}/lsm/lsmcli/cmdline.*
-%{_bindir}/sim_lsmplugin
-%{_sysconfdir}/lsm/pluginconf.d/sim.conf
-
-%files -n %{libstoragemgmt}-smis-plugin
-%defattr(-,root,root,-)
-%dir %{python_sitelib}/lsm/plugin/smispy
-%{python_sitelib}/lsm/plugin/smispy/__init__.*
-%{python_sitelib}/lsm/plugin/smispy/smis.*
-%{python_sitelib}/lsm/plugin/smispy/dmtf.*
-%{python_sitelib}/lsm/plugin/smispy/utils.*
-%{python_sitelib}/lsm/plugin/smispy/smis_common.*
-%{python_sitelib}/lsm/plugin/smispy/smis_cap.*
-%{python_sitelib}/lsm/plugin/smispy/smis_sys.*
-%{python_sitelib}/lsm/plugin/smispy/smis_pool.*
-%{python_sitelib}/lsm/plugin/smispy/smis_disk.*
-%{python_sitelib}/lsm/plugin/smispy/smis_vol.*
-%{python_sitelib}/lsm/plugin/smispy/smis_ag.*
-%{_bindir}/smispy_lsmplugin
-
-%files -n %{libstoragemgmt}-netapp-plugin
-%defattr(-,root,root,-)
-%dir %{python_sitelib}/lsm/plugin/ontap
-%{python_sitelib}/lsm/plugin/ontap/__init__.*
-%{python_sitelib}/lsm/plugin/ontap/na.*
-%{python_sitelib}/lsm/plugin/ontap/ontap.*
-%{_bindir}/ontap_lsmplugin
-
-%files -n %{libstoragemgmt}-targetd-plugin
-%defattr(-,root,root,-)
-%dir %{python_sitelib}/lsm/plugin/targetd
-%{python_sitelib}/lsm/plugin/targetd/__init__.*
-%{python_sitelib}/lsm/plugin/targetd/targetd.*
-%{_bindir}/targetd_lsmplugin
-
-%files -n %{libstoragemgmt}-nstor-plugin
-%defattr(-,root,root,-)
-%dir %{python_sitelib}/lsm/plugin/nstor
-%{python_sitelib}/lsm/plugin/nstor/__init__.*
-%{python_sitelib}/lsm/plugin/nstor/nstor.*
-%{_bindir}/nstor_lsmplugin
-
-%if 0%{?with_megaraid}
-%files -n %{libstoragemgmt}-megaraid-plugin
-%defattr(-,root,root,-)
-%dir %{python_sitelib}/lsm/plugin/megaraid
-%{python_sitelib}/lsm/plugin/megaraid/__init__.*
-%{python_sitelib}/lsm/plugin/megaraid/megaraid.*
-%{python_sitelib}/lsm/plugin/megaraid/utils.*
-%{_bindir}/megaraid_lsmplugin
-%{_sysconfdir}/lsm/pluginconf.d/megaraid.conf
-%{_mandir}/man1/megaraid_lsmplugin.1*
-%endif
-
-%if 0%{?with_hpsa}
-%files -n %{libstoragemgmt}-hpsa-plugin
-%defattr(-,root,root,-)
-%dir %{python_sitelib}/lsm/plugin/hpsa
-%{python_sitelib}/lsm/plugin/hpsa/__init__.*
-%{python_sitelib}/lsm/plugin/hpsa/hpsa.*
-%{python_sitelib}/lsm/plugin/hpsa/utils.*
-%{_bindir}/hpsa_lsmplugin
-%{_sysconfdir}/lsm/pluginconf.d/hpsa.conf
-%{_mandir}/man1/hpsa_lsmplugin.1*
-%endif
-
-%files udev
-%defattr(-,root,root,-)
-%{udev_dir}/udev/scan-scsi-target
-%{udev_dir}/udev/rules.d/90-scsi-ua.rules
-
-%if 0%{?with_rest_api}
-%files -n %{libstoragemgmt}-rest
-%defattr(-,root,root,-)
-%{_bindir}/lsm_restd
-%if 0%{?with_systemd}
-%{_unitdir}/libstoragemgmt-rest.service
-%endif
-%endif
-
-%changelog
-* Thu Dec 4 2014 Tony Asleson <***@redhat.com> 1.1.0-1
-- Library adds:
-
- API Constants for new pool element types and plugin changes to support it
- * C constants:
- LSM_POOL_ELEMENT_TYPE_VOLUME_FULL, LSM_POOL_ELEMENT_TYPE_VOLUME_THIN
- * Py constants:
- Pool.ELEMENT_TYPE_VOLUME_FULL, Poll.ELEMENT_TYPE_THIN
-
- lsmcli:
- * lt - Alias for 'list --type target_ports'
- * Removed --init for volume-mask, it was broken for targetd (the only
- user) and instead of fixing we are going to improve targetd to support
- access groups in the next release
-
-- Numerous code improvements, including a big SMI-S plugin refactor,
- source code documentation corrections
-
-- Bug fix: Use correct default values for anonymous uid/gid in lsmcli
-- Bug fix: simc simulator not working for allowable NULL parameters for:
- * fs_child_dependency
- * fs_child_dependency_rm
- * fs_snapshot_restore
-- Bug fix: lsm_restd memory leak corrections
-- Bug fix: NetApp plugin, correctly set export path when caller specifies
- default in API
-- Bug fix: Add file locking to sim plugin to prevent concurrent modification
-- Bug fix: Consistently report common error conditions for NO_STATE_CHANGE,
- EXISTS_INITIATOR for all plugins
-- Bug fix: Number of bugs addressed in SMI-S plugin including:
- * EMC: Correct error path when replicating a volume with a duplicate
- volume name
- * HDS: Correctly create thinly provisioned volume on thinly provisioned
- pool
-
-* Sun Sep 7 2014 Tony Asleson <***@redhat.com> 1.0.0-1
-- Release version 1
-- Numerous constants re-naming & removing
-- Removed the pool create/delete until things work better,
- esp. WRT SMI-S
-- Added checks for initiator ID verification
-- Added checks for vpd 0x83 verification
-- Simplified error logging (removed domain & level)
-- Re-named functions for online,offline -> enable,disable
-- Always use objects instead of object ID in function
- params
-- Removed individual files from fs snapshot creation
-- Add unsupported actions for pools
-- lsm_capability_set_n uses a -1 to terminate list
-- Volume status removed, replaced with admin state
-- Removed ibmiv7k plugin
-- Explicitly specify python2
-- Error path consistency changes (same error for same condition
- across plug-ins)
-- Numerous bug fixes
-
-* Thu Jul 3 2014 Tony Asleson <***@redhat.com> 0.1.0-1
-- Release candidate for a 1.0.0 release
-- Optional data removed
-- Initiator only functions removed
-- Pool create from from volumes removed
-- Code directory structure updated
-- Target port listing added
-
-* Tue Feb 18 2014 Gris Ge <***@redhat.com> 0.0.24-2
-- Introduce a REST daemon(only for systemd yet).
-- Allowing enable/disable ibm_v7k plugin via 'rpmbuild --with ibm_v7k' or
- 'rpmbuild --without ibm_v7k'.
-- Fix the compile warning about data of changelog by changing
- 'Thu Nov 27 2013' to 'Wed Nov 27 2013'.
-
-* Thu Jan 30 2014 Tony Asleson <***@redhat.com> 0.0.24-1
-- Command line interface (CLI) re-factored and improved to be easier to use
- and more consistent, man pages have been updated
-- Command line output now has '-s, --script' for an additional way to output
- information for consumption in scripts
-- Command line option '-o' for retrieving optional/extended data for disks &
- pools
-- Pool creation/deleting in CLI & python API
-- Numerous small bug fixes
-- C API, added ability to list disks, list plugins and retrieve optional
- data for disks
-- SSL for SMI-S is more stringent on certificate checking for newer
- distributions, new URI option "no_ssl_verify=yes" to disable
-
-* Wed Nov 27 2013 Tony Asleson <***@redhat.com> 0.0.23-1
-- Addition of listing disks implemented for SMI-S and Ontap plugins
- (new, not in C library yet)
-- Add the ability to list currently installed and usable plug-ins
-- Verify return types are correct in python client calls
-- Added the ability to retrieve optional data (new, not in C library yet)
-- Visibility reductions for python code (somethings were public when should be
- private
-- Add calls to create/delete pools (new, not in C library yet)
-- Add missing initiator type for SAS
-- Improved vpd83 retrieval for SMI-S
-- Performance improvements for SMI-S plug-in
-- Numerous small bug fixes
-- Nstor plugin, additional testing and bug fixes
-- lsmd, added call to setgroups and enable full relo and PIE (ASLR) for
- security improvements
-- simulator state is now versioned
-- SCSI Unit Attention uevent handling
-
-* Mon Aug 12 2013 Tony Asleson <***@redhat.com> 0.0.22-1
-- Numerous code improvments/fixes
-- BZ 968384
-- BZ 990577
-
-* Tue Jul 16 2013 Tony Asleson <***@redhat.com> 0.0.21-1
-- Don't include IBM7K plugin for RHEL > 6 missing paramakio
-- IEC binary size handling
-- Functionality improvements for IBM V7K array
-- Workaround for python bug on F19
-- Bugfix (BZ 968384)
-- Package plug-ins as separately in rpm packages
-
-* Fri May 24 2013 Tony Asleson <***@redhat.com> 0.0.20-1
-- Python library files now in separate rpm
-- Additional debug for plug-ins when exceptions occur
-- iSCSI CHAP support modified to handle both inbound and outbound authentication
-- VOLUME_THIN Added as new capability flag
-- IBM V7000 storage array support
-- NFS export support for targetd
-- EXPORT_CUSTOM_PATH added capability flag
-
-* Sat Apr 20 2013 Tony Asleson <***@redhat.com> 0.0.19-1
-- Improved E-Series array support
-- Ontap plug-in: improve performance with many Volumes
-- lsmcli: Number of corrections on handling unit specifiers
-- lsmcli: Correct stack track when stdout is written to while closed
-- Fix build to work with automake >= 1.12
-
-* Thu Mar 7 2013 Tony Asleson <***@redhat.com> 0.0.18-1
-- lsmd: Re-written in C
-- Simplify fs_delete
-- Corrections for C client against Python plugin
-- Testing: Run cross language unit test too
-- Initial FS support for targetd plugin
-- Fix multi-arch python issues which prevent py and compiled py files
- from being identical on different arches
-
-* Thu Jan 31 2013 Tony Asleson <***@redhat.com> 0.0.17-1
-- Inconsistency corrections between C and Python API
-- Source code documentation updates
-- NexentaStor plug-in has been added
-
-* Wed Jan 2 2013 Tony Asleson <***@redhat.com> 0.0.16-1
-- lsmcli: Add confirmation prompt for data loss operations
-- lsmcli: Display enumerated values as text
-- lsmcli: Exit with 7 for --job-status when not complete
-- Fixed URI example to reference an existing plug-in
-- lsmcli: Retrieve plug-in desc. and version (lsmcli --plugin-info)
-- simc: Implement CHAP auth function (no-op)
-- lsmcli: Change check for determining if lsmd is running
-- Disable mirroring for SMI-S as it needs some re-work
-
-* Mon Nov 19 2012 Tony Asleson <***@redhat.com> 0.0.15-1
-- Pool parameter is optional when replicating a volume
-- Code improvements(Memory leak fix, lsmcli checks if lsmd is running)
-- Source code documentation updates
-- Ability to override simulator data storage location
-- make check target added to run unit tests
-
-* Fri Oct 19 2012 Tony Asleson <***@redhat.com> 0.0.14-1
-- test/cmdline.py added to automatically test what an array supports
-- Bug fixes (local plug-in execution, smi-s delete clone, code warnings)
-- targetd: (uri syntax consistency change, initialization code change)
-- Pool id added to volume information
-- lsmcli: Added --replicate-volume-range-block-size <system id> to retrieve
- replicated block size
-
-* Fri Sep 28 2012 Tony Asleson (Red Hat) <***@redhat.com> 0.0.13-1
-- targetD Feature adds/fixes for initiators, init_granted_to_volume,
- volumes_accessible_by_init, initiator_grant, initiator_revoke
-- SMI-S added compatibility with CIM_StorageConfigurationService
-- SMI-S bug fixes/changes to support XIV arrays (Basic functionality verified)
-- SMI-S Proxy layer added to allow different internal implementations of smi-s
- client
-- Added missing version information for C plug-in API
-- lsmcli URI can be stored in file .lsmcli in users home directory
-
-* Fri Sep 07 2012 Tony Asleson (Red Hat) <***@redhat.com> 0.0.12-1
-- SMI-S plug-in enhancements (Detach before delete, bug fixes for eSeries)
-- Added version specifier for non-opaque structs in plug-in callback interface
-- Documentation updates (doxygen, man pages)
-- Ontap plug-in: support timeout values
-- lsmcli, return back async. values other than volumes when using --job-status
-
-* Mon Aug 13 2012 Tony Asleson <***@redhat.com> 0.0.11-1
-- SMI-S fixes and improvements (WaitForCopyState, _get_class_instance)
-- Methods for arrays that don't support access groups to grant access
- for luns to initiators etc.
-- ISCSI Chap authentication
-- System level status field for overall array status
-- targetd updates for mapping targets to initiators
-- Simulator updates (python & C)
-- Removed tog-pegasus dependency (SMI-S is python plug-in)
-- Removed lsmVolumeStatus as it was implemented and redundant
-- initscript, check for /var/run and create if missing
-
-* Fri Jul 20 2012 Tony Asleson <***@redhat.com> 0.0.10-1
-- Numerous updates and re-name for plug-in targetd_lsmplugin
-- targetd_lsmplugin included in release
-- Memory leak fixes and improved unit tests
-- Initial capability query support, implemented for all plug-ins
-- Flags variable added to API calls, (Warning: C API/ABI breakage, python
- unaffected)
-- Bug fixes for NetApp ontap plug-in
-- SMI-S bug fixes (initiator listing and replication, mode and sync types)
-- Added ability to specify mirroring async or sync for replication
-- Added version header file to allow client version header checks
-- Simulator plug-in written in C, simc_lsmplugin is available
-
-* Tue Jun 12 2012 Tony Asleson <***@redhat.com> 0.0.9-1
-- Initial checkin of lio plug-in
-- System filtering via URI (smispy)
-- Error code mapping (ontap)
-- Fixed build so same build tarball is used for all binaries
-
-* Mon Jun 4 2012 Tony Asleson <***@redhat.com> 0.0.8-1
-- Make building of SMI-S CPP plugin optional
-- Add pkg-config file
-- SMIS: Fix exception while retrieving Volumes
-- SMIS: Fix exception while retrieving Volumes
-- lsm: Add package imports
-- Make Smis class available in lsm python package
-- Add option to disable building C unit test
-- Make simulator classes available in lsm python package
-- Make ontap class available in lsm python package
-- Changes to support building on Fedora 17 (v2)
-- Spec. file updates from feedback from T. Callaway (spot)
-- F17 linker symbol visibility correction
-- Remove unneeded build dependencies and cleaned up some warnings
-- C Updates, client C library feature parity with python
-
-* Fri May 11 2012 Tony Asleson <***@redhat.com> 0.0.7-1
-- Bug fix for smi-s constants
-- Display formatting improvements
-- Added header option for lsmcli
-- Improved version handling for builds
-- Made terminology consistent
-- Ability to list visibility for access groups and volumes
-- Simulator plug-in fully supports all block operations
-- Added support for multiple systems with a single plug-in instance
-
-* Fri Apr 20 2012 Tony Asleson <***@redhat.com> 0.0.6-1
-- Documentation improvements (man & source code)
-- Support for access groups
-- Unified spec files Fedora/RHEL
-- Package version auto generate
-- Rpm target added to make
-- Bug fix for missing optional property on volume retrieval (smispy plug-in)
-
-* Fri Apr 6 2012 Tony Asleson <***@redhat.com> 0.0.5-1
-- Spec file clean-up improvements
-- Async. operation added to lsmcli and ability to check on job status
-- Sub volume replication support
-- Ability to check for child dependencies on VOLUMES, FS and files
-- SMI-S Bug fixes and improvements
-
-* Mon Mar 26 2012 Tony Asleson <***@redhat.com> 0.0.4-1
-- Restore from snapshot
-- Job identifiers string instead of integer
-- Updated license address
-
-* Wed Mar 14 2012 Tony Asleson <***@redhat.com> 0.0.3-1
-- Changes to installer, daemon uid, gid, /var/run/lsm/*
-- NFS improvements and bug fixes
-- Python library clean up (rpmlint errors)
-
-* Sun Mar 11 2012 Tony Asleson <***@redhat.com> 0.0.2-1
-- Added NetApp native plugin
-
-* Mon Feb 6 2012 Tony Asleson <***@redhat.com> 0.0.1alpha-1
-- Initial version of package
diff --git a/plugin/Makefile.am b/plugin/Makefile.am
deleted file mode 100644
index 3c35fa4..0000000
--- a/plugin/Makefile.am
+++ /dev/null
@@ -1,48 +0,0 @@
-SUBDIRS=simc megaraid hpsa
-
-plugindir = $(pythondir)/lsm/plugin
-
-plugin_PYTHON= __init__.py
-
-simdir = $(plugindir)/sim
-sim_PYTHON = \
- sim/__init__.py \
- sim/simulator.py \
- sim/simarray.py
-
-targetddir = $(plugindir)/targetd
-targetd_PYTHON = \
- targetd/__init__.py \
- targetd/targetd.py
-
-ontapdir = $(plugindir)/ontap
-ontap_PYTHON = \
- ontap/__init__.py \
- ontap/ontap.py \
- ontap/na.py
-
-smispydir = $(plugindir)/smispy
-smispy_PYTHON = \
- smispy/__init__.py \
- smispy/smis.py \
- smispy/utils.py \
- smispy/smis_common.py \
- smispy/dmtf.py \
- smispy/smis_cap.py \
- smispy/smis_sys.py \
- smispy/smis_pool.py \
- smispy/smis_disk.py \
- smispy/smis_ag.py \
- smispy/smis_vol.py
-
-nstordir = $(plugindir)/nstor
-nstor_PYTHON = \
- nstor/__init__.py \
- nstor/nstor.py
-
-dist_bin_SCRIPTS= \
- sim/sim_lsmplugin \
- smispy/smispy_lsmplugin \
- nstor/nstor_lsmplugin \
- ontap/ontap_lsmplugin \
- targetd/targetd_lsmplugin
diff --git a/plugin/__init__.py b/plugin/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/plugin/hpsa/Makefile.am b/plugin/hpsa/Makefile.am
deleted file mode 100644
index 3076cbc..0000000
--- a/plugin/hpsa/Makefile.am
+++ /dev/null
@@ -1,8 +0,0 @@
-if WITH_HPSA
-plugindir = $(pythondir)/lsm/plugin
-hpsadir = $(plugindir)/hpsa
-
-hpsa_PYTHON = __init__.py hpsa.py utils.py
-
-dist_bin_SCRIPTS= hpsa_lsmplugin
-endif
diff --git a/plugin/hpsa/__init__.py b/plugin/hpsa/__init__.py
deleted file mode 100644
index 61332b4..0000000
--- a/plugin/hpsa/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from lsm.plugin.hpsa.hpsa import SmartArray
diff --git a/plugin/hpsa/hpsa.py b/plugin/hpsa/hpsa.py
deleted file mode 100644
index 76eb4a7..0000000
--- a/plugin/hpsa/hpsa.py
+++ /dev/null
@@ -1,533 +0,0 @@
-# Copyright (C) 2015 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: Gris Ge <***@redhat.com>
-
-import os
-import errno
-import re
-
-from lsm import (
- IPlugin, Client, Capabilities, VERSION, LsmError, ErrorNumber, uri_parse,
- System, Pool, size_human_2_size_bytes, search_property, Volume, Disk)
-
-from lsm.plugin.hpsa.utils import cmd_exec, ExecError, file_read
-
-
-def _handle_errors(method):
- def _wrapper(*args, **kwargs):
- try:
- return method(*args, **kwargs)
- except LsmError:
- raise
- except KeyError as key_error:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "Expected key missing from SmartArray hpssacli output:%s" %
- key_error)
- except ExecError as exec_error:
- if 'No controllers detected' in exec_error.stdout:
- raise LsmError(
- ErrorNumber.NOT_FOUND_SYSTEM,
- "No HP SmartArray deteceted by hpssacli.")
- else:
- raise LsmError(ErrorNumber.PLUGIN_BUG, str(exec_error))
- except Exception as common_error:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "Got unexpected error %s" % common_error)
-
- return _wrapper
-
-
-def _sys_status_of(hp_ctrl_status):
- """
- Base on data of "hpssacli ctrl all show status"
- """
- status_info = ''
- status = System.STATUS_UNKNOWN
- check_list = [
- 'Controller Status', 'Cache Status', 'Battery/Capacitor Status']
- for key_name in check_list:
- if key_name in hp_ctrl_status and hp_ctrl_status[key_name] != 'OK':
- # TODO(Gris Ge): Beg HP for possible values
- status = System.STATUS_OTHER
- status_info += hp_ctrl_status[key_name]
-
- if status != System.STATUS_OTHER:
- status = System.STATUS_OK
-
- return status, status_info
-
-
-def _parse_hpssacli_output(output):
- """
- Got a output string of hpssacli to dictionary(nested).
- Skipped these line:
- 1. Starts with 'Note:'
- This is just a message right after controller. We don't neet it
- yet.
- 2. The 'Physical Drives' line.
- It should indented after 'Internal Drive Cage' like.
- If not ignored, we might got duplication line error.
- After ignored, it's phsycial disks will directly stored as
- key of 'Internal Drive Cage' dictionary.
- """
- output_lines = [
- l for l in output.split("\n")
- if l and not l.startswith('Note:') and
- not l.strip() == 'Physical Drives']
-
- data = {}
-
- # Detemine indention level
- top_indention_level = sorted(
- set(
- len(line) - len(line.lstrip())
- for line in output_lines))[0]
-
- indent_2_data = {
- top_indention_level: data
- }
-
- for line_num in range(len(output_lines)):
- cur_line = output_lines[line_num]
- if cur_line.strip() == 'None attached':
- continue
- if line_num + 1 == len(output_lines):
- nxt_line = ''
- else:
- nxt_line = output_lines[line_num + 1]
-
- cur_indent_count = len(cur_line) - len(cur_line.lstrip())
- nxt_indent_count = len(nxt_line) - len(nxt_line.lstrip())
-
- cur_line_splitted = cur_line.split(": ")
- cur_data_pointer = indent_2_data[cur_indent_count]
-
- if nxt_indent_count > cur_indent_count:
- nxt_line_splitted = nxt_line.split(": ")
- new_data = {}
-
- if cur_line.lstrip() not in cur_data_pointer:
- cur_data_pointer[cur_line.lstrip()] = new_data
- indent_2_data[nxt_indent_count] = new_data
- else:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "_parse_hpssacli_output(): Found duplicate line %s" %
- cur_line)
- else:
- if len(cur_line_splitted) == 1:
- cur_data_pointer[cur_line.lstrip()] = None
- else:
- cur_data_pointer[cur_line_splitted[0].lstrip()] = \
- ": ".join(cur_line_splitted[1:]).strip()
- return data
-
-
-def _hp_size_to_lsm(hp_size):
- """
- HP Using 'TB, GB, MB, KB' and etc, for LSM, they are 'TiB' and etc.
- Return int of block bytes
- """
- re_regex = re.compile("^([0-9.]+) +([EPTGMK])B$")
- re_match = re_regex.match(hp_size)
- if re_match:
- return size_human_2_size_bytes(
- "%s%siB" % (re_match.group(1), re_match.group(2)))
-
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "_hp_size_to_lsm(): Got unexpected HP size string %s" %
- hp_size)
-
-
-def _pool_status_of(hp_array):
- """
- Return (status, status_info)
- """
- if hp_array['Status'] == 'OK':
- return Pool.STATUS_OK, ''
- else:
- # TODO(Gris Ge): Try degrade a RAID or fail a RAID.
- return Pool.STATUS_OTHER, hp_array['Status']
-
-
-def _pool_id_of(sys_id, array_name):
- return "%s:%s" % (sys_id, array_name.replace(' ', ''))
-
-
-def _disk_type_of(hp_disk):
- disk_interface = hp_disk['Interface Type']
- if disk_interface == 'SATA':
- return Disk.TYPE_SATA
- elif disk_interface == 'Solid State SATA':
- return Disk.TYPE_SSD
- elif disk_interface == 'SAS':
- return Disk.TYPE_SAS
-
- return Disk.TYPE_UNKNOWN
-
-
-def _disk_status_of(hp_disk, flag_free):
- # TODO(Gris Ge): Need more document or test for non-OK disks.
- if hp_disk['Status'] == 'OK':
- disk_status = Disk.STATUS_OK
- else:
- disk_status = Disk.STATUS_OTHER
-
- if flag_free:
- disk_status |= Disk.STATUS_FREE
-
- return disk_status
-
-
-def _hp_raid_type_to_lsm(hp_ld):
- """
- Based on this property:
- Fault Tolerance: 0/1/5/6/1+0
- """
- hp_raid_level = hp_ld['Fault Tolerance']
- if hp_raid_level == '0':
- return Volume.RAID_TYPE_RAID0
- elif hp_raid_level == '1':
- # TODO(Gris Ge): Investigate whether HP has 4 disks RAID 1.
- # In LSM, that's RAID10.
- return Volume.RAID_TYPE_RAID1
- elif hp_raid_level == '5':
- return Volume.RAID_TYPE_RAID5
- elif hp_raid_level == '6':
- return Volume.RAID_TYPE_RAID6
- elif hp_raid_level == '1+0':
- return Volume.RAID_TYPE_RAID10
-
- return Volume.RAID_TYPE_UNKNOWN
-
-
-class SmartArray(IPlugin):
- _DEFAULT_BIN_PATHS = [
- "/usr/sbin/hpssacli", "/opt/hp/hpssacli/bld/hpssacli"]
-
- def __init__(self):
- self._sacli_bin = None
-
- def _find_sacli(self):
- """
- Try _DEFAULT_MDADM_BIN_PATHS
- """
- for cur_path in SmartArray._DEFAULT_BIN_PATHS:
- if os.path.lexists(cur_path):
- self._sacli_bin = cur_path
-
- if not self._sacli_bin:
- raise LsmError(
- ErrorNumber.INVALID_ARGUMENT,
- "SmartArray sacli is not installed correctly")
-
- @_handle_errors
- def plugin_register(self, uri, password, timeout, flags=Client.FLAG_RSVD):
- if os.geteuid() != 0:
- raise LsmError(
- ErrorNumber.INVALID_ARGUMENT,
- "This plugin requires root privilege both daemon and client")
- uri_parsed = uri_parse(uri)
- self._sacli_bin = uri_parsed.get('parameters', {}).get('hpssacli')
- if not self._sacli_bin:
- self._find_sacli()
-
- self._sacli_exec(['version'], flag_convert=False)
-
- @_handle_errors
- def plugin_unregister(self, flags=Client.FLAG_RSVD):
- pass
-
- @_handle_errors
- def job_status(self, job_id, flags=Client.FLAG_RSVD):
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported yet")
-
- @_handle_errors
- def job_free(self, job_id, flags=Client.FLAG_RSVD):
- pass
-
- @_handle_errors
- def plugin_info(self, flags=Client.FLAG_RSVD):
- return "HP SmartArray Plugin", VERSION
-
- @_handle_errors
- def time_out_set(self, ms, flags=Client.FLAG_RSVD):
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported yet")
-
- @_handle_errors
- def time_out_get(self, flags=Client.FLAG_RSVD):
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported yet")
-
- @_handle_errors
- def capabilities(self, system, flags=Client.FLAG_RSVD):
- cur_lsm_syss = self.systems()
- if system.id not in list(s.id for s in cur_lsm_syss):
- raise LsmError(
- ErrorNumber.NOT_FOUND_SYSTEM,
- "System not found")
- cap = Capabilities()
- cap.set(Capabilities.VOLUMES)
- cap.set(Capabilities.DISKS)
- cap.set(Capabilities.VOLUME_RAID_INFO)
- return cap
-
- def _sacli_exec(self, sacli_cmds, flag_convert=True):
- """
- If flag_convert is True, convert data into dict.
- """
- sacli_cmds.insert(0, self._sacli_bin)
- try:
- output = cmd_exec(sacli_cmds)
- except OSError as os_error:
- if os_error.errno == errno.ENOENT:
- raise LsmError(
- ErrorNumber.INVALID_ARGUMENT,
- "hpssacli binary '%s' is not exist or executable." %
- self._sacli_bin)
- else:
- raise
-
- if flag_convert:
- return _parse_hpssacli_output(output)
- else:
- return output
-
- @_handle_errors
- def systems(self, flags=0):
- """
- Depend on command:
- hpssacli ctrl all show detail
- hpssacli ctrl all show status
- """
- rc_lsm_syss = []
- ctrl_all_show = self._sacli_exec(
- ["ctrl", "all", "show", "detail"])
- ctrl_all_status = self._sacli_exec(
- ["ctrl", "all", "show", "status"])
-
- for ctrl_name in ctrl_all_show.keys():
- ctrl_data = ctrl_all_show[ctrl_name]
- sys_id = ctrl_data['Serial Number']
- (status, status_info) = _sys_status_of(ctrl_all_status[ctrl_name])
-
- plugin_data = "%s" % ctrl_data['Slot']
-
- rc_lsm_syss.append(
- System(sys_id, ctrl_name, status, status_info, plugin_data))
-
- return rc_lsm_syss
-
- @staticmethod
- def _hp_array_to_lsm_pool(hp_array, array_name, sys_id, ctrl_num):
- pool_id = _pool_id_of(sys_id, array_name)
- name = array_name
- elem_type = Pool.ELEMENT_TYPE_VOLUME | Pool.ELEMENT_TYPE_VOLUME_FULL
- unsupported_actions = 0
- # TODO(Gris Ge): HP does not provide a precise number of bytes.
- free_space = _hp_size_to_lsm(hp_array['Unused Space'])
- total_space = free_space
- for key_name in hp_array.keys():
- if key_name.startswith('Logical Drive'):
- total_space += _hp_size_to_lsm(hp_array[key_name]['Size'])
-
- (status, status_info) = _pool_status_of(hp_array)
-
- plugin_data = "%s:%s" % (
- ctrl_num, array_name[len("Array: "):])
-
- return Pool(
- pool_id, name, elem_type, unsupported_actions,
- total_space, free_space, status, status_info,
- sys_id, plugin_data)
-
- @_handle_errors
- def pools(self, search_key=None, search_value=None,
- flags=Client.FLAG_RSVD):
- """
- Depend on command:
- hpssacli ctrl all show config detail
- """
- lsm_pools = []
- ctrl_all_conf = self._sacli_exec(
- ["ctrl", "all", "show", "config", "detail"])
- for ctrl_data in ctrl_all_conf.values():
- sys_id = ctrl_data['Serial Number']
- ctrl_num = ctrl_data['Slot']
- for key_name in ctrl_data.keys():
- if key_name.startswith("Array:"):
- lsm_pools.append(
- SmartArray._hp_array_to_lsm_pool(
- ctrl_data[key_name], key_name, sys_id, ctrl_num))
-
- return search_property(lsm_pools, search_key, search_value)
-
- @staticmethod
- def _hp_ld_to_lsm_vol(hp_ld, pool_id, sys_id, ctrl_num, array_num,
- hp_ld_name):
- ld_num = hp_ld_name[len("Logical Drive: "):]
- vpd83 = hp_ld['Unique Identifier'].lower()
- # No document or command output indicate block size
- # of volume. So we try to read from linux kernel, if failed
- # try 512 and roughly calculate the sector count.
- regex_match = re.compile("/dev/(sd[a-z]+)").search(hp_ld['Disk Name'])
- vol_name = hp_ld_name
- if regex_match:
- sd_name = regex_match.group(1)
- block_size = int(file_read(
- "/sys/block/%s/queue/logical_block_size" % sd_name))
- num_of_blocks = int(file_read("/sys/block/%s/size" % sd_name))
- vol_name += ": /dev/%s" % sd_name
- else:
- block_size = 512
- num_of_blocks = int(_hp_size_to_lsm(hp_ld['Size']) / block_size)
-
- plugin_data = "%s:%s:%s" % (ctrl_num, array_num, ld_num)
-
- # HP SmartArray does not allow disabling volume.
- return Volume(
- vpd83, vol_name, vpd83, block_size, num_of_blocks,
- Volume.ADMIN_STATE_ENABLED, sys_id, pool_id, plugin_data)
-
- @_handle_errors
- def volumes(self, search_key=None, search_value=None,
- flags=Client.FLAG_RSVD):
- """
- Depend on command:
- hpssacli ctrl all show config detail
- """
- lsm_vols = []
- ctrl_all_conf = self._sacli_exec(
- ["ctrl", "all", "show", "config", "detail"])
- for ctrl_data in ctrl_all_conf.values():
- ctrl_num = ctrl_data['Slot']
- sys_id = ctrl_data['Serial Number']
- for key_name in ctrl_data.keys():
- if not key_name.startswith("Array:"):
- continue
- pool_id = _pool_id_of(sys_id, key_name)
- array_num = key_name[len('Array: '):]
- for array_key_name in ctrl_data[key_name].keys():
- if not array_key_name.startswith("Logical Drive"):
- continue
- lsm_vols.append(
- SmartArray._hp_ld_to_lsm_vol(
- ctrl_data[key_name][array_key_name],
- pool_id, sys_id, ctrl_num, array_num,
- array_key_name))
-
- return search_property(lsm_vols, search_key, search_value)
-
- @staticmethod
- def _hp_disk_to_lsm_disk(hp_disk, sys_id, ctrl_num, key_name,
- flag_free=False):
- disk_id = hp_disk['Serial Number']
- disk_num = key_name[len("physicaldrive "):]
- disk_name = "%s %s" % (hp_disk['Model'], disk_num)
- disk_type = _disk_type_of(hp_disk)
- blk_size = int(hp_disk['Native Block Size'])
- blk_count = int(_hp_size_to_lsm(hp_disk['Size']) / blk_size)
- status = _disk_status_of(hp_disk, flag_free)
- plugin_data = "%s:%s" % (ctrl_num, disk_num)
-
- return Disk(
- disk_id, disk_name, disk_type, blk_size, blk_count,
- status, sys_id, plugin_data)
-
- @_handle_errors
- def disks(self, search_key=None, search_value=None,
- flags=Client.FLAG_RSVD):
- """
- Depend on command:
- hpssacli ctrl all show config detail
- """
- # TODO(Gris Ge): Need real test on spare disk.
- rc_lsm_disks = []
- ctrl_all_conf = self._sacli_exec(
- ["ctrl", "all", "show", "config", "detail"])
- for ctrl_data in ctrl_all_conf.values():
- sys_id = ctrl_data['Serial Number']
- ctrl_num = ctrl_data['Slot']
- for key_name in ctrl_data.keys():
- if key_name.startswith("Array:"):
- for array_key_name in ctrl_data[key_name].keys():
- if array_key_name.startswith("physicaldrive"):
- rc_lsm_disks.append(
- SmartArray._hp_disk_to_lsm_disk(
- ctrl_data[key_name][array_key_name],
- sys_id, ctrl_num, array_key_name,
- flag_free=False))
-
- if key_name == 'unassigned':
- for array_key_name in ctrl_data[key_name].keys():
- if array_key_name.startswith("physicaldrive"):
- rc_lsm_disks.append(
- SmartArray._hp_disk_to_lsm_disk(
- ctrl_data[key_name][array_key_name],
- sys_id, ctrl_num, array_key_name,
- flag_free=True))
-
- return search_property(rc_lsm_disks, search_key, search_value)
-
- @_handle_errors
- def volume_raid_info(self, volume, flags=Client.FLAG_RSVD):
- """
- Depend on command:
- hpssacli ctrl slot=0 show config detail
- """
- if not volume.plugin_data:
- raise LsmError(
- ErrorNumber.INVALID_ARGUMENT,
- "Ilegal input volume argument: missing plugin_data property")
-
- (ctrl_num, array_num, ld_num) = volume.plugin_data.split(":")
- ctrl_data = self._sacli_exec(
- ["ctrl", "slot=%s" % ctrl_num, "show", "config", "detail"]
- ).values()[0]
-
- disk_count = 0
- strip_size = Volume.STRIP_SIZE_UNKNOWN
- stripe_size = Volume.OPT_IO_SIZE_UNKNOWN
- raid_type = Volume.RAID_TYPE_UNKNOWN
- for key_name in ctrl_data.keys():
- if key_name != "Array: %s" % array_num:
- continue
- for array_key_name in ctrl_data[key_name].keys():
- if array_key_name == "Logical Drive: %s" % ld_num:
- hp_ld = ctrl_data[key_name][array_key_name]
- raid_type = _hp_raid_type_to_lsm(hp_ld)
- strip_size = _hp_size_to_lsm(hp_ld['Strip Size'])
- stripe_size = _hp_size_to_lsm(hp_ld['Full Stripe Size'])
- elif array_key_name.startswith("physicaldrive"):
- hp_disk = ctrl_data[key_name][array_key_name]
- if hp_disk['Drive Type'] == 'Data Drive':
- disk_count += 1
-
- if disk_count == 0:
- if strip_size == Volume.STRIP_SIZE_UNKNOWN:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "volume_raid_info(): Got logical drive %s entry, " %
- ld_num + "but no physicaldrive entry: %s" %
- ctrl_data.items())
-
- raise LsmError(
- ErrorNumber.NOT_FOUND_VOLUME,
- "Volume not found")
-
- return [raid_type, strip_size, disk_count, strip_size, stripe_size]
diff --git a/plugin/hpsa/hpsa_lsmplugin b/plugin/hpsa/hpsa_lsmplugin
deleted file mode 100755
index 07230f5..0000000
--- a/plugin/hpsa/hpsa_lsmplugin
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env python2
-# Copyright (C) 2015 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: tasleson
-# Gris Ge <***@redhat.com>
-
-import sys
-import syslog
-import traceback
-
-try:
- from lsm import PluginRunner
- from lsm.plugin.hpsa import SmartArray
-
- if __name__ == '__main__':
- PluginRunner(SmartArray, sys.argv).run()
-except Exception:
- #This should be quite rare, but when it does happen this is pretty
- #key in understanding what happened, especially when it happens when
- #running from the daemon.
- msg = str(traceback.format_exc())
- syslog.syslog(syslog.LOG_ERR, msg)
- sys.stderr.write(msg)
- sys.exit(1)
diff --git a/plugin/hpsa/utils.py b/plugin/hpsa/utils.py
deleted file mode 100644
index 92e27eb..0000000
--- a/plugin/hpsa/utils.py
+++ /dev/null
@@ -1,58 +0,0 @@
-## Copyright (C) 2015 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: Gris Ge <***@redhat.com>
-
-import subprocess
-import os
-
-
-def cmd_exec(cmds):
- """
- Execute provided command and return the STDOUT as string.
- Raise ExecError if command return code is not zero
- """
- cmd_popen = subprocess.Popen(
- cmds, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
- env={"PATH": os.getenv("PATH")})
- str_stdout = "".join(list(cmd_popen.stdout)).strip()
- str_stderr = "".join(list(cmd_popen.stderr)).strip()
- errno = cmd_popen.wait()
- if errno != 0:
- raise ExecError(" ".join(cmds), errno, str_stdout, str_stderr)
- return str_stdout
-
-
-def file_read(file_path):
- """
- Read file and return string of file content.
- """
- fd = open(file_path, 'r')
- content = fd.read()
- fd.close()
- return content
-
-
-class ExecError(Exception):
- def __init__(self, cmd, errno, stdout, stderr, *args, **kwargs):
- Exception.__init__(self, *args, **kwargs)
- self.cmd = cmd
- self.errno = errno
- self.stdout = stdout
- self.stderr = stderr
-
- def __str__(self):
- return "cmd: '%s', errno: %d, stdout: '%s', stderr: '%s'" % \
- (self.cmd, self.errno, self.stdout, self.stderr)
diff --git a/plugin/megaraid/Makefile.am b/plugin/megaraid/Makefile.am
deleted file mode 100644
index a4b6b1c..0000000
--- a/plugin/megaraid/Makefile.am
+++ /dev/null
@@ -1,8 +0,0 @@
-if WITH_MEGARAID
-plugindir = $(pythondir)/lsm/plugin
-megaraiddir = $(plugindir)/megaraid
-
-megaraid_PYTHON = __init__.py megaraid.py utils.py
-
-dist_bin_SCRIPTS= megaraid_lsmplugin
-endif
diff --git a/plugin/megaraid/__init__.py b/plugin/megaraid/__init__.py
deleted file mode 100644
index 8f4602c..0000000
--- a/plugin/megaraid/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from lsm.plugin.megaraid.megaraid import MegaRAID
diff --git a/plugin/megaraid/megaraid.py b/plugin/megaraid/megaraid.py
deleted file mode 100644
index 78603fc..0000000
--- a/plugin/megaraid/megaraid.py
+++ /dev/null
@@ -1,548 +0,0 @@
-# Copyright (C) 2015 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: Gris Ge <***@redhat.com>
-
-import os
-import json
-import re
-import errno
-
-from lsm import (uri_parse, search_property, size_human_2_size_bytes,
- Capabilities, LsmError, ErrorNumber, System, Client,
- Disk, VERSION, IPlugin, Pool, Volume)
-
-from lsm.plugin.megaraid.utils import cmd_exec, ExecError
-
-# Naming scheme
-# mega_sys_path /c0
-# mega_disk_path /c0/e64/s0
-
-
-def _handle_errors(method):
- def _wrapper(*args, **kwargs):
- try:
- return method(*args, **kwargs)
- except LsmError:
- raise
- except KeyError as key_error:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "Expected key missing from MegaRAID storcli output:%s" %
- key_error)
- except ExecError as exec_error:
- raise LsmError(ErrorNumber.PLUGIN_BUG, str(exec_error))
- except Exception as common_error:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "Got unexpected error %s" % common_error)
-
- return _wrapper
-
-
-def _blk_count_of(mega_disk_size):
- blk_count_regex = re.compile("(0x[0-9a-f]+) Sectors")
- blk_count_search = blk_count_regex.search(mega_disk_size)
- if blk_count_search:
- return int(blk_count_search.group(1), 16)
- return Disk.BLOCK_COUNT_NOT_FOUND
-
-
-def _disk_type_of(disk_show_basic_dict):
- """
- Return the 'Drive /c0/e64/s0' entry of '/c0/e64/s0 show all'
- """
- disk_media = disk_show_basic_dict['Med']
- disk_interface = disk_show_basic_dict['Intf']
- if disk_media == 'HDD':
- if disk_interface == 'SATA':
- return Disk.TYPE_SATA
- elif disk_interface == 'SAS':
- return Disk.TYPE_SAS
- elif disk_interface == 'Parallel SCSI':
- return Disk.TYPE_SCSI
- elif disk_interface == 'FC':
- return Disk.TYPE_FC
- else:
- return Disk.TYPE_HDD
- elif disk_media == 'SSD':
- return Disk.TYPE_SSD
-
- return Disk.TYPE_UNKNOWN
-
-_DISK_STATE_MAP = {
- 'Onln': Disk.STATUS_OK,
- 'Offln': Disk.STATUS_ERROR,
- 'GHS': Disk.STATUS_SPARE_DISK | Disk.STATUS_OK,
- 'DHS': Disk.STATUS_SPARE_DISK | Disk.STATUS_OK,
- 'UGood': Disk.STATUS_FREE | Disk.STATUS_OK,
- 'UBad': Disk.STATUS_FREE | Disk.STATUS_ERROR,
- 'Rbld': Disk.STATUS_RECONSTRUCT,
-}
-
-
-def _disk_status_of(disk_show_basic_dict, disk_show_stat_dict):
- disk_status = _DISK_STATE_MAP.get(
- disk_show_basic_dict['State'], 0)
-
- if disk_show_stat_dict['Media Error Count'] or \
- disk_show_stat_dict['Other Error Count'] or \
- disk_show_stat_dict['S.M.A.R.T alert flagged by drive'] != 'No':
- disk_status -= Disk.STATUS_OK
- disk_status |= Disk.STATUS_ERROR
-
- elif disk_show_stat_dict['Predictive Failure Count']:
- disk_status -= Disk.STATUS_OK
- disk_status |= Disk.STATUS_PREDICTIVE_FAILURE
-
- if disk_show_basic_dict['Sp'] == 'D':
- disk_status |= Disk.STATUS_STOPPED
-
- if disk_show_basic_dict['Sp'] == 'F':
- disk_status |= Disk.STATUS_OTHER
-
- if disk_status == 0:
- disk_status = Disk.STATUS_UNKNOWN
-
- return disk_status
-
-
-def _mega_size_to_lsm(mega_size):
- """
- LSI Using 'TB, GB, MB, KB' and etc, for LSM, they are 'TiB' and etc.
- Return int of block bytes
- """
- re_regex = re.compile("^([0-9.]+) ([EPTGMK])B$")
- re_match = re_regex.match(mega_size)
- if re_match:
- return size_human_2_size_bytes(
- "%s%siB" % (re_match.group(1), re_match.group(2)))
-
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "_mega_size_to_lsm(): Got unexpected LSI size string %s" %
- mega_size)
-
-
-_POOL_STATUS_MAP = {
- 'Onln': Pool.STATUS_OK,
- 'Dgrd': Pool.STATUS_DEGRADED,
- 'Pdgd': Pool.STATUS_DEGRADED,
- 'Offln': Pool.STATUS_ERROR,
- 'Rbld': Pool.STATUS_RECONSTRUCTING,
- 'Optl': Pool.STATUS_OK,
- # TODO(Gris Ge): The 'Optl' is undocumented, check with LSI.
-}
-
-
-def _pool_status_of(dg_top):
- """
- Return status
- """
- if dg_top['State'] in _POOL_STATUS_MAP.keys():
- return _POOL_STATUS_MAP[dg_top['State']]
- return Pool.STATUS_UNKNOWN
-
-
-def _pool_id_of(dg_id, sys_id):
- return "%s:DG%s" % (sys_id, dg_id)
-
-
-_RAID_TYPE_MAP = {
- 'RAID0': Volume.RAID_TYPE_RAID0,
- 'RAID1': Volume.RAID_TYPE_RAID1,
- 'RAID5': Volume.RAID_TYPE_RAID5,
- 'RAID6': Volume.RAID_TYPE_RAID6,
- 'RAID00': Volume.RAID_TYPE_RAID0,
- # Some MegaRAID only support max 16 disks in each span.
- # To support 16+ disks in on group, MegaRAI has RAID00 or even RAID000.
- # All of them are considered as RAID0
- 'RAID10': Volume.RAID_TYPE_RAID10,
- 'RAID50': Volume.RAID_TYPE_RAID50,
- 'RAID60': Volume.RAID_TYPE_RAID60,
-}
-
-
-def _mega_raid_type_to_lsm(vd_basic_info, vd_prop_info):
- raid_type = _RAID_TYPE_MAP.get(
- vd_basic_info['TYPE'], Volume.RAID_TYPE_UNKNOWN)
-
- # In LSI, four disks or more RAID1 is actually a RAID10.
- if raid_type == Volume.RAID_TYPE_RAID1 and \
- int(vd_prop_info['Number of Drives Per Span']) >= 4:
- raid_type = Volume.RAID_TYPE_RAID10
-
- return raid_type
-
-
-class MegaRAID(IPlugin):
- _DEFAULT_BIN_PATHS = [
- "/opt/MegaRAID/storcli/storcli64", "/opt/MegaRAID/storcli/storcli"]
- _CMD_JSON_OUTPUT_SWITCH = 'J'
-
- def __init__(self):
- self._storcli_bin = None
-
- def _find_storcli(self):
- """
- Try _DEFAULT_BIN_PATHS
- """
- for cur_path in MegaRAID._DEFAULT_BIN_PATHS:
- if os.path.lexists(cur_path):
- self._storcli_bin = cur_path
-
- if not self._storcli_bin:
- raise LsmError(
- ErrorNumber.INVALID_ARGUMENT,
- "MegaRAID storcli is not installed correctly")
-
- @_handle_errors
- def plugin_register(self, uri, password, timeout, flags=Client.FLAG_RSVD):
- if os.geteuid() != 0:
- raise LsmError(
- ErrorNumber.INVALID_ARGUMENT,
- "This plugin requires root privilege both daemon and client")
- uri_parsed = uri_parse(uri)
- self._storcli_bin = uri_parsed.get('parameters', {}).get('storcli')
- if not self._storcli_bin:
- self._find_storcli()
-
- # change working dir to "/tmp" as storcli will create a log file
- # named as 'MegaSAS.log'.
- os.chdir("/tmp")
- self._storcli_exec(['-v'], flag_json=False)
-
- @_handle_errors
- def plugin_unregister(self, flags=Client.FLAG_RSVD):
- pass
-
- @_handle_errors
- def job_status(self, job_id, flags=Client.FLAG_RSVD):
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported yet")
-
- @_handle_errors
- def job_free(self, job_id, flags=Client.FLAG_RSVD):
- pass
-
- @_handle_errors
- def plugin_info(self, flags=Client.FLAG_RSVD):
- return "LSI MegaRAID Plugin", VERSION
-
- @_handle_errors
- def time_out_set(self, ms, flags=Client.FLAG_RSVD):
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported yet")
-
- @_handle_errors
- def time_out_get(self, flags=Client.FLAG_RSVD):
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported yet")
-
- @_handle_errors
- def capabilities(self, system, flags=Client.FLAG_RSVD):
- cur_lsm_syss = self.systems()
- if system.id not in list(s.id for s in cur_lsm_syss):
- raise LsmError(
- ErrorNumber.NOT_FOUND_SYSTEM,
- "System not found")
- cap = Capabilities()
- cap.set(Capabilities.DISKS)
- cap.set(Capabilities.VOLUMES)
- cap.set(Capabilities.VOLUME_RAID_INFO)
- return cap
-
- def _storcli_exec(self, storcli_cmds, flag_json=True):
- storcli_cmds.insert(0, self._storcli_bin)
- if flag_json:
- storcli_cmds.append(MegaRAID._CMD_JSON_OUTPUT_SWITCH)
- try:
- output = cmd_exec(storcli_cmds)
- except OSError as os_error:
- if os_error.errno == errno.ENOENT:
- raise LsmError(
- ErrorNumber.INVALID_ARGUMENT,
- "storcli binary '%s' is not exist or executable." %
- self._storcli_bin)
- else:
- raise
-
- if flag_json:
- output_dict = json.loads(output)
- ctrl_output = output_dict.get('Controllers')
- if len(ctrl_output) != 1:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "_storcli_exec(): Unexpected output from MegaRAID "
- "storcli: %s" % output_dict)
-
- rc_status = ctrl_output[0].get('Command Status')
- if rc_status.get('Status') != 'Success':
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "MegaRAID storcli failed with error %d: %s" %
- (rc_status['Status Code'], rc_status['Description']))
- real_data = ctrl_output[0].get('Response Data')
- if real_data and 'Response Data' in real_data.keys():
- return real_data['Response Data']
-
- return real_data
- else:
- return output
-
- def _ctrl_count(self):
- return self._storcli_exec(
- ["show", "ctrlcount"]).get("Controller Count")
-
- def _lsm_status_of_ctrl(self, ctrl_show_all_output):
- lsi_status_info = ctrl_show_all_output['Status']
- status_info = ''
- status = System.STATUS_UNKNOWN
- if lsi_status_info['Controller Status'] == 'Optimal':
- status = System.STATUS_OK
- else:
- # TODO(Gris Ge): Try pull a disk off to check whether this change.
- status_info = "%s: " % lsi_status_info['Controller Status']
- for key_name in lsi_status_info.keys():
- if key_name == 'Controller Status':
- continue
- if lsi_status_info[key_name] != 0 and \
- lsi_status_info[key_name] != 'No' and \
- lsi_status_info[key_name] != 'NA':
- status_info += " %s:%s" % (
- key_name, lsi_status_info[key_name])
-
- return status, status_info
-
- def _sys_id_of_ctrl_num(self, ctrl_num, ctrl_show_all_output=None):
- if ctrl_show_all_output is None:
- return self._storcli_exec(
- ["/c%d" % ctrl_num, "show"])['Serial Number']
- else:
- return ctrl_show_all_output['Basics']['Serial Number']
-
- @_handle_errors
- def systems(self, flags=Client.FLAG_RSVD):
- rc_lsm_syss = []
- for ctrl_num in range(self._ctrl_count()):
- ctrl_show_all_output = self._storcli_exec(
- ["/c%d" % ctrl_num, "show", "all"])
- sys_id = self._sys_id_of_ctrl_num(ctrl_num, ctrl_show_all_output)
- sys_name = "%s %s %s ver: %s" % (
- ctrl_show_all_output['Basics']['Model'],
- ctrl_show_all_output['Bus']['Host Interface'],
- ctrl_show_all_output['Basics']['PCI Address'],
- ctrl_show_all_output['Version']['Firmware Package Build'],
- )
- (status, status_info) = self._lsm_status_of_ctrl(
- ctrl_show_all_output)
- plugin_data = "/c%d"
- # Since PCI slot sequence might change.
- # This string just stored for quick system verification.
-
- rc_lsm_syss.append(
- System(sys_id, sys_name, status, status_info, plugin_data))
-
- return rc_lsm_syss
-
- @_handle_errors
- def disks(self, search_key=None, search_value=None,
- flags=Client.FLAG_RSVD):
- rc_lsm_disks = []
- mega_disk_path_regex = re.compile(
- r"^Drive (\/c[0-9]+\/e[0-9]+\/s[0-9]+) - Detailed Information$")
-
- for ctrl_num in range(self._ctrl_count()):
- sys_id = self._sys_id_of_ctrl_num(ctrl_num)
-
- disk_show_output = self._storcli_exec(
- ["/c%d/eall/sall" % ctrl_num, "show", "all"])
- for drive_name in disk_show_output.keys():
- re_match = mega_disk_path_regex.match(drive_name)
- if not re_match:
- continue
-
- mega_disk_path = re_match.group(1)
- # Assuming only 1 disk attached to each slot.
- disk_show_basic_dict = disk_show_output[
- "Drive %s" % mega_disk_path][0]
- disk_show_attr_dict = disk_show_output[drive_name][
- 'Drive %s Device attributes' % mega_disk_path]
- disk_show_stat_dict = disk_show_output[drive_name][
- 'Drive %s State' % mega_disk_path]
-
- disk_id = disk_show_attr_dict['SN'].strip()
- disk_name = "Disk %s %s %s" % (
- disk_show_basic_dict['DID'],
- disk_show_attr_dict['Manufacturer Id'].strip(),
- disk_show_attr_dict['Model Number'])
- disk_type = _disk_type_of(disk_show_basic_dict)
- blk_size = size_human_2_size_bytes(
- disk_show_basic_dict['SeSz'])
- blk_count = _blk_count_of(disk_show_attr_dict['Coerced size'])
- status = _disk_status_of(
- disk_show_basic_dict, disk_show_stat_dict)
-
- plugin_data = mega_disk_path
-
- rc_lsm_disks.append(
- Disk(
- disk_id, disk_name, disk_type, blk_size, blk_count,
- status, sys_id, plugin_data))
-
- return search_property(rc_lsm_disks, search_key, search_value)
-
- @staticmethod
- def _dg_free_size(dg_num, free_space_list):
- """
- Get information from 'FREE SPACE DETAILS' of /c0/dall show all.
- """
- for free_space in free_space_list:
- if int(free_space['DG']) == int(dg_num):
- return _mega_size_to_lsm(free_space['Size'])
-
- return 0
-
- def _dg_top_to_lsm_pool(self, dg_top, free_space_list, ctrl_num):
- sys_id = self._sys_id_of_ctrl_num(ctrl_num)
- pool_id = _pool_id_of(dg_top['DG'], sys_id)
- name = '%s Disk Group %s' % (dg_top['Type'], dg_top['DG'])
- elem_type = Pool.ELEMENT_TYPE_VOLUME | Pool.ELEMENT_TYPE_VOLUME_FULL
- unsupported_actions = 0
- # TODO(Gris Ge): contact LSI to get accurate total space and free
- # space. The size we are using here is not what host
- # got.
- total_space = _mega_size_to_lsm(dg_top['Size'])
- free_space = MegaRAID._dg_free_size(dg_top['DG'], free_space_list)
- status = _pool_status_of(dg_top)
- status_info = ''
- if status == Pool.STATUS_UNKNOWN:
- status_info = dg_top['State']
-
- plugin_data = "/c%d/d%s" % (ctrl_num, dg_top['DG'])
-
- return Pool(
- pool_id, name, elem_type, unsupported_actions,
- total_space, free_space, status, status_info,
- sys_id, plugin_data)
-
- @_handle_errors
- def pools(self, search_key=None, search_value=None,
- flags=Client.FLAG_RSVD):
- lsm_pools = []
- for ctrl_num in range(self._ctrl_count()):
- dg_show_output = self._storcli_exec(
- ["/c%d/dall" % ctrl_num, "show", "all"])
- free_space_list = dg_show_output.get('FREE SPACE DETAILS', [])
- for dg_top in dg_show_output['TOPOLOGY']:
- if dg_top['Arr'] != '-':
- continue
- if dg_top['DG'] == '-':
- continue
- lsm_pools.append(
- self._dg_top_to_lsm_pool(
- dg_top, free_space_list, ctrl_num))
-
- return search_property(lsm_pools, search_key, search_value)
-
- @staticmethod
- def _vd_to_lsm_vol(vd_id, dg_id, sys_id, vd_basic_info, vd_pd_info_list,
- vd_prop_info, vd_path):
-
- vol_id = "%s:VD%d" % (sys_id, vd_id)
- name = "VD %d" % vd_id
- vpd83 = '' # TODO(Gris Ge): Beg LSI to provide this information.
- block_size = size_human_2_size_bytes(vd_pd_info_list[0]['SeSz'])
- num_of_blocks = vd_prop_info['Number of Blocks']
- admin_state = Volume.ADMIN_STATE_ENABLED
- if vd_prop_info['Exposed to OS'] != 'Yes' or \
- vd_basic_info['Access'] != 'RW':
- admin_state = Volume.ADMIN_STATE_DISABLED
- pool_id = _pool_id_of(dg_id, sys_id)
- plugin_data = vd_path
- return Volume(
- vol_id, name, vpd83, block_size, num_of_blocks, admin_state,
- sys_id, pool_id, plugin_data)
-
- @_handle_errors
- def volumes(self, search_key=None, search_value=None,
- flags=Client.FLAG_RSVD):
- lsm_vols = []
- for ctrl_num in range(self._ctrl_count()):
- vol_show_output = self._storcli_exec(
- ["/c%d/vall" % ctrl_num, "show", "all"])
- sys_id = self._sys_id_of_ctrl_num(ctrl_num)
- for key_name in vol_show_output.keys():
- if key_name.startswith('/c'):
- vd_basic_info = vol_show_output[key_name][0]
- (dg_id, vd_id) = vd_basic_info['DG/VD'].split('/')
- dg_id = int(dg_id)
- vd_id = int(vd_id)
- vd_pd_info_list = vol_show_output['PDs for VD %d' % vd_id]
-
- vd_prop_info = vol_show_output['VD%d Properties' % vd_id]
-
- lsm_vols.append(
- MegaRAID._vd_to_lsm_vol(
- vd_id, dg_id, sys_id, vd_basic_info,
- vd_pd_info_list, vd_prop_info, key_name))
-
- return search_property(lsm_vols, search_key, search_value)
-
- @_handle_errors
- def volume_raid_info(self, volume, flags=Client.FLAG_RSVD):
- if not volume.plugin_data:
- raise LsmError(
- ErrorNumber.INVALID_ARGUMENT,
- "Ilegal input volume argument: missing plugin_data property")
-
- vd_path = volume.plugin_data
- vol_show_output = self._storcli_exec([vd_path, "show", "all"])
- vd_basic_info = vol_show_output[vd_path][0]
- vd_id = int(vd_basic_info['DG/VD'].split('/')[-1])
- vd_prop_info = vol_show_output['VD%d Properties' % vd_id]
-
- raid_type = _mega_raid_type_to_lsm(vd_basic_info, vd_prop_info)
- strip_size = _mega_size_to_lsm(vd_prop_info['Strip Size'])
- disk_count = (
- int(vd_prop_info['Number of Drives Per Span']) *
- int(vd_prop_info['Span Depth']))
- if raid_type == Volume.RAID_TYPE_RAID0:
- strip_count = disk_count
- elif raid_type == Volume.RAID_TYPE_RAID1:
- strip_count = 1
- elif raid_type == Volume.RAID_TYPE_RAID5:
- strip_count = disk_count - 1
- elif raid_type == Volume.RAID_TYPE_RAID6:
- strip_count = disk_count - 2
- elif raid_type == Volume.RAID_TYPE_RAID50:
- strip_count = (
- (int(vd_prop_info['Number of Drives Per Span']) - 1) *
- int(vd_prop_info['Span Depth']))
- elif raid_type == Volume.RAID_TYPE_RAID60:
- strip_count = (
- (int(vd_prop_info['Number of Drives Per Span']) - 2) *
- int(vd_prop_info['Span Depth']))
- elif raid_type == Volume.RAID_TYPE_RAID10:
- strip_count = (
- int(vd_prop_info['Number of Drives Per Span']) / 2 *
- int(vd_prop_info['Span Depth']))
- else:
- # MegaRAID does not support 15 or 16 yet.
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "volume_raid_info(): Got unexpected RAID type: %s" %
- vd_basic_info['TYPE'])
-
- return [
- raid_type, strip_size, disk_count, strip_size,
- strip_size * strip_count]
diff --git a/plugin/megaraid/megaraid_lsmplugin b/plugin/megaraid/megaraid_lsmplugin
deleted file mode 100755
index 5aaa0e8..0000000
--- a/plugin/megaraid/megaraid_lsmplugin
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env python2
-
-# Copyright (C) 2011-2013 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: tasleson
-
-import sys
-import syslog
-import traceback
-
-try:
- from lsm import PluginRunner
- from lsm.plugin.megaraid import MegaRAID
-
- if __name__ == '__main__':
- PluginRunner(MegaRAID, sys.argv).run()
-except Exception:
- #This should be quite rare, but when it does happen this is pretty
- #key in understanding what happened, especially when it happens when
- #running from the daemon.
- msg = str(traceback.format_exc())
- syslog.syslog(syslog.LOG_ERR, msg)
- sys.stderr.write(msg)
- sys.exit(1)
diff --git a/plugin/megaraid/utils.py b/plugin/megaraid/utils.py
deleted file mode 100644
index 4290b39..0000000
--- a/plugin/megaraid/utils.py
+++ /dev/null
@@ -1,47 +0,0 @@
-## Copyright (C) 2015 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: Gris Ge <***@redhat.com>
-
-import subprocess
-import os
-
-def cmd_exec(cmds):
- """
- Execute provided command and return the STDOUT as string.
- Raise ExecError if command return code is not zero
- """
- cmd_popen = subprocess.Popen(
- cmds, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
- env={"PATH": os.getenv("PATH")})
- str_stdout = "".join(list(cmd_popen.stdout)).strip()
- str_stderr = "".join(list(cmd_popen.stderr)).strip()
- errno = cmd_popen.wait()
- if errno != 0:
- raise ExecError(" ".join(cmds), errno, str_stdout, str_stderr)
- return str_stdout
-
-
-class ExecError(Exception):
- def __init__(self, cmd, errno, stdout, stderr, *args, **kwargs):
- Exception.__init__(self, *args, **kwargs)
- self.cmd = cmd
- self.errno = errno
- self.stdout = stdout
- self.stderr = stderr
-
- def __str__(self):
- return "cmd: '%s', errno: %d, stdout: '%s', stderr: '%s'" % \
- (self.cmd, self.errno, self.stdout, self.stderr)
diff --git a/plugin/nstor/__init__.py b/plugin/nstor/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/plugin/nstor/nstor.py b/plugin/nstor/nstor.py
deleted file mode 100644
index 0705534..0000000
--- a/plugin/nstor/nstor.py
+++ /dev/null
@@ -1,879 +0,0 @@
-#
-# Copyright (C) 2013-2014 Nexenta Systems, Inc.
-# All rights reserved.
-#
-# 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: legkodymov
-# Gris Ge <***@redhat.com>
-
-import urllib2
-import sys
-import urlparse
-try:
- import simplejson as json
-except ImportError:
- import json
-import base64
-import time
-import traceback
-import copy
-
-from lsm import (AccessGroup, Capabilities, ErrorNumber, FileSystem, INfs,
- IStorageAreaNetwork, LsmError, NfsExport, Pool,
- FsSnapshot, System, VERSION, Volume, md5, error,
- common_urllib2_error_handler, search_property)
-
-
-def handle_nstor_errors(method):
- def nstor_wrapper(*args, **kwargs):
- try:
- return method(*args, **kwargs)
- except LsmError as lsm:
- raise
- except Exception as e:
- error("Unexpected exception:\n" + traceback.format_exc())
- raise LsmError(ErrorNumber.PLUGIN_BUG, str(e),
- traceback.format_exc())
- return nstor_wrapper
-
-
-class NexentaStor(INfs, IStorageAreaNetwork):
-
- _V3_PORT = '2000' # Management port for v3.x device
- _V4_PORT = '8457' # Management port for v4.x device
-
- def plugin_info(self, flags=0):
- # TODO: Change this to something more appropriate
- return "NexentaStor support", VERSION
-
- def __init__(self):
- self.uparse = None
- self.password = None
- self.timeout = None
- self._system = None
- self._port = NexentaStor._V3_PORT
- self._scheme = 'http'
-
- def _ns_request(self, path, data):
- response = None
- parms = json.dumps(data)
-
- url = '%s://%s:%s/%s' % \
- (self._scheme, self.uparse.hostname, self._port, path)
- request = urllib2.Request(url, parms)
-
- username = self.uparse.username or 'admin'
- base64string = base64.encodestring('%s:%s' %
- (username, self.password))[:-1]
- request.add_header('Authorization', 'Basic %s' % base64string)
- request.add_header('Content-Type', 'application/json')
- try:
- response = urllib2.urlopen(request, timeout=self.timeout / 1000)
- except Exception as e:
- try:
- common_urllib2_error_handler(e)
- except LsmError as lsm_e:
- exc_info = sys.exc_info()
- if lsm_e.code == ErrorNumber.NETWORK_CONNREFUSED:
- if not self.uparse.port and \
- self._port == NexentaStor._V3_PORT:
- self._port = NexentaStor._V4_PORT
- return self._ns_request(path, data)
-
- raise exc_info[0], exc_info[1], exc_info[2]
-
- resp_json = response.read()
- resp = json.loads(resp_json)
- if resp['error']:
-
- if 'message' in resp['error']:
- msg = resp['error']['message']
- # Check to see if there is a better way to do this...
- if 'dataset already exists' in msg:
- raise LsmError(ErrorNumber.NAME_CONFLICT, msg)
-
- if 'Unable to destroy hostgroup' in msg:
- raise LsmError(ErrorNumber.IS_MASKED, msg)
-
- raise LsmError(ErrorNumber.PLUGIN_BUG, resp['error'])
- return resp['result']
-
- def _request(self, method, obj, params):
- return self._ns_request('rest/nms', {"method": method, "object": obj,
- "params": params})
-
- @property
- def system(self):
- if self._system is None:
- license_info = self._request("get_license_info", "appliance", [])
- fqdn = self._request("get_fqdn", "appliance", [])
- self._system = System(license_info['machine_sig'], fqdn,
- System.STATUS_OK, '')
- return self._system
-
- def plugin_register(self, uri, password, timeout, flags=0):
- self.uparse = urlparse.urlparse(uri)
- self.password = password or 'nexenta'
- self.timeout = timeout
-
- if self.uparse.port:
- self._port = self.uparse.port
-
- if self.uparse.scheme.lower() == 'nstor+ssl':
- self._scheme = 'https'
-
- @staticmethod
- def _to_bytes(size):
- if size.lower().endswith('k'):
- return int(float(size[:-1]) * 1024)
- if size.lower().endswith('m'):
- return int(float(size[:-1]) * 1024 * 1024)
- if size.lower().endswith('g'):
- return int(float(size[:-1]) * 1024 * 1024 * 1024)
- if size.lower().endswith('t'):
- return int(float(size[:-1]) * 1024 * 1024 * 1024 * 1024)
- if size.lower().endswith('p'):
- return int(float(size[:-1]) * 1024 * 1024 * 1024 * 1024 * 1024)
- if size.lower().endswith('e'):
- return int(
- float(size[:-1]) * 1024 * 1024 * 1024 * 1024 * 1024 * 1024)
- return size
-
- @handle_nstor_errors
- def pools(self, search_key=None, search_value=None, flags=0):
- pools_list = self._request("get_all_names", "volume", [""])
-
- pools = []
- for pool in pools_list:
- if pool == 'syspool':
- continue
- pool_info = self._request("get_child_props", "volume",
- [str(pool), ""])
-
- pools.append(Pool(pool_info['name'], pool_info['name'],
- Pool.ELEMENT_TYPE_VOLUME |
- Pool.ELEMENT_TYPE_VOLUME_THIN |
- Pool.ELEMENT_TYPE_FS,
- 0,
- NexentaStor._to_bytes(pool_info['size']),
- NexentaStor._to_bytes(pool_info['free']),
- Pool.STATUS_UNKNOWN, '', self.system.id))
-
- return search_property(pools, search_key, search_value)
-
- @handle_nstor_errors
- def fs(self, search_key=None, search_value=None, flags=0):
- fs_list = self._request("get_all_names", "folder", [""])
-
- fss = []
- pools = {}
- for fs in fs_list:
- pool_name = NexentaStor._get_pool_id(fs)
- if pool_name == 'syspool':
- continue
- if pool_name not in pools:
- pool_info = self._request("get_child_props", "volume",
- [str(fs), ""])
- pools[pool_name] = pool_info
- else:
- pool_info = pools[pool_name]
- fss.append(
- FileSystem(fs, fs, NexentaStor._to_bytes(pool_info['size']),
- self._to_bytes(pool_info['available']), pool_name,
- fs))
-
- return search_property(fss, search_key, search_value)
-
- @handle_nstor_errors
- def fs_create(self, pool, name, size_bytes, flags=0):
- """
- Consider you have 'data' pool and folder 'a' in it (data/a)
- If you want create 'data/a/b', command line should look like:
- --create-fs=a/b --pool=data --size=1G
- """
- if name.startswith(pool.name + '/'):
- chunks = name.split('/')[1:]
- name = '/'.join(chunks)
- fs_name = self._request("create", "folder", [pool.name, name])[0]
- filesystem = FileSystem(fs_name, fs_name, pool.total_space,
- pool.free_space, pool.id, fs_name)
- return None, filesystem
-
- @handle_nstor_errors
- def fs_delete(self, fs, flags=0):
- result = self._request("destroy", "folder", [fs.name, "-r"])
- return
-
- @handle_nstor_errors
- def fs_snapshots(self, fs, flags=0):
- snapshot_list = self._request("get_names", "snapshot", [fs.name])
-
- snapshots = []
- for snapshot in snapshot_list:
- snapshot_info = self._request("get_child_props", "snapshot",
- [snapshot, "creation_seconds"])
- snapshots.append(FsSnapshot(snapshot, snapshot,
- snapshot_info['creation_seconds']))
-
- return snapshots
-
- @handle_nstor_errors
- def fs_snapshot_create(self, fs, snapshot_name, flags=0):
- full_name = "%s@%s" % (fs.name, snapshot_name)
-
- self._request("create", "snapshot", [full_name, "0"])
- snapshot_info = self._request("get_child_props", "snapshot",
- [full_name, "creation_seconds"])
- return None, FsSnapshot(full_name, full_name,
- snapshot_info['creation_seconds'])
-
- @handle_nstor_errors
- def fs_snapshot_delete(self, fs, snapshot, flags=0):
- self._request("destroy", "snapshot", [snapshot.name, ""])
- return
-
- @handle_nstor_errors
- def time_out_set(self, ms, flags=0):
- self.timeout = ms
- return
-
- @handle_nstor_errors
- def time_out_get(self, flags=0):
- return self.timeout
-
- @handle_nstor_errors
- def plugin_unregister(self, flags=0):
- return
-
- @handle_nstor_errors
- def job_status(self, job_id, flags=0):
- return
-
- @handle_nstor_errors
- def job_free(self, job_id, flags=0):
- return
-
- @handle_nstor_errors
- def capabilities(self, system, flags=0):
- c = Capabilities()
-
- #File system
- c.set(Capabilities.FS)
- c.set(Capabilities.FS_DELETE)
- #c.set(Capabilities.FS_RESIZE)
- c.set(Capabilities.FS_CREATE)
- c.set(Capabilities.FS_CLONE)
- # c.set(Capabilities.FILE_CLONE)
- c.set(Capabilities.FS_SNAPSHOTS)
- c.set(Capabilities.FS_SNAPSHOT_CREATE)
- c.set(Capabilities.FS_SNAPSHOT_DELETE)
- c.set(Capabilities.FS_SNAPSHOT_RESTORE)
- # c.set(Capabilities.FS_SNAPSHOT_RESTORE_SPECIFIC_FILES)
- c.set(Capabilities.FS_CHILD_DEPENDENCY)
- c.set(Capabilities.FS_CHILD_DEPENDENCY_RM)
- # c.set(Capabilities.FS_CHILD_DEPENDENCY_RM_SPECIFIC_FILES)
-
- # #NFS
- c.set(Capabilities.EXPORT_AUTH)
- c.set(Capabilities.EXPORTS)
- c.set(Capabilities.EXPORT_FS)
- c.set(Capabilities.EXPORT_REMOVE)
- c.set(Capabilities.EXPORT_CUSTOM_PATH)
- #
- # #Block operations
- c.set(Capabilities.VOLUMES)
- c.set(Capabilities.VOLUME_CREATE)
- c.set(Capabilities.VOLUME_RESIZE)
- # c.set(Capabilities.VOLUME_REPLICATE)
- # c.set(Capabilities.VOLUME_REPLICATE_CLONE)
- # c.set(Capabilities.VOLUME_REPLICATE_COPY)
- # c.set(Capabilities.VOLUME_REPLICATE_MIRROR_ASYNC)
- # c.set(Capabilities.VOLUME_REPLICATE_MIRROR_SYNC)
- # c.set(Capabilities.VOLUME_COPY_RANGE_BLOCK_SIZE)
- # c.set(Capabilities.VOLUME_COPY_RANGE)
- # c.set(Capabilities.VOLUME_COPY_RANGE_CLONE)
- # c.set(Capabilities.VOLUME_COPY_RANGE_COPY)
- c.set(Capabilities.VOLUME_DELETE)
- # c.set(Capabilities.VOLUME_ENABLE)
- # c.set(Capabilities.VOLUME_DISABLE)
- c.set(Capabilities.VOLUME_MASK)
- c.set(Capabilities.VOLUME_UNMASK)
- c.set(Capabilities.ACCESS_GROUPS)
- c.set(Capabilities.ACCESS_GROUP_CREATE_ISCSI_IQN)
- c.set(Capabilities.ACCESS_GROUP_DELETE)
- c.set(Capabilities.ACCESS_GROUP_INITIATOR_ADD_ISCSI_IQN)
- c.set(Capabilities.ACCESS_GROUP_INITIATOR_DELETE)
- c.set(Capabilities.VOLUMES_ACCESSIBLE_BY_ACCESS_GROUP)
- c.set(Capabilities.ACCESS_GROUPS_GRANTED_TO_VOLUME)
- c.set(Capabilities.VOLUME_CHILD_DEPENDENCY)
- c.set(Capabilities.VOLUME_CHILD_DEPENDENCY_RM)
-
- c.set(Capabilities.VOLUME_ISCSI_CHAP_AUTHENTICATION)
-
- return c
-
- @handle_nstor_errors
- def systems(self, flags=0):
- return [self.system]
-
- @handle_nstor_errors
- def fs_resize(self, fs, new_size_bytes, flags=0):
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not implemented")
-
- @staticmethod
- def _get_pool_id(fs_name):
- return fs_name.split('/')[0]
-
- @handle_nstor_errors
- def fs_clone(self, src_fs, dest_fs_name, snapshot=None, flags=0):
- folder = src_fs.name.split('/')[0]
- dest = folder + '/' + dest_fs_name
-
- if snapshot is None:
- # User did not supply a snapshot, so we will create one for them
- name = src_fs.name.split('/')[0]
- snapshot = self.fs_snapshot_create(
- src_fs, name + "_clone_ss_" + md5(time.ctime()))[1]
-
- self._request("clone", "folder", [snapshot.name, dest])
- pool_id = NexentaStor._get_pool_id(dest)
- pool_info = self._request("get_child_props", "volume", [pool_id, ""])
- fs = FileSystem(dest, dest, NexentaStor._to_bytes(pool_info['size']),
- NexentaStor._to_bytes(pool_info['available']), pool_id,
- self.system.id)
- return None, fs
-
- @handle_nstor_errors
- def fs_snapshot_restore(self, fs, snapshot, files, restore_files,
- all_files=False, flags=0):
- self._request("rollback", "snapshot", [snapshot.name, '-r'])
- return
-
- def _dependencies_list(self, fs_name, volume=False):
- obj = "folder"
- if volume:
- obj = 'volume'
- pool_id = NexentaStor._get_pool_id(fs_name)
- fs_list = self._request("get_all_names", "folder", ["^%s/" % pool_id])
-
- dependency_list = []
- for filesystem in fs_list:
- origin = self._request("get_child_prop", "folder",
- [filesystem, 'origin'])
- if origin.startswith("%s/" % fs_name) or \
- origin.startswith("%s@" % fs_name):
- dependency_list.append(filesystem)
- return dependency_list
-
- @handle_nstor_errors
- def fs_child_dependency(self, fs, files, flags=0):
- # Function get list of all folders of requested pool,
- # then it checks if 'fs' is the origin of one of folders
- return len(self._dependencies_list(fs.name)) > 0
-
- @handle_nstor_errors
- def fs_child_dependency_rm(self, fs, files, flags=0):
- dep_list = self._dependencies_list(fs.name)
- for dep in dep_list:
- clone_name = dep.split('@')[0]
- self._request("promote", "folder", [clone_name])
- return None
-
- @handle_nstor_errors
- def export_auth(self, flags=0):
- """
- Returns the types of authentication that are available for NFS
- """
- result = self._request("get_share_confopts", "netstorsvc",
- ['svc:/network/nfs/server:default'])
- rc = []
- methods = result['auth_type']['opts'].split(';')
- for m in methods:
- rc.append(m.split('=>')[0])
- return rc
-
- @handle_nstor_errors
- def exports(self, search_key=None, search_value=None, flags=0):
- """
- Get a list of all exported file systems on the controller.
- """
- exp_list = self._request("get_shared_folders", "netstorsvc",
- ['svc:/network/nfs/server:default', ''])
-
- exports = []
- for e in exp_list:
- opts = self._request("get_shareopts", "netstorsvc",
- ['svc:/network/nfs/server:default', e])
- exports.append(NfsExport(md5(opts['name']), e, opts['name'],
- opts['auth_type'], opts['root'],
- opts['read_write'], opts['read_only'],
- 'N/A', 'N/A', opts['extra_options']))
-
- return search_property(exports, search_key, search_value)
-
- @handle_nstor_errors
- def export_fs(self, fs_id, export_path, root_list, rw_list, ro_list,
- anon_uid, anon_gid, auth_type, options, flags=0):
- """
- Exports a filesystem as specified in the export
- """
- if export_path is None:
- raise LsmError(ErrorNumber.INVALID_ARGUMENT,
- "Export path is required")
-
- md5_id = md5(export_path)
- fs_dict = {'auth_type': 'sys', 'anonymous': 'false'}
- if ro_list:
- fs_dict['read_only'] = ','.join(ro_list)
- if rw_list:
- fs_dict['read_write'] = ','.join(rw_list)
- if anon_uid or anon_gid:
- fs_dict['anonymous'] = 'true'
- if root_list:
- fs_dict['root'] = ','.join(root_list)
- if auth_type:
- fs_dict['auth_type'] = str(auth_type)
- if '*' in rw_list:
- fs_dict['anonymous'] = 'true'
- if options:
- fs_dict['extra_options'] = str(options)
-
- result = self._request("share_folder", "netstorsvc",
- ['svc:/network/nfs/server:default',
- fs_id, fs_dict])
- return NfsExport(md5_id, fs_id, export_path, auth_type, root_list,
- rw_list, ro_list, anon_uid, anon_gid, options)
-
- @handle_nstor_errors
- def export_remove(self, export, flags=0):
- """
- Removes the specified export
- """
- self._request("unshare_folder", "netstorsvc",
- ['svc:/network/nfs/server:default', export.fs_id, '0'])
- return
-
- ########### SAN
-
- @staticmethod
- def _calc_group(name):
- return 'lsm_' + md5(name)[0:8]
-
- @handle_nstor_errors
- def volumes(self, search_key=None, search_value=None, flags=0):
- """
- Returns an array of volume objects
-
- """
- vol_list = []
- lu_list = self._request("get_names", "zvol", [""])
-
- # lu_list = self._ns_request('rest/nms',
- # {"method": "get_lu_list",
- # "object": "scsidisk",
- # "params": ['']})
- for lu in lu_list:
- try:
- lu_props = self._request("get_lu_props", "scsidisk", [lu])
- except:
- lu_props = {'guid': '', 'state': 'N/A'}
-
- zvol_props = self._request("get_child_props", "zvol", [lu, ""])
-
- block_size = NexentaStor._to_bytes(zvol_props['volblocksize'])
- size_bytes = int(zvol_props['size_bytes'])
- num_of_blocks = size_bytes / block_size
- admin_state = Volume.ADMIN_STATE_ENABLED
-
- vol_list.append(
- Volume(lu, lu, lu_props['guid'].lower(),
- block_size, num_of_blocks,
- admin_state, self.system.id,
- NexentaStor._get_pool_id(lu)))
-
- return search_property(vol_list, search_key, search_value)
-
- @handle_nstor_errors
- def volume_create(self, pool, volume_name, size_bytes, provisioning,
- flags=0):
- """
- Creates a volume, given a pool, volume name, size and provisioning
-
- returns a tuple (job_id, new volume)
- Note: Tuple return values are mutually exclusive, when one
- is None the other must be valid.
- """
- if volume_name.startswith(pool.name + '/'):
- chunks = volume_name.split('/')[1:]
- volume_name = '/'.join(chunks)
- sparse = provisioning in (Volume.PROVISION_DEFAULT,
- Volume.PROVISION_THIN,
- Volume.PROVISION_UNKNOWN)
- if sparse:
- sparse = '1'
- else:
- sparse = '0'
- name = '%s/%s' % (pool.name, volume_name)
- block_size = ''
-
- self._request("create", "zvol",
- [name, str(size_bytes), block_size, sparse])
-
- self._request("set_child_prop", "zvol", [name, 'compression', 'on'])
-
- self._request("set_child_prop", "zvol",
- [name, 'logbias', 'throughput'])
-
- self._request("create_lu", "scsidisk", [name, []])
- vols = self.volumes('id', name)
- return None, vols[0]
-
- @handle_nstor_errors
- def volume_delete(self, volume, flags=0):
- """
- Deletes a volume.
-
- Returns None on success, else raises an LsmError
- """
- ag = self.access_groups_granted_to_volume(volume)
-
- if len(ag):
- raise LsmError(ErrorNumber.IS_MASKED,
- "Volume is masked to access group")
-
- self._request("delete_lu", "scsidisk", [volume.id])
- self._request("destroy", "zvol", [volume.id, ''])
- return
-
- @handle_nstor_errors
- def volume_resize(self, volume, new_size_bytes, flags=0):
- """
- Re-sizes a volume.
-
- Returns a tuple (job_id, re-sized_volume)
- Note: Tuple return values are mutually exclusive, when one
- is None the other must be valid.
- """
- self._request("set_child_prop", "zvol",
- [volume.name, 'volsize', str(new_size_bytes)])
- self._request("realign_size", "scsidisk", [volume.name])
- new_num_of_blocks = new_size_bytes / volume.block_size
- return None, Volume(volume.id, volume.name, volume.vpd83,
- volume.block_size, new_num_of_blocks,
- volume.admin_state, volume.system_id,
- volume.pool_id)
-
- @handle_nstor_errors
- def volume_replicate(self, pool, rep_type, volume_src, name, flags=0):
- """
- Replicates a volume from the specified pool. In this library, to
- replicate means to create a new volume which is a copy of the source.
-
- Returns a tuple (job_id, replicated volume)
- Note: Tuple return values are mutually exclusive, when one
- is None the other must be valid.
- """
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "volume_replicate not implemented")
-
- # if rep_type == Volume.REPLICATE_CLONE:
- # return
- # elif rep_type == Volume.REPLICATE_COPY:
- # return
- # elif rep_type == Volume.REPLICATE_MIRROR_SYNC:
- # return
- # elif rep_type == Volume.REPLICATE_MIRROR_ASYNC:
- # # AutoSync job - code not yet ready
- # rec = {'type': 'minute', 'auto-mount': '', 'dircontent': '0',
- # 'direction': '0', 'keep_src': '1', 'keep_dst': '1',
- # 'auto-clone': '0', 'marker': '', 'method': 'sync',
- # 'proto': 'zfs', 'period': '1', 'exclude': '',
- # 'from-host': 'localhost', 'from-fs': str(volume_src.name),
- # 'to-host': 'localhost', 'to-fs': '/backup',
- # 'progress-marker': '', 'day': '0',
- # 'hour': '0', 'minute': '0', 'options': ' -P1024 -n4',
- # 'from-snapshot': '', 'force': '46', 'retry': '0',
- # 'retry-timestamp': '0', 'comment': '', 'flags': '4',
- # 'trace_level': '10', 'rate_limit': '0',
- # 'autosync_role': 'master:no', 'action': '',
- # 'reverse_capable': '0', 'last_replic_time': '',
- # 'time_started': 'N/A',
- # '_unique': 'type from-host from-fs to-host to-fs',
- # 'zip_level': '0', 'success_counter': '0', 'trunk': '',
- # 'estimations': '0', 'marker_name': "AutoSync",
- # 'latest-suffix': '', 'custom_name': ''}
- # ret = self._ns_request('rest/nms', {"method": "fmri_create",
- # "object": "autosvc",
- # "params": ['auto-sync', '',
- # str(volume_src.name),
- # False, rec]})
- # return
- # elif rep_type == Volume.REPLICATE_UNKNOWN:
- # return
-
- # return
-
- @handle_nstor_errors
- def iscsi_chap_auth(self, init_id, in_user, in_password, out_user,
- out_password, flags=0):
- """
- Register a user/password for the specified initiator for CHAP
- authentication.
- """
- if in_user is None:
- in_user = ""
-
- if in_password is None:
- in_password = ""
-
- if out_user is not None or out_password is not None:
- raise LsmError(ErrorNumber.INVALID_ARGUMENT,
- "outbound chap authentication is not supported at "
- "this time")
-
- try:
- self._request("create_initiator", "iscsitarget",
- [init_id,
- {'initiatorchapuser': in_user,
- 'initiatorchapsecret': in_password}])
- except:
- self._request("modify_initiator", "iscsitarget",
- [init_id,
- {'initiatorchapuser': in_user,
- 'initiatorchapsecret': in_password}])
-
- self._request("modify_initiator", "iscsitarget",
- [init_id,
- {'initiatorchapuser': in_user,
- 'initiatorchapsecret': in_password}])
- return
-
- def _get_views(self, volume_name):
- results = []
- try:
- results = self._request("list_lun_mapping_entries", "scsidisk",
- [volume_name])
- except Exception:
- pass
- return results
-
- def _volume_mask(self, group_name, volume_name):
- self._request("add_lun_mapping_entry", "scsidisk",
- [volume_name, {'host_group': group_name}])
- return
-
- @handle_nstor_errors
- def volume_mask(self, access_group, volume, flags=0):
- """
- Allows an access group to access a volume.
- """
- # Pre-check for already masked.
- if list(v.id for v in
- self.volumes_accessible_by_access_group(access_group)
- if v.id == volume.id):
- raise LsmError(
- ErrorNumber.NO_STATE_CHANGE,
- "Volume is already masked to requested access group")
-
- self._volume_mask(access_group.name, volume.name)
- return
-
- @handle_nstor_errors
- def volume_unmask(self, access_group, volume, flags=0):
- """
- Revokes access for an access group for a volume
- """
- views = self._get_views(volume.name)
- view_number = -1
- for view in views:
- if view['host_group'] == access_group.name:
- view_number = view['entry_number']
- if view_number == -1:
- raise LsmError(ErrorNumber.NO_STATE_CHANGE,
- "There is no such mapping for volume %s" %
- volume.name)
-
- self._request("remove_lun_mapping_entry", "scsidisk",
- [volume.name, view_number])
- return
-
- @handle_nstor_errors
- def access_groups(self, search_key=None, search_value=None, flags=0):
- """
- Returns a list of access groups
- """
- hg_list = self._request("list_hostgroups", "stmf", [])
-
- ag_list = []
- for hg in hg_list:
- init_ids = self._request("list_hostgroup_members", "stmf", [hg])
- ag_list.append(
- AccessGroup(hg, hg, init_ids, AccessGroup.INIT_TYPE_ISCSI_IQN,
- self.system.id))
- return search_property(ag_list, search_key, search_value)
-
- @handle_nstor_errors
- def access_group_create(self, name, init_id, init_type, system,
- flags=0):
- """
- Creates of access group
- """
- if system.id != self.system.id:
- raise LsmError(ErrorNumber.NOT_FOUND_SYSTEM,
- "System %s not found" % system.id)
- if init_type != AccessGroup.INIT_TYPE_ISCSI_IQN:
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "Nstor only support iSCSI Access Group")
- # Check that init_id is not a part of another hostgroup
- for ag in self.access_groups():
- if init_id in ag.init_ids:
- raise LsmError(ErrorNumber.EXISTS_INITIATOR,
- "%s is already part of %s access group" %
- (init_id, ag.name))
-
- if name == ag.name:
- raise LsmError(ErrorNumber.NAME_CONFLICT,
- "Access group with name exists!")
- self._request("create_hostgroup", "stmf", [name])
- self._add_initiator(name, init_id)
-
- return AccessGroup(name, name, [init_id], init_type, system.id)
-
- @handle_nstor_errors
- def access_group_delete(self, access_group, flags=0):
- """
- Deletes an access group
- """
- vols = self.volumes_accessible_by_access_group(access_group)
- if len(vols):
- raise LsmError(ErrorNumber.IS_MASKED,
- "Access Group has volume(s) masked")
-
- self._request("destroy_hostgroup", "stmf", [access_group.name])
- return
-
- @handle_nstor_errors
- def _add_initiator(self, group_name, initiator_id, remove=False):
- command = "add_hostgroup_member"
- if remove:
- command = "remove_hostgroup_member"
-
- self._request(command, "stmf", [group_name, initiator_id])
- return
-
- def _access_group_initiators(self, access_group):
- hg_list = self._request("list_hostgroups", "stmf", [])
- if access_group.name not in hg_list:
- raise LsmError(ErrorNumber.NOT_FOUND_ACCESS_GROUP,
- "AccessGroup %s(%s) not found" %
- (access_group.name, access_group.id))
-
- return self._request("list_hostgroup_members", "stmf",
- [access_group.name])
-
- @handle_nstor_errors
- def access_group_initiator_add(self, access_group, init_id, init_type,
- flags=0):
- """
- Adds an initiator to an access group
- """
- if init_type != AccessGroup.INIT_TYPE_ISCSI_IQN:
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "Nstor only support iSCSI Access Group")
-
- init_ids = self._access_group_initiators(access_group)
- if init_id in init_ids:
- # Already in requested group.
- return copy.deepcopy(access_group)
-
- self._add_initiator(access_group.name, init_id)
- init_ids = self._request("list_hostgroup_members", "stmf",
- [access_group.name])
- return AccessGroup(access_group.name, access_group.name,
- init_ids, AccessGroup.INIT_TYPE_ISCSI_IQN,
- access_group.id)
-
- @handle_nstor_errors
- def access_group_initiator_delete(self, access_group, init_id, init_type,
- flags=0):
- """
- Deletes an initiator from an access group
- """
- init_ids = self._access_group_initiators(access_group)
- if init_id not in init_ids:
- # Already removed from requested group.
- return copy.deepcopy(access_group)
- self._add_initiator(access_group.name, init_id, True)
- init_ids = self._request("list_hostgroup_members", "stmf",
- [access_group.name])
- return AccessGroup(access_group.name, access_group.name,
- init_ids, AccessGroup.INIT_TYPE_ISCSI_IQN,
- access_group.id)
-
- @handle_nstor_errors
- def volumes_accessible_by_access_group(self, access_group, flags=0):
- """
- Returns the list of volumes that access group has access to.
- """
- volumes = []
- all_volumes_list = self.volumes(flags=flags)
- for vol in all_volumes_list:
- for view in self._get_views(vol.name):
- if view['host_group'] == access_group.name:
- volumes.append(vol)
- return volumes
-
- @handle_nstor_errors
- def access_groups_granted_to_volume(self, volume, flags=0):
- """
- Returns the list of access groups that have access to the specified
- """
- ag_list = self.access_groups(flags=flags)
-
- hg = []
- for view in self._get_views(volume.name):
- for ag in ag_list:
- if ag.name == view['host_group']:
- hg.append(ag)
- return hg
-
- @handle_nstor_errors
- def volume_child_dependency(self, volume, flags=0):
- """
- Returns True if this volume has other volumes which are dependant on
- it. Implies that this volume cannot be deleted or possibly modified
- because it would affect its children.
- """
- return len(self._dependencies_list(volume.name, True)) > 0
-
- @handle_nstor_errors
- def volume_child_dependency_rm(self, volume, flags=0):
- """
- If this volume has child dependency, this method call will fully
- replicate the blocks removing the relationship between them. This
- should return None (success) if volume_child_dependency would return
- False.
-
- Note: This operation could take a very long time depending on the size
- of the volume and the number of child dependencies.
-
- Returns None if complete else job id, raises LsmError on errors.
- """
- dep_list = self._dependencies_list(volume.name)
- for dep in dep_list:
- clone_name = dep.split('@')[0]
- self._request("promote", "volume", [clone_name])
- return None
diff --git a/plugin/nstor/nstor_lsmplugin b/plugin/nstor/nstor_lsmplugin
deleted file mode 100755
index 82c3171..0000000
--- a/plugin/nstor/nstor_lsmplugin
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/usr/bin/env python2
-
-#
-# Copyright (C) 2012 Nexenta Systems, Inc.
-# All rights reserved.
-#
-# 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: legkodymov
-import sys
-import syslog
-import traceback
-
-try:
- from lsm.plugin.nstor.nstor import NexentaStor
- from lsm import PluginRunner
-
- if __name__ == '__main__':
- PluginRunner(NexentaStor, sys.argv).run()
-except Exception:
- #This should be quite rare, but when it does happen this is pretty
- #key in understanding what happened, especially when it happens when
- #running from the daemon.
- msg = str(traceback.format_exc())
- syslog.syslog(syslog.LOG_ERR, msg)
- sys.stderr.write(msg)
- sys.exit(1)
diff --git a/plugin/ontap/__init__.py b/plugin/ontap/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/plugin/ontap/na.py b/plugin/ontap/na.py
deleted file mode 100644
index b68577c..0000000
--- a/plugin/ontap/na.py
+++ /dev/null
@@ -1,840 +0,0 @@
-# Copyright (C) 2012-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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: tasleson
-
-import urllib2
-import socket
-import sys
-from xml.etree import ElementTree
-import time
-from binascii import hexlify
-from _ssl import SSLError
-
-from M2Crypto import RC4
-
-from lsm.external.xmltodict import convert_xml_to_dict
-from lsm import (ErrorNumber)
-
-
-#Set to an appropriate directory and file to dump the raw response.
-xml_debug = None
-
-
-def netapp_filer_parse_response(resp):
- if xml_debug:
- out = open(xml_debug, "wb")
- out.write(resp)
- out.close()
-
- return convert_xml_to_dict(ElementTree.fromstring(resp))
-
-
-def param_value(val):
- """
- Given a parameter to pass to filer, convert to XML
- """
- rc = ""
- if type(val) is dict or isinstance(val, dict):
- for k, v in val.items():
- rc += "<%s>%s</%s>" % (k, param_value(v), k)
- elif type(val) is list or isinstance(val, list):
- for i in val:
- rc += param_value(i)
- else:
- rc = val
- return rc
-
-
-def netapp_filer(host, username, password, timeout, command, parameters=None,
- ssl=False):
- """
- Issue a command to the NetApp filer.
- Note: Change to default ssl on before we ship a release version.
- """
- proto = 'http'
- if ssl:
- proto = 'https'
-
- url = "%s://%s/servlets/netapp.servlets.admin.XMLrequest_filer" % \
- (proto, host)
-
- req = urllib2.Request(url)
- req.add_header('Content-Type', 'text/xml')
-
- password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
- password_manager.add_password(None, url, username, password)
- auth_manager = urllib2.HTTPBasicAuthHandler(password_manager)
-
- opener = urllib2.build_opener(auth_manager)
- urllib2.install_opener(opener)
-
- #build the command and the arguments for it
- p = ""
-
- if parameters:
- for k, v in parameters.items():
- p += "<%s>%s</%s>" % (k, param_value(v), k)
-
- payload = "<%s>\n%s\n</%s>" % (command, p, command)
-
- data = """<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE netapp SYSTEM "file:/etc/netapp_filer.dtd">
-<netapp xmlns="http://www.netapp.com/filer/admin" version="1.1">
-%s
-</netapp>
-""" % payload
-
- handler = None
- rc = None
- try:
- handler = urllib2.urlopen(req, data, float(timeout))
-
- if handler.getcode() == 200:
- rc = netapp_filer_parse_response(handler.read())
- except urllib2.HTTPError as he:
- raise
- except urllib2.URLError as ue:
- if isinstance(ue.reason, socket.timeout):
- raise FilerError(Filer.ETIMEOUT, "Connection timeout")
- else:
- raise
- except socket.timeout:
- raise FilerError(Filer.ETIMEOUT, "Connection timeout")
- except SSLError as sse:
- # The ssl library doesn't give a good way to find specific reason.
- # We are doing a string contains which is not ideal, but other than
- # throwing a generic error in this case there isn't much we can do
- # to be more specific.
- if "timed out" in str(sse).lower():
- raise FilerError(Filer.ETIMEOUT, "Connection timeout (SSL)")
- else:
- raise FilerError(Filer.EUNKNOWN,
- "SSL error occurred (%s)", str(sse))
- finally:
- if handler:
- handler.close()
-
- return rc
-
-
-class FilerError(Exception):
- """
- Class represents a NetApp bad return code
- """
- IGROUP_NOT_CONTAIN_GIVEN_INIT = 9007
- IGROUP_ALREADY_HAS_INIT = 9008
- NO_SUCH_IGROUP = 9003
-
- # Using the name from NetApp SDK netapp_errno.h
- EVDISK_ERROR_VDISK_EXISTS = 9012 # LUN name already in use
- EVDISK_ERROR_VDISK_EXPORTED = 9013 # LUN is currently mapped
- EVDISK_ERROR_VDISK_NOT_ENABLED = 9014 # LUN is not online
- EVDISK_ERROR_VDISK_NOT_DISABLED = 9015 # LUN is not offline
- EVDISK_ERROR_NO_SUCH_LUNMAP = 9016 # LUN is already unmapped
- EVDISK_ERROR_INITGROUP_MAPS_EXIST = 9029 # LUN maps for this initiator
- # group exist
- EVDISK_ERROR_SIZE_TOO_LARGE = 9034 # LUN size too large.
- EVDISK_ERROR_NO_SUCH_VOLUME = 9036 # NetApp Volume not exists.
- EVDISK_ERROR_SIZE_TOO_SMALL = 9041 # Specified too small a size
- EVDISK_ERROR_SIZE_UNCHANGED = 9042 # requested size is the same.
- EVDISK_ERROR_INITGROUP_HAS_VDISK = 9023 # Already masked
-
- def __init__(self, errno, reason, *args, **kwargs):
- Exception.__init__(self, *args, **kwargs)
- self.errno = int(errno)
- self.reason = reason
-
-
-def to_list(v):
- """
- The return values in hash form can either be a single hash item or a list
- of hash items, this code handles both to make callers always get a list.
- """
- rc = []
- if v is not None:
- if isinstance(v, list):
- rc = v
- else:
- rc.append(v)
- return rc
-
-
-class Filer(object):
- """
- Class to handle NetApp API calls.
- Note: These are using lsm terminology.
- """
- EUNKNOWN = 10 # Non-specific error
- ENAVOL_NAME_DUPE = 17 # Volume name collision
- ENOSPC = 28 # Out of space
- ETIMEOUT = 60 # Time-out
- EINVALID_ISCSI_NAME = 9006 # Invalid ISCSI IQN
- EDUPE_VOLUME_PATH = 9012 # Duplicate volume name
- ENO_SUCH_VOLUME = 9017 # lun not found
- ESIZE_TOO_LARGE = 9034 # Specified too large a size
- ENO_SUCH_FS = 9036 # FS not found
- EVOLUME_TOO_SMALL = 9041 # Specified too small a size
- EAPILICENSE = 13008 # Unlicensed API
- EFSDOESNOTEXIST = 13040 # FS does not exist
- EFSOFFLINE = 13042 # FS is offline.
- EFSNAMEINVALID = 13044 # FS Name invalid
- ENOSPACE = 13062 # Not enough space
- ESERVICENOTLICENSED = 13902 # Not licensed
- ECLONE_NAME_EXISTS = 14952 # Clone with same name exists
- ECLONE_LICENSE_EXPIRED = 14955 # Not licensed
- ECLONE_NOT_LICENSED = 14956 # Not licensed
-
- (LSM_VOL_PREFIX, LSM_INIT_PREFIX) = ('lsm_lun_container', 'lsm_init_')
-
- def _invoke(self, command, parameters=None):
-
- rc = netapp_filer(self.host, self.username, self.password,
- self.timeout, command, parameters, self.ssl)
-
- t = rc['netapp']['results']['attrib']
-
- if t['status'] != 'passed':
- raise FilerError(t['errno'], t['reason'])
-
- return rc['netapp']['results']
-
- def __init__(self, host, username, password, timeout, ssl=True):
- self.host = host
- self.username = username
- self.password = password
- self.timeout = timeout
- self.ssl = ssl
-
- def system_info(self):
- rc = self._invoke('system-get-info')
- return rc['system-info']
-
- def validate(self):
- #TODO: Validate that everything we need to function is available?
- self._invoke('system-api-list')
- return None
-
- def disks(self):
- disks = self._invoke('disk-list-info')
- return disks['disk-details']['disk-detail-info']
-
- def aggregates(self, aggr_name=None):
- """
- Return a list of aggregates
- If aggr_name provided, return [na_aggr]
- """
- if aggr_name:
- pools = self._invoke('aggr-list-info', {'aggregate': aggr_name})
- else:
- pools = self._invoke('aggr-list-info')
- tmp = pools['aggregates']['aggr-info']
- return to_list(tmp)
-
- def aggregate_volume_names(self, aggr_name):
- """
- Return a list of volume names that are on an aggregate
- """
- vol_names = []
- rc = self._invoke('aggr-list-info', {'aggregate': aggr_name})
-
- aggr = rc['aggregates']['aggr-info']
-
- if aggr is not None and aggr['volumes'] is not None:
- vols = aggr['volumes']['contained-volume-info']
- vol_names = [e['name'] for e in to_list(vols)]
- return vol_names
-
- def lun_build_name(self, volume_name, file_name):
- """
- Given a volume name and file return full path"
- """
- return '/vol/%s/%s' % (volume_name, file_name)
-
- def luns_get_specific(self, aggr, na_lun_name=None, na_volume_name=None):
- """
- Return all logical units, or information about one or for all those
- on a volume name.
- """
- rc = []
-
- if na_lun_name is not None:
- luns = self._invoke('lun-list-info', {'path': na_lun_name})
- elif na_volume_name is not None:
- luns = self._invoke('lun-list-info',
- {'volume-name': na_volume_name})
- else:
- luns = self._invoke('lun-list-info')
-
- return to_list(luns['luns']['lun-info'])
-
- def _get_aggr_info(self):
- aggrs = self._invoke('aggr-list-info')
- tmp = to_list(aggrs['aggregates']['aggr-info'])
- return [x for x in tmp if x['volumes'] is not None]
-
- def luns_get_all(self):
- """
- Return all lun-info
- """
- try:
- return to_list(self._invoke('lun-list-info')['luns']['lun-info'])
- except TypeError:
- # No LUN found.
- return []
-
- def lun_min_size(self):
- return self._invoke('lun-get-minsize', {'type': 'image'})['min-size']
-
- def lun_create(self, full_path_name, size_bytes, flag_thin=False):
- """
- Creates a lun
- If flag_thin set to True, will set 'space-reservation-enabled' as
- 'false' which means "create a LUN without any space being reserved".
- """
- params = {'path': full_path_name,
- 'size': size_bytes}
- if flag_thin is True:
- params['space-reservation-enabled'] = 'false'
-
- self._invoke('lun-create-by-size', params)
-
- def lun_delete(self, lun_path):
- """
- Deletes a lun given a lun path
- """
- self._invoke('lun-destroy', {'path': lun_path})
-
- def lun_resize(self, lun_path, size_bytes):
- """
- Re-sizes a lun
- """
- self._invoke('lun-resize', {'path': lun_path, 'size': size_bytes,
- 'force': 'true'})
-
- def volume_resize(self, na_vol_name, size_diff_kb):
- """
- Given a NetApp volume name and a size change in kb, re-size the
- NetApp volume.
- """
- params = {'volume': na_vol_name}
-
- if size_diff_kb > 0:
- params['new-size'] = '+' + str(size_diff_kb) + 'k'
- else:
- params['new-size'] = str(size_diff_kb) + 'k'
-
- self._invoke('volume-size', params)
- return None
-
- def volumes(self, volume_name=None):
- """
- Return a list of NetApp volumes
- """
- if not volume_name:
- v = self._invoke('volume-list-info')
- else:
- v = self._invoke('volume-list-info', {'volume': volume_name})
-
- t = v['volumes']['volume-info']
- rc = to_list(t)
- return rc
-
- def volume_create(self, aggr_name, vol_name, size_in_bytes):
- """
- Creates a volume given an aggr_name, volume name and size in bytes.
- """
- params = {'containing-aggr-name': aggr_name,
- 'size': int(size_in_bytes * 1.30),
- #There must be a better way to account for this
- 'volume': vol_name}
-
- self._invoke('volume-create', params)
-
- #Turn off scheduled snapshots
- self._invoke('volume-set-option', {'volume': vol_name,
- 'option-name': 'nosnap',
- 'option-value': 'on', })
-
- #Turn off auto export!
- self.nfs_export_remove(['/vol/' + vol_name])
-
- def volume_clone(self, src_volume, dest_volume, snapshot=None):
- """
- Clones a volume given a source volume name, destination volume name
- and optional backing snapshot.
- """
- params = {'parent-volume': src_volume, 'volume': dest_volume}
- if snapshot:
- params['parent-snapshot'] = snapshot.name
- self._invoke('volume-clone-create', params)
-
- def volume_delete(self, vol_name):
- """
- Deletes a volume and everything on it.
- """
- online = False
-
- try:
- self._invoke('volume-offline', {'name': vol_name})
- online = True
- except FilerError as f_error:
- if f_error.errno != Filer.EFSDOESNOTEXIST:
- raise
-
- try:
- self._invoke('volume-destroy', {'name': vol_name})
- except FilerError as f_error:
- #If the volume was online, we will return it to same status
- # Store the original exception information
- exception_info = sys.exc_info()
-
- if online:
- try:
- self._invoke('volume-online', {'name': vol_name})
- except FilerError:
- pass
- raise exception_info[1], None, exception_info[2]
-
- def volume_names(self):
- """
- Return a list of volume names
- """
- vols = self.volumes()
- return [v['name'] for v in vols]
-
- def clone(self, source_path, dest_path, backing_snapshot=None,
- ranges=None):
- """
- Creates a file clone
- """
- params = {'source-path': source_path}
-
- #You can have source == dest, but if you do you can only specify source
- if source_path != dest_path:
- params['destination-path'] = dest_path
-
- if backing_snapshot:
- raise FilerError(ErrorNumber.NO_SUPPORT,
- "Support for backing luns not implemented "
- "for this API version")
- #params['snapshot-name']= backing_snapshot
-
- if ranges:
- block_ranges = []
- for r in ranges:
- values = {'block-count': r.block_count,
- 'destination-block-number': r.dest_block,
- 'source-block-number': r.src_block}
-
- block_ranges.append({'block-range': values})
-
- params['block-ranges'] = block_ranges
-
- rc = self._invoke('clone-start', params)
-
- c_id = rc['clone-id']
-
- while True:
- progress = self._invoke('clone-list-status',
- {'clone-id': c_id})
-
- # According to the spec the output is optional, if not present
- # then we are done and good
- if 'status' in progress:
- progress = progress['status']['ops-info']
-
- if progress['clone-state'] == 'failed':
- self._invoke('clone-clear', {'clone-id': c_id})
- raise FilerError(progress['error'], progress['reason'])
- elif progress['clone-state'] == 'running' \
- or progress['clone-state'] == 'fail exit':
- # State needs to transition to failed before we can
- # clear it!
- time.sleep(0.2) # Don't hog cpu
- elif progress['clone-state'] == 'completed':
- return
- else:
- raise FilerError(ErrorNumber.NO_SUPPORT,
- 'Unexpected state=' +
- progress['clone-state'])
- else:
- return
-
- def lun_online(self, lun_path):
- self._invoke('lun-online', {'path': lun_path})
-
- def lun_offline(self, lun_path):
- self._invoke('lun-offline', {'path': lun_path})
-
- def igroups(self, group_name=None):
- rc = []
-
- if group_name:
- g = self._invoke('igroup-list-info',
- {'initiator-group-name': group_name})
- else:
- g = self._invoke('igroup-list-info')
-
- if g['initiator-groups']:
- rc = to_list(g['initiator-groups']['initiator-group-info'])
- return rc
-
- def igroup_create(self, name, igroup_type):
- params = {'initiator-group-name': name,
- 'initiator-group-type': igroup_type}
- self._invoke('igroup-create', params)
-
- def igroup_delete(self, name):
- self._invoke('igroup-destroy', {'initiator-group-name': name})
-
- @staticmethod
- def encode(password):
- rc4 = RC4.RC4()
- rc4.set_key("#u82fyi8S5\017pPemw")
- return hexlify(rc4.update(password))
-
- def iscsi_initiator_add_auth(self, initiator, user_name, password,
- out_user, out_password):
- pw = self.encode(password)
-
- args = {'initiator': initiator}
-
- if user_name and len(user_name) and password and len(password):
- args.update({'user-name': user_name,
- 'password': pw, 'auth-type': "CHAP"})
-
- if out_user and len(out_user) and \
- out_password and len(out_password):
- args.update({'outbound-user-name': out_user,
- 'outbound-password': out_password})
- else:
- args.update({'initiator': initiator, 'auth-type': "none"})
-
- self._invoke('iscsi-initiator-add-auth', args)
-
- def igroup_add_initiator(self, ig, initiator):
- self._invoke('igroup-add',
- {'initiator-group-name': ig, 'initiator': initiator})
-
- def igroup_del_initiator(self, ig, initiator):
- self._invoke('igroup-remove',
- {'initiator-group-name': ig,
- 'initiator': initiator,
- 'force': 'true'})
-
- def lun_map(self, igroup, lun_path):
- self._invoke('lun-map', {'initiator-group': igroup, 'path': lun_path})
-
- def lun_unmap(self, igroup, lun_path):
- self._invoke(
- 'lun-unmap', {'initiator-group': igroup, 'path': lun_path})
-
- def lun_map_list_info(self, lun_path):
- initiator_groups = []
- rc = self._invoke('lun-map-list-info', {'path': lun_path})
- if rc['initiator-groups'] is not None:
- igi = to_list(rc['initiator-groups'])
- for i in igi:
- group_name = i['initiator-group-info']['initiator-group-name']
- initiator_groups.append(self.igroups(group_name)[0])
-
- return initiator_groups
-
- def lun_initiator_list_map_info(self, initiator_id, initiator_group_name):
- """
- Given an initiator_id and initiator group name, return a list of
- lun-info
- """
- luns = []
-
- rc = self._invoke('lun-initiator-list-map-info',
- {'initiator': initiator_id})
-
- if rc['lun-maps']:
-
- lun_name_list = to_list(rc['lun-maps']['lun-map-info'])
-
- #Get all the lun with information about aggr
- all_luns = self.luns_get_all()
-
- for l in lun_name_list:
- if l['initiator-group'] == initiator_group_name:
- for al in all_luns:
- if al['path'] == l['path']:
- luns.append(al)
- return luns
-
- def snapshots(self, volume_name):
- rc = []
- args = {'target-type': 'volume', 'target-name': volume_name}
- ss = self._invoke('snapshot-list-info', args)
- if ss['snapshots']:
- rc = to_list(ss['snapshots']['snapshot-info'])
- return rc
-
- def snapshot_create(self, volume_name, snapshot_name):
- self._invoke('snapshot-create', {'volume': volume_name,
- 'snapshot': snapshot_name})
- return [v for v in self.snapshots(volume_name)
- if v['name'] == snapshot_name][0]
-
- def snapshot_file_restore_num(self):
- """
- Returns the number of executing file restore snapshots.
- """
- rc = self._invoke('snapshot-restore-file-info')
- if 'sfsr-in-progress' in rc:
- return int(rc['sfsr-in-progress'])
-
- return 0
-
- def snapshot_restore_volume(self, fs_name, snapshot_name):
- """
- Restores all files on a volume
- """
- params = {'snapshot': snapshot_name, 'volume': fs_name}
- self._invoke('snapshot-restore-volume', params)
-
- def snapshot_restore_file(self, snapshot_name, restore_path, restore_file):
- """
- Restore a list of files
- """
- params = {'snapshot': snapshot_name, 'path': restore_path}
-
- if restore_file:
- params['restore-path'] = restore_file
-
- self._invoke('snapshot-restore-file', params)
-
- def snapshot_delete(self, volume_name, snapshot_name):
- self._invoke('snapshot-delete',
- {'volume': volume_name, 'snapshot': snapshot_name})
-
- def export_auth_types(self):
- rc = self._invoke('nfs-get-supported-sec-flavors')
- return [e['flavor'] for e in
- to_list(rc['sec-flavor']['sec-flavor-info'])]
-
- @staticmethod
- def _build_list(pylist, list_name, elem_name):
- """
- Given a python list, build the appropriate dict that contains the
- list items so that it can be converted to xml to be sent on the wire.
- """
- return [{list_name: {elem_name: l}} for l in pylist]
-
- @staticmethod
- def _build_export_fs_all():
- return Filer._build_list(
- ['true'], 'exports-hostname-info', 'all-hosts')
-
- @staticmethod
- def _build_export_fs_list(hosts):
- if hosts[0] == '*':
- return Filer._build_export_fs_all()
- else:
- return Filer._build_list(hosts, 'exports-hostname-info', 'name')
-
- def _build_export_rules(self, volume_path, export_path, ro_list, rw_list,
- root_list, anonuid=None, sec_flavor=None):
- """
- Common logic to build up the rules for nfs
- """
-
- #One of the more complicated data structures to push down to the
- #controller
- rule = {'pathname': volume_path}
- if volume_path != export_path:
- rule['actual-pathname'] = volume_path
- rule['pathname'] = export_path
-
- rule['security-rules'] = {}
- rule['security-rules']['security-rule-info'] = {}
-
- r = rule['security-rules']['security-rule-info']
-
- if len(ro_list):
- r['read-only'] = Filer._build_export_fs_list(ro_list)
-
- if len(rw_list):
- r['read-write'] = Filer._build_export_fs_list(rw_list)
-
- if len(root_list):
- r['root'] = Filer._build_export_fs_list(root_list)
-
- if anonuid:
- uid = long(anonuid)
- if uid != -1 and uid != 0xFFFFFFFFFFFFFFFF:
- r['anon'] = str(uid)
-
- if sec_flavor:
- r['sec-flavor'] = Filer._build_list(
- [sec_flavor], 'sec-flavor-info', 'flavor')
-
- return rule
-
- def nfs_export_fs2(self, volume_path, export_path, ro_list, rw_list,
- root_list, anonuid=None, sec_flavor=None):
- """
- NFS export a volume.
- """
-
- rule = self._build_export_rules(
- volume_path, export_path, ro_list, rw_list, root_list, anonuid,
- sec_flavor)
-
- params = {'persistent': 'true',
- 'rules': {'exports-rule-info-2': [rule]}, 'verbose': 'true'}
- self._invoke('nfs-exportfs-append-rules-2', params)
-
- def nfs_export_fs_modify2(self, volume_path, export_path, ro_list, rw_list,
- root_list, anonuid=None, sec_flavor=None):
-
- """
- Modifies an existing rule.
- """
- rule = self._build_export_rules(
- volume_path, export_path, ro_list, rw_list, root_list, anonuid,
- sec_flavor)
-
- params = {
- 'persistent': 'true', 'rule': {'exports-rule-info-2': [rule]}}
- self._invoke('nfs-exportfs-modify-rule-2', params)
-
- def nfs_export_remove(self, export_paths):
- """
- Removes an existing export
- """
- assert (type(export_paths) is list)
- paths = Filer._build_list(export_paths, 'pathname-info', 'name')
- self._invoke('nfs-exportfs-delete-rules',
- {'pathnames': paths, 'persistent': 'true'})
-
- def nfs_exports(self):
- """
- Returns a list of exports (in hash form)
- """
- rc = []
- exports = self._invoke('nfs-exportfs-list-rules')
- if 'rules' in exports and exports['rules']:
- rc = to_list(exports['rules']['exports-rule-info'])
- return rc
-
- def volume_children(self, volume):
- params = {'volume': volume}
-
- rc = self._invoke('volume-list-info', params)
-
- if 'clone-children' in rc['volumes']['volume-info']:
- tmp = rc['volumes']['volume-info']['clone-children'][
- 'clone-child-info']
- rc = [c['clone-child-name'] for c in to_list(tmp)]
- else:
- rc = None
-
- return rc
-
- def volume_split_clone(self, volume):
- self._invoke('volume-clone-split-start', {'volume': volume})
-
- def volume_split_status(self):
- result = []
-
- rc = self._invoke('volume-clone-split-status')
-
- if 'clone-split-details' in rc:
- tmp = rc['clone-split-details']['clone-split-detail-info']
- result = [r['name'] for r in to_list(tmp)]
-
- return result
-
- def fcp_list(self):
- fcp_list = []
-
- try:
-
- rc = self._invoke('fcp-adapter-list-info')
-
- if 'fcp-config-adapters' in rc:
- if 'fcp-config-adapter-info' in rc['fcp-config-adapters']:
- fc_config = rc['fcp-config-adapters']
- adapters = fc_config['fcp-config-adapter-info']
- for f in adapters:
- fcp_list.append(dict(addr=f['port-name'],
- adapter=f['adapter']))
- except FilerError as na:
- if na.errno != Filer.EAPILICENSE:
- raise
-
- return fcp_list
-
- def iscsi_node_name(self):
- try:
- rc = self._invoke('iscsi-node-get-name')
- if 'node-name' in rc:
- return rc['node-name']
- except FilerError as na:
- if na.errno != Filer.EAPILICENSE:
- raise
- return None
-
- def interface_get_infos(self):
- i_info = {}
-
- rc = self._invoke('net-ifconfig-get')
-
- if 'interface-config-info' in rc:
- i_config = rc['interface-config-info']
- if 'interface-config-info' in i_config:
- tmp = to_list(i_config['interface-config-info'])
- for i in tmp:
- i_info[i['interface-name']] = i
-
- return i_info
-
- def iscsi_list(self):
- i_list = []
-
- # Get interface information
- i_info = self.interface_get_infos()
-
- try:
- rc = self._invoke('iscsi-portal-list-info')
-
- if 'iscsi-portal-list-entries' in rc:
- portal_entries = rc['iscsi-portal-list-entries']
- if 'iscsi-portal-list-entry-info' in portal_entries:
- tmp = portal_entries['iscsi-portal-list-entry-info']
- portals = to_list(tmp)
- for p in portals:
- mac = i_info[p['interface-name']]['mac-address']
- i_list.append(dict(interface=p['interface-name'],
- ip=p['ip-address'],
- port=p['ip-port'],
- mac=mac))
- except FilerError as na:
- if na.errno != Filer.EAPILICENSE:
- raise
-
- return i_list
-
-if __name__ == '__main__':
- try:
- #TODO: Need some unit test code
- pass
-
- except FilerError as fe:
- print 'Errno=', fe.errno, 'reason=', fe.reason
diff --git a/plugin/ontap/ontap.py b/plugin/ontap/ontap.py
deleted file mode 100644
index f9f1f56..0000000
--- a/plugin/ontap/ontap.py
+++ /dev/null
@@ -1,1332 +0,0 @@
-# Copyright (C) 2011-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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
-# USA
-#
-# Author: tasleson
-# Gris Ge <***@redhat.com>
-
-import os
-import urlparse
-import copy
-
-import na
-from lsm import (Volume, FileSystem, FsSnapshot, NfsExport,
- AccessGroup, System, Capabilities, Disk, Pool,
- IStorageAreaNetwork, INfs, LsmError, ErrorNumber, JobStatus,
- md5, VERSION, common_urllib2_error_handler,
- search_property, TargetPort)
-
-#Maps na to lsm, this is expected to expand over time.
-e_map = {
- na.Filer.ENOSPC: ErrorNumber.NOT_ENOUGH_SPACE,
- na.Filer.ENO_SUCH_VOLUME: ErrorNumber.NOT_FOUND_VOLUME,
- na.Filer.ESIZE_TOO_LARGE: ErrorNumber.NOT_ENOUGH_SPACE,
- na.Filer.ENOSPACE: ErrorNumber.NOT_ENOUGH_SPACE,
- na.Filer.ENO_SUCH_FS: ErrorNumber.NOT_FOUND_FS,
- na.Filer.EAPILICENSE: ErrorNumber.NOT_LICENSED,
- na.Filer.EFSDOESNOTEXIST: ErrorNumber.NOT_FOUND_FS,
- na.Filer.EFSOFFLINE: ErrorNumber.NO_SUPPORT_ONLINE_CHANGE,
- na.Filer.EFSNAMEINVALID: ErrorNumber.INVALID_ARGUMENT,
- na.Filer.ESERVICENOTLICENSED: ErrorNumber.NOT_LICENSED,
- na.Filer.ECLONE_LICENSE_EXPIRED: ErrorNumber.NOT_LICENSED,
- na.Filer.ECLONE_NOT_LICENSED: ErrorNumber.NOT_LICENSED,
- na.Filer.EINVALID_ISCSI_NAME: ErrorNumber.INVALID_ARGUMENT,
- na.Filer.ETIMEOUT: ErrorNumber.TIMEOUT,
- na.Filer.EUNKNOWN: ErrorNumber.PLUGIN_BUG,
- na.Filer.EDUPE_VOLUME_PATH: ErrorNumber.NAME_CONFLICT,
- na.Filer.ENAVOL_NAME_DUPE: ErrorNumber.NAME_CONFLICT,
- na.Filer.ECLONE_NAME_EXISTS: ErrorNumber.NAME_CONFLICT
-}
-
-
-def error_map(oe):
- """
- Maps a ontap error code to a lsm error code.
- Returns a tuple containing error code and text.
- """
- if oe.errno in e_map:
- return e_map[oe.errno], oe.reason
- else:
- return ErrorNumber.PLUGIN_BUG, \
- oe.reason + " (vendor error code= " + str(oe.errno) + ")"
-
-
-def handle_ontap_errors(method):
- def na_wrapper(*args, **kwargs):
- try:
- return method(*args, **kwargs)
- except LsmError:
- raise
- except na.FilerError as oe:
- error_code, error_msg = error_map(oe)
- raise LsmError(error_code, error_msg)
- except Exception as e:
- common_urllib2_error_handler(e)
-
- return na_wrapper
-
-
-_INIT_TYPE_CONV = {
- 'iscsi': AccessGroup.INIT_TYPE_ISCSI_IQN,
- 'fcp': AccessGroup.INIT_TYPE_WWPN,
- 'mixed': AccessGroup.INIT_TYPE_ISCSI_WWPN_MIXED,
-}
-
-
-def _na_init_type_to_lsm(na_ag):
- if 'initiator-group-type' in na_ag:
- if na_ag['initiator-group-type'] in _INIT_TYPE_CONV.keys():
- return _INIT_TYPE_CONV[na_ag['initiator-group-type']]
- else:
- return AccessGroup.INIT_TYPE_OTHER
- return AccessGroup.INIT_TYPE_UNKNOWN
-
-
-def _lsm_vol_to_na_vol_path(vol):
- return vol.id
-
-
-class Ontap(IStorageAreaNetwork, INfs):
- TMO_CONV = 1000.0
-
- (SS_JOB, SPLIT_JOB) = ('ontap-ss-file-restore', 'ontap-clone-split')
-
- VOLUME_PREFIX = '/vol'
-
- NA_VOL_STATUS_TO_LSM = {
- 'offline': Pool.STATUS_STOPPED,
- 'online': Pool.STATUS_OK,
- 'restricted': Pool.STATUS_OTHER,
- 'unknown': Pool.STATUS_UNKNOWN,
- 'creating': Pool.STATUS_INITIALIZING,
- 'failed': Pool.STATUS_ERROR,
- 'partial': Pool.STATUS_ERROR,
-
- }
-
- NA_VOL_STATUS_TO_LSM_STATUS_INFO = {
- 'partial': 'all the disks in the volume are not available.',
- 'restricted': 'volume is restricted to protocol accesses',
- }
-
- # strip size: http://www.netapp.com/us/media/tr-3001.pdf
- _STRIP_SIZE = 4096
- _OPT_IO_SIZE = 65536
-
- def __init__(self):
- self.f = None
- self.sys_info = None
-
- @handle_ontap_errors
- def plugin_register(self, uri, password, timeout, flags=0):
- ssl = False
- u = urlparse.urlparse(uri)
-
- if u.scheme.lower() == 'ontap+ssl':
- ssl = True
-
- self.f = na.Filer(u.hostname, u.username, password,
- timeout / Ontap.TMO_CONV, ssl)
- #Smoke test
- i = self.f.system_info()
- #TODO Get real filer status
- self.sys_info = System(i['system-id'], i['system-name'],
- System.STATUS_OK, '')
- return self.f.validate()
-
- def time_out_set(self, ms, flags=0):
- self.f.timeout = int(ms / Ontap.TMO_CONV)
-
- def time_out_get(self, flags=0):
- return int(self.f.timeout * Ontap.TMO_CONV)
-
- def plugin_unregister(self, flags=0):
- pass
-
- @staticmethod
- def _create_vpd(sn):
- """
- Construct the vpd83 for this lun
- """
- return "60a98000" + ''.join(["%02x" % ord(x) for x in sn])
-
- @staticmethod
- def _lsm_lun_name(path_name):
- return os.path.basename(path_name)
-
- def _lun(self, l):
- block_size = int(l['block-size'])
- num_blocks = int(l['size']) / block_size
- pool_id = "/".join(l['path'].split('/')[0:3])
- vol_id = l['path']
- vol_name = os.path.basename(vol_id)
- admin_state = Volume.ADMIN_STATE_ENABLED
- if l['online'] == 'false':
- admin_state = Volume.ADMIN_STATE_DISABLED
-
- return Volume(vol_id, vol_name,
- Ontap._create_vpd(l['serial-number']), block_size,
- num_blocks, admin_state, self.sys_info.id, pool_id)
-
- def _vol(self, v, pools=None):
- pool_name = v['containing-aggregate']
-
- if pools is None:
- pools = self.pools()
-
- for p in pools:
- if p.name == pool_name:
- return FileSystem(v['uuid'], v['name'], int(v['size-total']),
- int(v['size-available']), p.id,
- self.sys_info.id)
-
- @staticmethod
- def _ss(s):
- #If we use the newer API we can use the uuid instead of this fake
- #md5 one
- return FsSnapshot(md5(s['name'] + s['access-time']), s['name'],
- s['access-time'])
-
- _NA_DISK_TYPE_TO_LSM = {
- 'ATA': Disk.TYPE_ATA,
- 'BSAS': Disk.TYPE_SATA,
- 'EATA': Disk.TYPE_ATA,
- 'FCAL': Disk.TYPE_FC,
- 'FSAS': Disk.TYPE_NL_SAS,
- 'LUN': Disk.TYPE_OTHER,
- 'MSATA': Disk.TYPE_SATA,
- 'SAS': Disk.TYPE_SAS,
- 'SATA': Disk.TYPE_SATA,
- 'SCSI': Disk.TYPE_SCSI,
- 'SSD': Disk.TYPE_SSD,
- 'XATA': Disk.TYPE_ATA,
- 'XSAS': Disk.TYPE_SAS,
- 'unknown': Disk.TYPE_UNKNOWN,
- }
-
- @staticmethod
- def _disk_type_of(na_disk):
- """
- Convert na_disk['effective-disk-type'] to LSM disk type.
- """
- na_disk_type = na_disk['effective-disk-type']
- if na_disk_type in Ontap._NA_DISK_TYPE_TO_LSM.keys():
- return Ontap._NA_DISK_TYPE_TO_LSM[na_disk_type]
- return Disk.TYPE_UNKNOWN
-
- @staticmethod
- def _disk_id(na_disk):
- """
- The md5sum of na_disk['disk-uid']
- """
- return md5(na_disk['disk-uid'])
-
- @staticmethod
- def _status_of_na_disk(na_disk):
- """
- Retrieve Disk.status from NetApp ONTAP disk-detail-info.
- TODO: API document does not provide enough explaination.
- Need lab test to verify.
- """
- status = 0
-
- if 'raid-state' in na_disk:
- rs = na_disk['raid-state']
- if rs == "broken":
- if na_disk['broken-details'] == 'admin removed' or \
- na_disk['broken-details'] == 'admin failed':
- status |= Disk.STATUS_REMOVED
- elif na_disk['broken-details'] == 'admin testing':
- status |= Disk.STATUS_STOPPED | \
- Disk.STATUS_MAINTENANCE_MODE
- else:
- status |= Disk.STATUS_ERROR
- elif rs == "unknown":
- status |= Disk.STATUS_UNKNOWN
- elif rs == 'zeroing':
- status |= Disk.STATUS_INITIALIZING | Disk.STATUS_SPARE_DISK
- elif rs == 'reconstructing' or rs == 'copy':
- # "reconstructing' should be a pool status, not disk status.
- # disk under reconstructing should be considered as OK.
- status |= Disk.STATUS_OK | Disk.STATUS_RECONSTRUCT
- elif rs == 'spare':
- if 'is-zeroed' in na_disk and na_disk['is-zeroed'] == 'true':
- status |= Disk.STATUS_OK | Disk.STATUS_SPARE_DISK
- else:
- # If spare disk is not zerored, it will be automaticlly
- # zeroed before assigned to aggregate.
- # Hence we consider non-zeroed spare disks as stopped
- # spare disks.
- status |= Disk.STATUS_STOPPED | Disk.STATUS_SPARE_DISK
- elif rs == 'present':
- status |= Disk.STATUS_OK
- elif rs == 'partner':
- # Before we have good way to connect two controller,
- # we have to mark partner disk as OTHER
- return Disk.STATUS_OTHER
-
- if 'is-prefailed' in na_disk and na_disk['is-prefailed'] == 'true':
- status |= Disk.STATUS_STOPPING
-
- if 'is-offline' in na_disk and na_disk['is-offline'] == 'true':
- status |= Disk.STATUS_ERROR
-
- if 'aggregate' not in na_disk:
- # All free disks are automatically marked as spare disks. They
- # could easily convert to data or parity disk without any
- # explicit command.
- status |= Disk.STATUS_FREE
-
- if status == 0:
- status = Disk.STATUS_UNKNOWN
-
- return status
-
- @staticmethod
- def _status_info_of_na_disk(na_disk):
- """
- Provide more explainaion in Disk.status_info.
- TODO: API document does not provide enough explaination.
- Need lab test to verify.
- """
- status_info = ''
- if 'raid-state' in na_disk:
- rs = na_disk['raid-state']
- if rs == 'reconstructing':
- status_info = "Reconstruction progress: %s%%" %\
- str(na_disk['reconstruction-percent'])
- if 'broken-details' in na_disk:
- status_info = na_disk['broken-details']
- return status_info
-
- def _disk(self, d, flag):
- status = Ontap._status_of_na_disk(d)
- return Disk(self._disk_id(d), d['name'],
- Ontap._disk_type_of(d),
- int(d['bytes-per-sector']), int(d['physical-blocks']),
- status, self.sys_info.id)
-
- @handle_ontap_errors
- def volumes(self, search_key=None, search_value=None, flags=0):
- luns = self.f.luns_get_all()
- return search_property(
- [self._lun(l) for l in luns], search_key, search_value)
-
- # This is based on NetApp ONTAP Manual pages:
- # https://library.netapp.com/ecmdocs/ECMP1196890/html/man1/na_aggr.1.html
- _AGGR_RAID_STATUS_CONV = {
- 'normal': Pool.STATUS_OK,
- 'verifying': Pool.STATUS_VERIFYING,
- 'copying': Pool.STATUS_INITIALIZING,
- 'ironing': Pool.STATUS_VERIFYING,
- 'resyncing': Pool.STATUS_RECONSTRUCTING,
- 'mirror degraded': Pool.STATUS_DEGRADED,
- 'needs check': Pool.STATUS_ERROR,
- 'initializing': Pool.STATUS_INITIALIZING,
- 'growing': Pool.STATUS_GROWING,
- 'partial': Pool.STATUS_ERROR,
- 'noparity': Pool.STATUS_OTHER,
- 'degraded': Pool.STATUS_DEGRADED,
- 'reconstruct': Pool.STATUS_RECONSTRUCTING,
- 'out-of-date': Pool.STATUS_OTHER,
- 'foreign': Pool.STATUS_OTHER,
- }
-
- _AGGR_RAID_ST_INFO_CONV = {
- 'copying': 'The aggregate is currently the target aggregate of an'
- 'active aggr copy operation. ',
- 'invalid': 'The aggregate does not contain any volume and no volume'
- 'can be added to it. Typically this happens after an '
- 'aborted aggregate copy operation. ',
- 'needs check': 'A WAFL consistency check needs to be performed on '
- 'the aggregate. ',
- 'partial': 'Two or more disks are missing.',
- # noparity, no document found.
- 'noparity': 'NetApp ONTAP mark this aggregate as "noparity". ',
- # out-of-data: no document found.
- 'out-of-date': 'NetApp ONTAP mark this aggregate as "out-of-date". ',
- 'foreign': "The disks that the aggregate contains were moved to the"
- "current node from another node. "
- }
-
- @staticmethod
- def _status_of_na_aggr(na_aggr):
- """
- Use aggr-info['state'] and ['raid-status'] for Pool.status and
- status_info.
- Return (status, status_info)
- """
- status = 0
- status_info = ''
- na_aggr_raid_status_list = list(
- x.strip() for x in na_aggr['raid-status'].split(','))
- for na_aggr_raid_status in na_aggr_raid_status_list:
- if na_aggr_raid_status in Ontap._AGGR_RAID_STATUS_CONV.keys():
- status |= Ontap._AGGR_RAID_STATUS_CONV[na_aggr_raid_status]
- if na_aggr_raid_status in Ontap._AGGR_RAID_ST_INFO_CONV.keys():
- status_info += \
- Ontap._AGGR_RAID_ST_INFO_CONV[na_aggr_raid_status]
-
- # Now check na_aggr['state']
- na_aggr_state = na_aggr['state'].strip()
-
- if na_aggr_state == 'online' or na_aggr_state == 'creating':
- pass
- elif na_aggr_state == 'offline':
- # When aggr is marked as offline, the restruction is stoped.
- if status & Pool.STATUS_RECONSTRUCTING:
- status -= Pool.STATUS_RECONSTRUCTING
- status |= Pool.STATUS_DEGRADED
- status |= Pool.STATUS_STOPPED
- else:
- status_info += "%s " % na_aggr_state
-
- if status == 0:
- status = Pool.STATUS_OK
-
- return status, status_info
-
- def _pool_from_na_aggr(self, na_aggr, na_disks, flags):
- pool_id = na_aggr['name']
- pool_name = na_aggr['name']
- total_space = int(na_aggr['size-total'])
- free_space = int(na_aggr['size-available'])
- system_id = self.sys_info.id
- (status, status_info) = self._status_of_na_aggr(na_aggr)
-
- element_type = (Pool.ELEMENT_TYPE_POOL | Pool.ELEMENT_TYPE_FS)
-
- # The system aggregate can be used to create both FS and volumes, but
- # you can't take it offline or delete it.
- if pool_name == 'aggr0':
- element_type = element_type | Pool.ELEMENT_TYPE_SYS_RESERVED
-
- return Pool(pool_id, pool_name, element_type, 0, total_space,
- free_space, status, status_info, system_id)
-
- @staticmethod
- def _status_info_of_na_vol(na_vol):
- na_vol_state = na_vol['state']
- if na_vol_state in Ontap.NA_VOL_STATUS_TO_LSM_STATUS_INFO.keys():
- return Ontap.NA_VOL_STATUS_TO_LSM_STATUS_INFO[na_vol_state]
- return ''
-
- @staticmethod
- def _pool_id_of_na_vol_name(na_vol_name):
- return "%s/%s" % (Ontap.VOLUME_PREFIX, na_vol_name)
-
- def _pool_from_na_vol(self, na_vol, na_aggrs, flags):
- element_type = Pool.ELEMENT_TYPE_VOLUME
- # Thin provisioning is controled by:
- # 1. NetApp Volume level:
- # 'guarantee' option and 'fractional_reserve' option.
- # If 'guarantee' is 'file', 'fractional_reserve' is forced to
- # be 100, we can create Thin LUN and full allocated LUN.
- # If 'guarantee' is 'volume' and 'fractional_reserve' is 100, we
- # can create full LUN.
- # If 'guarantee' is 'volume' and 'fractional_reserve' is less
- # than 100, we can only create thin LUN.
- # If 'guarantee' is 'none', we can only create thin LUN.
- # 2. NetApp LUN level:
- # If option 'reservation' is enabled, it's a full allocated LUN
- # when parent NetApp volume allowed.
- # If option 'reservation' is disabled, it's a thin LUN if
- # parent NetApp volume allowed.
-
- if 'space-reserve' in na_vol and \
- 'space-reserve-enabled' in na_vol and \
- 'reserve' in na_vol and \
- na_vol['space-reserve-enabled'] == 'true':
- # 'space-reserve' and 'space-reserve-enabled' might not appear if
- # the flexible volume is restricted or offline.
- if na_vol['space-reserve'] == 'file':
- # space-reserve: 'file' means only LUN or file marked as
- # 'Space Reservation: enabled' will be reserve all space.
- element_type |= Pool.ELEMENT_TYPE_VOLUME_THIN
- element_type |= Pool.ELEMENT_TYPE_VOLUME_FULL
- elif na_vol['space-reserve'] == 'volume':
- # space-reserve: 'volume' means only LUN or file marked as
- # 'Space Reservation: enabled' will be reserve all space.
- if na_vol['reserve'] == na_vol['reserve-required']:
- # When 'reserve' == 'reserve-required' it means option
- # 'fractional_reserve' is set to 100, only with that we
- # can create full alocated LUN.
- element_type |= Pool.ELEMENT_TYPE_VOLUME_FULL
- else:
- element_type |= Pool.ELEMENT_TYPE_VOLUME_THIN
- elif na_vol['space-reserve'] == 'none':
- element_type |= Pool.ELEMENT_TYPE_VOLUME_THIN
-
- pool_name = na_vol['name']
- pool_id = self._pool_id_of_na_vol_name(na_vol['name'])
- total_space = int(na_vol['size-total'])
- free_space = int(na_vol['size-available'])
- system_id = self.sys_info.id
- status = Pool.STATUS_UNKNOWN
- status_info = ''
- if 'containing-aggregate' in na_vol:
- for na_aggr in na_aggrs:
- if na_aggr['name'] == na_vol['containing-aggregate']:
- status = self._status_of_na_aggr(na_aggr)[0]
- if not (status & Pool.STATUS_OK):
- status_info = "Parrent pool '%s'" \
- % na_aggr['name']
- break
-
- if status & Pool.STATUS_OK and na_vol['state'] == 'offline':
- status = Pool.STATUS_STOPPED
- status_info = 'Disabled by admin'
-
- # This volume should be noted that it is reserved for system
- # and thus cannot be removed.
- if pool_name == '/vol/vol0':
- element_type |= Pool.ELEMENT_TYPE_SYS_RESERVED
-
- return Pool(pool_id, pool_name, element_type, 0, total_space,
- free_space, status, status_info, system_id)
-
- @handle_ontap_errors
- def capabilities(self, system, flags=0):
- cap = Capabilities()
- cap.set(Capabilities.VOLUMES)
- cap.set(Capabilities.VOLUME_CREATE)
- cap.set(Capabilities.VOLUME_RESIZE)
- cap.set(Capabilities.VOLUME_REPLICATE)
- cap.set(Capabilities.VOLUME_REPLICATE_CLONE)
- cap.set(Capabilities.VOLUME_COPY_RANGE_BLOCK_SIZE)
- cap.set(Capabilities.VOLUME_COPY_RANGE)
- cap.set(Capabilities.VOLUME_COPY_RANGE_CLONE)
- cap.set(Capabilities.VOLUME_DELETE)
- cap.set(Capabilities.VOLUME_ENABLE)
- cap.set(Capabilities.VOLUME_DISABLE)
- cap.set(Capabilities.VOLUME_ISCSI_CHAP_AUTHENTICATION)
- cap.set(Capabilities.VOLUME_MASK)
- cap.set(Capabilities.VOLUME_UNMASK)
- cap.set(Capabilities.ACCESS_GROUPS)
- cap.set(Capabilities.ACCESS_GROUP_CREATE_WWPN)
- cap.set(Capabilities.ACCESS_GROUP_CREATE_ISCSI_IQN)
- cap.set(Capabilities.ACCESS_GROUP_DELETE)
- cap.set(Capabilities.ACCESS_GROUP_INITIATOR_ADD_WWPN)
- cap.set(Capabilities.ACCESS_GROUP_INITIATOR_ADD_ISCSI_IQN)
- cap.set(Capabilities.ACCESS_GROUP_INITIATOR_DELETE)
- cap.set(Capabilities.VOLUMES_ACCESSIBLE_BY_ACCESS_GROUP)
- cap.set(Capabilities.ACCESS_GROUPS_GRANTED_TO_VOLUME)
- cap.set(Capabilities.VOLUME_CHILD_DEPENDENCY)
- cap.set(Capabilities.VOLUME_CHILD_DEPENDENCY_RM)
- cap.set(Capabilities.FS)
- cap.set(Capabilities.FS_DELETE)
- cap.set(Capabilities.FS_RESIZE)
- cap.set(Capabilities.FS_CREATE)
- cap.set(Capabilities.FS_CLONE)
- cap.set(Capabilities.FILE_CLONE)
- cap.set(Capabilities.FS_SNAPSHOTS)
- cap.set(Capabilities.FS_SNAPSHOT_CREATE)
- cap.set(Capabilities.FS_SNAPSHOT_DELETE)
- cap.set(Capabilities.FS_SNAPSHOT_RESTORE)
- cap.set(Capabilities.FS_CHILD_DEPENDENCY)
- cap.set(Capabilities.FS_CHILD_DEPENDENCY_RM)
- cap.set(Capabilities.EXPORT_AUTH)
- cap.set(Capabilities.EXPORTS)
- cap.set(Capabilities.EXPORT_FS)
- cap.set(Capabilities.EXPORT_REMOVE)
- cap.set(Capabilities.EXPORT_CUSTOM_PATH)
- cap.set(Capabilities.TARGET_PORTS)
- cap.set(Capabilities.DISKS)
- cap.set(Capabilities.VOLUME_RAID_INFO)
- return cap
-
- @handle_ontap_errors
- def plugin_info(self, flags=0):
- return "NetApp Filer support", VERSION
-
- @handle_ontap_errors
- def disks(self, search_key=None, search_value=None, flags=0):
- disks = self.f.disks()
- return search_property(
- [self._disk(d, flags) for d in disks], search_key, search_value)
-
- @handle_ontap_errors
- def pools(self, search_key=None, search_value=None, flags=0):
- pools = []
- na_aggrs = self.f.aggregates()
- na_disks = []
- # We do extra flags check in order to save self.f.disks() calls
- # in case we have multiple aggregates.
- for na_aggr in na_aggrs:
- pools.extend([self._pool_from_na_aggr(na_aggr, na_disks, flags)])
- na_vols = self.f.volumes()
- for na_vol in na_vols:
- pools.extend([self._pool_from_na_vol(na_vol, na_aggrs, flags)])
- return search_property(pools, search_key, search_value)
-
- @handle_ontap_errors
- def systems(self, flags=0):
- return [self.sys_info]
-
- def _get_volume(self, vol_name, pool_id):
- return self._lun(self.f.luns_get_specific(pool_id, vol_name, None)[0])
-
- @handle_ontap_errors
- def volume_create(self, pool, volume_name, size_bytes, provisioning,
- flags=0):
-
- if not pool.element_type & Pool.ELEMENT_TYPE_VOLUME:
- raise LsmError(ErrorNumber.INVALID_ARGUMENT,
- "Pool not suitable for creating volumes")
-
- # Even pool is full or thin only pool, we still allow user to
- # create full or thin LUN in case that's what they intend to do so.
- # TODO: allow user to query provising status of certain LUN. We can
- # use THIN(not effective) or FULL(not effective) to indicate
- # pool setting not allow thin/full LUN yet, user can change pool
- # setting.
- # Wise user can check pool.element_type before creating full or thin
- # volume.
- flag_thin = False
- if provisioning == Volume.PROVISION_THIN:
- flag_thin = True
-
- na_vol_name = pool.name
-
- lun_name = self.f.lun_build_name(na_vol_name, volume_name)
-
- try:
- self.f.lun_create(lun_name, size_bytes, flag_thin)
- except na.FilerError as fe:
- if fe.errno == na.FilerError.EVDISK_ERROR_SIZE_TOO_LARGE:
- raise LsmError(
- ErrorNumber.NOT_ENOUGH_SPACE,
- "No enough requested free size in pool")
- elif fe.errno == na.FilerError.EVDISK_ERROR_VDISK_EXISTS:
- raise LsmError(
- ErrorNumber.NAME_CONFLICT,
- "Requested volume name is already used by other volume")
- elif fe.errno == na.FilerError.EVDISK_ERROR_SIZE_TOO_SMALL:
- # Size too small should not be raised. By API defination,
- # we should create a LUN with mimun size.
- min_size = self.f.lun_min_size()
- return self.volume_create(
- pool, volume_name, min_size, provisioning, flags)
- elif fe.errno == na.FilerError.EVDISK_ERROR_NO_SUCH_VOLUME:
- # When NetApp volume is offline, we will get this error also.
- self._check_na_volume(na_vol_name)
- else:
- raise
-
- #Get the information about the newly created LUN
- return None, self._get_volume(lun_name, pool.id)
-
- @staticmethod
- def _vol_to_na_volume_name(volume):
- return os.path.dirname(_lsm_vol_to_na_vol_path(volume))[5:]
-
- @handle_ontap_errors
- def volume_delete(self, volume, flags=0):
- try:
- self.f.lun_delete(_lsm_vol_to_na_vol_path(volume))
- except na.FilerError as f_error:
- # We don't use handle_ontap_errors which use netapp
- # error message which is not suitable for LSM user.
- if f_error.errno == na.FilerError.EVDISK_ERROR_VDISK_EXPORTED:
- raise LsmError(ErrorNumber.IS_MASKED,
- "Volume is masked to access group")
- raise
- return None
-
- @staticmethod
- def _size_kb_padded(size_bytes):
- return int((size_bytes / 1024) * 1.3)
-
- @handle_ontap_errors
- def volume_resize(self, volume, new_size_bytes, flags=0):
- try:
- self.f.lun_resize(_lsm_vol_to_na_vol_path(volume), new_size_bytes)
- except na.FilerError as fe:
- if fe.errno == na.FilerError.EVDISK_ERROR_SIZE_TOO_SMALL:
- min_size = self.f.lun_min_size()
- try:
- self.f.lun_resize(_lsm_vol_to_na_vol_path(volume),
- min_size)
- except na.FilerError as fe:
- if fe.errno == na.FilerError.EVDISK_ERROR_SIZE_UNCHANGED:
- # As requested size is not the one we are send to
- # self.f.lun_resize(), we should silently pass.
- pass
- else:
- raise
- elif fe.errno == na.FilerError.EVDISK_ERROR_SIZE_UNCHANGED:
- raise LsmError(ErrorNumber.NO_STATE_CHANGE,
- "Requested size is the same as current "
- "volume size")
- else:
- raise
- return None, self._get_volume(_lsm_vol_to_na_vol_path(volume),
- volume.pool_id)
-
- def _check_na_volume(self, na_vol_name):
- na_vols = self.f.volumes(volume_name=na_vol_name)
- if len(na_vols) == 0:
- raise LsmError(ErrorNumber.NOT_FOUND_POOL,
- "Pool not found")
- elif len(na_vols) == 1:
- # NetApp Volume is disabled.
- if na_vols[0]['state'] == 'offline':
- raise LsmError(ErrorNumber.POOL_NOT_READY,
- "Pool not ready for volume creation")
- else:
- raise LsmError(ErrorNumber.PLUGIN_BUG,
- "volume_create(): "
- "Got 2 or more na_vols: %s" % na_vols)
-
- def _volume_on_aggr(self, pool, volume):
- search = Ontap._vol_to_na_volume_name(volume)
- contained_volumes = self.f.aggregate_volume_names(pool.name)
- return search in contained_volumes
-
- @handle_ontap_errors
- def volume_replicate(self, pool, rep_type, volume_src, name, flags=0):
- #At the moment we are only supporting space efficient writeable
- #logical units. Add support for the others later.
- if rep_type != Volume.REPLICATE_CLONE:
- raise LsmError(ErrorNumber.NO_SUPPORT, "rep_type not supported")
-
- #Check to see if our volume is on a pool that was passed in or that
- #the pool itself is None
- if pool is None or self._volume_on_aggr(pool, volume_src):
- #Thin provision copy the logical unit
- dest = os.path.dirname(_lsm_vol_to_na_vol_path(volume_src)) + '/' \
- + name
- self.f.clone(_lsm_vol_to_na_vol_path(volume_src), dest)
- return None, self._get_volume(dest, volume_src.pool_id)
- else:
- #TODO Need to get instructions on how to provide this
- #functionality
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "Unable to replicate volume to different pool")
-
- @handle_ontap_errors
- def volume_replicate_range_block_size(self, system, flags=0):
- return 4096
-
- @handle_ontap_errors
- def volume_replicate_range(self, rep_type, volume_src, volume_dest, ranges,
- flags=0):
- if rep_type != Volume.REPLICATE_CLONE:
- raise LsmError(ErrorNumber.NO_SUPPORT, "rep_type not supported")
- self.f.clone(_lsm_vol_to_na_vol_path(volume_src),
- _lsm_vol_to_na_vol_path(volume_dest), None, ranges)
-
- @handle_ontap_errors
- def volume_enable(self, volume, flags=0):
- try:
- return self.f.lun_online(_lsm_vol_to_na_vol_path(volume))
- except na.FilerError as fe:
- if fe.errno == na.FilerError.EVDISK_ERROR_VDISK_NOT_DISABLED:
- raise LsmError(ErrorNumber.NO_STATE_CHANGE,
- "Volume is already enabled")
- raise
-
- @handle_ontap_errors
- def volume_disable(self, volume, flags=0):
- try:
- return self.f.lun_offline(_lsm_vol_to_na_vol_path(volume))
- except na.FilerError as fe:
- if fe.errno == na.FilerError.EVDISK_ERROR_VDISK_NOT_ENABLED:
- raise LsmError(ErrorNumber.NO_STATE_CHANGE,
- "Volume is already disabled")
- raise
-
- @handle_ontap_errors
- def volume_mask(self, access_group, volume, flags=0):
- igroups = self.f.igroups(group_name=access_group.name)
- if len(igroups) != 1:
- raise LsmError(ErrorNumber.NOT_FOUND_ACCESS_GROUP,
- "AccessGroup %s(%d) not found" %
- (access_group.name, access_group.id))
-
- cur_init_ids = Ontap._initiators_in_group(igroups[0])
- if len(cur_init_ids) == 0:
- raise LsmError(
- ErrorNumber.EMPTY_ACCESS_GROUP,
- "Refuse to do volume masking against empty access group")
- try:
- self.f.lun_map(access_group.name, _lsm_vol_to_na_vol_path(volume))
- except na.FilerError as fe:
- if fe.errno == na.FilerError.EVDISK_ERROR_INITGROUP_HAS_VDISK:
- raise LsmError(
- ErrorNumber.NO_STATE_CHANGE,
- "Volume is already masked to requested access group")
- else:
- raise
- return None
-
- @handle_ontap_errors
- def volume_unmask(self, access_group, volume, flags=0):
- try:
- self.f.lun_unmap(
- access_group.name, _lsm_vol_to_na_vol_path(volume))
- except na.FilerError as filer_error:
- if filer_error.errno == na.FilerError.EVDISK_ERROR_NO_SUCH_LUNMAP:
- raise LsmError(
- ErrorNumber.NO_STATE_CHANGE,
- "Volume is not masked to requested access group")
- else:
- raise
- return None
-
- @staticmethod
- def _initiators_in_group(g):
- rc = []
- if g:
- if 'initiators' in g and g['initiators'] is not None:
- initiators = na.to_list(g['initiators']['initiator-info'])
- for i in initiators:
- rc.append(i['initiator-name'])
- return rc
-
- def _access_group(self, g):
- name = g['initiator-group-name']
-
- if 'initiator-group-uuid' in g:
- ag_id = g['initiator-group-uuid']
- else:
- ag_id = md5(name)
-
- return AccessGroup(ag_id, name, Ontap._initiators_in_group(g),
- _na_init_type_to_lsm(g), self.sys_info.id)
-
- @handle_ontap_errors
- def access_groups(self, search_key=None, search_value=None, flags=0):
- groups = self.f.igroups()
- return search_property(
- [self._access_group(g) for g in groups], search_key, search_value)
-
- @handle_ontap_errors
- def access_group_create(self, name, init_id, init_type, system,
- flags=0):
- if self.sys_info.id != system.id:
- raise LsmError(ErrorNumber.NOT_FOUND_SYSTEM,
- "System %s not found" % system.id)
-
- # NetApp sometimes(real hardware 8.0.2 and simulator 8.1.1) does not
- # raise error for initiator conflict.
- #
- # Precheck for initiator conflict
- cur_lsm_groups = self.access_groups()
- for cur_lsm_group in cur_lsm_groups:
- if cur_lsm_group.name == name:
- raise LsmError(
- ErrorNumber.NAME_CONFLICT,
- "Requested access group name is already used by other "
- "access group")
- if init_id in cur_lsm_group.init_ids:
- raise LsmError(
- ErrorNumber.EXISTS_INITIATOR,
- "Requested initiator is already used by other "
- "access group")
-
- if init_type == AccessGroup.INIT_TYPE_ISCSI_IQN:
- self.f.igroup_create(name, 'iscsi')
- elif init_type == AccessGroup.INIT_TYPE_WWPN:
- self.f.igroup_create(name, 'fcp')
- else:
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "ONTAP only support iSCSI and FC/FCoE, but got "
- "init_type: %d" % init_type)
-
- self.f.igroup_add_initiator(name, init_id)
-
- groups = self.access_groups()
- for g in groups:
- if g.name == name:
- return g
-
- raise LsmError(ErrorNumber.PLUGIN_BUG,
- "access_group_create(): Unable to find access group "
- "%s just created!" % name)
-
- @handle_ontap_errors
- def access_group_delete(self, access_group, flags=0):
- try:
- return self.f.igroup_delete(access_group.name)
- except na.FilerError as f_error:
- if f_error.errno == \
- na.FilerError.EVDISK_ERROR_INITGROUP_MAPS_EXIST:
- raise LsmError(ErrorNumber.IS_MASKED,
- "Access Group has volume masked")
- raise
-
- @handle_ontap_errors
- def access_group_initiator_add(self, access_group, init_id, init_type,
- flags=0):
- try:
- self.f.igroup_add_initiator(access_group.name, init_id)
- except na.FilerError as oe:
- if oe.errno == na.FilerError.IGROUP_ALREADY_HAS_INIT:
- return copy.deepcopy(access_group)
- elif oe.errno == na.FilerError.NO_SUCH_IGROUP:
- raise LsmError(ErrorNumber.NOT_FOUND_ACCESS_GROUP,
- "AccessGroup %s(%d) not found" %
- (access_group.name, access_group.id))
- else:
- raise
- na_ags = self.f.igroups(access_group.name)
- if len(na_ags) != 1:
- raise LsmError(ErrorNumber.PLUGIN_BUG,
- "access_group_initiator_add(): Got unexpected"
- "(not 1) count of na_ag: %s" % na_ags)
-
- return self._access_group(na_ags[0])
-
- @handle_ontap_errors
- def access_group_initiator_delete(self, access_group, init_id, init_type,
- flags=0):
- igroups = self.f.igroups(group_name=access_group.name)
- if len(igroups) != 1:
- raise LsmError(ErrorNumber.NOT_FOUND_ACCESS_GROUP,
- "AccessGroup %s(%d) not found" %
- (access_group.name, access_group.id))
-
- cur_init_ids = Ontap._initiators_in_group(igroups[0])
- if init_id not in cur_init_ids:
- raise LsmError(
- ErrorNumber.NO_STATE_CHANGE,
- "Initiator %s does not exist in access group %s" %
- (init_id, access_group.name))
-
- if len(cur_init_ids) == 1:
- raise LsmError(
- ErrorNumber.LAST_INIT_IN_ACCESS_GROUP,
- "Refuse to remove last initiator from access group")
-
- self.f.igroup_del_initiator(access_group.name, init_id)
-
- na_ags = self.f.igroups(access_group.name)
- if len(na_ags) != 1:
- raise LsmError(ErrorNumber.PLUGIN_BUG,
- "access_group_initiator_add(): Got unexpected"
- "(not 1) count of na_ag: %s" % na_ags)
-
- return self._access_group(na_ags[0])
-
- @handle_ontap_errors
- def volumes_accessible_by_access_group(self, access_group, flags=0):
- rc = []
-
- if len(access_group.init_ids):
- luns = self.f.lun_initiator_list_map_info(access_group.init_ids[0],
- access_group.name)
- rc = [self._lun(l) for l in luns]
-
- return rc
-
- @handle_ontap_errors
- def access_groups_granted_to_volume(self, volume, flags=0):
- groups = self.f.lun_map_list_info(_lsm_vol_to_na_vol_path(volume))
- return [self._access_group(g) for g in groups]
-
- @handle_ontap_errors
- def iscsi_chap_auth(self, init_id, in_user, in_password, out_user,
- out_password, flags=0):
- if out_user and out_password and \
- (in_user is None or in_password is None):
- raise LsmError(ErrorNumber.INVALID_ARGUMENT,
- "out_user and out_password only supported if "
- "inbound is supplied")
-
- self.f.iscsi_initiator_add_auth(init_id, in_user, in_password,
- out_user, out_password)
-
- @staticmethod
- def _rpercent(total, current):
- p = 1 - (current / float(total))
- p = min(int(100 * p), 100)
- return p
-
- def _restore_file_status(self, num):
- running = self.f.snapshot_file_restore_num()
-
- if running:
- running = min(num, running)
- return JobStatus.INPROGRESS, Ontap._rpercent(num, running), None
-
- return JobStatus.COMPLETE, 100, None
-
- def _clone_split_status(self, volumes):
- vols = volumes.split(',')
- current = len(vols)
-
- #It doesn't appear that we have a good percentage
- #indicator from the clone split status...
- running = self.f.volume_split_status()
-
- for v in vols:
- if v not in running:
- current -= 1
-
- if not running:
- return JobStatus.COMPLETE, 100, None
- else:
- return JobStatus.INPROGRESS, \
- Ontap._rpercent(len(vols), current), None
-
- @handle_ontap_errors
- def job_status(self, job_id, flags=0):
- if job_id is None and '@' not in job_id:
- raise LsmError(ErrorNumber.INVALID_ARGUMENT,
- "Invalid job, missing @")
-
- job = job_id.split('@', 2)
-
- if job[0] == Ontap.SS_JOB:
- return self._restore_file_status(int(job[1]))
- elif job[0] == Ontap.SPLIT_JOB:
- return self._clone_split_status(job[1])
-
- raise LsmError(ErrorNumber.INVALID_ARGUMENT, "Invalid job")
-
- @handle_ontap_errors
- def job_free(self, job_id, flags=0):
- return None
-
- @handle_ontap_errors
- def fs(self, search_key=None, search_value=None, flags=0):
- volumes = self.f.volumes()
- pools = self.pools()
- return search_property(
- [self._vol(v, pools) for v in volumes], search_key, search_value)
-
- @handle_ontap_errors
- def fs_delete(self, fs, flags=0):
- self.f.volume_delete(fs.name)
-
- @handle_ontap_errors
- def fs_resize(self, fs, new_size_bytes, flags=0):
- diff = new_size_bytes - fs.total_space
-
- diff = Ontap._size_kb_padded(diff)
- self.f.volume_resize(fs.name, diff)
- return None, self._vol(self.f.volumes(fs.name)[0])
-
- @handle_ontap_errors
- def fs_create(self, pool, name, size_bytes, flags=0):
- self.f.volume_create(pool.name, name, size_bytes)
- return None, self._vol(self.f.volumes(name)[0])
-
- @handle_ontap_errors
- def fs_clone(self, src_fs, dest_fs_name, snapshot=None, flags=0):
- self.f.volume_clone(src_fs.name, dest_fs_name, snapshot)
- return None, self._vol(self.f.volumes(dest_fs_name)[0])
-
- @staticmethod
- def build_name(volume_name, relative_name):
- return "/vol/%s/%s" % (volume_name, relative_name)
-
- @handle_ontap_errors
- def fs_file_clone(self, fs, src_file_name, dest_file_name, snapshot=None,
- flags=0):
- full_src = Ontap.build_name(fs.name, src_file_name)
- full_dest = Ontap.build_name(fs.name, dest_file_name)
-
- ss = None
- if snapshot:
- ss = snapshot.name
-
- self.f.clone(full_src, full_dest, ss)
- return None
-
- @handle_ontap_errors
- def fs_snapshots(self, fs, flags=0):
- snapshots = self.f.snapshots(fs.name)
- return [Ontap._ss(s) for s in snapshots]
-
- @handle_ontap_errors
- def fs_snapshot_create(self, fs, snapshot_name, flags=0):
- #We can't do files, so we will do them all
- snap = self.f.snapshot_create(fs.name, snapshot_name)
- return None, Ontap._ss(snap)
-
- @handle_ontap_errors
- def fs_snapshot_delete(self, fs, snapshot, flags=0):
- self.f.snapshot_delete(fs.name, snapshot.name)
-
- def _ss_restore_files(self, volume_name, snapshot_name, files,
- restore_files):
- for i in range(len(files)):
- src = Ontap.build_name(volume_name, files[i])
- dest = None
- if restore_files and len(restore_files):
- dest = Ontap.build_name(volume_name, restore_files[i])
- self.f.snapshot_restore_file(snapshot_name, src, dest)
-
- @handle_ontap_errors
- def fs_snapshot_restore(self, fs, snapshot, files, restore_files,
- all_files=False, flags=0):
- """
- Restores a FS or files on a FS.
- Note: Restoring an individual file is a O(n) operation, i.e. time it
- takes to restore a file depends on the file size. Reverting an entire
- FS is O(1). Try to avoid restoring individual files from a snapshot.
- """
- if files is None and all_files:
- self.f.snapshot_restore_volume(fs.name, snapshot.name)
- return None
- elif files:
- if restore_files and len(files) != len(restore_files):
- raise LsmError(ErrorNumber.INVALID_ARGUMENT,
- "num files != num restore_files")
-
- self._ss_restore_files(fs.name, snapshot.name, files,
- restore_files)
- return "%s@%d" % (Ontap.SS_JOB, len(files))
- else:
- raise LsmError(ErrorNumber.INVALID_ARGUMENT,
- "Invalid parameter combination")
-
- @handle_ontap_errors
- def export_auth(self, flags=0):
- """
- Returns the types of authentication that are available for NFS
- """
- return self.f.export_auth_types()
-
- @staticmethod
- def _get_group(access_group, e):
- rc = []
-
- if access_group in e:
- for r in na.to_list(e[access_group]['exports-hostname-info']):
- if 'all-hosts' in r:
- if r['all-hosts'] == 'true':
- rc.append('*')
- else:
- rc.append(r['name'])
- return rc
-
- @staticmethod
- def _get_value(key, e):
- if key in e:
- return e[key]
- else:
- return None
-
- @staticmethod
- def _get_volume_id(volumes, vol_name):
- for v in volumes:
- if v.name == vol_name:
- return v.id
- raise RuntimeError("Volume not found in volumes:" +
- ":".join(volumes) + " " + vol_name)
-
- @staticmethod
- def _get_volume_from_path(path):
- #Volume paths have the form /vol/<volume name>/<rest of path>
- return path[5:].split('/')[0]
-
- @staticmethod
- def _export(volumes, e):
- if 'actual-pathname' in e:
- path = e['actual-pathname']
- export = e['pathname']
- else:
- path = e['pathname']
- export = e['pathname']
-
- vol_name = Ontap._get_volume_from_path(path)
- fs_id = Ontap._get_volume_id(volumes, vol_name)
-
- return NfsExport(md5(vol_name + fs_id), fs_id, export,
- e['sec-flavor']['sec-flavor-info']['flavor'],
- Ontap._get_group('root', e),
- Ontap._get_group('read-write', e),
- Ontap._get_group('read-only', e),
- NfsExport.ANON_UID_GID_NA, NfsExport.ANON_UID_GID_NA,
- None)
-
- @handle_ontap_errors
- def exports(self, search_key=None, search_value=None, flags=0):
- #Get the file systems once and pass to _export which needs to lookup
- #the file system id by name.
- v = self.fs()
- return search_property(
- [Ontap._export(v, e) for e in self.f.nfs_exports()],
- search_key, search_value)
-
- def _get_volume_from_id(self, fs_id):
- fs = self.fs()
- for i in fs:
- if i.id == fs_id:
- return i
- raise RuntimeError("fs id not found in fs:" + fs_id)
-
- def _current_export(self, export_path):
- """
- Checks to see if we already have this export.
- """
- cur_exports = self.exports()
- for ce in cur_exports:
- if ce.export_path == export_path:
- return True
-
- return False
-
- @handle_ontap_errors
- def export_fs(self, fs_id, export_path, root_list, rw_list, ro_list,
- anon_uid, anon_gid, auth_type, options, flags=0):
- """
- Creates or modifies the specified export
- """
- # NetApp does not support anon_gid setting.
- if not (anon_gid == -1 or anon_gid == 0xFFFFFFFFFFFFFFFF):
- raise LsmError(ErrorNumber.INVALID_ARGUMENT,
- "ontap plugin does not support "
- "anon_gid setting")
-
- #Get the volume info from the fs_id
- vol = self._get_volume_from_id(fs_id)
-
- # API states that if export path is None the plug-in will select
- # export path
- if export_path is None:
- export_path = '/vol/' + vol.name
-
- #If the export already exists we need to update the existing export
- #not create a new one.
- if self._current_export(export_path):
- method = self.f.nfs_export_fs_modify2
- else:
- method = self.f.nfs_export_fs2
-
- method('/vol/' + vol.name,
- export_path,
- ro_list,
- rw_list,
- root_list,
- anon_uid,
- auth_type)
-
- current_exports = self.exports()
- for e in current_exports:
- if e.fs_id == fs_id and e.export_path == export_path:
- return e
-
- raise LsmError(ErrorNumber.PLUGIN_BUG,
- "export not created successfully!")
-
- @handle_ontap_errors
- def export_remove(self, export, flags=0):
- self.f.nfs_export_remove([export.export_path])
-
- @handle_ontap_errors
- def volume_child_dependency(self, volume, flags=0):
- return False
-
- @handle_ontap_errors
- def volume_child_dependency_rm(self, volume, flags=0):
- return None
-
- @handle_ontap_errors
- def fs_child_dependency(self, fs, files=None, flags=0):
- rc = False
-
- #TODO: Make sure file actually exists if specified
-
- if not files:
- children = self.f.volume_children(fs.name)
- if children:
- rc = True
- return rc
-
- @handle_ontap_errors
- def fs_child_dependency_rm(self, fs, files=None, flags=0):
- if files:
- return None
- else:
- children = self.f.volume_children(fs.name)
- if children:
- for c in children:
- self.f.volume_split_clone(c)
- return "%s@%s" % (Ontap.SPLIT_JOB, ",".join(children))
- return None
-
- @handle_ontap_errors
- def target_ports(self, search_key=None, search_value=None, flags=0):
- tp = []
-
- #Get all FC
- fcp = self.f.fcp_list()
-
- for f in fcp:
- a = f['addr']
- adapter = f['adapter']
- tp.append(TargetPort(md5(a), TargetPort.TYPE_FC, a, a, a,
- adapter, self.sys_info.id))
-
- node_name = self.f.iscsi_node_name()
- iscsi = self.f.iscsi_list()
- for i in iscsi:
- #Get all iSCSI
- service_address = node_name
- network_address = "%s:%s" % (i['ip'], i['port'])
- physical_address = i['mac']
- physical_name = i['interface']
- tid = md5(service_address + network_address + physical_address +
- physical_name)
- tp.append(TargetPort(tid, TargetPort.TYPE_ISCSI,
- service_address,
- network_address,
- physical_address,
- physical_name,
- self.sys_info.id))
-
- return search_property(tp, search_key, search_value)
-
- @staticmethod
- def _raid_type_of_na_aggr(na_aggr):
- na_raid_statuses = na_aggr['raid-status'].split(',')
- if 'mixed_raid_type' in na_raid_statuses:
- return Volume.RAID_TYPE_MIXED
- elif 'raid0' in na_raid_statuses:
- return Volume.RAID_TYPE_RAID0
- elif 'raid4' in na_raid_statuses:
- return Volume.RAID_TYPE_RAID4
- elif 'raid_dp' in na_raid_statuses:
- return Volume.RAID_TYPE_RAID6
- return Volume.RAID_TYPE_UNKNOWN
-
- @handle_ontap_errors
- def volume_raid_info(self, volume, flags=0):
- na_vol_name = Ontap._get_volume_from_path(volume.pool_id)
- na_vol = self.f.volumes(volume_name=na_vol_name)
- if len(na_vol) == 0:
- # If parent pool not found, then this LSM volume should not exist.
- raise LsmError(
- ErrorNumber.NOT_FOUND_VOLUME,
- "Volume not found")
- if len(na_vol) != 1:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "volume_raid_info(): Got 2+ na_vols from self.f.volumes() "
- "%s" % na_vol)
-
- na_vol = na_vol[0]
- na_aggr_name = na_vol['containing-aggregate']
- na_aggr = self.f.aggregates(aggr_name=na_aggr_name)[0]
- raid_type = Ontap._raid_type_of_na_aggr(na_aggr)
- disk_count = int(na_aggr['disk-count'])
-
- return [
- raid_type, Ontap._STRIP_SIZE, disk_count, Ontap._STRIP_SIZE,
- Ontap._OPT_IO_SIZE]
diff --git a/plugin/ontap/ontap_lsmplugin b/plugin/ontap/ontap_lsmplugin
deleted file mode 100755
index 396106c..0000000
--- a/plugin/ontap/ontap_lsmplugin
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env python2
-
-# Copyright (C) 2011-2013 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: tasleson
-
-import sys
-import syslog
-import traceback
-
-try:
- from lsm.plugin.ontap.ontap import Ontap
- from lsm import PluginRunner
-
- if __name__ == '__main__':
- PluginRunner(Ontap, sys.argv).run()
-except Exception:
- #This should be quite rare, but when it does happen this is pretty
- #key in understanding what happened, especially when it happens when
- #running from the daemon.
- msg = str(traceback.format_exc())
- syslog.syslog(syslog.LOG_ERR, msg)
- sys.stderr.write(msg)
- sys.exit(1)
diff --git a/plugin/sim/__init__.py b/plugin/sim/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/plugin/sim/sim_lsmplugin b/plugin/sim/sim_lsmplugin
deleted file mode 100755
index 9a7aa1d..0000000
--- a/plugin/sim/sim_lsmplugin
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env python2
-
-# Copyright (C) 2011-2013 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: tasleson
-
-import sys
-import syslog
-import traceback
-
-try:
- from lsm import PluginRunner
- from lsm.plugin.sim.simulator import SimPlugin
-
- if __name__ == '__main__':
- PluginRunner(SimPlugin, sys.argv).run()
-except Exception:
- #This should be quite rare, but when it does happen this is pretty
- #key in understanding what happened, especially when it happens when
- #running from the daemon.
- msg = str(traceback.format_exc())
- syslog.syslog(syslog.LOG_ERR, msg)
- sys.stderr.write(msg)
- sys.exit(1)
diff --git a/plugin/sim/simarray.py b/plugin/sim/simarray.py
deleted file mode 100644
index ae14848..0000000
--- a/plugin/sim/simarray.py
+++ /dev/null
@@ -1,2280 +0,0 @@
-# Copyright (C) 2011-2015 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: tasleson
-# Gris Ge <***@redhat.com>
-
-import random
-import tempfile
-import os
-import time
-import sqlite3
-
-
-from lsm import (size_human_2_size_bytes)
-from lsm import (System, Volume, Disk, Pool, FileSystem, AccessGroup,
- FsSnapshot, NfsExport, md5, LsmError, TargetPort,
- ErrorNumber, JobStatus)
-
-
-def _handle_errors(method):
- def wrapper(*args, **kargs):
- try:
- return method(*args, **kargs)
- except sqlite3.OperationalError as sql_error:
- if type(args[0]) is SimArray and hasattr(args[0], 'bs_obj'):
- args[0].bs_obj.trans_rollback()
- if str(sql_error) == 'database is locked':
- raise LsmError(
- ErrorNumber.TIMEOUT,
- "Timeout to require lock on state file")
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "Got unexpected error from sqlite3: %s" % str(sql_error))
- except LsmError:
- if type(args[0]) is SimArray and hasattr(args[0], 'bs_obj'):
- args[0].bs_obj.trans_rollback()
- raise
- except Exception as base_error:
- if type(args[0]) is SimArray and hasattr(args[0], 'bs_obj'):
- args[0].bs_obj.trans_rollback()
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "Got unexpected error: %s" % str(base_error))
- return wrapper
-
-
-def _random_vpd():
- """
- Generate a random VPD83 NAA_Type3 ID
- """
- vpd = ['60']
- for _ in range(0, 15):
- vpd.append(str('%02x' % (random.randint(0, 255))))
- return "".join(vpd)
-
-
-class PoolRAID(object):
- MEMBER_TYPE_UNKNOWN = 0
- MEMBER_TYPE_DISK = 1
- MEMBER_TYPE_DISK_MIX = 10
- MEMBER_TYPE_DISK_ATA = 11
- MEMBER_TYPE_DISK_SATA = 12
- MEMBER_TYPE_DISK_SAS = 13
- MEMBER_TYPE_DISK_FC = 14
- MEMBER_TYPE_DISK_SOP = 15
- MEMBER_TYPE_DISK_SCSI = 16
- MEMBER_TYPE_DISK_NL_SAS = 17
- MEMBER_TYPE_DISK_HDD = 18
- MEMBER_TYPE_DISK_SSD = 19
- MEMBER_TYPE_DISK_HYBRID = 110
- MEMBER_TYPE_DISK_LUN = 111
-
- MEMBER_TYPE_POOL = 2
-
- _MEMBER_TYPE_2_DISK_TYPE = {
- MEMBER_TYPE_DISK: Disk.TYPE_UNKNOWN,
- MEMBER_TYPE_DISK_MIX: Disk.TYPE_UNKNOWN,
- MEMBER_TYPE_DISK_ATA: Disk.TYPE_ATA,
- MEMBER_TYPE_DISK_SATA: Disk.TYPE_SATA,
- MEMBER_TYPE_DISK_SAS: Disk.TYPE_SAS,
- MEMBER_TYPE_DISK_FC: Disk.TYPE_FC,
- MEMBER_TYPE_DISK_SOP: Disk.TYPE_SOP,
- MEMBER_TYPE_DISK_SCSI: Disk.TYPE_SCSI,
- MEMBER_TYPE_DISK_NL_SAS: Disk.TYPE_NL_SAS,
- MEMBER_TYPE_DISK_HDD: Disk.TYPE_HDD,
- MEMBER_TYPE_DISK_SSD: Disk.TYPE_SSD,
- MEMBER_TYPE_DISK_HYBRID: Disk.TYPE_HYBRID,
- MEMBER_TYPE_DISK_LUN: Disk.TYPE_LUN,
- }
-
- @staticmethod
- def member_type_is_disk(member_type):
- """
- Returns True if defined 'member_type' is disk.
- False when else.
- """
- return member_type in PoolRAID._MEMBER_TYPE_2_DISK_TYPE
-
- @staticmethod
- def disk_type_to_member_type(disk_type):
- for m_type, d_type in PoolRAID._MEMBER_TYPE_2_DISK_TYPE.items():
- if disk_type == d_type:
- return m_type
- return PoolRAID.MEMBER_TYPE_UNKNOWN
-
- _RAID_DISK_CHK = {
- Volume.RAID_TYPE_JBOD: lambda x: x > 0,
- Volume.RAID_TYPE_RAID0: lambda x: x > 0,
- Volume.RAID_TYPE_RAID1: lambda x: x == 2,
- Volume.RAID_TYPE_RAID3: lambda x: x >= 3,
- Volume.RAID_TYPE_RAID4: lambda x: x >= 3,
- Volume.RAID_TYPE_RAID5: lambda x: x >= 3,
- Volume.RAID_TYPE_RAID6: lambda x: x >= 4,
- Volume.RAID_TYPE_RAID10: lambda x: x >= 4 and x % 2 == 0,
- Volume.RAID_TYPE_RAID15: lambda x: x >= 6 and x % 2 == 0,
- Volume.RAID_TYPE_RAID16: lambda x: x >= 8 and x % 2 == 0,
- Volume.RAID_TYPE_RAID50: lambda x: x >= 6 and x % 2 == 0,
- Volume.RAID_TYPE_RAID60: lambda x: x >= 8 and x % 2 == 0,
- Volume.RAID_TYPE_RAID51: lambda x: x >= 6 and x % 2 == 0,
- Volume.RAID_TYPE_RAID61: lambda x: x >= 8 and x % 2 == 0,
- }
-
- _RAID_PARITY_DISK_COUNT_FUNC = {
- Volume.RAID_TYPE_JBOD: lambda x: x,
- Volume.RAID_TYPE_RAID0: lambda x: x,
- Volume.RAID_TYPE_RAID1: lambda x: 1,
- Volume.RAID_TYPE_RAID3: lambda x: x - 1,
- Volume.RAID_TYPE_RAID4: lambda x: x - 1,
- Volume.RAID_TYPE_RAID5: lambda x: x - 1,
- Volume.RAID_TYPE_RAID6: lambda x: x - 2,
- Volume.RAID_TYPE_RAID10: lambda x: x / 2,
- Volume.RAID_TYPE_RAID15: lambda x: x / 2 - 1,
- Volume.RAID_TYPE_RAID16: lambda x: x / 2 - 2,
- Volume.RAID_TYPE_RAID50: lambda x: x - 2,
- Volume.RAID_TYPE_RAID60: lambda x: x - 4,
- Volume.RAID_TYPE_RAID51: lambda x: x / 2 - 1,
- Volume.RAID_TYPE_RAID61: lambda x: x / 2 - 2,
- }
-
- @staticmethod
- def data_disk_count(raid_type, disk_count):
- """
- Return a integer indicating how many disks should be used as
- real data(not mirrored or parity) disks.
- Treating RAID 5 and 6 using fixed parity disk.
- """
- if raid_type not in PoolRAID._RAID_DISK_CHK.keys():
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "data_disk_count(): Got unsupported raid type(%d)" %
- raid_type)
-
- if PoolRAID._RAID_DISK_CHK[raid_type](disk_count) is False:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "data_disk_count(): Illegal disk count"
- "(%d) for raid type(%d)" % (disk_count, raid_type))
- return PoolRAID._RAID_PARITY_DISK_COUNT_FUNC[raid_type](disk_count)
-
-
-class BackStore(object):
- VERSION = "3.1"
- VERSION_SIGNATURE = 'LSM_SIMULATOR_DATA_%s_%s' % (VERSION, md5(VERSION))
- JOB_DEFAULT_DURATION = 1
- JOB_DATA_TYPE_VOL = 1
- JOB_DATA_TYPE_FS = 2
- JOB_DATA_TYPE_FS_SNAP = 3
-
- SYS_ID = "sim-01"
- SYS_NAME = "LSM simulated storage plug-in"
- BLK_SIZE = 512
- STRIP_SIZE = 131072 # 128 KiB
-
- _LIST_SPLITTER = '#'
-
- SYS_KEY_LIST = ['id', 'name', 'status', 'status_info', 'version']
-
- POOL_KEY_LIST = [
- 'id', 'name', 'status', 'status_info',
- 'element_type', 'unsupported_actions', 'raid_type',
- 'member_type', 'parent_pool_id', 'total_space', 'free_space']
-
- DISK_KEY_LIST = [
- 'id', 'name', 'total_space', 'disk_type', 'status',
- 'owner_pool_id', 'role']
-
- VOL_KEY_LIST = [
- 'id', 'vpd83', 'name', 'total_space', 'consumed_size',
- 'pool_id', 'admin_state', 'thinp']
-
- TGT_KEY_LIST = [
- 'id', 'port_type', 'service_address', 'network_address',
- 'physical_address', 'physical_name']
-
- AG_KEY_LIST = ['id', 'name', 'init_type', 'init_ids_str']
-
- JOB_KEY_LIST = ['id', 'duration', 'timestamp', 'data_type', 'data_id']
-
- FS_KEY_LIST = [
- 'id', 'name', 'total_space', 'free_space', 'consumed_size',
- 'pool_id']
-
- FS_SNAP_KEY_LIST = [
- 'id', 'fs_id', 'name', 'timestamp']
-
- EXP_KEY_LIST = [
- 'id', 'fs_id', 'exp_path', 'auth_type', 'anon_uid', 'anon_gid',
- 'options', 'exp_root_hosts_str', 'exp_rw_hosts_str',
- 'exp_ro_hosts_str']
-
- def __init__(self, statefile, timeout):
- if not os.path.exists(statefile):
- os.close(os.open(statefile, os.O_WRONLY | os.O_CREAT))
- # Due to umask, os.open() created file migt not be 666 permission.
- os.chmod(statefile, 0o666)
-
- self.statefile = statefile
- self.lastrowid = None
- self.sql_conn = sqlite3.connect(
- statefile, timeout=int(timeout/1000), isolation_level="IMMEDIATE")
- # Create tables no matter exist or not. No lock required.
-
- sql_cmd = "PRAGMA foreign_keys = ON;\n"
-
- sql_cmd += (
- """
- CREATE TABLE systems (
- id TEXT PRIMARY KEY,
- name TEXT NOT NULL,
- status INTEGER NOT NULL,
- status_info TEXT,
- version TEXT NOT NULL);
- """)
- # version hold the signature of data
-
- sql_cmd += (
- "CREATE TABLE tgts ("
- "id INTEGER PRIMARY KEY, "
- "port_type INTEGER NOT NULL, "
- "service_address TEXT NOT NULL, "
- "network_address TEXT NOT NULL, "
- "physical_address TEXT NOT NULL, "
- "physical_name TEXT NOT NULL);\n")
-
- sql_cmd += (
- "CREATE TABLE pools ("
- "id INTEGER PRIMARY KEY, "
- "name TEXT UNIQUE NOT NULL, "
- "status INTEGER NOT NULL, "
- "status_info TEXT, "
- "element_type INTEGER NOT NULL, "
- "unsupported_actions INTEGER, "
- "raid_type INTEGER NOT NULL, "
- "parent_pool_id INTEGER, " # Indicate this pool is allocated from
- # other pool
- "member_type INTEGER, "
- "total_space LONG);\n") # total_space here is only for
- # sub-pool (pool from pool)
-
- sql_cmd += (
- "CREATE TABLE disks ("
- "id INTEGER PRIMARY KEY, "
- "total_space LONG NOT NULL, "
- "disk_type INTEGER NOT NULL, "
- "status INTEGER NOT NULL, "
- "disk_prefix TEXT NOT NULL, "
- "owner_pool_id INTEGER, " # Indicate this disk is used to
- # assemble a pool
- "role TEXT,"
- "FOREIGN KEY(owner_pool_id) "
- "REFERENCES pools(id) ON DELETE CASCADE );\n")
-
- sql_cmd += (
- "CREATE TABLE volumes ("
- "id INTEGER PRIMARY KEY, "
- "vpd83 TEXT NOT NULL, "
- "name TEXT UNIQUE NOT NULL, "
- "total_space LONG NOT NULL, "
- "consumed_size LONG NOT NULL, " # Reserved for future thinp
- # support.
- "admin_state INTEGER, "
- "thinp INTEGER NOT NULL, "
- "pool_id INTEGER NOT NULL, "
- "FOREIGN KEY(pool_id) "
- "REFERENCES pools(id) ON DELETE CASCADE);\n")
-
- sql_cmd += (
- "CREATE TABLE ags ("
- "id INTEGER PRIMARY KEY, "
- "name TEXT UNIQUE NOT NULL);\n")
-
- sql_cmd += (
- "CREATE TABLE inits ("
- "id TEXT UNIQUE NOT NULL, "
- "init_type INTEGER NOT NULL, "
- "owner_ag_id INTEGER NOT NULL, "
- "FOREIGN KEY(owner_ag_id) "
- "REFERENCES ags(id) ON DELETE CASCADE);\n")
-
- sql_cmd += (
- "CREATE TABLE vol_masks ("
- "vol_id INTEGER NOT NULL, "
- "ag_id INTEGER NOT NULL, "
- "FOREIGN KEY(vol_id) REFERENCES volumes(id) ON DELETE CASCADE, "
- "FOREIGN KEY(ag_id) REFERENCES ags(id) ON DELETE CASCADE);\n")
-
- sql_cmd += (
- "CREATE TABLE vol_reps ("
- "rep_type INTEGER, "
- "src_vol_id INTEGER NOT NULL, "
- "dst_vol_id INTEGER NOT NULL, "
- "FOREIGN KEY(src_vol_id) "
- "REFERENCES volumes(id) ON DELETE CASCADE, "
- "FOREIGN KEY(dst_vol_id) "
- "REFERENCES volumes(id) ON DELETE CASCADE);\n")
-
- sql_cmd += (
- "CREATE TABLE fss ("
- "id INTEGER PRIMARY KEY, "
- "name TEXT UNIQUE NOT NULL, "
- "total_space LONG NOT NULL, "
- "consumed_size LONG NOT NULL, "
- "free_space LONG, "
- "pool_id INTEGER NOT NULL, "
- "FOREIGN KEY(pool_id) "
- "REFERENCES pools(id) ON DELETE CASCADE);\n")
-
- sql_cmd += (
- "CREATE TABLE fs_snaps ("
- "id INTEGER PRIMARY KEY, "
- "name TEXT UNIQUE NOT NULL, "
- "fs_id INTEGER NOT NULL, "
- "timestamp LONG NOT NULL, "
- "FOREIGN KEY(fs_id) "
- "REFERENCES fss(id) ON DELETE CASCADE);\n")
-
- sql_cmd += (
- "CREATE TABLE fs_clones ("
- "src_fs_id INTEGER NOT NULL, "
- "dst_fs_id INTEGER NOT NULL, "
- "FOREIGN KEY(src_fs_id) "
- "REFERENCES fss(id) ON DELETE CASCADE, "
- "FOREIGN KEY(dst_fs_id) "
- "REFERENCES fss(id) ON DELETE CASCADE);\n")
-
- sql_cmd += (
- "CREATE TABLE exps ("
- "id INTEGER PRIMARY KEY, "
- "fs_id INTEGER NOT NULL, "
- "exp_path TEXT UNIQUE NOT NULL, "
- "auth_type TEXT, "
- "anon_uid INTEGER, "
- "anon_gid INTEGER, "
- "options TEXT, "
- "FOREIGN KEY(fs_id) "
- "REFERENCES fss(id) ON DELETE CASCADE);\n")
-
- sql_cmd += (
- "CREATE TABLE exp_root_hosts("
- "host TEXT NOT NULL, "
- "exp_id INTEGER NOT NULL, "
- "FOREIGN KEY(exp_id) "
- "REFERENCES exps(id) ON DELETE CASCADE);\n")
-
- sql_cmd += (
- "CREATE TABLE exp_rw_hosts("
- "host TEXT NOT NULL, "
- "exp_id INTEGER NOT NULL, "
- "FOREIGN KEY(exp_id) "
- "REFERENCES exps(id) ON DELETE CASCADE);\n")
-
- sql_cmd += (
- "CREATE TABLE exp_ro_hosts("
- "host TEXT NOT NULL, "
- "exp_id INTEGER NOT NULL, "
- "FOREIGN KEY(exp_id) "
- "REFERENCES exps(id) ON DELETE CASCADE);\n")
-
- sql_cmd += (
- "CREATE TABLE jobs ("
- "id INTEGER PRIMARY KEY, "
- "duration INTEGER NOT NULL, "
- "timestamp TEXT NOT NULL, "
- "data_type INTEGER, "
- "data_id TEXT);\n")
-
- # Create views
- sql_cmd += (
- """
- CREATE VIEW pools_view AS
- SELECT
- pool.id,
- pool.name,
- pool.status,
- pool.status_info,
- pool.element_type,
- pool.unsupported_actions,
- pool.raid_type,
- pool.member_type,
- pool.parent_pool_id,
- ifnull(pool.total_space,
- ifnull(SUM(disk.total_space), 0))
- total_space,
- ifnull(pool.total_space,
- ifnull(SUM(disk.total_space), 0)) -
- ifnull(SUM(volume.consumed_size), 0) -
- ifnull(SUM(fs.consumed_size), 0) -
- ifnull(SUM(pool2.total_space), 0)
- free_space
-
- FROM
- pools pool
- LEFT JOIN disks disk
- ON pool.id = disk.owner_pool_id AND
- disk.role = 'DATA'
- LEFT JOIN volumes volume
- ON volume.pool_id = pool.id
- LEFT JOIN fss fs
- ON fs.pool_id = pool.id
- LEFT JOIN pools pool2
- ON pool2.parent_pool_id = pool.id
-
- GROUP BY
- pool.id
- ;
- """)
- sql_cmd += (
- """
- CREATE VIEW disks_view AS
- SELECT
- id,
- disk_prefix || '_' || id
- name,
- total_space,
- disk_type,
- role,
- status,
- owner_pool_id
- FROM
- disks
- ;
- """)
- sql_cmd += (
- """
- CREATE VIEW volumes_by_ag_view AS
- SELECT
- vol.id,
- vol.vpd83,
- vol.name,
- vol.total_space,
- vol.consumed_size,
- vol.pool_id,
- vol.admin_state,
- vol.thinp,
- vol_mask.ag_id ag_id
- FROM
- volumes vol
- LEFT JOIN vol_masks vol_mask
- ON vol_mask.vol_id = vol.id
- ;
- """)
-
- sql_cmd += (
- """
- CREATE VIEW ags_view AS
- SELECT
- ag.id,
- ag.name,
- CASE
- WHEN count(DISTINCT init.init_type) = 1
- THEN init.init_type
- WHEN count(DISTINCT init.init_type) = 2
- THEN %s
- ELSE %s
- END
- init_type,
- group_concat(init.id, '%s') init_ids_str
- FROM
- ags ag
- LEFT JOIN inits init
- ON ag.id = init.owner_ag_id
- GROUP BY
- ag.id
- ORDER BY
- init.init_type
- ;
- """ % (
- AccessGroup.INIT_TYPE_ISCSI_WWPN_MIXED,
- AccessGroup.INIT_TYPE_UNKNOWN, BackStore._LIST_SPLITTER))
-
- sql_cmd += (
- """
- CREATE VIEW ags_by_vol_view AS
- SELECT
- ag_new.id,
- ag_new.name,
- ag_new.init_type,
- ag_new.init_ids_str,
- vol_mask.vol_id vol_id
- FROM
- (
- SELECT
- ag.id,
- ag.name,
- CASE
- WHEN count(DISTINCT init.init_type) = 1
- THEN init.init_type
- WHEN count(DISTINCT init.init_type) = 2
- THEN %s
- ELSE %s
- END
- init_type,
- group_concat(init.id, '%s') init_ids_str
- FROM
- ags ag
- LEFT JOIN inits init
- ON ag.id = init.owner_ag_id
- GROUP BY
- ag.id
- ORDER BY
- init.init_type
- ) ag_new
- LEFT JOIN vol_masks vol_mask
- ON vol_mask.ag_id = ag_new.id
- ;
- """ % (
- AccessGroup.INIT_TYPE_ISCSI_WWPN_MIXED,
- AccessGroup.INIT_TYPE_UNKNOWN, BackStore._LIST_SPLITTER))
-
- sql_cmd += (
- """
- CREATE VIEW exps_view AS
- SELECT
- exp.id,
- exp.fs_id,
- exp.exp_path,
- exp.auth_type,
- exp.anon_uid,
- exp.anon_gid,
- exp.options,
- exp2.exp_root_hosts_str,
- exp3.exp_rw_hosts_str,
- exp4.exp_ro_hosts_str
- FROM
- exps exp
- LEFT JOIN (
- SELECT
- exp_t2.id,
- group_concat(
- exp_root_host.host, '%s')
- exp_root_hosts_str
- FROM
- exps exp_t2
- LEFT JOIN exp_root_hosts exp_root_host
- ON exp_t2.id = exp_root_host.exp_id
- GROUP BY
- exp_t2.id
- ) exp2
- ON exp.id = exp2.id
- LEFT JOIN (
- SELECT
- exp_t3.id,
- group_concat(
- exp_rw_host.host, '%s')
- exp_rw_hosts_str
- FROM
- exps exp_t3
- LEFT JOIN exp_rw_hosts exp_rw_host
- ON exp_t3.id = exp_rw_host.exp_id
- GROUP BY
- exp_t3.id
- ) exp3
- ON exp.id = exp3.id
- LEFT JOIN (
- SELECT
- exp_t4.id,
- group_concat(
- exp_ro_host.host, '%s')
- exp_ro_hosts_str
- FROM
- exps exp_t4
- LEFT JOIN exp_ro_hosts exp_ro_host
- ON exp_t4.id = exp_ro_host.exp_id
- GROUP BY
- exp_t4.id
- ) exp4
- ON exp.id = exp4.id
- GROUP BY
- exp.id;
- ;
- """ % (
- BackStore._LIST_SPLITTER, BackStore._LIST_SPLITTER,
- BackStore._LIST_SPLITTER))
-
- sql_cur = self.sql_conn.cursor()
- try:
- sql_cur.executescript(sql_cmd)
- except sqlite3.OperationalError as sql_error:
- if 'already exists' in str(sql_error):
- pass
- else:
- raise sql_error
-
- def _check_version(self):
- sim_syss = self.sim_syss()
- if len(sim_syss) == 0 or not sim_syss[0]:
- return False
- else:
- if 'version' in sim_syss[0] and \
- sim_syss[0]['version'] == BackStore.VERSION_SIGNATURE:
- return True
-
- raise LsmError(
- ErrorNumber.INVALID_ARGUMENT,
- "Stored simulator state incompatible with "
- "simulator, please move or delete %s" % self.statefile)
-
- def check_version_and_init(self):
- """
- Raise error if version not match.
- If empty database found, initiate.
- """
- # The complex lock workflow is all caused by python sqlite3 do
- # autocommit for "CREATE TABLE" command.
- self.trans_begin()
- if self._check_version():
- self.trans_commit()
- return
- else:
- self._data_add(
- 'systems',
- {
- 'id': BackStore.SYS_ID,
- 'name': BackStore.SYS_NAME,
- 'status': System.STATUS_OK,
- 'status_info': "",
- 'version': BackStore.VERSION_SIGNATURE,
- })
-
- size_bytes_2t = size_human_2_size_bytes('2TiB')
- size_bytes_512g = size_human_2_size_bytes('512GiB')
- # Add 2 SATA disks(2TiB)
- pool_1_disks = []
- for _ in range(0, 2):
- self._data_add(
- 'disks',
- {
- 'disk_prefix': "2TiB SATA Disk",
- 'total_space': size_bytes_2t,
- 'disk_type': Disk.TYPE_SATA,
- 'status': Disk.STATUS_OK,
- })
- pool_1_disks.append(self.lastrowid)
-
- test_pool_disks = []
- # Add 6 SAS disks(2TiB)
- for _ in range(0, 6):
- self._data_add(
- 'disks',
- {
- 'disk_prefix': "2TiB SAS Disk",
- 'total_space': size_bytes_2t,
- 'disk_type': Disk.TYPE_SAS,
- 'status': Disk.STATUS_OK,
- })
- if len(test_pool_disks) < 2:
- test_pool_disks.append(self.lastrowid)
-
- ssd_pool_disks = []
- # Add 5 SSD disks(512GiB)
- for _ in range(0, 5):
- self._data_add(
- 'disks',
- {
- 'disk_prefix': "512GiB SSD Disk",
- 'total_space': size_bytes_512g,
- 'disk_type': Disk.TYPE_SSD,
- 'status': Disk.STATUS_OK,
- })
- if len(ssd_pool_disks) < 2:
- ssd_pool_disks.append(self.lastrowid)
-
- # Add 7 SSD disks(2TiB)
- for _ in range(0, 7):
- self._data_add(
- 'disks',
- {
- 'disk_prefix': "2TiB SSD Disk",
- 'total_space': size_bytes_2t,
- 'disk_type': Disk.TYPE_SSD,
- 'status': Disk.STATUS_OK,
- })
-
- pool_1_id = self.sim_pool_create_from_disk(
- name='Pool 1',
- raid_type=Volume.RAID_TYPE_RAID1,
- sim_disk_ids=pool_1_disks,
- element_type=Pool.ELEMENT_TYPE_POOL |
- Pool.ELEMENT_TYPE_FS |
- Pool.ELEMENT_TYPE_VOLUME |
- Pool.ELEMENT_TYPE_DELTA |
- Pool.ELEMENT_TYPE_SYS_RESERVED,
- unsupported_actions=Pool.UNSUPPORTED_VOLUME_GROW |
- Pool.UNSUPPORTED_VOLUME_SHRINK)
-
- self.sim_pool_create_sub_pool(
- name='Pool 2(sub pool of Pool 1)',
- parent_pool_id=pool_1_id,
- element_type=Pool.ELEMENT_TYPE_FS |
- Pool.ELEMENT_TYPE_VOLUME |
- Pool.ELEMENT_TYPE_DELTA,
- size=size_bytes_512g)
-
- self.sim_pool_create_from_disk(
- name='Pool 3',
- raid_type=Volume.RAID_TYPE_RAID1,
- sim_disk_ids=ssd_pool_disks,
- element_type=Pool.ELEMENT_TYPE_FS |
- Pool.ELEMENT_TYPE_VOLUME |
- Pool.ELEMENT_TYPE_DELTA)
-
- self.sim_pool_create_from_disk(
- name='lsm_test_aggr',
- element_type=Pool.ELEMENT_TYPE_FS |
- Pool.ELEMENT_TYPE_VOLUME |
- Pool.ELEMENT_TYPE_DELTA,
- raid_type=Volume.RAID_TYPE_RAID0,
- sim_disk_ids=test_pool_disks)
-
- self._data_add(
- 'tgts',
- {
- 'port_type': TargetPort.TYPE_FC,
- 'service_address': '50:0a:09:86:99:4b:8d:c5',
- 'network_address': '50:0a:09:86:99:4b:8d:c5',
- 'physical_address': '50:0a:09:86:99:4b:8d:c5',
- 'physical_name': 'FC_a_0b',
- })
-
- self._data_add(
- 'tgts',
- {
- 'port_type': TargetPort.TYPE_FCOE,
- 'service_address': '50:0a:09:86:99:4b:8d:c6',
- 'network_address': '50:0a:09:86:99:4b:8d:c6',
- 'physical_address': '50:0a:09:86:99:4b:8d:c6',
- 'physical_name': 'FCoE_b_0c',
- })
- self._data_add(
- 'tgts',
- {
- 'port_type': TargetPort.TYPE_ISCSI,
- 'service_address': 'iqn.1986-05.com.example:sim-tgt-03',
- 'network_address': 'sim-iscsi-tgt-3.example.com:3260',
- 'physical_address': 'a4:4e:31:47:f4:e0',
- 'physical_name': 'iSCSI_c_0d',
- })
- self._data_add(
- 'tgts',
- {
- 'port_type': TargetPort.TYPE_ISCSI,
- 'service_address': 'iqn.1986-05.com.example:sim-tgt-03',
- 'network_address': '10.0.0.1:3260',
- 'physical_address': 'a4:4e:31:47:f4:e1',
- 'physical_name': 'iSCSI_c_0e',
- })
- self._data_add(
- 'tgts',
- {
- 'port_type': TargetPort.TYPE_ISCSI,
- 'service_address': 'iqn.1986-05.com.example:sim-tgt-03',
- 'network_address': '[2001:470:1f09:efe:a64e:31ff::1]:3260',
- 'physical_address': 'a4:4e:31:47:f4:e1',
- 'physical_name': 'iSCSI_c_0e',
- })
-
- self.trans_commit()
- return
-
- def _sql_exec(self, sql_cmd, key_list=None):
- """
- Execute sql command and get all output.
- If key_list is not None, will convert returned sql data to a list of
- dictionaries.
- """
- sql_cur = self.sql_conn.cursor()
- sql_cur.execute(sql_cmd)
- self.lastrowid = sql_cur.lastrowid
- sql_output = sql_cur.fetchall()
- if key_list and sql_output:
- return list(
- dict(zip(key_list, value_list))
- for value_list in sql_output
- if value_list)
- else:
- return sql_output
-
- def _get_table(self, table_name, key_list):
- sql_cmd = "SELECT %s FROM %s" % (",".join(key_list), table_name)
- return self._sql_exec(sql_cmd, key_list)
-
- def trans_begin(self):
- self.sql_conn.execute("BEGIN IMMEDIATE TRANSACTION;")
-
- def trans_commit(self):
- self.sql_conn.commit()
-
- def trans_rollback(self):
- self.sql_conn.rollback()
-
- def _data_add(self, table_name, data_dict):
- keys = data_dict.keys()
- values = ['' if v is None else str(v) for v in data_dict.values()]
-
- sql_cmd = "INSERT INTO %s (%s) VALUES (%s);" % \
- (table_name,
- "'%s'" % ("', '".join(keys)),
- "'%s'" % ("', '".join(values)))
- self._sql_exec(sql_cmd)
-
- def _data_find(self, table, condition, key_list, flag_unique=False):
- sql_cmd = "SELECT %s FROM %s WHERE %s" % (
- ",".join(key_list), table, condition)
- sim_datas = self._sql_exec(sql_cmd, key_list)
- if flag_unique:
- if len(sim_datas) == 0:
- return None
- elif len(sim_datas) == 1:
- return sim_datas[0]
- else:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "_data_find(): Got non-unique data: %s" % locals())
- else:
- return sim_datas
-
- def _data_update(self, table, data_id, column_name, value):
- if value is None:
- value = ''
-
- sql_cmd = "UPDATE %s SET %s='%s' WHERE id='%s'" % \
- (table, column_name, value, data_id)
-
- self._sql_exec(sql_cmd)
-
- def _data_delete(self, table, condition):
- sql_cmd = "DELETE FROM %s WHERE %s;" % (table, condition)
- self._sql_exec(sql_cmd)
-
- def sim_job_create(self, job_data_type=None, data_id=None):
- """
- Return a job id(Integer)
- """
- self._data_add(
- "jobs",
- {
- "duration": os.getenv(
- "LSM_SIM_TIME", BackStore.JOB_DEFAULT_DURATION),
- "timestamp": time.time(),
- "data_type": job_data_type,
- "data_id": data_id,
- })
- return self.lastrowid
-
- def sim_job_delete(self, sim_job_id):
- self._data_delete('jobs', 'id="%s"' % sim_job_id)
-
- def sim_job_status(self, sim_job_id):
- """
- Return (progress, data_type, data) tuple.
- progress is the integer of percent.
- """
- sim_job = self._data_find(
- 'jobs', 'id=%s' % sim_job_id, BackStore.JOB_KEY_LIST,
- flag_unique=True)
- if sim_job is None:
- raise LsmError(
- ErrorNumber.NOT_FOUND_JOB, "Job not found")
-
- progress = int(
- (time.time() - float(sim_job['timestamp'])) /
- sim_job['duration'] * 100)
-
- data = None
- data_type = None
-
- if progress >= 100:
- progress = 100
- if sim_job['data_type'] == BackStore.JOB_DATA_TYPE_VOL:
- data = self.sim_vol_of_id(sim_job['data_id'])
- data_type = sim_job['data_type']
- elif sim_job['data_type'] == BackStore.JOB_DATA_TYPE_FS:
- data = self.sim_fs_of_id(sim_job['data_id'])
- data_type = sim_job['data_type']
- elif sim_job['data_type'] == BackStore.JOB_DATA_TYPE_FS_SNAP:
- data = self.sim_fs_snap_of_id(sim_job['data_id'])
- data_type = sim_job['data_type']
-
- return (progress, data_type, data)
-
- def sim_syss(self):
- """
- Return a list of sim_sys dict.
- """
- return self._get_table('systems', BackStore.SYS_KEY_LIST)
-
- def sim_disks(self):
- """
- Return a list of sim_disk dict.
- """
- return self._get_table('disks_view', BackStore.DISK_KEY_LIST)
-
- def sim_pools(self):
- """
- Return a list of sim_pool dict.
- """
- return self._get_table('pools_view', BackStore.POOL_KEY_LIST)
-
- def sim_pool_of_id(self, sim_pool_id):
- return self._sim_data_of_id(
- "pools_view", sim_pool_id, BackStore.POOL_KEY_LIST,
- ErrorNumber.NOT_FOUND_POOL, "Pool")
-
- def sim_pool_create_from_disk(self, name, sim_disk_ids, raid_type,
- element_type, unsupported_actions=0):
- # Detect disk type
- disk_type = None
- for sim_disk in self.sim_disks():
- if sim_disk['id'] not in sim_disk_ids:
- continue
- if disk_type is None:
- disk_type = sim_disk['disk_type']
- elif disk_type != sim_disk['disk_type']:
- disk_type = None
- break
- member_type = PoolRAID.MEMBER_TYPE_DISK
- if disk_type is not None:
- member_type = PoolRAID.disk_type_to_member_type(disk_type)
-
- self._data_add(
- 'pools',
- {
- 'name': name,
- 'status': Pool.STATUS_OK,
- 'status_info': '',
- 'element_type': element_type,
- 'unsupported_actions': unsupported_actions,
- 'raid_type': raid_type,
- 'member_type': member_type,
- })
-
- data_disk_count = PoolRAID.data_disk_count(
- raid_type, len(sim_disk_ids))
-
- # update disk owner
- sim_pool_id = self.lastrowid
- for sim_disk_id in sim_disk_ids[:data_disk_count]:
- self._data_update(
- 'disks', sim_disk_id, 'owner_pool_id', sim_pool_id)
- self._data_update(
- 'disks', sim_disk_id, 'role', 'DATA')
-
- for sim_disk_id in sim_disk_ids[data_disk_count:]:
- self._data_update(
- 'disks', sim_disk_id, 'owner_pool_id', sim_pool_id)
- self._data_update(
- 'disks', sim_disk_id, 'role', 'PARITY')
-
- return sim_pool_id
-
- def sim_pool_create_sub_pool(self, name, parent_pool_id, size,
- element_type, unsupported_actions=0):
- self._data_add(
- 'pools',
- {
- 'name': name,
- 'status': Pool.STATUS_OK,
- 'status_info': '',
- 'element_type': element_type,
- 'unsupported_actions': unsupported_actions,
- 'raid_type': Volume.RAID_TYPE_OTHER,
- 'member_type': PoolRAID.MEMBER_TYPE_POOL,
- 'parent_pool_id': parent_pool_id,
- 'total_space': size,
- })
- return self.lastrowid
-
- def sim_pool_disks_count(self, sim_pool_id):
- return self._sql_exec(
- "SELECT COUNT(id) FROM disks WHERE owner_pool_id=%s;" %
- sim_pool_id)[0][0]
-
- def sim_pool_data_disks_count(self, sim_pool_id=None):
- return self._sql_exec(
- "SELECT COUNT(id) FROM disks WHERE "
- "owner_pool_id=%s and role='DATA';" % sim_pool_id)[0][0]
-
- def sim_vols(self, sim_ag_id=None):
- """
- Return a list of sim_vol dict.
- """
- if sim_ag_id:
- return self._data_find(
- 'volumes_by_ag_view', 'ag_id=%s' % sim_ag_id,
- BackStore.VOL_KEY_LIST)
- else:
- return self._get_table('volumes', BackStore.VOL_KEY_LIST)
-
- def _sim_data_of_id(self, table_name, data_id, key_list, lsm_error_no,
- data_name):
- sim_data = self._data_find(
- table_name, 'id=%s' % data_id, key_list, flag_unique=True)
- if sim_data is None:
- if lsm_error_no:
- raise LsmError(
- lsm_error_no, "%s not found" % data_name)
- else:
- return None
- return sim_data
-
- def sim_vol_of_id(self, sim_vol_id):
- """
- Return sim_vol if found. Raise error if not found.
- """
- return self._sim_data_of_id(
- "volumes", sim_vol_id, BackStore.VOL_KEY_LIST,
- ErrorNumber.NOT_FOUND_VOLUME,
- "Volume")
-
- def _check_pool_free_space(self, sim_pool_id, size_bytes):
- sim_pool = self.sim_pool_of_id(sim_pool_id)
-
- if (sim_pool['free_space'] < size_bytes):
- raise LsmError(ErrorNumber.NOT_ENOUGH_SPACE,
- "Insufficient space in pool")
-
- @staticmethod
- def _block_rounding(size_bytes):
- return (size_bytes + BackStore.BLK_SIZE - 1) / \
- BackStore.BLK_SIZE * BackStore.BLK_SIZE
-
- def sim_vol_create(self, name, size_bytes, sim_pool_id, thinp):
- size_bytes = BackStore._block_rounding(size_bytes)
- self._check_pool_free_space(sim_pool_id, size_bytes)
- sim_vol = dict()
- sim_vol['vpd83'] = _random_vpd()
- sim_vol['name'] = name
- sim_vol['thinp'] = thinp
- sim_vol['pool_id'] = sim_pool_id
- sim_vol['total_space'] = size_bytes
- sim_vol['consumed_size'] = size_bytes
- sim_vol['admin_state'] = Volume.ADMIN_STATE_ENABLED
-
- try:
- self._data_add("volumes", sim_vol)
- except sqlite3.IntegrityError as sql_error:
- raise LsmError(
- ErrorNumber.NAME_CONFLICT,
- "Name '%s' is already in use by other volume" % name)
-
- return self.lastrowid
-
- def sim_vol_delete(self, sim_vol_id):
- """
- This does not check whether volume exist or not.
- """
- # Check existence.
- self.sim_vol_of_id(sim_vol_id)
-
- if self._sim_ag_ids_of_masked_vol(sim_vol_id):
- raise LsmError(
- ErrorNumber.IS_MASKED,
- "Volume is masked to access group")
-
- dst_sim_vol_ids = self.dst_sim_vol_ids_of_src(sim_vol_id)
- if len(dst_sim_vol_ids) >= 1:
- for dst_sim_vol_id in dst_sim_vol_ids:
- if dst_sim_vol_id != sim_vol_id:
- # Don't raise error on volume internal replication.
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "Requested volume is a replication source")
-
- self._data_delete("volumes", 'id="%s"' % sim_vol_id)
-
- def sim_vol_mask(self, sim_vol_id, sim_ag_id):
- self.sim_vol_of_id(sim_vol_id)
- self.sim_ag_of_id(sim_ag_id)
- exist_mask = self._data_find(
- 'vol_masks', 'ag_id="%s" AND vol_id="%s"' %
- (sim_ag_id, sim_vol_id), ['vol_id'])
- if exist_mask:
- raise LsmError(
- ErrorNumber.NO_STATE_CHANGE,
- "Volume is already masked to requested access group")
-
- self._data_add(
- "vol_masks", {'ag_id': sim_ag_id, 'vol_id': sim_vol_id})
-
- return None
-
- def sim_vol_unmask(self, sim_vol_id, sim_ag_id):
- self.sim_vol_of_id(sim_vol_id)
- self.sim_ag_of_id(sim_ag_id)
- condition = 'ag_id="%s" AND vol_id="%s"' % (sim_ag_id, sim_vol_id)
- exist_mask = self._data_find('vol_masks', condition, ['vol_id'])
- if exist_mask:
- self._data_delete('vol_masks', condition)
- else:
- raise LsmError(
- ErrorNumber.NO_STATE_CHANGE,
- "Volume is not masked to requested access group")
- return None
-
- def _sim_vol_ids_of_masked_ag(self, sim_ag_id):
- return list(
- m['vol_id'] for m in self._data_find(
- 'vol_masks', 'ag_id="%s"' % sim_ag_id, ['vol_id']))
-
- def _sim_ag_ids_of_masked_vol(self, sim_vol_id):
- return list(
- m['ag_id'] for m in self._data_find(
- 'vol_masks', 'vol_id="%s"' % sim_vol_id, ['ag_id']))
-
- def sim_vol_resize(self, sim_vol_id, new_size_bytes):
- org_new_size_bytes = new_size_bytes
- new_size_bytes = BackStore._block_rounding(new_size_bytes)
- sim_vol = self.sim_vol_of_id(sim_vol_id)
- if sim_vol['total_space'] == new_size_bytes:
- if org_new_size_bytes != new_size_bytes:
- # Even volume size is identical to rounded size,
- # but it's not what user requested, hence we silently pass.
- return
- else:
- raise LsmError(
- ErrorNumber.NO_STATE_CHANGE,
- "Volume size is identical to requested")
-
- sim_pool = self.sim_pool_of_id(sim_vol['pool_id'])
-
- increment = new_size_bytes - sim_vol['total_space']
-
- if increment > 0:
-
- if sim_pool['unsupported_actions'] & Pool.UNSUPPORTED_VOLUME_GROW:
- raise LsmError(
- ErrorNumber.NO_SUPPORT,
- "Requested pool does not allow volume size grow")
-
- if sim_pool['free_space'] < increment:
- raise LsmError(
- ErrorNumber.NOT_ENOUGH_SPACE, "Insufficient space in pool")
-
- elif sim_pool['unsupported_actions'] & Pool.UNSUPPORTED_VOLUME_SHRINK:
- raise LsmError(
- ErrorNumber.NO_SUPPORT,
- "Requested pool does not allow volume size grow")
-
- # TODO(Gris Ge): If a volume is in a replication relationship, resize
- # should be handled properly.
- self._data_update(
- 'volumes', sim_vol_id, "total_space", new_size_bytes)
- self._data_update(
- 'volumes', sim_vol_id, "consumed_size", new_size_bytes)
-
- def dst_sim_vol_ids_of_src(self, src_sim_vol_id):
- """
- Return a list of dst_vol_id for provided source volume ID.
- """
- self.sim_vol_of_id(src_sim_vol_id)
- return list(
- d['dst_vol_id'] for d in self._data_find(
- 'vol_reps', 'src_vol_id="%s"' % src_sim_vol_id,
- ['dst_vol_id']))
-
- def sim_vol_replica(self, src_sim_vol_id, dst_sim_vol_id, rep_type,
- blk_ranges=None):
- self.sim_vol_of_id(src_sim_vol_id)
- self.sim_vol_of_id(dst_sim_vol_id)
-
- # TODO(Gris Ge): Use consumed_size < total_space to reflect the CLONE
- # type.
- cur_src_sim_vol_ids = list(
- r['src_vol_id'] for r in self._data_find(
- 'vol_reps', 'dst_vol_id="%s"' % dst_sim_vol_id,
- ['src_vol_id']))
- if len(cur_src_sim_vol_ids) == 1 and \
- cur_src_sim_vol_ids[0] == src_sim_vol_id:
- # src and dst match. Maybe user are overriding old setting.
- pass
- elif len(cur_src_sim_vol_ids) == 0:
- pass
- else:
- # TODO(Gris Ge): Need to introduce new API error
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "Target volume is already a replication target for other "
- "source volume")
-
- self._data_add(
- 'vol_reps',
- {
- 'src_vol_id': src_sim_vol_id,
- 'dst_vol_id': dst_sim_vol_id,
- 'rep_type': rep_type,
- })
-
- # No need to trace block range due to lack of query method.
-
- def sim_vol_src_replica_break(self, src_sim_vol_id):
-
- if not self.dst_sim_vol_ids_of_src(src_sim_vol_id):
- raise LsmError(
- ErrorNumber.NO_STATE_CHANGE,
- "Provided volume is not a replication source")
-
- self._data_delete(
- 'vol_reps', 'src_vol_id="%s"' % src_sim_vol_id)
-
- def sim_vol_state_change(self, sim_vol_id, new_admin_state):
- sim_vol = self.sim_vol_of_id(sim_vol_id)
- if sim_vol['admin_state'] == new_admin_state:
- raise LsmError(
- ErrorNumber.NO_STATE_CHANGE,
- "Volume admin state is identical to requested")
-
- self._data_update(
- 'volumes', sim_vol_id, "admin_state", new_admin_state)
-
- @staticmethod
- def _sim_ag_format(sim_ag):
- """
- Update 'init_type' and 'init_ids' of sim_ag
- """
- sim_ag['init_ids'] = sim_ag['init_ids_str'].split(
- BackStore._LIST_SPLITTER)
- del sim_ag['init_ids_str']
- return sim_ag
-
- def sim_ags(self, sim_vol_id=None):
- if sim_vol_id:
- sim_ags = self._data_find(
- 'ags_by_vol_view', 'vol_id=%s' % sim_vol_id,
- BackStore.AG_KEY_LIST)
- else:
- sim_ags = self._get_table('ags_view', BackStore.AG_KEY_LIST)
-
- return [BackStore._sim_ag_format(a) for a in sim_ags]
-
- def _sim_init_create(self, init_type, init_id, sim_ag_id):
- try:
- self._data_add(
- "inits",
- {
- 'id': init_id,
- 'init_type': init_type,
- 'owner_ag_id': sim_ag_id
- })
- except sqlite3.IntegrityError as sql_error:
- raise LsmError(
- ErrorNumber.EXISTS_INITIATOR,
- "Initiator '%s' is already in use by other access group" %
- init_id)
-
- def iscsi_chap_auth_set(self, init_id, in_user, in_pass, out_user,
- out_pass):
- # Currently, there is no API method to query status of iscsi CHAP.
- return None
-
- def sim_ag_create(self, name, init_type, init_id):
- try:
- self._data_add("ags", {'name': name})
- sim_ag_id = self.lastrowid
- except sqlite3.IntegrityError as sql_error:
- raise LsmError(
- ErrorNumber.NAME_CONFLICT,
- "Name '%s' is already in use by other access group" %
- name)
-
- self._sim_init_create(init_type, init_id, sim_ag_id)
-
- return sim_ag_id
-
- def sim_ag_delete(self, sim_ag_id):
- self.sim_ag_of_id(sim_ag_id)
- if self._sim_vol_ids_of_masked_ag(sim_ag_id):
- raise LsmError(
- ErrorNumber.IS_MASKED,
- "Access group has volume masked to")
-
- self._data_delete('ags', 'id="%s"' % sim_ag_id)
-
- def sim_ag_init_add(self, sim_ag_id, init_id, init_type):
- sim_ag = self.sim_ag_of_id(sim_ag_id)
- if init_id in sim_ag['init_ids']:
- raise LsmError(
- ErrorNumber.NO_STATE_CHANGE,
- "Initiator already in access group")
-
- if init_type != AccessGroup.INIT_TYPE_ISCSI_IQN and \
- init_type != AccessGroup.INIT_TYPE_WWPN:
- raise LsmError(
- ErrorNumber.NO_SUPPORT,
- "Only support iSCSI IQN and WWPN initiator type")
-
- self._sim_init_create(init_type, init_id, sim_ag_id)
- return None
-
- def sim_ag_init_delete(self, sim_ag_id, init_id):
- sim_ag = self.sim_ag_of_id(sim_ag_id)
- if init_id not in sim_ag['init_ids']:
- raise LsmError(
- ErrorNumber.NO_STATE_CHANGE,
- "Initiator is not in defined access group")
- if len(sim_ag['init_ids']) == 1:
- raise LsmError(
- ErrorNumber.LAST_INIT_IN_ACCESS_GROUP,
- "Refused to remove the last initiator from access group")
-
- self._data_delete('inits', 'id="%s"' % init_id)
-
- def sim_ag_of_id(self, sim_ag_id):
- sim_ag = self._sim_data_of_id(
- "ags_view", sim_ag_id, BackStore.AG_KEY_LIST,
- ErrorNumber.NOT_FOUND_ACCESS_GROUP,
- "Access Group")
- BackStore._sim_ag_format(sim_ag)
- return sim_ag
-
- def sim_fss(self):
- """
- Return a list of sim_fs dict.
- """
- return self._get_table('fss', BackStore.FS_KEY_LIST)
-
- def sim_fs_of_id(self, sim_fs_id, raise_error=True):
- lsm_error_no = ErrorNumber.NOT_FOUND_FS
- if not raise_error:
- lsm_error_no = None
-
- return self._sim_data_of_id(
- "fss", sim_fs_id, BackStore.FS_KEY_LIST, lsm_error_no,
- "File System")
-
- def sim_fs_create(self, name, size_bytes, sim_pool_id):
- size_bytes = BackStore._block_rounding(size_bytes)
- self._check_pool_free_space(sim_pool_id, size_bytes)
- try:
- self._data_add(
- "fss",
- {
- 'name': name,
- 'total_space': size_bytes,
- 'consumed_size': size_bytes,
- 'free_space': size_bytes,
- 'pool_id': sim_pool_id,
- })
- except sqlite3.IntegrityError as sql_error:
- raise LsmError(
- ErrorNumber.NAME_CONFLICT,
- "Name '%s' is already in use by other fs" % name)
- return self.lastrowid
-
- def sim_fs_delete(self, sim_fs_id):
- self.sim_fs_of_id(sim_fs_id)
- if self.clone_dst_sim_fs_ids_of_src(sim_fs_id):
- # TODO(Gris Ge): API does not have dedicate error for this
- # scenario.
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "Requested file system is a clone source")
-
- if self.sim_fs_snaps(sim_fs_id):
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "Requested file system has snapshot attached")
-
- if self._data_find('exps', 'fs_id="%s"' % sim_fs_id, ['id']):
- # TODO(Gris Ge): API does not have dedicate error for this
- # scenario
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "Requested file system is exported via NFS")
-
- self._data_delete("fss", 'id="%s"' % sim_fs_id)
-
- def sim_fs_resize(self, sim_fs_id, new_size_bytes):
- org_new_size_bytes = new_size_bytes
- new_size_bytes = BackStore._block_rounding(new_size_bytes)
- sim_fs = self.sim_fs_of_id(sim_fs_id)
-
- if sim_fs['total_space'] == new_size_bytes:
- if new_size_bytes != org_new_size_bytes:
- return
- else:
- raise LsmError(
- ErrorNumber.NO_STATE_CHANGE,
- "File System size is identical to requested")
-
- # TODO(Gris Ge): If a fs is in a clone/snapshot relationship, resize
- # should be handled properly.
-
- sim_pool = self.sim_pool_of_id(sim_fs['pool_id'])
-
- if new_size_bytes > sim_fs['total_space'] and \
- sim_pool['free_space'] < new_size_bytes - sim_fs['total_space']:
- raise LsmError(
- ErrorNumber.NOT_ENOUGH_SPACE, "Insufficient space in pool")
-
- self._data_update(
- 'fss', sim_fs_id, "total_space", new_size_bytes)
- self._data_update(
- 'fss', sim_fs_id, "consumed_size", new_size_bytes)
- self._data_update(
- 'fss', sim_fs_id, "free_space", new_size_bytes)
-
- def sim_fs_snaps(self, sim_fs_id):
- self.sim_fs_of_id(sim_fs_id)
- return self._data_find(
- 'fs_snaps', 'fs_id="%s"' % sim_fs_id, BackStore.FS_SNAP_KEY_LIST)
-
- def sim_fs_snap_of_id(self, sim_fs_snap_id, sim_fs_id=None):
- sim_fs_snap = self._sim_data_of_id(
- 'fs_snaps', sim_fs_snap_id, BackStore.FS_SNAP_KEY_LIST,
- ErrorNumber.NOT_FOUND_FS_SS, 'File system snapshot')
- if sim_fs_id and sim_fs_snap['fs_id'] != sim_fs_id:
- raise LsmError(
- ErrorNumber.NOT_FOUND_FS_SS,
- "Defined file system snapshot ID is not belong to requested "
- "file system")
- return sim_fs_snap
-
- def sim_fs_snap_create(self, sim_fs_id, name):
- self.sim_fs_of_id(sim_fs_id)
- try:
- self._data_add(
- 'fs_snaps',
- {
- 'name': name,
- 'fs_id': sim_fs_id,
- 'timestamp': int(time.time()),
- })
- except sqlite3.IntegrityError as sql_error:
- raise LsmError(
- ErrorNumber.NAME_CONFLICT,
- "The name is already used by other file system snapshot")
- return self.lastrowid
-
- def sim_fs_snap_restore(self, sim_fs_id, sim_fs_snap_id, files,
- restore_files, flag_all_files):
- # Currently LSM cannot query stauts of this action.
- # we simply check existence
- self.sim_fs_of_id(sim_fs_id)
- if sim_fs_snap_id:
- self.sim_fs_snap_of_id(sim_fs_snap_id, sim_fs_id)
- return
-
- def sim_fs_snap_delete(self, sim_fs_snap_id, sim_fs_id):
- self.sim_fs_of_id(sim_fs_id)
- self.sim_fs_snap_of_id(sim_fs_snap_id, sim_fs_id)
- self._data_delete('fs_snaps', 'id="%s"' % sim_fs_snap_id)
-
- def sim_fs_snap_del_by_fs(self, sim_fs_id):
- sql_cmd = "DELETE FROM fs_snaps WHERE fs_id='%s';" % sim_fs_id
- self._sql_exec(sql_cmd)
-
- def sim_fs_clone(self, src_sim_fs_id, dst_sim_fs_id, sim_fs_snap_id):
- self.sim_fs_of_id(src_sim_fs_id)
- self.sim_fs_of_id(dst_sim_fs_id)
-
- if sim_fs_snap_id:
- # No need to trace state of snap id here due to lack of
- # query method.
- # We just check snapshot existence
- self.sim_fs_snap_of_id(sim_fs_snap_id, src_sim_fs_id)
-
- self._data_add(
- 'fs_clones',
- {
- 'src_fs_id': src_sim_fs_id,
- 'dst_fs_id': dst_sim_fs_id,
- })
-
- def sim_fs_file_clone(self, sim_fs_id, src_fs_name, dst_fs_name,
- sim_fs_snap_id):
- # We don't have API to query file level clone.
- # Simply check existence
- self.sim_fs_of_id(sim_fs_id)
- if sim_fs_snap_id:
- self.sim_fs_snap_of_id(sim_fs_snap_id, sim_fs_id)
- return
-
- def clone_dst_sim_fs_ids_of_src(self, src_sim_fs_id):
- """
- Return a list of dst_fs_id for provided clone source fs ID.
- """
- self.sim_fs_of_id(src_sim_fs_id)
- return list(
- d['dst_fs_id'] for d in self._data_find(
- 'fs_clones', 'src_fs_id="%s"' % src_sim_fs_id,
- ['dst_fs_id']))
-
- def sim_fs_src_clone_break(self, src_sim_fs_id):
- self._data_delete('fs_clones', 'src_fs_id="%s"' % src_sim_fs_id)
-
- def _sim_exp_format(self, sim_exp):
- for key_name in ['root_hosts', 'rw_hosts', 'ro_hosts']:
- table_name = "exp_%s_str" % key_name
- if sim_exp[table_name]:
- sim_exp[key_name] = sim_exp[table_name].split(
- BackStore._LIST_SPLITTER)
- else:
- sim_exp[key_name] = []
- del sim_exp[table_name]
- return sim_exp
-
- def sim_exps(self):
- return list(
- self._sim_exp_format(e)
- for e in self._get_table('exps_view', BackStore.EXP_KEY_LIST))
-
- def sim_exp_of_id(self, sim_exp_id):
- return self._sim_exp_format(
- self._sim_data_of_id(
- 'exps_view', sim_exp_id, BackStore.EXP_KEY_LIST,
- ErrorNumber.NOT_FOUND_NFS_EXPORT, 'NFS Export'))
-
- def sim_exp_create(self, sim_fs_id, exp_path, root_hosts, rw_hosts,
- ro_hosts, anon_uid, anon_gid, auth_type, options):
- if exp_path is None:
- exp_path = "/nfs_exp_%s" % _random_vpd()[:8]
- self.sim_fs_of_id(sim_fs_id)
-
- try:
- self._data_add(
- 'exps',
- {
- 'fs_id': sim_fs_id,
- 'exp_path': exp_path,
- 'anon_uid': anon_uid,
- 'anon_gid': anon_gid,
- 'auth_type': auth_type,
- 'options': options,
- })
- except sqlite3.IntegrityError as sql_error:
- # TODO(Gris Ge): Should we create new error instead of
- # NAME_CONFLICT?
- raise LsmError(
- ErrorNumber.NAME_CONFLICT,
- "Export path is already used by other NFS export")
-
- sim_exp_id = self.lastrowid
-
- for root_host in root_hosts:
- self._data_add(
- 'exp_root_hosts',
- {
- 'host': root_host,
- 'exp_id': sim_exp_id,
- })
- for rw_host in rw_hosts:
- self._data_add(
- 'exp_rw_hosts',
- {
- 'host': rw_host,
- 'exp_id': sim_exp_id,
- })
- for ro_host in ro_hosts:
- self._data_add(
- 'exp_ro_hosts',
- {
- 'host': ro_host,
- 'exp_id': sim_exp_id,
- })
-
- return sim_exp_id
-
- def sim_exp_delete(self, sim_exp_id):
- self.sim_exp_of_id(sim_exp_id)
- self._data_delete('exps', 'id="%s"' % sim_exp_id)
-
- def sim_tgts(self):
- """
- Return a list of sim_tgt dict.
- """
- return self._get_table('tgts', BackStore.TGT_KEY_LIST)
-
-
-class SimArray(object):
- SIM_DATA_FILE = os.getenv("LSM_SIM_DATA",
- tempfile.gettempdir() + '/lsm_sim_data')
-
- ID_FMT = 5
-
- @staticmethod
- def _sim_id_to_lsm_id(sim_id, prefix):
- return "%s_ID_%0*d" % (prefix, SimArray.ID_FMT, sim_id)
-
- @staticmethod
- def _lsm_id_to_sim_id(lsm_id, lsm_error):
- try:
- return int(lsm_id[-SimArray.ID_FMT:])
- except ValueError:
- raise lsm_error
-
- @staticmethod
- def _sim_job_id_of(job_id):
- return SimArray._lsm_id_to_sim_id(
- job_id, LsmError(ErrorNumber.NOT_FOUND_JOB, "Job not found"))
-
- @staticmethod
- def _sim_pool_id_of(pool_id):
- return SimArray._lsm_id_to_sim_id(
- pool_id, LsmError(ErrorNumber.NOT_FOUND_POOL, "Pool not found"))
-
- @staticmethod
- def _sim_vol_id_of(vol_id):
- return SimArray._lsm_id_to_sim_id(
- vol_id, LsmError(
- ErrorNumber.NOT_FOUND_VOLUME, "Volume not found"))
-
- @staticmethod
- def _sim_fs_id_of(fs_id):
- return SimArray._lsm_id_to_sim_id(
- fs_id, LsmError(
- ErrorNumber.NOT_FOUND_FS, "File system not found"))
-
- @staticmethod
- def _sim_fs_snap_id_of(snap_id):
- return SimArray._lsm_id_to_sim_id(
- snap_id, LsmError(
- ErrorNumber.NOT_FOUND_FS_SS,
- "File system snapshot not found"))
-
- @staticmethod
- def _sim_exp_id_of(exp_id):
- return SimArray._lsm_id_to_sim_id(
- exp_id, LsmError(
- ErrorNumber.NOT_FOUND_NFS_EXPORT,
- "File system export not found"))
-
- @staticmethod
- def _sim_ag_id_of(ag_id):
- return SimArray._lsm_id_to_sim_id(
- ag_id, LsmError(
- ErrorNumber.NOT_FOUND_NFS_EXPORT,
- "File system export not found"))
-
- @_handle_errors
- def __init__(self, statefile, timeout):
- if statefile is None:
- statefile = SimArray.SIM_DATA_FILE
-
- self.bs_obj = BackStore(statefile, timeout)
- self.bs_obj.check_version_and_init()
- self.statefile = statefile
- self.timeout = timeout
-
- def _job_create(self, data_type=None, sim_data_id=None):
- sim_job_id = self.bs_obj.sim_job_create(
- data_type, sim_data_id)
- return SimArray._sim_id_to_lsm_id(sim_job_id, 'JOB')
-
- @_handle_errors
- def job_status(self, job_id, flags=0):
- sim_job_id = SimArray._sim_job_id_of(job_id)
-
- (progress, data_type, sim_data) = self.bs_obj.sim_job_status(
- sim_job_id)
- status = JobStatus.INPROGRESS
- if progress == 100:
- status = JobStatus.COMPLETE
-
- data = None
- if data_type == BackStore.JOB_DATA_TYPE_VOL:
- data = SimArray._sim_vol_2_lsm(sim_data)
- elif data_type == BackStore.JOB_DATA_TYPE_FS:
- data = SimArray._sim_fs_2_lsm(sim_data)
- elif data_type == BackStore.JOB_DATA_TYPE_FS_SNAP:
- data = SimArray._sim_fs_snap_2_lsm(sim_data)
-
- return (status, progress, data)
-
- @_handle_errors
- def job_free(self, job_id, flags=0):
- self.bs_obj.trans_begin()
- self.bs_obj.sim_job_delete(SimArray._sim_job_id_of(job_id))
- self.bs_obj.trans_commit()
- return None
-
- @_handle_errors
- def time_out_set(self, ms, flags=0):
- self.bs_obj = BackStore(self.statefile, int(ms/1000))
- self.timeout = ms
- return None
-
- @_handle_errors
- def time_out_get(self, flags=0):
- return self.timeout
-
- @staticmethod
- def _sim_sys_2_lsm(sim_sys):
- return System(
- sim_sys['id'], sim_sys['name'], sim_sys['status'],
- sim_sys['status_info'])
-
- @_handle_errors
- def systems(self):
- return list(
- SimArray._sim_sys_2_lsm(sim_sys)
- for sim_sys in self.bs_obj.sim_syss())
-
- @staticmethod
- def _sim_vol_2_lsm(sim_vol):
- vol_id = SimArray._sim_id_to_lsm_id(sim_vol['id'], 'VOL')
- pool_id = SimArray._sim_id_to_lsm_id(sim_vol['pool_id'], 'POOL')
- return Volume(vol_id, sim_vol['name'], sim_vol['vpd83'],
- BackStore.BLK_SIZE,
- int(sim_vol['total_space'] / BackStore.BLK_SIZE),
- sim_vol['admin_state'], BackStore.SYS_ID,
- pool_id)
-
- @_handle_errors
- def volumes(self):
- return list(
- SimArray._sim_vol_2_lsm(v) for v in self.bs_obj.sim_vols())
-
- @staticmethod
- def _sim_pool_2_lsm(sim_pool):
- pool_id = SimArray._sim_id_to_lsm_id(sim_pool['id'], 'POOL')
- name = sim_pool['name']
- total_space = sim_pool['total_space']
- free_space = sim_pool['free_space']
- status = sim_pool['status']
- status_info = sim_pool['status_info']
- sys_id = BackStore.SYS_ID
- element_type = sim_pool['element_type']
- unsupported_actions = sim_pool['unsupported_actions']
- return Pool(
- pool_id, name, element_type, unsupported_actions, total_space,
- free_space, status, status_info, sys_id)
-
- @_handle_errors
- def pools(self, flags=0):
- self.bs_obj.trans_begin()
- sim_pools = self.bs_obj.sim_pools()
- self.bs_obj.trans_rollback()
- return list(
- SimArray._sim_pool_2_lsm(sim_pool) for sim_pool in sim_pools)
-
- @staticmethod
- def _sim_disk_2_lsm(sim_disk):
- disk_status = Disk.STATUS_OK
- if sim_disk['role'] is None:
- disk_status |= Disk.STATUS_FREE
-
- return Disk(
- SimArray._sim_id_to_lsm_id(sim_disk['id'], 'DISK'),
- sim_disk['name'],
- sim_disk['disk_type'], BackStore.BLK_SIZE,
- int(sim_disk['total_space'] / BackStore.BLK_SIZE),
- disk_status, BackStore.SYS_ID)
-
- @_handle_errors
- def disks(self):
- return list(
- SimArray._sim_disk_2_lsm(sim_disk)
- for sim_disk in self.bs_obj.sim_disks())
-
- @_handle_errors
- def volume_create(self, pool_id, vol_name, size_bytes, thinp, flags=0,
- _internal_use=False):
- """
- The '_internal_use' parameter is only for SimArray internal use.
- This method will return the new sim_vol id instead of job_id when
- '_internal_use' marked as True.
- """
- if _internal_use is False:
- self.bs_obj.trans_begin()
-
- new_sim_vol_id = self.bs_obj.sim_vol_create(
- vol_name, size_bytes, SimArray._sim_pool_id_of(pool_id), thinp)
-
- if _internal_use:
- return new_sim_vol_id
-
- job_id = self._job_create(
- BackStore.JOB_DATA_TYPE_VOL, new_sim_vol_id)
- self.bs_obj.trans_commit()
-
- return job_id, None
-
- @_handle_errors
- def volume_delete(self, vol_id, flags=0):
- self.bs_obj.trans_begin()
- self.bs_obj.sim_vol_delete(SimArray._sim_vol_id_of(vol_id))
- job_id = self._job_create()
- self.bs_obj.trans_commit()
- return job_id
-
- @_handle_errors
- def volume_resize(self, vol_id, new_size_bytes, flags=0):
- self.bs_obj.trans_begin()
-
- sim_vol_id = SimArray._sim_vol_id_of(vol_id)
- self.bs_obj.sim_vol_resize(sim_vol_id, new_size_bytes)
- job_id = self._job_create(
- BackStore.JOB_DATA_TYPE_VOL, sim_vol_id)
- self.bs_obj.trans_commit()
-
- return job_id, None
-
- @_handle_errors
- def volume_replicate(self, dst_pool_id, rep_type, src_vol_id, new_vol_name,
- flags=0):
- self.bs_obj.trans_begin()
-
- src_sim_vol_id = SimArray._sim_pool_id_of(src_vol_id)
- # Verify the existence of source volume
- src_sim_vol = self.bs_obj.sim_vol_of_id(src_sim_vol_id)
-
- dst_sim_vol_id = self.volume_create(
- dst_pool_id, new_vol_name, src_sim_vol['total_space'],
- src_sim_vol['thinp'], _internal_use=True)
-
- self.bs_obj.sim_vol_replica(src_sim_vol_id, dst_sim_vol_id, rep_type)
-
- job_id = self._job_create(
- BackStore.JOB_DATA_TYPE_VOL, dst_sim_vol_id)
- self.bs_obj.trans_commit()
-
- return job_id, None
-
- @_handle_errors
- def volume_replicate_range_block_size(self, sys_id, flags=0):
- if sys_id != BackStore.SYS_ID:
- raise LsmError(
- ErrorNumber.NOT_FOUND_SYSTEM,
- "System not found")
- return BackStore.BLK_SIZE
-
- @_handle_errors
- def volume_replicate_range(self, rep_type, src_vol_id, dst_vol_id, ranges,
- flags=0):
- self.bs_obj.trans_begin()
-
- # TODO(Gris Ge): check whether star_blk + count is out of volume
- # boundary
- # TODO(Gris Ge): Should check block overlap.
-
- self.bs_obj.sim_vol_replica(
- SimArray._sim_pool_id_of(src_vol_id),
- SimArray._sim_pool_id_of(dst_vol_id), rep_type, ranges)
-
- job_id = self._job_create()
-
- self.bs_obj.trans_commit()
- return job_id
-
- @_handle_errors
- def volume_enable(self, vol_id, flags=0):
- self.bs_obj.trans_begin()
- self.bs_obj.sim_vol_state_change(
- SimArray._sim_vol_id_of(vol_id), Volume.ADMIN_STATE_ENABLED)
- self.bs_obj.trans_commit()
- return None
-
- @_handle_errors
- def volume_disable(self, vol_id, flags=0):
- self.bs_obj.trans_begin()
- self.bs_obj.sim_vol_state_change(
- SimArray._sim_vol_id_of(vol_id), Volume.ADMIN_STATE_DISABLED)
- self.bs_obj.trans_commit()
- return None
-
- @_handle_errors
- def volume_child_dependency(self, vol_id, flags=0):
- # TODO(Gris Ge): API defination is blur:
- # 0. Should we break replication if provided volume is a
- # replication target?
- # Assuming answer is no.
- # 1. _client.py comments incorrect:
- # "Implies that this volume cannot be deleted or possibly
- # modified because it would affect its children"
- # The 'modify' here is incorrect. If data on source volume
- # changes, SYNC_MIRROR replication will change all target
- # volumes.
- # 2. Should 'mask' relationship included?
- # # Assuming only replication counts here.
- # 3. For volume internal block replication, should we return
- # True or False.
- # # Assuming False
- # 4. volume_child_dependency_rm() against volume internal
- # block replication, remove replication or raise error?
- # # Assuming remove replication
- src_sim_vol_id = SimArray._sim_vol_id_of(vol_id)
- dst_sim_vol_ids = self.bs_obj.dst_sim_vol_ids_of_src(src_sim_vol_id)
- for dst_sim_fs_id in dst_sim_vol_ids:
- if dst_sim_fs_id != src_sim_vol_id:
- return True
- return False
-
- @_handle_errors
- def volume_child_dependency_rm(self, vol_id, flags=0):
- self.bs_obj.trans_begin()
-
- self.bs_obj.sim_vol_src_replica_break(
- SimArray._sim_vol_id_of(vol_id))
-
- job_id = self._job_create()
- self.bs_obj.trans_commit()
- return job_id
-
- @staticmethod
- def _sim_fs_2_lsm(sim_fs):
- fs_id = SimArray._sim_id_to_lsm_id(sim_fs['id'], 'FS')
- pool_id = SimArray._sim_id_to_lsm_id(sim_fs['id'], 'POOL')
- return FileSystem(fs_id, sim_fs['name'],
- sim_fs['total_space'], sim_fs['free_space'],
- pool_id, BackStore.SYS_ID)
-
- @_handle_errors
- def fs(self):
- return list(SimArray._sim_fs_2_lsm(f) for f in self.bs_obj.sim_fss())
-
- @_handle_errors
- def fs_create(self, pool_id, fs_name, size_bytes, flags=0,
- _internal_use=False):
-
- if not _internal_use:
- self.bs_obj.trans_begin()
-
- new_sim_fs_id = self.bs_obj.sim_fs_create(
- fs_name, size_bytes, SimArray._sim_pool_id_of(pool_id))
-
- if _internal_use:
- return new_sim_fs_id
-
- job_id = self._job_create(
- BackStore.JOB_DATA_TYPE_FS, new_sim_fs_id)
- self.bs_obj.trans_commit()
-
- return job_id, None
-
- @_handle_errors
- def fs_delete(self, fs_id, flags=0):
- self.bs_obj.trans_begin()
- self.bs_obj.sim_fs_delete(SimArray._sim_fs_id_of(fs_id))
- job_id = self._job_create()
- self.bs_obj.trans_commit()
- return job_id
-
- @_handle_errors
- def fs_resize(self, fs_id, new_size_bytes, flags=0):
- sim_fs_id = SimArray._sim_fs_id_of(fs_id)
- self.bs_obj.trans_begin()
- self.bs_obj.sim_fs_resize(sim_fs_id, new_size_bytes)
- job_id = self._job_create(BackStore.JOB_DATA_TYPE_FS, sim_fs_id)
- self.bs_obj.trans_commit()
- return job_id, None
-
- @_handle_errors
- def fs_clone(self, src_fs_id, dst_fs_name, snap_id, flags=0):
- self.bs_obj.trans_begin()
-
- sim_fs_snap_id = None
- if snap_id:
- sim_fs_snap_id = SimArray._sim_fs_snap_id_of(snap_id)
-
- src_sim_fs_id = SimArray._sim_fs_id_of(src_fs_id)
- src_sim_fs = self.bs_obj.sim_fs_of_id(src_sim_fs_id)
- pool_id = SimArray._sim_id_to_lsm_id(src_sim_fs['pool_id'], 'POOL')
-
- dst_sim_fs_id = self.fs_create(
- pool_id, dst_fs_name, src_sim_fs['total_space'],
- _internal_use=True)
-
- self.bs_obj.sim_fs_clone(src_sim_fs_id, dst_sim_fs_id, sim_fs_snap_id)
-
- job_id = self._job_create(
- BackStore.JOB_DATA_TYPE_FS, dst_sim_fs_id)
- self.bs_obj.trans_commit()
-
- return job_id, None
-
- @_handle_errors
- def fs_file_clone(self, fs_id, src_fs_name, dst_fs_name, snap_id, flags=0):
- self.bs_obj.trans_begin()
- sim_fs_snap_id = None
- if snap_id:
- sim_fs_snap_id = SimArray._sim_fs_snap_id_of(snap_id)
-
- self.bs_obj.sim_fs_file_clone(
- SimArray._sim_fs_id_of(fs_id), src_fs_name, dst_fs_name,
- sim_fs_snap_id)
-
- job_id = self._job_create()
- self.bs_obj.trans_commit()
- return job_id
-
- @staticmethod
- def _sim_fs_snap_2_lsm(sim_fs_snap):
- snap_id = SimArray._sim_id_to_lsm_id(sim_fs_snap['id'], 'FS_SNAP')
- return FsSnapshot(
- snap_id, sim_fs_snap['name'], sim_fs_snap['timestamp'])
-
- @_handle_errors
- def fs_snapshots(self, fs_id, flags=0):
- return list(
- SimArray._sim_fs_snap_2_lsm(s)
- for s in self.bs_obj.sim_fs_snaps(
- SimArray._sim_fs_id_of(fs_id)))
-
- @_handle_errors
- def fs_snapshot_create(self, fs_id, snap_name, flags=0):
- self.bs_obj.trans_begin()
- sim_fs_snap_id = self.bs_obj.sim_fs_snap_create(
- SimArray._sim_fs_id_of(fs_id), snap_name)
- job_id = self._job_create(
- BackStore.JOB_DATA_TYPE_FS_SNAP, sim_fs_snap_id)
- self.bs_obj.trans_commit()
- return job_id, None
-
- @_handle_errors
- def fs_snapshot_delete(self, fs_id, snap_id, flags=0):
- self.bs_obj.trans_begin()
- self.bs_obj.sim_fs_snap_delete(
- SimArray._sim_fs_snap_id_of(snap_id),
- SimArray._sim_fs_id_of(fs_id))
- job_id = self._job_create()
- self.bs_obj.trans_commit()
- return job_id
-
- @_handle_errors
- def fs_snapshot_restore(self, fs_id, snap_id, files, restore_files,
- flag_all_files, flags):
- self.bs_obj.trans_begin()
- sim_fs_snap_id = None
- if snap_id:
- sim_fs_snap_id = SimArray._sim_fs_snap_id_of(snap_id)
-
- self.bs_obj.sim_fs_snap_restore(
- SimArray._sim_fs_id_of(fs_id),
- sim_fs_snap_id, files, restore_files, flag_all_files)
-
- job_id = self._job_create()
- self.bs_obj.trans_commit()
- return job_id
-
- @_handle_errors
- def fs_child_dependency(self, fs_id, files, flags=0):
- sim_fs_id = SimArray._sim_fs_id_of(fs_id)
- self.bs_obj.trans_begin()
- if self.bs_obj.clone_dst_sim_fs_ids_of_src(sim_fs_id) == [] and \
- self.bs_obj.sim_fs_snaps(sim_fs_id) == []:
- self.bs_obj.trans_rollback()
- return False
- self.bs_obj.trans_rollback()
- return True
-
- @_handle_errors
- def fs_child_dependency_rm(self, fs_id, files, flags=0):
- """
- Assuming API defination is break all clone relationship and remove
- all snapshot of this source file system.
- """
- self.bs_obj.trans_begin()
- if self.fs_child_dependency(fs_id, files) is False:
- raise LsmError(
- ErrorNumber.NO_STATE_CHANGE,
- "No snapshot or fs clone target found for this file system")
-
- src_sim_fs_id = SimArray._sim_fs_id_of(fs_id)
- self.bs_obj.sim_fs_src_clone_break(src_sim_fs_id)
- self.bs_obj.sim_fs_snap_del_by_fs(src_sim_fs_id)
- job_id = self._job_create()
- self.bs_obj.trans_begin()
- return job_id
-
- @staticmethod
- def _sim_exp_2_lsm(sim_exp):
- exp_id = SimArray._sim_id_to_lsm_id(sim_exp['id'], 'EXP')
- fs_id = SimArray._sim_id_to_lsm_id(sim_exp['fs_id'], 'FS')
- return NfsExport(exp_id, fs_id, sim_exp['exp_path'],
- sim_exp['auth_type'], sim_exp['root_hosts'],
- sim_exp['rw_hosts'], sim_exp['ro_hosts'],
- sim_exp['anon_uid'], sim_exp['anon_gid'],
- sim_exp['options'])
-
- @_handle_errors
- def exports(self, flags=0):
- return [SimArray._sim_exp_2_lsm(e) for e in self.bs_obj.sim_exps()]
-
- @_handle_errors
- def fs_export(self, fs_id, exp_path, root_hosts, rw_hosts, ro_hosts,
- anon_uid, anon_gid, auth_type, options, flags=0):
- self.bs_obj.trans_begin()
- sim_exp_id = self.bs_obj.sim_exp_create(
- SimArray._sim_fs_id_of(fs_id), exp_path, root_hosts, rw_hosts,
- ro_hosts, anon_uid, anon_gid, auth_type, options)
- sim_exp = self.bs_obj.sim_exp_of_id(sim_exp_id)
- self.bs_obj.trans_commit()
- return SimArray._sim_exp_2_lsm(sim_exp)
-
- @_handle_errors
- def fs_unexport(self, exp_id, flags=0):
- self.bs_obj.trans_begin()
- self.bs_obj.sim_exp_delete(SimArray._sim_exp_id_of(exp_id))
- self.bs_obj.trans_commit()
- return None
-
- @staticmethod
- def _sim_ag_2_lsm(sim_ag):
- ag_id = SimArray._sim_id_to_lsm_id(sim_ag['id'], 'AG')
- return AccessGroup(ag_id, sim_ag['name'], sim_ag['init_ids'],
- sim_ag['init_type'], BackStore.SYS_ID)
-
- @_handle_errors
- def ags(self):
- return list(SimArray._sim_ag_2_lsm(a) for a in self.bs_obj.sim_ags())
-
- @_handle_errors
- def access_group_create(self, name, init_id, init_type, sys_id, flags=0):
- if sys_id != BackStore.SYS_ID:
- raise LsmError(
- ErrorNumber.NOT_FOUND_SYSTEM,
- "System not found")
- self.bs_obj.trans_begin()
- new_sim_ag_id = self.bs_obj.sim_ag_create(name, init_type, init_id)
- new_sim_ag = self.bs_obj.sim_ag_of_id(new_sim_ag_id)
- self.bs_obj.trans_commit()
- return SimArray._sim_ag_2_lsm(new_sim_ag)
-
- @_handle_errors
- def access_group_delete(self, ag_id, flags=0):
- self.bs_obj.trans_begin()
- self.bs_obj.sim_ag_delete(SimArray._sim_ag_id_of(ag_id))
- self.bs_obj.trans_commit()
- return None
-
- @_handle_errors
- def access_group_initiator_add(self, ag_id, init_id, init_type, flags=0):
- sim_ag_id = SimArray._sim_ag_id_of(ag_id)
- self.bs_obj.trans_begin()
- self.bs_obj.sim_ag_init_add(sim_ag_id, init_id, init_type)
- new_sim_ag = self.bs_obj.sim_ag_of_id(sim_ag_id)
- self.bs_obj.trans_commit()
- return SimArray._sim_ag_2_lsm(new_sim_ag)
-
- @_handle_errors
- def access_group_initiator_delete(self, ag_id, init_id, init_type,
- flags=0):
- sim_ag_id = SimArray._sim_ag_id_of(ag_id)
- self.bs_obj.trans_begin()
- self.bs_obj.sim_ag_init_delete(sim_ag_id, init_id)
- sim_ag = self.bs_obj.sim_ag_of_id(sim_ag_id)
- self.bs_obj.trans_commit()
- return SimArray._sim_ag_2_lsm(sim_ag)
-
- @_handle_errors
- def volume_mask(self, ag_id, vol_id, flags=0):
- self.bs_obj.trans_begin()
- self.bs_obj.sim_vol_mask(
- SimArray._sim_vol_id_of(vol_id),
- SimArray._sim_ag_id_of(ag_id))
- self.bs_obj.trans_commit()
- return None
-
- @_handle_errors
- def volume_unmask(self, ag_id, vol_id, flags=0):
- self.bs_obj.trans_begin()
- self.bs_obj.sim_vol_unmask(
- SimArray._sim_vol_id_of(vol_id),
- SimArray._sim_ag_id_of(ag_id))
- self.bs_obj.trans_commit()
- return None
-
- @_handle_errors
- def volumes_accessible_by_access_group(self, ag_id, flags=0):
- self.bs_obj.trans_begin()
-
- sim_vols = self.bs_obj.sim_vols(
- sim_ag_id=SimArray._sim_ag_id_of(ag_id))
-
- self.bs_obj.trans_rollback()
- return [SimArray._sim_vol_2_lsm(v) for v in sim_vols]
-
- @_handle_errors
- def access_groups_granted_to_volume(self, vol_id, flags=0):
- self.bs_obj.trans_begin()
- sim_ags = self.bs_obj.sim_ags(
- sim_vol_id=SimArray._sim_vol_id_of(vol_id))
- self.bs_obj.trans_rollback()
- return [SimArray._sim_ag_2_lsm(a) for a in sim_ags]
-
- @_handle_errors
- def iscsi_chap_auth(self, init_id, in_user, in_pass, out_user, out_pass,
- flags=0):
- self.bs_obj.trans_begin()
- self.bs_obj.iscsi_chap_auth_set(
- init_id, in_user, in_pass, out_user, out_pass)
- self.bs_obj.trans_commit()
- return None
-
- @staticmethod
- def _sim_tgt_2_lsm(sim_tgt):
- tgt_id = "TGT_PORT_ID_%0*d" % (SimArray.ID_FMT, sim_tgt['id'])
- return TargetPort(
- tgt_id, sim_tgt['port_type'], sim_tgt['service_address'],
- sim_tgt['network_address'], sim_tgt['physical_address'],
- sim_tgt['physical_name'],
- BackStore.SYS_ID)
-
- @_handle_errors
- def target_ports(self):
- return list(SimArray._sim_tgt_2_lsm(t) for t in self.bs_obj.sim_tgts())
-
- @_handle_errors
- def volume_raid_info(self, lsm_vol):
- sim_pool = self.bs_obj.sim_pool_of_id(
- SimArray._lsm_id_to_sim_id(
- lsm_vol.pool_id,
- LsmError(ErrorNumber.NOT_FOUND_POOL, "Pool not found")))
-
- raid_type = sim_pool['raid_type']
- strip_size = Volume.STRIP_SIZE_UNKNOWN
- min_io_size = BackStore.BLK_SIZE
- opt_io_size = Volume.OPT_IO_SIZE_UNKNOWN
- disk_count = Volume.DISK_COUNT_UNKNOWN
-
- if sim_pool['member_type'] == PoolRAID.MEMBER_TYPE_POOL:
- parent_sim_pool = self.bs_obj.sim_pool_of_id(
- sim_pool['parent_pool_id'])
- raid_type = parent_sim_pool['raid_type']
-
- disk_count = self.bs_obj.sim_pool_disks_count(
- parent_sim_pool['id'])
- data_disk_count = self.bs_obj.sim_pool_data_disks_count(
- parent_sim_pool['id'])
- else:
- disk_count = self.bs_obj.sim_pool_disks_count(
- sim_pool['id'])
- data_disk_count = self.bs_obj.sim_pool_data_disks_count(
- sim_pool['id'])
-
- if raid_type == Volume.RAID_TYPE_UNKNOWN or \
- raid_type == Volume.RAID_TYPE_OTHER:
- return [
- raid_type, strip_size, disk_count, min_io_size,
- opt_io_size]
-
- if raid_type == Volume.RAID_TYPE_MIXED:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "volume_raid_info(): Got unsupported RAID_TYPE_MIXED pool "
- "%s" % sim_pool['id'])
-
- if raid_type == Volume.RAID_TYPE_RAID1 or \
- raid_type == Volume.RAID_TYPE_JBOD:
- strip_size = BackStore.BLK_SIZE
- min_io_size = BackStore.BLK_SIZE
- opt_io_size = BackStore.BLK_SIZE
- else:
- strip_size = BackStore.STRIP_SIZE
- min_io_size = BackStore.STRIP_SIZE
- opt_io_size = int(data_disk_count * BackStore.STRIP_SIZE)
-
- return [raid_type, strip_size, disk_count, min_io_size, opt_io_size]
diff --git a/plugin/sim/simulator.py b/plugin/sim/simulator.py
deleted file mode 100644
index d562cd6..0000000
--- a/plugin/sim/simulator.py
+++ /dev/null
@@ -1,294 +0,0 @@
-# Copyright (C) 2011-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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: tasleson
-# Gris Ge <***@redhat.com>
-
-from lsm import (uri_parse, VERSION, Capabilities, INfs,
- IStorageAreaNetwork, search_property)
-
-from simarray import SimArray
-
-
-class SimPlugin(INfs, IStorageAreaNetwork):
- """
- Simple class that implements enough to allow the framework to be exercised.
- """
- def __init__(self):
- self.uri = None
- self.password = None
- self.sim_array = None
-
- def plugin_register(self, uri, password, timeout, flags=0):
- self.uri = uri
- self.password = password
-
- #The caller may want to start clean, so we allow the caller to specify
- #a file to store and retrieve individual state.
- qp = uri_parse(uri)
- if 'parameters' in qp and 'statefile' in qp['parameters'] \
- and qp['parameters']['statefile'] is not None:
- self.sim_array = SimArray(qp['parameters']['statefile'], timeout)
- else:
- self.sim_array = SimArray(None, timeout)
-
- return None
-
- def plugin_unregister(self, flags=0):
- pass
-
- def job_status(self, job_id, flags=0):
- return self.sim_array.job_status(job_id, flags)
-
- def job_free(self, job_id, flags=0):
- return self.sim_array.job_free(job_id, flags)
-
- @staticmethod
- def _sim_data_2_lsm(sim_data):
- """
- Fake converter. SimArray already do SimData to LSM data convert.
- We move data convert to SimArray to make this sample plugin looks
- clean.
- But in real world, data converting is often handled by plugin itself
- rather than array.
- """
- return sim_data
-
- def time_out_set(self, ms, flags=0):
- self.sim_array.time_out_set(ms, flags)
- return None
-
- def time_out_get(self, flags=0):
- return self.sim_array.time_out_get(flags)
-
- def capabilities(self, system, flags=0):
- rc = Capabilities()
- rc.enable_all()
- rc.set(Capabilities.POOLS_QUICK_SEARCH, Capabilities.UNSUPPORTED)
- rc.set(Capabilities.VOLUMES_QUICK_SEARCH, Capabilities.UNSUPPORTED)
- rc.set(Capabilities.DISKS_QUICK_SEARCH, Capabilities.UNSUPPORTED)
- rc.set(Capabilities.FS_QUICK_SEARCH, Capabilities.UNSUPPORTED)
- rc.set(Capabilities.ACCESS_GROUPS_QUICK_SEARCH,
- Capabilities.UNSUPPORTED)
- rc.set(Capabilities.NFS_EXPORTS_QUICK_SEARCH, Capabilities.UNSUPPORTED)
- rc.set(Capabilities.TARGET_PORTS_QUICK_SEARCH,
- Capabilities.UNSUPPORTED)
- return rc
-
- def plugin_info(self, flags=0):
- return "Storage simulator", VERSION
-
- def systems(self, flags=0):
- sim_syss = self.sim_array.systems()
- return [SimPlugin._sim_data_2_lsm(s) for s in sim_syss]
-
- def pools(self, search_key=None, search_value=None, flags=0):
- sim_pools = self.sim_array.pools(flags)
- return search_property(
- [SimPlugin._sim_data_2_lsm(p) for p in sim_pools],
- search_key, search_value)
-
- def volumes(self, search_key=None, search_value=None, flags=0):
- sim_vols = self.sim_array.volumes()
- return search_property(
- [SimPlugin._sim_data_2_lsm(v) for v in sim_vols],
- search_key, search_value)
-
- def disks(self, search_key=None, search_value=None, flags=0):
- sim_disks = self.sim_array.disks()
- return search_property(
- [SimPlugin._sim_data_2_lsm(d) for d in sim_disks],
- search_key, search_value)
-
- def volume_create(self, pool, volume_name, size_bytes, provisioning,
- flags=0):
- sim_vol = self.sim_array.volume_create(
- pool.id, volume_name, size_bytes, provisioning, flags)
- return SimPlugin._sim_data_2_lsm(sim_vol)
-
- def volume_delete(self, volume, flags=0):
- return self.sim_array.volume_delete(volume.id, flags)
-
- def volume_resize(self, volume, new_size_bytes, flags=0):
- sim_vol = self.sim_array.volume_resize(
- volume.id, new_size_bytes, flags)
- return SimPlugin._sim_data_2_lsm(sim_vol)
-
- def volume_replicate(self, pool, rep_type, volume_src, name, flags=0):
- dst_pool_id = None
-
- if pool is not None:
- dst_pool_id = pool.id
- else:
- dst_pool_id = volume_src.pool_id
- return self.sim_array.volume_replicate(
- dst_pool_id, rep_type, volume_src.id, name, flags)
-
- def volume_replicate_range_block_size(self, system, flags=0):
- return self.sim_array.volume_replicate_range_block_size(
- system.id, flags)
-
- def volume_replicate_range(self, rep_type, volume_src, volume_dest,
- ranges, flags=0):
- return self.sim_array.volume_replicate_range(
- rep_type, volume_src.id, volume_dest.id, ranges, flags)
-
- def volume_enable(self, volume, flags=0):
- return self.sim_array.volume_enable(volume.id, flags)
-
- def volume_disable(self, volume, flags=0):
- return self.sim_array.volume_disable(volume.id, flags)
-
- def access_groups(self, search_key=None, search_value=None, flags=0):
- sim_ags = self.sim_array.ags()
- return search_property(
- [SimPlugin._sim_data_2_lsm(a) for a in sim_ags],
- search_key, search_value)
-
- def access_group_create(self, name, init_id, init_type, system,
- flags=0):
- sim_ag = self.sim_array.access_group_create(
- name, init_id, init_type, system.id, flags)
- return SimPlugin._sim_data_2_lsm(sim_ag)
-
- def access_group_delete(self, access_group, flags=0):
- return self.sim_array.access_group_delete(access_group.id, flags)
-
- def access_group_initiator_add(self, access_group, init_id, init_type,
- flags=0):
- sim_ag = self.sim_array.access_group_initiator_add(
- access_group.id, init_id, init_type, flags)
- return SimPlugin._sim_data_2_lsm(sim_ag)
-
- def access_group_initiator_delete(self, access_group, init_id, init_type,
- flags=0):
- sim_ag = self.sim_array.access_group_initiator_delete(
- access_group.id, init_id, init_type, flags)
- return SimPlugin._sim_data_2_lsm(sim_ag)
-
- def volume_mask(self, access_group, volume, flags=0):
- return self.sim_array.volume_mask(
- access_group.id, volume.id, flags)
-
- def volume_unmask(self, access_group, volume, flags=0):
- return self.sim_array.volume_unmask(
- access_group.id, volume.id, flags)
-
- def volumes_accessible_by_access_group(self, access_group, flags=0):
- sim_vols = self.sim_array.volumes_accessible_by_access_group(
- access_group.id, flags)
- return [SimPlugin._sim_data_2_lsm(v) for v in sim_vols]
-
- def access_groups_granted_to_volume(self, volume, flags=0):
- sim_vols = self.sim_array.access_groups_granted_to_volume(
- volume.id, flags)
- return [SimPlugin._sim_data_2_lsm(v) for v in sim_vols]
-
- def iscsi_chap_auth(self, init_id, in_user, in_password,
- out_user, out_password, flags=0):
- return self.sim_array.iscsi_chap_auth(
- init_id, in_user, in_password, out_user, out_password, flags)
-
- def volume_child_dependency(self, volume, flags=0):
- return self.sim_array.volume_child_dependency(volume.id, flags)
-
- def volume_child_dependency_rm(self, volume, flags=0):
- return self.sim_array.volume_child_dependency_rm(volume.id, flags)
-
- def fs(self, search_key=None, search_value=None, flags=0):
- sim_fss = self.sim_array.fs()
- return search_property(
- [SimPlugin._sim_data_2_lsm(f) for f in sim_fss],
- search_key, search_value)
-
- def fs_create(self, pool, name, size_bytes, flags=0):
- sim_fs = self.sim_array.fs_create(pool.id, name, size_bytes)
- return SimPlugin._sim_data_2_lsm(sim_fs)
-
- def fs_delete(self, fs, flags=0):
- return self.sim_array.fs_delete(fs.id, flags)
-
- def fs_resize(self, fs, new_size_bytes, flags=0):
- sim_fs = self.sim_array.fs_resize(
- fs.id, new_size_bytes, flags)
- return SimPlugin._sim_data_2_lsm(sim_fs)
-
- def fs_clone(self, src_fs, dest_fs_name, snapshot=None, flags=0):
- if snapshot is None:
- return self.sim_array.fs_clone(
- src_fs.id, dest_fs_name, None, flags)
- return self.sim_array.fs_clone(
- src_fs.id, dest_fs_name, snapshot.id, flags)
-
- def fs_file_clone(self, fs, src_file_name, dest_file_name, snapshot=None,
- flags=0):
- if snapshot is None:
- return self.sim_array.fs_file_clone(
- fs.id, src_file_name, dest_file_name, None, flags)
-
- return self.sim_array.fs_file_clone(
- fs.id, src_file_name, dest_file_name, snapshot.id, flags)
-
- def fs_snapshots(self, fs, flags=0):
- sim_snaps = self.sim_array.fs_snapshots(fs.id, flags)
- return [SimPlugin._sim_data_2_lsm(s) for s in sim_snaps]
-
- def fs_snapshot_create(self, fs, snapshot_name, flags=0):
- return self.sim_array.fs_snapshot_create(
- fs.id, snapshot_name, flags)
-
- def fs_snapshot_delete(self, fs, snapshot, flags=0):
- return self.sim_array.fs_snapshot_delete(
- fs.id, snapshot.id, flags)
-
- def fs_snapshot_restore(self, fs, snapshot, files, restore_files,
- all_files=False, flags=0):
- return self.sim_array.fs_snapshot_restore(
- fs.id, snapshot.id, files, restore_files, all_files, flags)
-
- def fs_child_dependency(self, fs, files, flags=0):
- return self.sim_array.fs_child_dependency(fs.id, files, flags)
-
- def fs_child_dependency_rm(self, fs, files, flags=0):
- return self.sim_array.fs_child_dependency_rm(fs.id, files, flags)
-
- def export_auth(self, flags=0):
- # The API should change some day
- return ["simple"]
-
- def exports(self, search_key=None, search_value=None, flags=0):
- sim_exps = self.sim_array.exports(flags)
- return search_property(
- [SimPlugin._sim_data_2_lsm(e) for e in sim_exps],
- search_key, search_value)
-
- def export_fs(self, fs_id, export_path, root_list, rw_list, ro_list,
- anon_uid, anon_gid, auth_type, options, flags=0):
- sim_exp = self.sim_array.fs_export(
- fs_id, export_path, root_list, rw_list, ro_list,
- anon_uid, anon_gid, auth_type, options, flags=0)
- return SimPlugin._sim_data_2_lsm(sim_exp)
-
- def export_remove(self, export, flags=0):
- return self.sim_array.fs_unexport(export.id, flags)
-
- def target_ports(self, search_key=None, search_value=None, flags=0):
- sim_tgts = self.sim_array.target_ports()
- return search_property(
- [SimPlugin._sim_data_2_lsm(t) for t in sim_tgts],
- search_key, search_value)
-
- def volume_raid_info(self, volume, flags=0):
- return self.sim_array.volume_raid_info(volume)
diff --git a/plugin/simc/Makefile.am b/plugin/simc/Makefile.am
deleted file mode 100644
index 40658ff..0000000
--- a/plugin/simc/Makefile.am
+++ /dev/null
@@ -1,11 +0,0 @@
-AM_CPPFLAGS = \
- -I$(top_srcdir)/c_binding/include \
- -***@srcdir@/c_binding/include \
- $(DEFS) $(LIBGLIB_CFLAGS)
-
-bin_PROGRAMS = simc_lsmplugin
-
-simc_lsmplugin_LDADD = \
- ../../c_binding/libstoragemgmt.la \
- $(LIBGLIB_LIBS) $(SSL_LIBS)
-simc_lsmplugin_SOURCES = simc_lsmplugin.c
diff --git a/plugin/simc/simc_lsmplugin.c b/plugin/simc/simc_lsmplugin.c
deleted file mode 100644
index 422a064..0000000
--- a/plugin/simc/simc_lsmplugin.c
+++ /dev/null
@@ -1,2301 +0,0 @@
-/*
- * Copyright (C) 2011-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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- *
- */
-
-#include <libstoragemgmt/libstoragemgmt_plug_interface.h>
-#include <string.h>
-#define _XOPEN_SOURCE
-#include <unistd.h>
-#include <crypt.h>
-#include <glib.h>
-#include <assert.h>
-#include <time.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <openssl/md5.h>
-
-#include "libstoragemgmt/libstoragemgmt_targetport.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-static char name[] = "Compiled plug-in example";
-static char version [] = "0.2.0";
-static char sys_id[] = "sim-01";
-
-#define BS 512
-#define MAX_SYSTEMS 1
-#define MAX_FS 32
-#define MAX_EXPORT 32
-
-/**
- * Creates a md5 string (DO NOT FREE RETURN VALUE as the string is static)
- * @param data Data to generate md5
- * @return Pointer to string which contains the string digest
- */
-char* md5(const char *data)
-{
- int i = 0;
- MD5_CTX c;
- unsigned char digest[16];
- static char digest_str[33];
-
- MD5_Init(&c);
- MD5_Update(&c, data, strlen(data));
- MD5_Final(digest, &c);
-
- for( i = 0; i < sizeof(digest); ++i ) {
- sprintf(&digest_str[i*2], "%02x", (unsigned int)digest[i]);
- }
- return digest_str;
-}
-
-/**
- * Removes an item from an array, shifting the elements and clearing the space
- * that was occupied at the end, use with caution :-)
- * @param array Base address for the array
- * @param remove_index Element index to remove
- * @param num_elems Number of elements currently in the array
- * @param elem_size Size of each array element
- */
-void remove_item( void *array, int remove_index, int num_elems,
- size_t elem_size)
-{
- if( array && (num_elems > 0) && (remove_index < num_elems) && elem_size ) {
- /*Are we at the end?, clear that which is at the end */
- if( remove_index + 1 == num_elems ) {
- memset(array + (elem_size * (num_elems - 1)), 0, elem_size);
- return;
- }
-
- /* Calculate the position of the one after that we want to remove */
- void *src_addr = (void*)(array + ((remove_index + 1) * elem_size));
-
- /* Calculate the destination */
- void *dest_addr = (void*)(array + (remove_index * elem_size));
-
- /* Shift the memory */
- memmove(dest_addr, src_addr, ((num_elems - 1) - remove_index) *
- elem_size);
- /* Clear that which was at the end */
- memset(array + (elem_size * (num_elems - 1)), 0, elem_size);
- }
-}
-
-struct allocated_volume {
- lsm_volume *v;
- lsm_pool *p;
-};
-
-struct allocated_fs {
- lsm_fs *fs;
- lsm_pool *p;
- GHashTable *ss;
- GHashTable *exports;
-};
-
-struct allocated_ag {
- lsm_access_group *ag;
- lsm_access_group_init_type ag_type;
-};
-
-struct plugin_data {
- uint32_t tmo;
- uint32_t num_systems;
- lsm_system *system[MAX_SYSTEMS];
-
- GHashTable *access_groups;
- GHashTable *group_grant;
- GHashTable *fs;
- GHashTable *jobs;
- GHashTable *pools;
- GHashTable *volumes;
- GHashTable *disks;
-};
-
-struct allocated_job {
- int polls;
- lsm_data_type type;
- void *return_data;
-};
-
-struct allocated_job *alloc_allocated_job( lsm_data_type type, void *return_data )
-{
- struct allocated_job *rc = malloc( sizeof(struct allocated_job) );
- if( rc ) {
- rc->polls = 0;
- rc->type = type;
- rc->return_data = return_data;
- }
- return rc;
-}
-
-void free_allocated_job(void *j)
-{
- struct allocated_job *job = j;
-
- if( job && job->return_data ) {
- switch( job->type ) {
- case(LSM_DATA_TYPE_ACCESS_GROUP):
- lsm_access_group_record_free((lsm_access_group *)job->return_data);
- break;
- case(LSM_DATA_TYPE_BLOCK_RANGE):
- lsm_block_range_record_free((lsm_block_range *)job->return_data);
- break;
- case(LSM_DATA_TYPE_FS):
- lsm_fs_record_free((lsm_fs *)job->return_data);
- break;
- case(LSM_DATA_TYPE_NFS_EXPORT):
- lsm_nfs_export_record_free((lsm_nfs_export *)job->return_data);
- break;
- case(LSM_DATA_TYPE_POOL):
- lsm_pool_record_free((lsm_pool *)job->return_data);
- break;
- case(LSM_DATA_TYPE_SS):
- lsm_fs_ss_record_free((lsm_fs_ss *)job->return_data);
- break;
- case(LSM_DATA_TYPE_STRING_LIST):
- lsm_string_list_free((lsm_string_list *)job->return_data);
- break;
- case(LSM_DATA_TYPE_SYSTEM):
- lsm_system_record_free((lsm_system *)job->return_data);
- break;
- case(LSM_DATA_TYPE_VOLUME):
- lsm_volume_record_free((lsm_volume *)job->return_data);
- break;
- default:
- break;
- }
- job->return_data = NULL;
- }
- free(job);
-}
-
-struct allocated_ag *alloc_allocated_ag( lsm_access_group *ag,
- lsm_access_group_init_type i)
-{
- struct allocated_ag *aag =
- (struct allocated_ag *)malloc(sizeof(struct allocated_ag));
- if( aag ) {
- aag->ag = ag;
- aag->ag_type = i;
- }
- return aag;
-}
-
-void free_allocated_ag(void *v)
-{
- if( v ) {
- struct allocated_ag *aag = (struct allocated_ag *)v;
- lsm_access_group_record_free(aag->ag);
- free(aag);
- }
-}
-
-void free_pool_record(void *p)
-{
- if( p ) {
- lsm_pool_record_free((lsm_pool*)p);
- }
-}
-
-void free_fs_record(struct allocated_fs *fs)
-{
- if( fs ) {
- g_hash_table_destroy(fs->ss);
- g_hash_table_destroy(fs->exports);
- lsm_fs_record_free(fs->fs);
- fs->p = NULL;
- free(fs);
- }
-}
-
-static void free_ss(void *s)
-{
- lsm_fs_ss_record_free((lsm_fs_ss *)s);
-}
-
-static void free_export(void *exp)
-{
- lsm_nfs_export_record_free((lsm_nfs_export *)exp);
-}
-
-static struct allocated_fs *alloc_fs_record() {
- struct allocated_fs *rc = (struct allocated_fs *)
- malloc(sizeof(struct allocated_fs));
- if( rc ) {
- rc->fs = NULL;
- rc->p = NULL;
- rc->ss = g_hash_table_new_full(g_str_hash, g_str_equal, free, free_ss);
- rc->exports = g_hash_table_new_full(g_str_hash, g_str_equal, free,
- free_export);
-
- if( !rc->ss || !rc->exports ) {
- if( rc->ss ) {
- g_hash_table_destroy(rc->ss);
- }
-
- if( rc->exports ) {
- g_hash_table_destroy(rc->exports);
- }
-
- free(rc);
- rc = NULL;
- }
- }
- return rc;
-}
-
-static int create_job(struct plugin_data *pd, char **job, lsm_data_type t,
- void *new_value, void **returned_value)
-{
- static int job_num = 0;
- int rc = LSM_ERR_JOB_STARTED;
- char job_id[64];
- char *key = NULL;
-
- /* Make this random */
- if( 0 ) {
- if( returned_value ) {
- *returned_value = new_value;
- }
- *job = NULL;
- rc = LSM_ERR_OK;
- } else {
- snprintf(job_id, sizeof(job_id), "JOB_%d", job_num);
- job_num += 1;
-
- if( returned_value ) {
- *returned_value = NULL;
- }
-
- *job = strdup(job_id);
- key = strdup(job_id);
-
- struct allocated_job *value = alloc_allocated_job(t, new_value);
- if( *job && key && value ) {
- g_hash_table_insert(pd->jobs, key, value);
- } else {
- free(*job);
- *job = NULL;
- free(key);
- key = NULL;
- free_allocated_job(value);
- value = NULL;
- rc = LSM_ERR_NO_MEMORY;
- }
- }
- return rc;
-}
-
-static int tmo_set(lsm_plugin_ptr c, uint32_t timeout, lsm_flag flags )
-{
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
-
- if(pd) {
- pd->tmo = timeout;
- return LSM_ERR_OK;
- }
- return LSM_ERR_INVALID_ARGUMENT;
-}
-
-static int tmo_get(lsm_plugin_ptr c, uint32_t *timeout, lsm_flag flags)
-{
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
-
- if(pd) {
- *timeout = pd->tmo;
- return LSM_ERR_OK;
- }
- return LSM_ERR_INVALID_ARGUMENT;
-}
-
-static int vol_accessible_by_ag(lsm_plugin_ptr c,
- lsm_access_group *group,
- lsm_volume **volumes[],
- uint32_t *count, lsm_flag flags);
-
-static int ag_granted_to_volume( lsm_plugin_ptr c,
- lsm_volume *volume,
- lsm_access_group **groups[],
- uint32_t *count, lsm_flag flags);
-
-static int cap(lsm_plugin_ptr c, lsm_system *system,
- lsm_storage_capabilities **cap, lsm_flag flags)
-{
- int rc = LSM_ERR_NO_MEMORY;
- *cap = lsm_capability_record_alloc(NULL);
-
- if( *cap ) {
- rc = lsm_capability_set_n(*cap, LSM_CAP_SUPPORTED,
- LSM_CAP_VOLUMES,
- LSM_CAP_VOLUME_CREATE,
- LSM_CAP_VOLUME_RESIZE,
- LSM_CAP_VOLUME_REPLICATE,
- LSM_CAP_VOLUME_REPLICATE_CLONE,
- LSM_CAP_VOLUME_REPLICATE_COPY,
- LSM_CAP_VOLUME_REPLICATE_MIRROR_ASYNC,
- LSM_CAP_VOLUME_REPLICATE_MIRROR_SYNC,
- LSM_CAP_VOLUME_COPY_RANGE_BLOCK_SIZE,
- LSM_CAP_VOLUME_COPY_RANGE,
- LSM_CAP_VOLUME_COPY_RANGE_CLONE,
- LSM_CAP_VOLUME_COPY_RANGE_COPY,
- LSM_CAP_VOLUME_DELETE,
- LSM_CAP_VOLUME_ENABLE,
- LSM_CAP_VOLUME_DISABLE,
- LSM_CAP_VOLUME_MASK,
- LSM_CAP_VOLUME_UNMASK,
- LSM_CAP_ACCESS_GROUPS,
- LSM_CAP_ACCESS_GROUP_CREATE_ISCSI_IQN,
- LSM_CAP_VOLUME_ISCSI_CHAP_AUTHENTICATION,
- LSM_CAP_ACCESS_GROUP_CREATE_WWPN,
- LSM_CAP_ACCESS_GROUP_INITIATOR_ADD_WWPN,
- LSM_CAP_ACCESS_GROUP_INITIATOR_DELETE,
- LSM_CAP_ACCESS_GROUP_DELETE,
- LSM_CAP_VOLUMES_ACCESSIBLE_BY_ACCESS_GROUP,
- LSM_CAP_ACCESS_GROUPS_GRANTED_TO_VOLUME,
- LSM_CAP_VOLUME_CHILD_DEPENDENCY,
- LSM_CAP_VOLUME_CHILD_DEPENDENCY_RM,
- LSM_CAP_FS,
- LSM_CAP_FS_DELETE,
- LSM_CAP_FS_RESIZE,
- LSM_CAP_FS_CREATE,
- LSM_CAP_FS_CLONE,
- LSM_CAP_FILE_CLONE,
- LSM_CAP_FS_SNAPSHOTS,
- LSM_CAP_FS_SNAPSHOT_CREATE,
- LSM_CAP_FS_SNAPSHOT_DELETE,
- LSM_CAP_FS_SNAPSHOT_RESTORE,
- LSM_CAP_FS_SNAPSHOT_RESTORE_SPECIFIC_FILES,
- LSM_CAP_FS_CHILD_DEPENDENCY,
- LSM_CAP_FS_CHILD_DEPENDENCY_RM,
- LSM_CAP_FS_CHILD_DEPENDENCY_RM_SPECIFIC_FILES,
- LSM_CAP_EXPORT_AUTH,
- LSM_CAP_EXPORTS,
- LSM_CAP_EXPORT_FS,
- LSM_CAP_EXPORT_REMOVE,
- LSM_CAP_VOLUME_RAID_INFO,
- -1
- );
-
- if( LSM_ERR_OK != rc ) {
- lsm_capability_record_free(*cap);
- *cap = NULL;
- }
- }
- return rc;
-}
-
-static int job_status(lsm_plugin_ptr c, const char *job_id,
- lsm_job_status *status, uint8_t *percent_complete,
- lsm_data_type *t,
- void **value, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
-
- if(pd) {
- struct allocated_job *val = (struct allocated_job*)
- g_hash_table_lookup(pd->jobs,job_id);
- if( val ) {
- *status = LSM_JOB_INPROGRESS;
-
- val->polls += 34;
-
- if( (val->polls) >= 100 ) {
- *t = val->type;
- *value = lsm_data_type_copy(val->type, val->return_data);
- *status = LSM_JOB_COMPLETE;
- *percent_complete = 100;
- } else {
- *percent_complete = val->polls;
- }
-
- } else {
- rc = LSM_ERR_NOT_FOUND_JOB;
- }
- } else {
- rc = LSM_ERR_INVALID_ARGUMENT;
- }
-
- return rc;
-}
-
-static int list_pools(lsm_plugin_ptr c, const char *search_key,
- const char *search_value, lsm_pool **pool_array[],
- uint32_t *count, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
- *count = g_hash_table_size(pd->pools);
-
- if( *count ) {
- *pool_array = lsm_pool_record_array_alloc( *count );
- if( *pool_array ) {
- uint32_t i = 0;
- char *k = NULL;
- lsm_pool *p = NULL;
- GHashTableIter iter;
- g_hash_table_iter_init(&iter, pd->pools);
- while(g_hash_table_iter_next(&iter,(gpointer) &k,(gpointer)&p)) {
- (*pool_array)[i] = lsm_pool_record_copy(p);
- if( !(*pool_array)[i] ) {
- rc = LSM_ERR_NO_MEMORY;
- lsm_pool_record_array_free(*pool_array, i);
- *count = 0;
- *pool_array = NULL;
- break;
- }
- ++i;
- }
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NO_MEMORY, "ENOMEM");
- }
- }
-
- if( LSM_ERR_OK == rc ) {
- lsm_plug_pool_search_filter(search_key, search_value, *pool_array, count);
- }
-
- return rc;
-}
-
-static int list_systems(lsm_plugin_ptr c, lsm_system **systems[],
- uint32_t *system_count, lsm_flag flags)
-{
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
-
- if(pd) {
- *system_count = pd->num_systems;
- *systems = lsm_system_record_array_alloc(MAX_SYSTEMS);
-
- if( *systems ) {
- (*systems)[0] = lsm_system_record_copy(pd->system[0]);
-
- if( (*systems)[0] ) {
- return LSM_ERR_OK;
- } else {
- lsm_system_record_array_free(*systems, pd->num_systems);
- }
- }
- return LSM_ERR_NO_MEMORY;
- } else {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-}
-
-static int job_free(lsm_plugin_ptr c, char *job_id, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
-
- if(pd) {
- if( !g_hash_table_remove(pd->jobs, job_id) ) {
- rc = LSM_ERR_NOT_FOUND_JOB;
- }
- } else {
- rc = LSM_ERR_INVALID_ARGUMENT;
- }
-
- return rc;
-}
-
-static struct lsm_mgmt_ops_v1 mgm_ops = {
- tmo_set,
- tmo_get,
- cap,
- job_status,
- job_free,
- list_pools,
- list_systems,
-};
-
-static int list_volumes(lsm_plugin_ptr c, const char *search_key,
- const char *search_value,
- lsm_volume **vols[], uint32_t *count, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
- *count = g_hash_table_size(pd->volumes);
-
- if( *count ) {
- *vols = lsm_volume_record_array_alloc( *count );
- if( *vols ) {
- uint32_t i = 0;
- char *k = NULL;
- struct allocated_volume *vol;
- GHashTableIter iter;
- g_hash_table_iter_init(&iter, pd->volumes);
- while(g_hash_table_iter_next(&iter,(gpointer) &k,(gpointer)&vol)) {
- (*vols)[i] = lsm_volume_record_copy(vol->v);
- if( !(*vols)[i] ) {
- rc = LSM_ERR_NO_MEMORY;
- lsm_volume_record_array_free(*vols, i);
- *count = 0;
- *vols = NULL;
- break;
- }
- ++i;
- }
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NO_MEMORY, "ENOMEM");
- }
- }
-
- if( LSM_ERR_OK == rc ) {
- lsm_plug_volume_search_filter(search_key, search_value, *vols, count);
- }
-
- return rc;
-}
-
-static int list_disks(lsm_plugin_ptr c, const char *search_key,
- const char *search_value, lsm_disk **disks[],
- uint32_t *count, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
- *count = g_hash_table_size(pd->disks);
-
-
- if( *count ) {
- *disks = lsm_disk_record_array_alloc( *count );
- if( *disks ) {
- uint32_t i = 0;
- char *k = NULL;
- lsm_disk *disk;
- GHashTableIter iter;
- g_hash_table_iter_init(&iter, pd->disks);
- while(g_hash_table_iter_next(&iter,(gpointer) &k,(gpointer)&disk)) {
- (*disks)[i] = lsm_disk_record_copy(disk);
- if( !(*disks)[i] ) {
- rc = LSM_ERR_NO_MEMORY;
- lsm_disk_record_array_free(*disks, i);
- *count = 0;
- *disks = NULL;
- break;
- }
- ++i;
- }
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NO_MEMORY, "ENOMEM");
- }
- }
-
- if( LSM_ERR_OK == rc ) {
- lsm_plug_disk_search_filter(search_key, search_value, *disks, count);
- }
-
- return rc;
-}
-
-static int list_targets(lsm_plugin_ptr c, const char *search_key,
- const char *search_value, lsm_target_port **tp[],
- uint32_t *count, lsm_flag flags)
-{
- uint32_t i = 0;
- const char p0[] = "50:0a:09:86:99:4b:8d:c5";
- const char p1[] = "50:0a:09:86:99:4b:8d:c6";
- int rc = LSM_ERR_OK;
-
- *count = 5;
- *tp = lsm_target_port_record_array_alloc(*count);
-
- if( *tp ) {
- (*tp)[0] = lsm_target_port_record_alloc("TGT_PORT_ID_01",
- LSM_TARGET_PORT_TYPE_FC, p0, p0, p0,
- "FC_a_0b", sys_id, NULL);
-
- (*tp)[1] = lsm_target_port_record_alloc("TGT_PORT_ID_02",
- LSM_TARGET_PORT_TYPE_FCOE, p1, p1, p1,
- "FC_a_0c", sys_id, NULL);
-
- (*tp)[2] = lsm_target_port_record_alloc("TGT_PORT_ID_03",
- LSM_TARGET_PORT_TYPE_ISCSI,
- "iqn.1986-05.com.example:sim-tgt-03",
- "sim-iscsi-tgt-3.example.com:3260",
- "a4:4e:31:47:f4:e0",
- "iSCSI_c_0d", sys_id, NULL);
-
- (*tp)[3] = lsm_target_port_record_alloc("TGT_PORT_ID_04",
- LSM_TARGET_PORT_TYPE_ISCSI,
- "iqn.1986-05.com.example:sim-tgt-03",
- "10.0.0.1:3260",
- "a4:4e:31:47:f4:e1",
- "iSCSI_c_0e", sys_id, NULL);
-
- (*tp)[4] = lsm_target_port_record_alloc("TGT_PORT_ID_05",
- LSM_TARGET_PORT_TYPE_ISCSI,
- "iqn.1986-05.com.example:sim-tgt-03",
- "[2001:470:1f09:efe:a64e:31ff::1]:3260",
- "a4:4e:31:47:f4:e1",
- "iSCSI_c_0e", sys_id, NULL);
-
- for( i = 0; i < *count; ++i ) {
- if ( !(*tp)[i] ) {
- rc = lsm_log_error_basic(c, LSM_ERR_NO_MEMORY, "ENOMEM");
- lsm_target_port_record_array_free(*tp, *count);
- *count = 0;
- break;
- }
- }
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NO_MEMORY, "ENOMEM");
- *count = 0;
- }
-
- if( LSM_ERR_OK == rc ) {
- lsm_plug_target_port_search_filter(search_key, search_value, *tp, count);
- }
-
- return rc;
-}
-
-static uint64_t pool_allocate(lsm_pool *p, uint64_t size)
-{
- uint64_t rounded_size = 0;
- uint64_t free_space = lsm_pool_free_space_get(p);
-
- rounded_size = (size/BS) * BS;
-
- if( free_space >= rounded_size ) {
- free_space -= rounded_size;
- lsm_pool_free_space_set(p, free_space);
- } else {
- rounded_size = 0;
- }
- return rounded_size;
-}
-
-void pool_deallocate(lsm_pool *p, uint64_t size)
-{
- uint64_t free_space = lsm_pool_free_space_get(p);
-
- free_space += size;
- lsm_pool_free_space_set(p, free_space);
-}
-
-static lsm_pool *find_pool(struct plugin_data *pd, const char* pool_id)
-{
- return (lsm_pool*) g_hash_table_lookup(pd->pools, pool_id);
-}
-
-static struct allocated_volume *find_volume(struct plugin_data *pd,
- const char* vol_id)
-{
- struct allocated_volume *rc = g_hash_table_lookup(pd->volumes, vol_id);
- return rc;
-}
-
-static struct allocated_volume * find_volume_name(struct plugin_data *pd,
- const char *name)
-{
- struct allocated_volume *found = NULL;
- char *k = NULL;
- struct allocated_volume *vol;
- GHashTableIter iter;
- g_hash_table_iter_init(&iter, pd->volumes);
- while(g_hash_table_iter_next(&iter,(gpointer) &k,(gpointer)&vol)) {
- if( strcmp(lsm_volume_name_get(vol->v), name) == 0 ) {
- found = vol;
- break;
- }
- }
- return found;
-}
-
-static int volume_create(lsm_plugin_ptr c, lsm_pool *pool,
- const char *volume_name, uint64_t size,
- lsm_volume_provision_type provisioning, lsm_volume **new_volume,
- char **job, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
-
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
- lsm_pool *p = find_pool(pd, lsm_pool_id_get(pool));
-
- if( p ) {
- if( !find_volume_name(pd, volume_name) ) {
- uint64_t allocated_size = pool_allocate(p, size);
- if( allocated_size ) {
- char *id = md5(volume_name);
-
- /* We create one to return and a copy to store in memory */
-
- lsm_volume *v = lsm_volume_record_alloc(id, volume_name,
- "60a980003246694a412b45673342616e",
- BS, allocated_size/BS, 0, sys_id,
- lsm_pool_id_get(pool), NULL);
-
- lsm_volume *to_store = lsm_volume_record_copy(v);
- struct allocated_volume *av = malloc(sizeof(struct allocated_volume));
-
- if( v && av && to_store) {
- av->v = to_store;
- av->p = p;
-
- /*
- * Make a copy of the key, as we may replace the volume,
- * but leave the key.
- */
- g_hash_table_insert(pd->volumes,
- (gpointer)strdup(lsm_volume_id_get(to_store)),
- (gpointer)av);
-
- rc = create_job(pd, job, LSM_DATA_TYPE_VOLUME, v,
- (void**)new_volume);
-
- } else {
- free(av);
- lsm_volume_record_free(v);
- lsm_volume_record_free(to_store);
- rc = lsm_log_error_basic(c, LSM_ERR_NO_MEMORY,
- "Check for leaks");
- }
-
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_ENOUGH_SPACE,
- "Insufficient space in pool");
- }
-
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NAME_CONFLICT, "Existing volume "
- "with name");
- }
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_POOL, "Pool not found!");
- }
- return rc;
-}
-
-static int volume_replicate(lsm_plugin_ptr c, lsm_pool *pool,
- lsm_replication_type rep_type, lsm_volume *volume_src,
- const char *name, lsm_volume **new_replicant,
- char **job, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- lsm_pool *pool_to_use = NULL;
-
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
-
- if( pool ) {
- pool_to_use = find_pool(pd, lsm_pool_id_get(pool));
- } else {
- pool_to_use = find_pool(pd, lsm_volume_pool_id_get(volume_src));
- }
-
- if( !pool_to_use ) {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_POOL,
- "Pool not found!");
- } else {
- if( find_volume(pd, lsm_volume_id_get(volume_src) )) {
- rc = volume_create(c, pool_to_use, name,
- lsm_volume_number_of_blocks_get(volume_src)*BS,
- LSM_VOLUME_PROVISION_DEFAULT, new_replicant, job, flags);
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_VOLUME,
- "Volume not found!");
- }
- }
- return rc;
-}
-
-static int volume_replicate_range_bs(lsm_plugin_ptr c, lsm_system *system,
- uint32_t *bs,
- lsm_flag flags)
-{
- *bs = BS;
- return LSM_ERR_OK;
-}
-
-static int volume_replicate_range(lsm_plugin_ptr c,
- lsm_replication_type rep_type,
- lsm_volume *source,
- lsm_volume *dest,
- lsm_block_range **ranges,
- uint32_t num_ranges, char **job,
- lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
-
- struct allocated_volume *src_v = find_volume(pd, lsm_volume_id_get(source));
- struct allocated_volume *dest_v = find_volume(pd, lsm_volume_id_get(dest));
-
- if( !src_v || !dest_v ) {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_VOLUME,
- "Src or dest volumes not found!");
- } else {
- rc = create_job(pd, job, LSM_DATA_TYPE_NONE, NULL, NULL);
- }
-
- return rc;
-}
-
-static int volume_resize(lsm_plugin_ptr c, lsm_volume *volume,
- uint64_t new_size, lsm_volume **resized_volume,
- char **job, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
- struct allocated_volume *av = find_volume(pd, lsm_volume_id_get(volume));
-
- if( av ) {
- lsm_volume *v = av->v;
- lsm_pool *p = av->p;
- uint64_t curr_size = lsm_volume_number_of_blocks_get(v) * BS;
-
- pool_deallocate(p, curr_size);
- uint64_t resized_size = pool_allocate(p, new_size);
- if( resized_size ) {
- lsm_volume *vp = lsm_volume_record_alloc(lsm_volume_id_get(v),
- lsm_volume_name_get(v),
- lsm_volume_vpd83_get(v),
- lsm_volume_block_size_get(v),
- resized_size/BS, 0, sys_id,
- lsm_volume_pool_id_get(volume), NULL);
-
- if( vp ) {
- av->v = vp;
- lsm_volume_record_free(v);
- rc = create_job(pd, job, LSM_DATA_TYPE_VOLUME,
- lsm_volume_record_copy(vp),
- (void**)resized_volume);
- } else {
- pool_deallocate(p, resized_size);
- pool_allocate(p, curr_size);
- rc = lsm_log_error_basic(c, LSM_ERR_NO_MEMORY, "ENOMEM");
- }
-
- } else {
- /*Could not accommodate re-sized, go back */
- pool_allocate(p, curr_size);
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_ENOUGH_SPACE,
- "Insufficient space in pool");
- }
-
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_VOLUME,
- "volume not found!");
- }
- return rc;
-}
-
-static int _volume_delete(lsm_plugin_ptr c, const char *volume_id)
-{
- int rc = LSM_ERR_OK;
- GHashTableIter iter;
- char *k = NULL;
- GHashTable *v = NULL;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
- struct allocated_volume *av = find_volume(pd, volume_id);
-
- if( av ) {
- lsm_volume *vp = av->v;
- pool_deallocate(av->p, lsm_volume_number_of_blocks_get(vp)*BS);
-
- g_hash_table_remove(pd->volumes, volume_id);
-
- g_hash_table_iter_init (&iter, pd->group_grant);
- while( g_hash_table_iter_next( &iter, (gpointer)&k, (gpointer)&v) ) {
- if( g_hash_table_lookup(v, volume_id) ) {
- g_hash_table_remove(v, volume_id );
- }
- }
-
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_VOLUME,
- "volume not found!");
- }
- return rc;
-}
-
-static int volume_delete(lsm_plugin_ptr c, lsm_volume *volume,
- char **job, lsm_flag flags)
-{
- lsm_access_group **groups = NULL;
- uint32_t count = 0;
-
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
-
- // Check to see if this volume is masked to any access groups, if it is we
- // will return an IS_MASKED error code.
- int rc = ag_granted_to_volume(c, volume, &groups, &count, LSM_CLIENT_FLAG_RSVD);
-
- if( LSM_ERR_OK == rc ) {
- lsm_access_group_record_array_free(groups, count);
- groups = NULL;
-
- if( !count ) {
-
- rc = _volume_delete(c, lsm_volume_id_get(volume));
-
- if( LSM_ERR_OK == rc ) {
- rc = create_job(pd, job, LSM_DATA_TYPE_NONE, NULL, NULL);
- }
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_IS_MASKED, "Volume is masked!");
- }
- }
- return rc;
-}
-
-static int volume_raid_info(lsm_plugin_ptr c, lsm_volume *volume,
- lsm_volume_raid_type *raid_type,
- uint32_t *strip_size, uint32_t *disk_count,
- uint32_t *min_io_size, uint32_t *opt_io_size,
- lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
- struct allocated_volume *av = find_volume(pd, lsm_volume_id_get(volume));
-
- if( !av) {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_VOLUME,
- "volume not found!");
- }
-
- *raid_type = LSM_VOLUME_RAID_TYPE_UNKNOWN;
- *strip_size = LSM_VOLUME_STRIP_SIZE_UNKNOWN;
- *disk_count = LSM_VOLUME_DISK_COUNT_UNKNOWN;
- *min_io_size = LSM_VOLUME_MIN_IO_SIZE_UNKNOWN;
- *opt_io_size = LSM_VOLUME_OPT_IO_SIZE_UNKNOWN;
- return rc;
-}
-
-static struct lsm_ops_v1_2 ops_v1_2 = {
- volume_raid_info
-};
-
-static int volume_enable_disable(lsm_plugin_ptr c, lsm_volume *v,
- lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
- struct allocated_volume *av = find_volume(pd, lsm_volume_id_get(v));
-
- if( !av) {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_VOLUME,
- "volume not found!");
- }
- return rc;
-}
-
-static int access_group_list(lsm_plugin_ptr c,
- const char *search_key,
- const char *search_value,
- lsm_access_group **groups[],
- uint32_t *group_count, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
-
- *group_count = g_hash_table_size(pd->access_groups);
-
- if( *group_count ) {
- *groups = lsm_access_group_record_array_alloc(*group_count);
- if( *groups ) {
- int i = 0;
- char *key = NULL;
- struct allocated_ag *val = NULL;
- GHashTableIter iter;
-
- g_hash_table_iter_init (&iter, pd->access_groups);
-
- while (g_hash_table_iter_next (&iter, (gpointer) &key,
- (gpointer)&val) ) {
- (*groups)[i] = lsm_access_group_record_copy(val->ag);
- if( !(*groups)[i] ) {
- rc = LSM_ERR_NO_MEMORY;
- lsm_access_group_record_array_free(*groups, i);
- *group_count = 0;
- groups = NULL;
- break;
- }
- ++i;
- }
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
- }
-
- if( LSM_ERR_OK == rc ) {
- lsm_plug_access_group_search_filter(search_key, search_value, *groups,
- group_count);
- }
-
- return rc;
-}
-
-static int _find_dup_init(struct plugin_data *pd, const char *initiator_id)
-{
- GList *all_aags = g_hash_table_get_values(pd->access_groups);
- guint y;
- int rc = 1;
- for(y = 0; y < g_list_length(all_aags); ++y) {
- struct allocated_ag *cur_aag =
- (struct allocated_ag *) g_list_nth_data(all_aags, y);
- if (cur_aag){
- lsm_string_list *inits =
- lsm_access_group_initiator_id_get(cur_aag->ag);
- int i;
- for(i = 0; i < lsm_string_list_size(inits); ++i) {
- const char *cur_init_id = lsm_string_list_elem_get(
- inits, i);
- if(strcmp(initiator_id, cur_init_id) == 0 ) {
- rc = 0;
- break;
- }
- }
- if (rc == 0){
- break;
- }else{
- cur_aag = (struct allocated_ag *) g_list_next(all_aags);
- }
- }
- }
- g_list_free(all_aags);
- return rc;
-}
-
-static int access_group_create(lsm_plugin_ptr c,
- const char *name,
- const char *initiator_id,
- lsm_access_group_init_type id_type,
- lsm_system *system,
- lsm_access_group **access_group,
- lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- lsm_access_group *ag = NULL;
- struct allocated_ag *aag = NULL;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
- char *id = strdup(md5(name));
-
- struct allocated_ag *find = (struct allocated_ag *)
- g_hash_table_lookup(pd->access_groups, id);
-
- if( !find ) {
- // check initiator conflict
- if ( _find_dup_init(pd, initiator_id) == 0 ){
- rc = lsm_log_error_basic(
- c, LSM_ERR_EXISTS_INITIATOR,
- "Requested initiator is used by other access group");
- }else{
- lsm_string_list *initiators = lsm_string_list_alloc(1);
- if( initiators && id &&
- (LSM_ERR_OK ==
- lsm_string_list_elem_set(initiators, 0, initiator_id))) {
- ag = lsm_access_group_record_alloc(
- id, name, initiators, id_type, lsm_system_id_get(system),
- NULL);
- aag = alloc_allocated_ag(ag, id_type);
- if( ag && aag ) {
- g_hash_table_insert(pd->access_groups, (gpointer)id,
- (gpointer)aag);
- *access_group = lsm_access_group_record_copy(ag);
- } else {
- free_allocated_ag(aag);
- lsm_access_group_record_free(ag);
- rc = lsm_log_error_basic(c, LSM_ERR_NO_MEMORY, "ENOMEM");
- }
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NO_MEMORY, "ENOMEM");
- }
- /* Initiators is copied when allocating a group record */
- lsm_string_list_free(initiators);
- }
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NAME_CONFLICT,
- "access group with same id found");
- }
-
- /*
- * If we were not successful free memory for id string, id is on the heap
- * because it is passed to the hash table.
- */
- if( LSM_ERR_OK != rc ) {
- free(id);
- }
-
- return rc;
-}
-
-static int access_group_delete( lsm_plugin_ptr c,
- lsm_access_group *group,
- lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- lsm_volume **volumes = NULL;
- uint32_t count = 0;
-
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
- const char *id = lsm_access_group_id_get(group);
-
- rc = vol_accessible_by_ag(c, group, &volumes, &count, LSM_CLIENT_FLAG_RSVD);
- lsm_volume_record_array_free(volumes, count);
- volumes = NULL;
-
- if( rc == LSM_ERR_OK ) {
- if( count ) {
- rc = lsm_log_error_basic(c, LSM_ERR_IS_MASKED,
- "access group has masked volumes!");
- } else {
- gboolean r = g_hash_table_remove(pd->access_groups, (gpointer)id);
-
- if( !r ) {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_ACCESS_GROUP,
- "access group not found");
- } else {
- g_hash_table_remove(pd->group_grant, id);
- }
-
- if( !g_hash_table_size(pd->access_groups) ) {
- assert( g_hash_table_size(pd->group_grant ) == 0);
- }
- }
- }
-
- return rc;
-}
-
-static int access_group_initiator_add( lsm_plugin_ptr c,
- lsm_access_group *group,
- const char *initiator_id,
- lsm_access_group_init_type id_type,
- lsm_access_group **updated_access_group,
- lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
-
- struct allocated_ag *find = (struct allocated_ag *)
- g_hash_table_lookup(pd->access_groups,
- lsm_access_group_id_get(group));
-
- if( find ) {
- lsm_string_list *inits = lsm_access_group_initiator_id_get(find->ag);
- rc = lsm_string_list_append(inits, initiator_id);
-
- if( LSM_ERR_OK == rc ) {
- *updated_access_group = lsm_access_group_record_copy(find->ag);
- if( !*updated_access_group ) {
- rc = LSM_ERR_NO_MEMORY;
- }
- }
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_ACCESS_GROUP,
- "access group not found");
- }
- return rc;
-}
-
-static int access_group_initiator_delete( lsm_plugin_ptr c,
- lsm_access_group *group,
- const char *initiator_id,
- lsm_access_group_init_type id_type,
- lsm_access_group **updated_access_group,
- lsm_flag flags)
-{
- int rc = LSM_ERR_INVALID_ARGUMENT;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
-
- struct allocated_ag *find = (struct allocated_ag *)
- g_hash_table_lookup(pd->access_groups,
- lsm_access_group_id_get(group));
-
- if( find ) {
- uint32_t i;
- lsm_string_list *inits = lsm_access_group_initiator_id_get(find->ag);
-
- for(i = 0; i < lsm_string_list_size(inits); ++i) {
- if( strcmp(initiator_id, lsm_string_list_elem_get(inits, i)) == 0 ) {
- lsm_string_list_delete(inits, i);
- rc = LSM_ERR_OK;
- break;
- }
- }
-
- if( LSM_ERR_OK == rc ) {
- *updated_access_group = lsm_access_group_record_copy(find->ag);
- if( !*updated_access_group ) {
- rc = LSM_ERR_NO_MEMORY;
- }
- }
-
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_ACCESS_GROUP,
- "access group not found");
- }
- return rc;
-}
-
-static int volume_mask(lsm_plugin_ptr c,
- lsm_access_group *group,
- lsm_volume *volume,
- lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
-
- struct allocated_ag *find = (struct allocated_ag *)
- g_hash_table_lookup(pd->access_groups,
- lsm_access_group_id_get(group));
-
- struct allocated_volume *av = find_volume(pd, lsm_volume_id_get(volume));
-
- if( find && av ) {
- GHashTable *grants = g_hash_table_lookup(pd->group_grant,
- lsm_access_group_id_get(find->ag));
- if( !grants ) {
- /* We don't have any mappings for this access group*/
- GHashTable *grant = g_hash_table_new_full(g_str_hash, g_str_equal,
- free, free);
- char *key = strdup(lsm_access_group_id_get(find->ag));
- char *vol_id = strdup(lsm_volume_id_get(volume));
- int *val = (int*) malloc(sizeof(int));
-
- if( grant && key && val && vol_id ) {
- *val = 1;
-
- /* Create the association for volume id and access value */
- g_hash_table_insert(grant, vol_id, val);
-
- /* Create the association for access groups */
- g_hash_table_insert(pd->group_grant, key, grant);
-
- } else {
- rc = LSM_ERR_NO_MEMORY;
- free(key);
- free(val);
- free(vol_id);
- if( grant ) {
- g_hash_table_destroy(grant);
- grant = NULL;
- }
- }
-
- } else {
- /* See if we have this volume in the access grants */
- char *vol_id = g_hash_table_lookup(grants, lsm_volume_id_get(volume));
- if( !vol_id ) {
- vol_id = strdup(lsm_volume_id_get(volume));
- int *val = (int*) malloc(sizeof(int));
- if( vol_id && val ) {
- *val = 1;
- g_hash_table_insert(grants, vol_id, val);
- } else {
- rc = LSM_ERR_NO_MEMORY;
- free(vol_id);
- free(val);
- }
-
- } else {
- rc = LSM_ERR_NO_STATE_CHANGE;
- }
- }
- } else {
- if( !av ) {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_VOLUME,
- "volume not found");
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_ACCESS_GROUP,
- "access group not found");
- }
- }
- return rc;
-}
-
-static int volume_unmask(lsm_plugin_ptr c,
- lsm_access_group *group,
- lsm_volume *volume,
- lsm_flag flags)
-{
- int rc = LSM_ERR_NO_STATE_CHANGE;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
-
- struct allocated_ag *find = (struct allocated_ag *)
- g_hash_table_lookup(pd->access_groups,
- lsm_access_group_id_get(group));
-
- struct allocated_volume *av = find_volume(pd, lsm_volume_id_get(volume));
-
- if( find && av ) {
- GHashTable *grants = g_hash_table_lookup(pd->group_grant,
- lsm_access_group_id_get(find->ag));
-
- if( grants ) {
- char *vol_id = g_hash_table_lookup(
- grants, lsm_volume_id_get(volume));
- if( vol_id ) {
- g_hash_table_remove(grants, lsm_volume_id_get(volume));
- rc = LSM_ERR_OK;
- }else{
- rc = LSM_ERR_NO_STATE_CHANGE;
- }
- }
-
- } else {
- if( !av ) {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_VOLUME,
- "volume not found");
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_ACCESS_GROUP,
- "access group not found");
- }
- }
- return rc;
-}
-
-static lsm_volume *get_volume_by_id(struct plugin_data *pd, const char *id)
-{
- struct allocated_volume *av = find_volume(pd, id);
- if( av ) {
- return av->v;
- }
- return NULL;
-}
-
-static int vol_accessible_by_ag(lsm_plugin_ptr c,
- lsm_access_group *group,
- lsm_volume **volumes[],
- uint32_t *count, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
-
- struct allocated_ag *find = (struct allocated_ag *)
- g_hash_table_lookup(pd->access_groups,
- lsm_access_group_id_get(group));
- if( find ) {
- GHashTable *grants = g_hash_table_lookup(pd->group_grant,
- lsm_access_group_id_get(find->ag));
- *count = 0;
-
- if( grants && g_hash_table_size(grants) ) {
- *count = g_hash_table_size(grants);
- GList *keys = g_hash_table_get_keys(grants);
- *volumes = lsm_volume_record_array_alloc(*count);
-
- if( keys && *volumes ) {
- GList *curr = NULL;
- int i = 0;
-
- for( curr = g_list_first(keys);
- curr != NULL;
- curr = g_list_next(curr), ++i ) {
-
- (*volumes)[i] = lsm_volume_record_copy(get_volume_by_id(pd,
- (char *)curr->data));
- if( !(*volumes)[i] ) {
- rc = LSM_ERR_NO_MEMORY;
- lsm_volume_record_array_free(*volumes, i);
- *volumes = NULL;
- *count = 0;
- break;
- }
- }
-
- /* Free the keys */
- g_list_free(keys);
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
- }
-
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_ACCESS_GROUP,
- "access group not found");
- }
- return rc;
-}
-
-static lsm_access_group *access_group_by_id(struct plugin_data *pd,
- const char *key)
-{
- struct allocated_ag *find = g_hash_table_lookup(pd->access_groups, key);
- if(find) {
- return find->ag;
- }
- return NULL;
-}
-
-static int ag_granted_to_volume( lsm_plugin_ptr c,
- lsm_volume *volume,
- lsm_access_group **groups[],
- uint32_t *count, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- GHashTableIter iter;
- char *k = NULL;
- GHashTable *v = NULL;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
- const char* volume_id = lsm_volume_id_get(volume);
- g_hash_table_iter_init (&iter, pd->group_grant);
- GSList *result = NULL;
-
- *count = 0;
-
- while( g_hash_table_iter_next( &iter, (gpointer)&k, (gpointer)&v) ) {
- if( g_hash_table_lookup(v, volume_id) ) {
- *count += 1;
- result = g_slist_prepend(result, access_group_by_id(pd, k));
- }
- }
-
- if( *count ) {
- int i = 0;
- *groups = lsm_access_group_record_array_alloc(*count);
- GSList *siter = NULL;
-
- if( *groups ) {
- for( siter = result; siter ; siter = g_slist_next(siter), i++) {
- (*groups)[i] = lsm_access_group_record_copy(
- (lsm_access_group *)siter->data);
-
- if( !(*groups)[i] ) {
- rc = LSM_ERR_NO_MEMORY;
- lsm_access_group_record_array_free(*groups, i);
- *groups = NULL;
- *count = 0;
- break;
- }
- }
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
- }
-
- if(result) {
- g_slist_free(result);
- }
- return rc;
-}
-
-int static volume_dependency(lsm_plugin_ptr c,
- lsm_volume *volume,
- uint8_t *yes, lsm_flag flags)
-{
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
- struct allocated_volume *av = find_volume(pd, lsm_volume_id_get(volume));
-
- if( av ) {
- *yes = 0;
- return LSM_ERR_OK;
- } else {
- return LSM_ERR_NOT_FOUND_VOLUME;
- }
-}
-
-int static volume_dependency_rm(lsm_plugin_ptr c,
- lsm_volume *volume,
- char **job, lsm_flag flags)
-{
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
- struct allocated_volume *av = find_volume(pd, lsm_volume_id_get(volume));
-
- if( av ) {
- return create_job(pd, job, LSM_DATA_TYPE_NONE, NULL, NULL);
- } else {
- return LSM_ERR_NOT_FOUND_VOLUME;
- }
-}
-
-static int iscsi_chap_auth(lsm_plugin_ptr c, const char *init_id,
- const char *in_user, const char *in_password,
- const char *out_user, const char *out_password,
- lsm_flag flags)
-{
- if (init_id) {
- return 0;
- }
- return LSM_ERR_INVALID_ARGUMENT;
-}
-
-static struct lsm_san_ops_v1 san_ops = {
- list_volumes,
- list_disks,
- volume_create,
- volume_replicate,
- volume_replicate_range_bs,
- volume_replicate_range,
- volume_resize,
- volume_delete,
- volume_enable_disable,
- volume_enable_disable,
- iscsi_chap_auth,
- access_group_list,
- access_group_create,
- access_group_delete,
- access_group_initiator_add,
- access_group_initiator_delete,
- volume_mask,
- volume_unmask,
- vol_accessible_by_ag,
- ag_granted_to_volume,
- volume_dependency,
- volume_dependency_rm,
- list_targets
-};
-
-static int fs_list(lsm_plugin_ptr c, const char *search_key,
- const char *search_value, lsm_fs **fs[], uint32_t *count,
- lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
- *count = g_hash_table_size(pd->fs);
-
- if( *count ) {
- *fs = lsm_fs_record_array_alloc( *count );
- if( *fs ) {
- uint32_t i = 0;
- char *k = NULL;
- struct allocated_fs *afs = NULL;
- GHashTableIter iter;
- g_hash_table_iter_init(&iter, pd->fs);
- while(g_hash_table_iter_next(&iter,(gpointer) &k,(gpointer)&afs)) {
- (*fs)[i] = lsm_fs_record_copy(afs->fs);
- if( !(*fs)[i] ) {
- rc = LSM_ERR_NO_MEMORY;
- lsm_fs_record_array_free(*fs, i);
- *count = 0;
- *fs = NULL;
- break;
- }
- ++i;
- }
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NO_MEMORY, "ENOMEM");
- }
- }
-
- if( LSM_ERR_OK == rc ) {
- lsm_plug_fs_search_filter(search_key, search_value, *fs, count);
- }
-
- return rc;
-}
-
-static int fs_create(lsm_plugin_ptr c, lsm_pool *pool, const char *name,
- uint64_t size_bytes, lsm_fs **fs, char **job, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
-
- lsm_pool *p = find_pool(pd, lsm_pool_id_get(pool));
-
-
- if( p && !g_hash_table_lookup(pd->fs, md5(name)) ) {
- uint64_t allocated_size = pool_allocate(p, size_bytes);
- if( allocated_size ) {
- char *id = md5(name);
- char *key = strdup(id);
- lsm_fs *new_fs = NULL;
-
- /* Make a copy to store and a copy to hand back to caller */
- lsm_fs *tfs = lsm_fs_record_alloc(id, name, allocated_size,
- allocated_size, lsm_pool_id_get(pool), sys_id, NULL);
- new_fs = lsm_fs_record_copy(tfs);
-
- /* Allocate the memory to keep the associations */
- struct allocated_fs *afs = alloc_fs_record();
-
- if( key && tfs && afs ) {
- afs->fs = tfs;
- afs->p = p;
- g_hash_table_insert(pd->fs, key, afs);
-
- rc = create_job(pd, job, LSM_DATA_TYPE_FS, new_fs, (void**)fs);
- } else {
- free(key);
- lsm_fs_record_free(new_fs);
- lsm_fs_record_free(tfs);
- free_fs_record(afs);
-
- *fs = NULL;
- rc = lsm_log_error_basic(c, LSM_ERR_NO_MEMORY, "ENOMEM");
- }
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_ENOUGH_SPACE,
- "Insufficient space in pool");
- }
- } else {
- if( p == NULL ) {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_POOL, "Pool not found!");
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NAME_CONFLICT,
- "File system with name exists");
- }
- }
- return rc;
-}
-
-static int fs_delete(lsm_plugin_ptr c, lsm_fs *fs, char **job, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
-
- if( !g_hash_table_remove(pd->fs, lsm_fs_id_get(fs)) ) {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_FS, "FS not found!");
- } else {
- rc = create_job(pd, job, LSM_DATA_TYPE_NONE, NULL, NULL);
- }
- return rc;
-}
-
-static int fs_resize(lsm_plugin_ptr c, lsm_fs *fs,
- uint64_t new_size_bytes, lsm_fs * *rfs,
- char **job, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
- struct allocated_fs *afs = g_hash_table_lookup(pd->fs, lsm_fs_id_get(fs));
-
- *rfs = NULL;
- *job = NULL;
-
- if( afs ) {
- lsm_pool *p = afs->p;
- lsm_fs *tfs = afs->fs;
-
- pool_deallocate(p, lsm_fs_total_space_get(tfs));
- uint64_t resized_size = pool_allocate(p, new_size_bytes);
-
- if( resized_size ) {
-
- lsm_fs *resized = lsm_fs_record_alloc(lsm_fs_id_get(tfs),
- lsm_fs_name_get(tfs),
- new_size_bytes,
- new_size_bytes,
- lsm_fs_pool_id_get(tfs),
- lsm_fs_system_id_get(tfs), NULL);
- lsm_fs *returned_copy = lsm_fs_record_copy(resized);
-
- if( resized && returned_copy ) {
- lsm_fs_record_free(tfs);
- afs->fs = resized;
-
- rc = create_job(pd, job, LSM_DATA_TYPE_FS, returned_copy,
- (void**)rfs);
-
- } else {
- lsm_fs_record_free(resized);
- lsm_fs_record_free(returned_copy);
- *rfs = NULL;
-
- pool_deallocate(p, new_size_bytes);
- pool_allocate(p, lsm_fs_total_space_get(tfs));
- rc = lsm_log_error_basic(c, LSM_ERR_NO_MEMORY,
- "ENOMEM");
- }
- } else {
- /*Could not accommodate re-sized, go back */
- pool_allocate(p, lsm_fs_total_space_get(tfs));
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_ENOUGH_SPACE,
- "Insufficient space in pool");
- }
-
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_FS,
- "file system not found!");
- }
- return rc;
-}
-
-static int fs_clone(lsm_plugin_ptr c, lsm_fs *src_fs, const char *dest_fs_name,
- lsm_fs **cloned_fs, lsm_fs_ss *optional_snapshot,
- char **job, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
-
- struct allocated_fs *find = g_hash_table_lookup(pd->fs, lsm_fs_id_get(src_fs));
-
- if( find ) {
- rc = fs_create(c, find->p, dest_fs_name, lsm_fs_total_space_get(find->fs),
- cloned_fs, job, flags);
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_FS, "Source fs not found");
- }
-
- return rc;
-}
-
-static int fs_file_clone(lsm_plugin_ptr c, lsm_fs *fs,
- const char *src_file_name,
- const char *dest_file_name,
- lsm_fs_ss *snapshot, char **job,
- lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
-
- struct allocated_fs *find = (struct allocated_fs *)g_hash_table_lookup(
- pd->fs, lsm_fs_id_get(fs));
- if( !find ) {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_FS, "fs not found");
- } else {
- rc = create_job(pd, job, LSM_DATA_TYPE_NONE, NULL, NULL);
- }
- return rc;
-}
-
-static int fs_child_dependency(lsm_plugin_ptr c, lsm_fs *fs,
- lsm_string_list *files,
- uint8_t *yes)
-{
- int rc = LSM_ERR_OK;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
- if( g_hash_table_lookup(pd->fs, lsm_fs_id_get(fs))) {
- *yes = 0;
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_FS, "fs not found");
- }
- return rc;
-}
-
-static int fs_child_dependency_rm( lsm_plugin_ptr c, lsm_fs *fs,
- lsm_string_list *files,
- char **job, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
- if( !g_hash_table_lookup(pd->fs, lsm_fs_id_get(fs))) {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_FS, "fs not found");
- } else {
- rc = create_job(pd, job, LSM_DATA_TYPE_NONE, NULL, NULL);
- }
- return rc;
-}
-
-static int ss_list(lsm_plugin_ptr c, lsm_fs * fs, lsm_fs_ss **ss[],
- uint32_t *count, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
-
- struct allocated_fs *find = (struct allocated_fs *)g_hash_table_lookup(
- pd->fs, lsm_fs_id_get(fs));
-
- if( find ) {
- char *k = NULL;
- lsm_fs_ss *v = NULL;
- GHashTableIter iter;
-
- *ss = NULL;
- *count = g_hash_table_size(find->ss);
-
- if( *count ) {
- *ss = lsm_fs_ss_record_array_alloc(*count);
- if( *ss ) {
- int i = 0;
- g_hash_table_iter_init(&iter, find->ss);
-
- while(g_hash_table_iter_next(&iter,
- (gpointer) &k,(gpointer)&v)) {
- (*ss)[i] = lsm_fs_ss_record_copy(v);
- if( !(*ss)[i] ) {
- rc = lsm_log_error_basic(c, LSM_ERR_NO_MEMORY, "ENOMEM");
- lsm_fs_ss_record_array_free(*ss, i);
- *ss = NULL;
- *count = 0;
- break;
- }
- ++i;
- }
-
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NO_MEMORY, "ENOMEM");
- *count = 0;
- }
- }
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_FS, "fs not found");
- }
- return rc;
-}
-
-static int ss_create(lsm_plugin_ptr c, lsm_fs *fs,
- const char *name,
- lsm_fs_ss **snapshot, char **job,
- lsm_flag flags)
-{
- int rc = LSM_ERR_NO_MEMORY;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
-
- struct allocated_fs *find = (struct allocated_fs *)g_hash_table_lookup(
- pd->fs, lsm_fs_id_get(fs));
-
- if( find ) {
- if( !g_hash_table_lookup(find->ss, md5(name)) ) {
- char *id = strdup(md5(name));
- if( id ) {
- lsm_fs_ss *ss = lsm_fs_ss_record_alloc(id, name, time(NULL), NULL);
- lsm_fs_ss *new_shot = lsm_fs_ss_record_copy(ss);
- if( ss && new_shot ) {
- g_hash_table_insert(find->ss, (gpointer)id, (gpointer)ss);
- rc = create_job(pd, job, LSM_DATA_TYPE_SS, new_shot,
- (void**)snapshot);
- } else {
- lsm_fs_ss_record_free(ss);
- ss = NULL;
- lsm_fs_ss_record_free(new_shot);
- *snapshot = NULL;
- free(id);
- id = NULL;
- }
- }
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NAME_CONFLICT,
- "snapshot name exists");
- }
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_FS, "fs not found");
- }
- return rc;
-}
-
-static int ss_delete(lsm_plugin_ptr c, lsm_fs *fs, lsm_fs_ss *ss,
- char **job, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
-
- struct allocated_fs *find = (struct allocated_fs *)g_hash_table_lookup(
- pd->fs, lsm_fs_id_get(fs));
-
- if( find ) {
- if( !g_hash_table_remove(find->ss, lsm_fs_ss_id_get(ss)) ) {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_FS_SS,
- "snapshot not found");
- } else {
- rc = create_job(pd, job, LSM_DATA_TYPE_NONE, NULL, NULL);
- }
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_FS, "fs not found");
- }
- return rc;
-}
-
-static int ss_restore(lsm_plugin_ptr c, lsm_fs *fs, lsm_fs_ss *ss,
- lsm_string_list *files,
- lsm_string_list *restore_files,
- int all_files, char **job, lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
-
- struct allocated_fs *find = (struct allocated_fs *)g_hash_table_lookup(
- pd->fs, lsm_fs_id_get(fs));
-
- if( find ) {
- if(!g_hash_table_lookup(find->ss, lsm_fs_ss_id_get(ss))) {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_FS_SS,
- "snapshot not found");
- } else {
- rc = create_job(pd, job, LSM_DATA_TYPE_NONE, NULL, NULL);
- }
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_FS, "fs not found");
- }
- return rc;
-}
-
-static struct lsm_fs_ops_v1 fs_ops = {
- fs_list,
- fs_create,
- fs_delete,
- fs_resize,
- fs_clone,
- fs_file_clone,
- fs_child_dependency,
- fs_child_dependency_rm,
- ss_list,
- ss_create,
- ss_delete,
- ss_restore
-};
-
-static int nfs_auth_types(lsm_plugin_ptr c, lsm_string_list **types,
- lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- *types = lsm_string_list_alloc(1);
- if( *types ) {
- rc = lsm_string_list_elem_set(*types, 0, "standard");
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
- return rc;
-}
-
-static int nfs_export_list( lsm_plugin_ptr c, const char *search_key,
- const char *search_value,
- lsm_nfs_export **exports[], uint32_t *count,
- lsm_flag flags)
-{
- int rc = LSM_ERR_OK;
- GHashTableIter fs_iter;
- GHashTableIter exports_iter;
- char *k = NULL;
- struct allocated_fs *v = NULL;
- GSList *result = NULL;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
-
- g_hash_table_iter_init (&fs_iter, pd->fs);
-
- *count = 0;
-
- /* Walk through each of the file systems and their associated exports */
- while( g_hash_table_iter_next( &fs_iter, (gpointer)&k, (gpointer)&v) ) {
- char *exp_key = NULL;
- lsm_nfs_export **exp_val = NULL;
-
- g_hash_table_iter_init (&exports_iter, v->exports );
- while( g_hash_table_iter_next( &exports_iter, (gpointer)&exp_key,
- (gpointer)&exp_val) ) {
- result = g_slist_prepend(result, exp_val);
- *count += 1;
- }
- }
-
- if( *count ) {
- int i = 0;
- GSList *s_iter = NULL;
- *exports = lsm_nfs_export_record_array_alloc(*count);
- if( *exports ) {
- for( s_iter = result; s_iter ; s_iter = g_slist_next(s_iter), i++) {
- (*exports)[i] = lsm_nfs_export_record_copy(
- (lsm_nfs_export *)s_iter->data);
-
- if( !(*exports)[i] ) {
- rc = LSM_ERR_NO_MEMORY;
- lsm_nfs_export_record_array_free(*exports, i);
- *exports = NULL;
- *count = 0;
- break;
- }
- }
- } else {
- rc = LSM_ERR_NO_MEMORY;
- }
- }
-
- if( result ) {
- g_slist_free(result);
- result = NULL;
- }
-
- if( LSM_ERR_OK == rc ) {
- lsm_plug_nfs_export_search_filter(search_key, search_value, *exports, count);
- }
-
- return rc;
-}
-
-static int nfs_export_create( lsm_plugin_ptr c,
- const char *fs_id,
- const char *export_path,
- lsm_string_list *root_list,
- lsm_string_list *rw_list,
- lsm_string_list *ro_list,
- uint64_t anon_uid,
- uint64_t anon_gid,
- const char *auth_type,
- const char *options,
- lsm_nfs_export **exported,
- lsm_flag flags
- )
-{
- int rc = LSM_ERR_OK;
- char auto_export[2048];
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
-
- struct allocated_fs *fs = g_hash_table_lookup(pd->fs, fs_id);
- if( fs ) {
- if (!export_path) {
- snprintf(auto_export, sizeof(auto_export), "/mnt/lsm/nfs/%s",
- lsm_fs_name_get(fs->fs));
- export_path = auto_export;
- }
-
- char *key = strdup(md5(export_path));
- *exported = lsm_nfs_export_record_alloc(md5(export_path),
- fs_id,
- export_path,
- auth_type,
- root_list,
- rw_list,
- ro_list,
- anon_uid,
- anon_gid,
- options, NULL);
-
- lsm_nfs_export *value = lsm_nfs_export_record_copy(*exported);
-
- if( key && *exported && value ) {
- g_hash_table_insert(fs->exports, key, value);
- } else {
- rc = LSM_ERR_NO_MEMORY;
- free(key);
- lsm_nfs_export_record_free(*exported);
- lsm_nfs_export_record_free(value);
- }
-
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_FS, "fs not found");
- }
- return rc;
-}
-
-static int nfs_export_remove( lsm_plugin_ptr c, lsm_nfs_export *e,
- lsm_flag flags )
-{
- int rc = LSM_ERR_OK;
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
-
- struct allocated_fs *fs = g_hash_table_lookup(pd->fs,
- lsm_nfs_export_fs_id_get(e));
- if( fs ) {
- if( !g_hash_table_remove(fs->exports, lsm_nfs_export_id_get(e))) {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_NFS_EXPORT,
- "export not found");
- }
- } else {
- rc = lsm_log_error_basic(c, LSM_ERR_NOT_FOUND_FS, "fs not found");
- }
- return rc;
-}
-
-static struct lsm_nas_ops_v1 nfs_ops = {
- nfs_auth_types,
- nfs_export_list,
- nfs_export_create,
- nfs_export_remove
-};
-
-
-void free_group_grant_hash(void *v)
-{
- g_hash_table_destroy((GHashTable *)v);
-}
-
-void free_allocated_fs(void *v)
-{
- free_fs_record((struct allocated_fs*)v);
-}
-
-void free_disk(void *d)
-{
- lsm_disk_record_free((lsm_disk *)d);
-}
-
-void free_allocated_volume(void *v)
-{
- if( v ) {
- struct allocated_volume *av = (struct allocated_volume *)v;
- lsm_volume_record_free(av->v);
- av->v = NULL;
- av->p = NULL; /* Pool takes care of itself */
- free(av);
- }
-}
-
-static void _unload(struct plugin_data *pd) {
- int i;
-
- if( pd ) {
-
- if( pd->disks ) {
- g_hash_table_destroy(pd->disks);
- pd->disks = NULL;
- }
-
- if( pd->jobs ) {
- g_hash_table_destroy(pd->jobs);
- pd->jobs = NULL;
- }
-
- if(pd->fs) {
- g_hash_table_destroy(pd->fs);
- pd->fs = NULL;
- }
-
- if(pd->group_grant) {
- g_hash_table_destroy(pd->group_grant);
- pd->group_grant = NULL;
- }
-
- if( pd->access_groups ) {
- g_hash_table_destroy(pd->access_groups);
- pd->access_groups = NULL;
- }
-
- if( pd->volumes ) {
- g_hash_table_destroy(pd->volumes);
- pd->volumes = NULL;
- }
-
- if( pd->pools ) {
- g_hash_table_destroy(pd->pools);
- pd->pools = NULL;
- }
-
- for( i = 0; i < pd->num_systems; ++i ) {
- lsm_system_record_free(pd->system[i]);
- pd->system[i]= NULL;
- }
- pd->num_systems = 0;
-
- free(pd);
- pd = NULL;
- }
-}
-
-int load( lsm_plugin_ptr c, const char *uri, const char *password,
- uint32_t timeout, lsm_flag flags)
-{
- struct plugin_data *pd = (struct plugin_data *)
- calloc(1, sizeof(struct plugin_data));
- int rc = LSM_ERR_NO_MEMORY;
- int i;
- lsm_pool *p = NULL;
- if( pd ) {
- pd->num_systems = 1;
- pd->system[0] = lsm_system_record_alloc(sys_id,
- "LSM simulated storage plug-in",
- LSM_SYSTEM_STATUS_OK, "", NULL);
-
- p = lsm_pool_record_alloc("POOL_3", "lsm_test_aggr",
- LSM_POOL_ELEMENT_TYPE_FS|
- LSM_POOL_ELEMENT_TYPE_VOLUME, 0,
- UINT64_MAX, UINT64_MAX,
- LSM_POOL_STATUS_OK, "",
- sys_id, 0);
- if( p ) {
- pd->pools = g_hash_table_new_full(g_str_hash, g_str_equal, free,
- free_pool_record);
-
- g_hash_table_insert(pd->pools, strdup(lsm_pool_id_get(p)), p);
-
- for( i = 0; i < 3; ++i ) {
- char name[32];
- snprintf(name, sizeof(name), "POOL_%d", i);
-
- p = lsm_pool_record_alloc(name, name, LSM_POOL_ELEMENT_TYPE_FS|
- LSM_POOL_ELEMENT_TYPE_VOLUME, 0, UINT64_MAX,
- UINT64_MAX, LSM_POOL_STATUS_OK, "",
- sys_id, NULL);
-
- if( p ) {
- g_hash_table_insert(pd->pools, strdup(lsm_pool_id_get(p)), p);
- } else {
- g_hash_table_destroy(pd->pools);
- pd->pools = NULL;
- break;
- }
- }
- }
-
- pd->volumes = g_hash_table_new_full(g_str_hash, g_str_equal, free,
- free_allocated_volume);
-
- pd->access_groups = g_hash_table_new_full(g_str_hash, g_str_equal,
- free, free_allocated_ag);
-
- /* We will delete the key, but the value will get cleaned up in its
- own container */
- pd->group_grant = g_hash_table_new_full(g_str_hash, g_str_equal,
- free, free_group_grant_hash);
-
- pd->fs = g_hash_table_new_full(g_str_hash, g_str_equal, free,
- free_allocated_fs);
-
- pd->jobs = g_hash_table_new_full(g_str_hash, g_str_equal, free,
- free_allocated_job);
-
- pd->disks = g_hash_table_new_full(g_str_hash, g_str_equal, free,
- free_disk);
-
-
- for( i = 0; i < 10; ++i ) {
- lsm_disk *d = NULL;
- char name[17];
- char *key = NULL;
- snprintf(name, sizeof(name), "Sim C disk %d", i);
-
- d = lsm_disk_record_alloc(md5(name), name, LSM_DISK_TYPE_SOP, 512,
- 0x8000000000000, LSM_DISK_STATUS_OK, sys_id);
-
- key = strdup(lsm_disk_id_get(d));
-
- if( !key || !d ) {
- g_hash_table_destroy(pd->disks);
- pd->disks = NULL;
-
- lsm_disk_record_free(d);
- d = NULL;
-
- free(key);
- key = NULL;
-
- break;
- }
-
- g_hash_table_insert(pd->disks, key, d);
- d = NULL;
- }
-
- if( !pd->system[0] || !pd->volumes || !pd->pools || !pd->access_groups
- || !pd->group_grant || !pd->fs || !pd->jobs || !pd->disks ) {
- rc = LSM_ERR_NO_MEMORY; /* We need to free everything */
- _unload(pd);
- pd = NULL;
- } else {
- rc = lsm_register_plugin_v1_2(
- c, pd, &mgm_ops, &san_ops, &fs_ops, &nfs_ops, &ops_v1_2);
- }
- }
- return rc;
-}
-
-
-
-int unload( lsm_plugin_ptr c, lsm_flag flags)
-{
- struct plugin_data *pd = (struct plugin_data*)lsm_private_data_get(c);
- if( pd ) {
- _unload(pd);
- return LSM_ERR_OK;
- } else {
- return LSM_ERR_INVALID_ARGUMENT;
- }
-}
-
-int main(int argc, char *argv[] )
-{
- return lsm_plugin_init_v1(argc, argv, load, unload, name, version);
-}
-
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/plugin/smispy/__init__.py b/plugin/smispy/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/plugin/smispy/dmtf.py b/plugin/smispy/dmtf.py
deleted file mode 100644
index c44db2f..0000000
--- a/plugin/smispy/dmtf.py
+++ /dev/null
@@ -1,246 +0,0 @@
-# Copyright (C) 2011-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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
-# USA
-#
-# Author: Gris Ge <***@redhat.com>
-
-# This class handle DMTF CIM constants and convert to LSM type.
-
-from pywbem import Uint16
-
-
-# CIM_StorageHardwareID['IDType']
-ID_TYPE_OTHER = Uint16(1)
-ID_TYPE_WWPN = Uint16(2)
-ID_TYPE_ISCSI = Uint16(5)
-
-TGT_PORT_USAGE_FRONTEND_ONLY = Uint16(2)
-TGT_PORT_USAGE_UNRESTRICTED = Uint16(4)
-# CIM_FCPort['PortDiscriminator']
-FC_PORT_PORT_DISCRIMINATOR_FCOE = Uint16(10)
-# CIM_NetworkPort['LinkTechnology']
-NET_PORT_LINK_TECH_ETHERNET = Uint16(2)
-# CIM_iSCSIProtocolEndpoint['Role']
-ISCSI_TGT_ROLE_TARGET = Uint16(3)
-# CIM_SCSIProtocolController['NameFormat']
-SPC_NAME_FORMAT_ISCSI = Uint16(3)
-# CIM_IPProtocolEndpoint['IPv6AddressType']
-IPV6_ADDR_TYPE_GUA = Uint16(6)
-# GUA: Global Unicast Address.
-# 2000::/3
-IPV6_ADDR_TYPE_6TO4 = Uint16(7)
-# IPv6 to IPv4 transition
-# ::ffff:0:0/96
-# ::ffff:0:0:0/96
-# 64:ff9b::/96 # well-known prefix
-# 2002::/16 # 6to4
-IPV6_ADDR_TYPE_ULA = Uint16(8)
-# ULA: Unique Local Address, aka Site Local Unicast.
-# fc00::/7
-
-# CIM_GroupMaskingMappingService.CreateGroup('Type')
-MASK_GROUP_TYPE_INIT = Uint16(2)
-MASK_GROUP_TYPE_TGT = Uint16(3)
-MASK_GROUP_TYPE_DEV = Uint16(4)
-
-# CIM_GroupMaskingMappingCapabilities['SupportedDeviceGroupFeatures']
-# Allowing empty DeviceMaskingGroup associated to SPC
-GMM_CAP_DEV_MG_ALLOW_EMPTY_W_SPC = Uint16(5)
-
-# CIM_GroupMaskingMappingCapabilities['SupportedAsynchronousActions']
-# and 'SupportedSynchronousActions'. They are using the same value map.
-GMM_CAP_DELETE_SPC = Uint16(24)
-GMM_CAP_DELETE_GROUP = Uint16(20)
-
-# CIM_StorageConfigurationCapabilities['SupportedStorageElementTypes']
-SCS_CAP_SUP_ST_VOLUME = Uint16(2)
-SCS_CAP_SUP_THIN_ST_VOLUME = Uint16(5)
-
-# CIM_StorageConfigurationCapabilities['SupportedAsynchronousActions']
-# and also for 'SupportedSynchronousActions'
-SCS_CAP_VOLUME_CREATE = Uint16(5)
-SCS_CAP_VOLUME_DELETE = Uint16(6)
-SCS_CAP_VOLUME_MODIFY = Uint16(7)
-
-# DSP 1033 Profile Registration
-INTEROP_NAMESPACES = ['interop', 'root/interop', 'root/PG_Interop']
-DEFAULT_NAMESPACE = 'interop'
-
-
-# DMTF CIM 2.37.0 experimental CIM_StoragePool['Usage']
-POOL_USAGE_UNRESTRICTED = 2
-POOL_USAGE_RESERVED_FOR_SYSTEM = 3
-POOL_USAGE_DELTA = 4
-POOL_USAGE_SPARE = 8
-
-# DMTF CIM 2.29.1 CIM_StorageConfigurationCapabilities
-# ['SupportedStorageElementFeatures']
-SUPPORT_VOL_CREATE = 3
-SUPPORT_ELEMENT_EXPAND = 12
-SUPPORT_ELEMENT_REDUCE = 13
-
-# DMTF CIM 2.37.0 experimental CIM_StorageConfigurationCapabilities
-# ['SupportedStorageElementTypes']
-ELEMENT_THICK_VOLUME = Uint16(2)
-ELEMENT_THIN_VOLUME = Uint16(5)
-
-# DMTF CIM 2.29.1 CIM_StorageConfigurationCapabilities
-# ['SupportedStoragePoolFeatures']
-ST_POOL_FEATURE_INEXTS = 2
-ST_POOL_FEATURE_SINGLE_INPOOL = 3
-ST_POOL_FEATURE_MULTI_INPOOL = 4
-
-# DMTF CIM 2.38.0+ CIM_StorageSetting['ThinProvisionedPoolType']
-THINP_POOL_TYPE_ALLOCATED = Uint16(7)
-
-# DMTF Disk Type
-DISK_TYPE_UNKNOWN = 0
-DISK_TYPE_OTHER = 1
-DISK_TYPE_HDD = 2
-DISK_TYPE_SSD = 3
-DISK_TYPE_HYBRID = 4
-
-# CIM_ManagedSystemElement['OperationalStatus']
-OP_STATUS_UNKNOWN = 0
-OP_STATUS_OTHER = 1
-OP_STATUS_OK = 2
-OP_STATUS_DEGRADED = 3
-OP_STATUS_STRESSED = 4
-OP_STATUS_PREDICTIVE_FAILURE = 5
-OP_STATUS_ERROR = 6
-OP_STATUS_NON_RECOVERABLE_ERROR = 7
-OP_STATUS_STARTING = 8
-OP_STATUS_STOPPING = 9
-OP_STATUS_STOPPED = 10
-OP_STATUS_IN_SERVICE = 11
-OP_STATUS_NO_CONTACT = 12
-OP_STATUS_LOST_COMMUNICATION = 13
-OP_STATUS_ABORTED = 14
-OP_STATUS_DORMANT = 15
-OP_STATUS_SUPPORTING_ENTITY_IN_ERROR = 16
-OP_STATUS_COMPLETED = 17
-OP_STATUS_POWER_MODE = 18
-
-_OP_STATUS_STR_CONV = {
- OP_STATUS_UNKNOWN: "UNKNOWN",
- OP_STATUS_OTHER: "OTHER",
- OP_STATUS_OK: "OK",
- OP_STATUS_DEGRADED: "DEGRADED",
- OP_STATUS_STRESSED: "STRESSED",
- OP_STATUS_PREDICTIVE_FAILURE: "PREDICTIVE_FAILURE",
- OP_STATUS_ERROR: "ERROR",
- OP_STATUS_NON_RECOVERABLE_ERROR: "NON_RECOVERABLE_ERROR",
- OP_STATUS_STARTING: "STARTING",
- OP_STATUS_STOPPING: "STOPPING",
- OP_STATUS_STOPPED: "STOPPED",
- OP_STATUS_IN_SERVICE: "IN_SERVICE",
- OP_STATUS_NO_CONTACT: "NO_CONTACT",
- OP_STATUS_LOST_COMMUNICATION: "LOST_COMMUNICATION",
- OP_STATUS_ABORTED: "ABORTED",
- OP_STATUS_DORMANT: "DORMANT",
- OP_STATUS_SUPPORTING_ENTITY_IN_ERROR: "SUPPORTING_ENTITY_IN_ERROR",
- OP_STATUS_COMPLETED: "COMPLETED",
- OP_STATUS_POWER_MODE: "POWER_MODE",
-}
-
-
-def _op_status_to_str(dmtf_op_status):
- """
- Just convert integer to string. NOT ALLOWING provide a list.
- Return emtpy string is not found.
- """
- try:
- return _OP_STATUS_STR_CONV[dmtf_op_status]
- except KeyError:
- return ''
-
-
-def op_status_list_conv(conv_dict, dmtf_op_status_list,
- unknown_value, other_value):
- status = 0
- status_info_list = []
- for dmtf_op_status in dmtf_op_status_list:
- if dmtf_op_status in conv_dict.keys():
- status |= conv_dict[dmtf_op_status]
- else:
- if dmtf_op_status in _OP_STATUS_STR_CONV.keys():
- status |= other_value
- status_info_list.append(_op_status_to_str(dmtf_op_status))
- continue
- if status == 0:
- status = unknown_value
- return status, " ".join(status_info_list)
-
-# CIM_ConcreteJob['JobState']
-JOB_STATE_NEW = 2
-JOB_STATE_STARTING = 3
-JOB_STATE_RUNNING = 4
-JOB_STATE_COMPLETED = 7
-
-# CIM_Synchronized['SyncType'] also used by
-# CIM_ReplicationService.CreateElementReplica() 'SyncType' parameter.
-SYNC_TYPE_MIRROR = Uint16(6)
-SYNC_TYPE_SNAPSHOT = Uint16(7)
-SYNC_TYPE_CLONE = Uint16(8)
-
-# CIM_Synchronized['Mode'] also used by
-# CIM_ReplicationService.CreateElementReplica() 'Mode' parameter.
-REPLICA_MODE_SYNC = Uint16(2)
-REPLICA_MODE_ASYNC = Uint16(3)
-
-# CIM_StorageVolume['NameFormat']
-VOL_NAME_FORMAT_OTHER = 1
-VOL_NAME_FORMAT_NNA = 9
-VOL_NAME_FORMAT_EUI64 = 10
-VOL_NAME_FORMAT_T10VID = 11
-
-# CIM_StorageVolume['NameNamespace']
-VOL_NAME_SPACE_OTHER = 1
-VOL_NAME_SPACE_VPD83_TYPE3 = 2
-VOL_NAME_SPACE_VPD83_TYPE2 = 3
-VOL_NAME_SPACE_VPD83_TYPE1 = 4
-
-# CIM_ReplicationServiceCapabilities['SupportedAsynchronousActions']
-# or CIM_ReplicationServiceCapabilities['SupportedSynchronousActions']
-REPLICA_CAP_ACTION_CREATE_ELEMENT = 2
-
-# CIM_ReplicationServiceCapabilities['SupportedReplicationTypes']
-REPLICA_CAP_TYPE_SYNC_MIRROR_LOCAL = 2
-REPLICA_CAP_TYPE_ASYNC_MIRROR_LOCAL = 3
-
-REPLICA_CAP_TYPE_SYNC_SNAPSHOT_LOCAL = 6
-REPLICA_CAP_TYPE_ASYNC_SNAPSHOT_LOCAL = 7
-
-REPLICA_CAP_TYPE_SYNC_CLONE_LOCAL = 10
-REPLICA_CAP_TYPE_ASYNC_CLONE_LOCAL = 11
-
-# CIM_Synchronized['CopyState']
-COPY_STATE_SYNC = Uint16(4)
-
-# CIM_StorageConfigurationCapabilities['SupportedCopyTypes']
-ST_CONF_CAP_COPY_TYPE_ASYNC = Uint16(2)
-ST_CONF_CAP_COPY_TYPE_SYNC = Uint16(3)
-ST_CONF_CAP_COPY_TYPE_UNSYNC_ASSOC = Uint16(4)
-ST_CONF_CAP_COPY_TYPE_UNSYNC_UNASSOC = Uint16(5)
-
-# CIM_StorageSynchronized['SyncState']
-ST_SYNC_STATE_SYNCHRONIZED = 6
-
-# CIM_ControllerConfigurationService.ExposePaths(DeviceAccesses)
-CTRL_CONF_SRV_DA_RW = Uint16(2)
-
-VOL_OTHER_INFO_NAA_VPD83_TYPE3H = 'NAA;VPD83Type3'
-
-VOL_USAGE_SYS_RESERVED = Uint16(3)
diff --git a/plugin/smispy/smis.py b/plugin/smispy/smis.py
deleted file mode 100644
index 6a165ea..0000000
--- a/plugin/smispy/smis.py
+++ /dev/null
@@ -1,2017 +0,0 @@
-# Copyright (C) 2011-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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
-# USA
-#
-# Author: tasleson
-# Gris Ge <***@redhat.com>
-
-from string import split
-import time
-import copy
-import os
-import re
-
-import pywbem
-from pywbem import CIMError
-import smis_cap
-import smis_sys
-import smis_pool
-import smis_disk
-from lsm.plugin.smispy import smis_vol
-from lsm.plugin.smispy import smis_ag
-import dmtf
-
-from lsm import (IStorageAreaNetwork, uri_parse, LsmError, ErrorNumber,
- JobStatus, md5, Volume, AccessGroup, Pool,
- VERSION, TargetPort,
- search_property)
-
-from utils import (merge_list, handle_cim_errors, hex_string_format)
-
-from smis_common import SmisCommon
-
-## Variable Naming scheme:
-# cim_xxx CIMInstance
-# cim_xxx_path CIMInstanceName
-# cim_sys CIM_ComputerSystem (root or leaf)
-# cim_pool CIM_StoragePool
-# cim_scs CIM_StorageConfigurationService
-# cim_vol CIM_StorageVolume
-# cim_rp CIM_RegisteredProfile
-# cim_init CIM_StorageHardwareID
-# cim_spc CIM_SCSIProtocolController
-# cim_init_mg CIM_InitiatorMaskingGroup
-# cim_fc_tgt CIM_FCPort
-# cim_iscsi_pg CIM_iSCSIProtocolEndpoint # iSCSI portal group
-# cim_iscsi_node CIM_SCSIProtocolController
-# cim_tcp CIM_TCPProtocolEndpoint,
-# cim_ip CIM_IPProtocolEndpoint
-# cim_eth CIM_EthernetPort
-# cim_pe CIM_SCSIProtocolEndpoint
-# cim_gmms CIM_GroupMaskingMappingService
-# cim_ccs CIM_ControllerConfigurationService
-# cim_rs CIM_ReplicationService
-# cim_hwms CIM_StorageHardwareIDManagementService
-#
-# sys Object of LSM System
-# pool Object of LSM Pool
-# vol Object of LSM Volume
-
-## Method Naming scheme:
-# _cim_xxx()
-# Return CIMInstance without any Associations() call.
-# _cim_xxx_of(cim_yyy)
-# Return CIMInstance associated to cim_yyy
-# _adj_cim_xxx()
-# Return CIMInstance with 'adj' only
-# _cim_xxx_of_id(some_id)
-# Return CIMInstance for given ID
-
-# Terminology
-# SPC CIM_SCSIProtocolController
-# BSP SNIA SMI-S 'Block Services Package' profile
-# Group M&M SNIA SMI-S 'Group Masking and Mapping' profile
-
-
-def _lsm_tgt_port_type_of_cim_fc_tgt(cim_fc_tgt):
- """
- We are assuming we got CIM_FCPort. Caller should make sure of that.
- Return TargetPool.PORT_TYPE_FC as fallback
- """
- # In SNIA SMI-S 1.6.1 public draft 2, 'PortDiscriminator' is mandatory
- # for FCoE target port.
- if 'PortDiscriminator' in cim_fc_tgt and \
- cim_fc_tgt['PortDiscriminator'] and \
- dmtf.FC_PORT_PORT_DISCRIMINATOR_FCOE in cim_fc_tgt['PortDiscriminator']:
- return TargetPort.TYPE_FCOE
- if 'LinkTechnology' in cim_fc_tgt and \
- cim_fc_tgt['LinkTechnology'] == dmtf.NET_PORT_LINK_TECH_ETHERNET:
- return TargetPort.TYPE_FCOE
- return TargetPort.TYPE_FC
-
-
-class Smis(IStorageAreaNetwork):
- """
- SMI-S plug-ing which exposes a small subset of the overall provided
- functionality of SMI-S
- """
- _JOB_ERROR_HANDLER = {
- SmisCommon.JOB_RETRIEVE_VOLUME_CREATE:
- smis_vol.volume_create_error_handler,
- }
-
- def __init__(self):
- self._c = None
- self.tmo = 0
-
- @handle_cim_errors
- def plugin_register(self, uri, password, timeout, flags=0):
- """
- Called when the plug-in runner gets the start request from the client.
- Checkout interop support status via:
- 1. Enumerate CIM_RegisteredProfile in 'interop' namespace.
- 2. if nothing found, then
- Enumerate CIM_RegisteredProfile in 'root/interop' namespace.
- 3. if nothing found, then
- Enumerate CIM_RegisteredProfile in user defined namespace.
- """
- protocol = 'http'
- port = SmisCommon.IAAN_WBEM_HTTP_PORT
- u = uri_parse(uri, ['scheme', 'netloc', 'host'], None)
-
- if u['scheme'].lower() == 'smispy+ssl':
- protocol = 'https'
- port = SmisCommon.IAAN_WBEM_HTTPS_PORT
-
- if 'port' in u:
- port = u['port']
-
- url = "%s://%s:%s" % (protocol, u['host'], port)
-
- # System filtering
- system_list = None
-
- if 'systems' in u['parameters']:
- system_list = split(u['parameters']["systems"], ":")
-
- namespace = None
- if 'namespace' in u['parameters']:
- namespace = u['parameters']['namespace']
-
- no_ssl_verify = False
- if "no_ssl_verify" in u["parameters"] \
- and u["parameters"]["no_ssl_verify"] == 'yes':
- no_ssl_verify = True
-
- debug_path = None
- if 'debug_path' in u['parameters']:
- debug_path = u['parameters']['debug_path']
-
- self._c = SmisCommon(
- url, u['username'], password, namespace, no_ssl_verify,
- debug_path, system_list)
-
- self.tmo = timeout
-
- @handle_cim_errors
- def time_out_set(self, ms, flags=0):
- self.tmo = ms
-
- @handle_cim_errors
- def time_out_get(self, flags=0):
- return self.tmo
-
- @handle_cim_errors
- def plugin_unregister(self, flags=0):
- self._c = None
-
- @handle_cim_errors
- def capabilities(self, system, flags=0):
- cim_sys = smis_sys.cim_sys_of_sys_id(self._c, system.id)
- return smis_cap.get(self._c, cim_sys, system)
-
- @handle_cim_errors
- def plugin_info(self, flags=0):
- return "Generic SMI-S support", VERSION
-
- @handle_cim_errors
- def job_status(self, job_id, flags=0):
- """
- Given a job id returns the current status as a tuple
- (status (enum), percent_complete(integer), volume (None or Volume))
- """
- completed_item = None
-
- error_handler = None
-
- (ignore, retrieve_data, method_data) = SmisCommon.parse_job_id(job_id)
-
- if retrieve_data in Smis._JOB_ERROR_HANDLER.keys():
- error_handler = Smis._JOB_ERROR_HANDLER[retrieve_data]
-
- cim_job_pros = SmisCommon.cim_job_pros()
- cim_job_pros.extend(
- ['JobState', 'PercentComplete', 'ErrorDescription',
- 'OperationalStatus'])
- cim_job = self._c.cim_job_of_job_id(job_id, cim_job_pros)
-
- job_state = cim_job['JobState']
-
- try:
- if job_state in (dmtf.JOB_STATE_NEW, dmtf.JOB_STATE_STARTING,
- dmtf.JOB_STATE_RUNNING):
- status = JobStatus.INPROGRESS
-
- pc = cim_job['PercentComplete']
- if pc > 100:
- percent_complete = 100
- else:
- percent_complete = pc
-
- elif job_state == dmtf.JOB_STATE_COMPLETED:
- status = JobStatus.COMPLETE
- percent_complete = 100
-
- if SmisCommon.cim_job_completed_ok(cim_job):
- if retrieve_data == SmisCommon.JOB_RETRIEVE_VOLUME or \
- retrieve_data == SmisCommon.JOB_RETRIEVE_VOLUME_CREATE:
- completed_item = self._new_vol_from_job(cim_job)
- else:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- str(cim_job['ErrorDescription']))
- else:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG, str(cim_job['ErrorDescription']))
-
- except Exception:
- if error_handler is not None:
- error_handler(self._c, method_data)
- else:
- raise
- return status, percent_complete, completed_item
-
- def _new_vol_from_name(self, out):
- """
- Given a volume by CIMInstanceName, return a lsm Volume object
- """
- cim_vol = None
- cim_vol_pros = smis_vol.cim_vol_pros()
-
- if 'TheElement' in out:
- cim_vol = self._c.GetInstance(
- out['TheElement'],
- PropertyList=cim_vol_pros)
- elif 'TargetElement' in out:
- cim_vol = self._c.GetInstance(
- out['TargetElement'],
- PropertyList=cim_vol_pros)
-
- pool_id = smis_pool.pool_id_of_cim_vol(self._c, cim_vol.path)
- sys_id = smis_sys.sys_id_of_cim_vol(cim_vol)
-
- return smis_vol.cim_vol_to_lsm_vol(cim_vol, pool_id, sys_id)
-
- def _new_vol_from_job(self, job):
- """
- Given a concrete job instance, return referenced volume as lsm volume
- """
- cim_vol_pros = smis_vol.cim_vol_pros()
- cim_vols = []
- # Workaround for HP 3PAR:
- # When doing volume-replicate for 'COPY" type, Associators() will
- # return [None] if PropertyList defined. It works well
- # for CLONE type.
- if job.path.classname == 'TPD_ConcreteJob':
- cim_vols = self._c.Associators(
- job.path,
- AssocClass='CIM_AffectedJobElement',
- ResultClass='CIM_StorageVolume')
- else:
- cim_vols = self._c.Associators(
- job.path,
- AssocClass='CIM_AffectedJobElement',
- ResultClass='CIM_StorageVolume',
- PropertyList=cim_vol_pros)
- for cim_vol in cim_vols:
- pool_id = smis_pool.pool_id_of_cim_vol(self._c, cim_vol.path)
- sys_id = smis_sys.sys_id_of_cim_vol(cim_vol)
- return smis_vol.cim_vol_to_lsm_vol(cim_vol, pool_id, sys_id)
- return None
-
- @handle_cim_errors
- def volumes(self, search_key=None, search_value=None, flags=0):
- """
- Return all volumes.
- We are basing on "Block Services Package" profile version 1.4 or
- later:
- CIM_ComputerSystem
- |
- | (CIM_HostedStoragePool)
- |
- v
- CIM_StoragePool
- |
- | (CIM_AllocatedFromStoragePool)
- |
- v
- CIM_StorageVolume
- As 'Block Services Package' is mandatory for 'Array' profile, we
- don't check support status here as startup() already checked 'Array'
- profile.
- """
- rc = []
- cim_sys_pros = smis_sys.cim_sys_id_pros()
- cim_syss = smis_sys.root_cim_sys(self._c, cim_sys_pros)
- cim_vol_pros = smis_vol.cim_vol_pros()
- for cim_sys in cim_syss:
- sys_id = smis_sys.sys_id_of_cim_sys(cim_sys)
- pool_pros = smis_pool.cim_pool_id_pros()
- cim_pools = smis_pool.cim_pools_of_cim_sys_path(
- self._c, cim_sys.path, pool_pros)
- for cim_pool in cim_pools:
- pool_id = smis_pool.pool_id_of_cim_pool(cim_pool)
- cim_vols = smis_vol.cim_vol_of_cim_pool_path(
- self._c, cim_pool.path, cim_vol_pros)
- for cim_vol in cim_vols:
- rc.append(
- smis_vol.cim_vol_to_lsm_vol(cim_vol, pool_id, sys_id))
- return search_property(rc, search_key, search_value)
-
- @handle_cim_errors
- def pools(self, search_key=None, search_value=None, flags=0):
- """
- Convert CIM_StoragePool to lsm.Pool.
- To list all CIM_StoragePool:
- 1. List all root CIM_ComputerSystem.
- 2. List all CIM_StoragePool associated to CIM_ComputerSystem.
- """
- rc = []
- cim_pool_pros = smis_pool.cim_pool_pros()
-
- cim_sys_pros = smis_sys.cim_sys_id_pros()
- cim_syss = smis_sys.root_cim_sys(self._c, cim_sys_pros)
-
- for cim_sys in cim_syss:
- system_id = smis_sys.sys_id_of_cim_sys(cim_sys)
- cim_pools = smis_pool.cim_pools_of_cim_sys_path(
- self._c, cim_sys.path, cim_pool_pros)
- for cim_pool in cim_pools:
- rc.append(
- smis_pool.cim_pool_to_lsm_pool(
- self._c, cim_pool, system_id))
-
- return search_property(rc, search_key, search_value)
-
- @handle_cim_errors
- def systems(self, flags=0):
- """
- Return the storage arrays accessible from this plug-in at this time
-
- As 'Block Services Package' is mandatory for 'Array' profile, we
- don't check support status here as startup() already checked 'Array'
- profile.
- """
- cim_sys_pros = smis_sys.cim_sys_pros()
- cim_syss = smis_sys.root_cim_sys(self._c, cim_sys_pros)
-
- return [smis_sys.cim_sys_to_lsm_sys(s) for s in cim_syss]
-
- @handle_cim_errors
- def volume_create(self, pool, volume_name, size_bytes, provisioning,
- flags=0):
- """
- Create a volume.
- """
- # Use user provide lsm.Pool.element_type to speed thing up.
- if not Pool.ELEMENT_TYPE_VOLUME & pool.element_type:
- raise LsmError(
- ErrorNumber.NO_SUPPORT,
- "Pool not suitable for creating volumes")
-
- # Use THICK volume by default unless unsupported or user requested.
- dmtf_element_type = dmtf.ELEMENT_THICK_VOLUME
-
- if provisioning == Volume.PROVISION_DEFAULT:
- # Prefer thick/full volume unless only thin volume supported.
- # HDS AMS only support thin volume in their thin pool.
- if not Pool.ELEMENT_TYPE_VOLUME_FULL & pool.element_type and \
- Pool.ELEMENT_TYPE_VOLUME_THIN & pool.element_type:
- dmtf_element_type = dmtf.ELEMENT_THIN_VOLUME
- else:
- # User is requesting certain type of volume
- if provisioning == Volume.PROVISION_FULL and \
- Pool.ELEMENT_TYPE_VOLUME_FULL & pool.element_type:
- dmtf_element_type = dmtf.ELEMENT_THICK_VOLUME
- elif (provisioning == Volume.PROVISION_THIN and
- Pool.ELEMENT_TYPE_VOLUME_THIN & pool.element_type):
- dmtf_element_type = dmtf.ELEMENT_THIN_VOLUME
- else:
- raise LsmError(
- ErrorNumber.NO_SUPPORT,
- "Pool not suitable for creating volume with "
- "requested provisioning type")
-
- # Get the Configuration service for the system we are interested in.
- cim_scs = self._c.cim_scs_of_sys_id(pool.system_id)
-
- cim_pool_path = smis_pool.lsm_pool_to_cim_pool_path(
- self._c, pool)
-
- in_params = {'ElementName': volume_name,
- 'ElementType': dmtf_element_type,
- 'InPool': cim_pool_path,
- 'Size': pywbem.Uint64(size_bytes)}
-
- error_handler = Smis._JOB_ERROR_HANDLER[
- SmisCommon.JOB_RETRIEVE_VOLUME_CREATE]
-
- return self._c.invoke_method(
- 'CreateOrModifyElementFromStoragePool', cim_scs.path,
- in_params,
- out_handler=self._new_vol_from_name,
- error_handler=error_handler,
- retrieve_data=SmisCommon.JOB_RETRIEVE_VOLUME_CREATE,
- method_data=volume_name)
-
- def _detach_netapp_e(self, vol, sync):
- #Get the Configuration service for the system we are interested in.
- cim_scs = self._c.cim_scs_of_sys_id(vol.system_id)
-
- in_params = {'Operation': pywbem.Uint16(2),
- 'Synchronization': sync.path}
-
- self._c.invoke_method_wait(
- 'ModifySynchronization', cim_scs.path, in_params)
-
- def _detach(self, vol, sync):
- if self._c.is_netappe():
- return self._detach_netapp_e(vol, sync)
-
- cim_rs = self._c.cim_rs_of_sys_id(vol.system_id, raise_error=False)
-
- if cim_rs:
- in_params = {'Operation': pywbem.Uint16(8),
- 'Synchronization': sync.path}
-
- self._c.invoke_method_wait(
- 'ModifyReplicaSynchronization', cim_rs.path, in_params)
-
- @staticmethod
- def _cim_name_match(a, b):
- if a['DeviceID'] == b['DeviceID'] \
- and a['SystemName'] == b['SystemName'] \
- and a['SystemCreationClassName'] == \
- b['SystemCreationClassName']:
- return True
- else:
- return False
-
- def _deal_volume_associations_netappe(self, vol, cim_vol_path):
- """
- Check a volume to see if it has any associations with other
- volumes.
- """
- rc = False
-
- ss = self._c.References(cim_vol_path,
- ResultClass='CIM_StorageSynchronized')
-
- if len(ss):
- for s in ss:
- if 'SyncedElement' in s:
- item = s['SyncedElement']
-
- if Smis._cim_name_match(item, cim_vol_path):
- self._detach(vol, s)
- rc = True
-
- if 'SystemElement' in s:
- item = s['SystemElement']
-
- if Smis._cim_name_match(item, cim_vol_path):
- self._detach(vol, s)
- rc = True
-
- return rc
-
- def _deal_volume_associations(self, vol, cim_vol_path):
- """
- Check a volume to see if it has any associations with other
- volumes and deal with them.
- """
- if self._c.is_netappe():
- return self._deal_volume_associations_netappe(vol, cim_vol_path)
-
- try:
- ss = self._c.References(cim_vol_path,
- ResultClass='CIM_StorageSynchronized')
- except pywbem.CIMError as e:
- if e[0] == pywbem.CIM_ERR_INVALID_CLASS:
- return
- else:
- raise
-
- if len(ss):
- for s in ss:
- # TODO: Need to see if detach is a supported operation in
- # replication capabilities.
- #
- # TODO: Theory of delete. Some arrays will automatically
- # detach a clone, check
- # ReplicationServiceCapabilities.GetSupportedFeatures() and
- # look for "Synchronized clone target detaches automatically".
- # If not automatic then detach manually. However, we have
- # seen arrays that don't report detach automatically that
- # don't need a detach.
- #
- # This code needs to be re-investigated to work with a wide
- # range of array vendors.
-
- if 'SyncState' in s and 'CopyType' in s:
- if s['SyncState'] == dmtf.ST_SYNC_STATE_SYNCHRONIZED and \
- s['CopyType'] != \
- dmtf.ST_CONF_CAP_COPY_TYPE_UNSYNC_ASSOC:
- if 'SyncedElement' in s:
- item = s['SyncedElement']
-
- if Smis._cim_name_match(item, cim_vol_path):
- self._detach(vol, s)
-
- if 'SystemElement' in s:
- item = s['SystemElement']
-
- if Smis._cim_name_match(item, cim_vol_path):
- self._detach(vol, s)
-
- def _volume_delete_netapp_e(self, volume, flags=0):
- cim_scs = self._c.cim_scs_of_sys_id(volume.system_id)
- cim_vol_path = smis_vol.lsm_vol_to_cim_vol_path(self._c, volume)
-
- #If we actually have an association to delete, the volume will be
- #deleted with the association, no need to call ReturnToStoragePool
- if not self._deal_volume_associations(volume, cim_vol_path):
- in_params = {'TheElement': cim_vol_path}
-
- #Delete returns None or Job number
- return self._c.invoke_method(
- 'ReturnToStoragePool', cim_scs.path, in_params)[0]
-
- #Loop to check to see if volume is actually gone yet!
- try:
- cim_vol = self._c.GetInstance(cim_vol_path, PropertyList=[])
- while cim_vol is not None:
- cim_vol = self._c.GetInstance(cim_vol_path, PropertyList=[])
- time.sleep(0.125)
- except (LsmError, CIMError) as e:
- pass
-
- @handle_cim_errors
- def volume_delete(self, volume, flags=0):
- """
- Delete a volume
- """
- cim_scs = self._c.cim_scs_of_sys_id(volume.system_id)
-
- cim_vol_path = smis_vol.lsm_vol_to_cim_vol_path(self._c, volume)
-
- self._deal_volume_associations(volume, cim_vol_path)
-
- in_params = {'TheElement': cim_vol_path}
-
- # Delete returns None or Job number
- return self._c.invoke_method(
- 'ReturnToStoragePool', cim_scs.path, in_params)[0]
-
- @handle_cim_errors
- def volume_resize(self, volume, new_size_bytes, flags=0):
- """
- Re-size a volume
- """
- cim_scs = self._c.cim_scs_of_sys_id(volume.system_id)
-
- cim_vol_path = smis_vol.lsm_vol_to_cim_vol_path(self._c, volume)
-
- in_params = {'ElementType': pywbem.Uint16(2),
- 'TheElement': cim_vol_path,
- 'Size': pywbem.Uint64(new_size_bytes)}
-
- return self._c.invoke_method(
- 'CreateOrModifyElementFromStoragePool', cim_scs.path, in_params,
- out_handler=self._new_vol_from_name,
- retrieve_data=SmisCommon.JOB_RETRIEVE_VOLUME)
-
- def _get_supported_sync_and_mode(self, system_id, rep_type):
- """
- Converts from a library capability to a suitable array capability
-
- returns a tuple (sync, mode)
- """
- rc = [None, None]
-
- cim_rs = self._c.cim_rs_of_sys_id(system_id, raise_error=False)
-
- if cim_rs:
- rs_cap = self._c.Associators(
- cim_rs.path,
- AssocClass='CIM_ElementCapabilities',
- ResultClass='CIM_ReplicationServiceCapabilities')[0]
-
- s_rt = rs_cap['SupportedReplicationTypes']
-
- if rep_type == Volume.REPLICATE_COPY:
- if dmtf.REPLICA_CAP_TYPE_SYNC_CLONE_LOCAL in s_rt:
- rc[0] = dmtf.SYNC_TYPE_CLONE
- rc[1] = dmtf.REPLICA_MODE_SYNC
- elif dmtf.REPLICA_CAP_TYPE_ASYNC_CLONE_LOCAL in s_rt:
- rc[0] = dmtf.SYNC_TYPE_CLONE
- rc[1] = dmtf.REPLICA_MODE_ASYNC
-
- elif rep_type == Volume.REPLICATE_MIRROR_ASYNC:
- if dmtf.REPLICA_CAP_TYPE_ASYNC_MIRROR_LOCAL in s_rt:
- rc[0] = dmtf.SYNC_TYPE_MIRROR
- rc[1] = dmtf.REPLICA_MODE_ASYNC
-
- elif rep_type == Volume.REPLICATE_MIRROR_SYNC:
- if dmtf.REPLICA_CAP_TYPE_SYNC_MIRROR_LOCAL in s_rt:
- rc[0] = dmtf.SYNC_TYPE_MIRROR
- rc[1] = dmtf.REPLICA_MODE_SYNC
-
- elif rep_type == Volume.REPLICATE_CLONE:
- if dmtf.REPLICA_CAP_TYPE_SYNC_CLONE_LOCAL in s_rt:
- rc[0] = dmtf.SYNC_TYPE_SNAPSHOT
- rc[1] = dmtf.REPLICA_MODE_SYNC
- elif dmtf.REPLICA_CAP_TYPE_ASYNC_CLONE_LOCAL in s_rt:
- rc[0] = dmtf.SYNC_TYPE_SNAPSHOT
- rc[1] = dmtf.REPLICA_MODE_ASYNC
-
- if rc[0] is None:
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "Replication type not supported")
-
- return tuple(rc)
-
- @handle_cim_errors
- def volume_replicate(self, pool, rep_type, volume_src, name, flags=0):
- """
- Replicate a volume
- """
- if rep_type == Volume.REPLICATE_MIRROR_ASYNC \
- or rep_type == Volume.REPLICATE_MIRROR_SYNC:
- raise LsmError(ErrorNumber.NO_SUPPORT, "Mirroring not supported")
-
- cim_rs = self._c.cim_rs_of_sys_id(
- volume_src.system_id, raise_error=False)
-
- # Some (EMC VMAX, Dot hill) SMI-S Provider allow duplicated
- # ElementName, we have to do pre-check here.
- if smis_vol.volume_name_exists(self._c, name):
- raise LsmError(ErrorNumber.NAME_CONFLICT,
- "Volume with name '%s' already exists!" % name)
-
- cim_pool_path = None
- if pool is not None:
- cim_pool_path = smis_pool.lsm_pool_to_cim_pool_path(self._c, pool)
-
- src_cim_vol_path = smis_vol.lsm_vol_to_cim_vol_path(
- self._c, volume_src)
-
- if cim_rs:
- method = 'CreateElementReplica'
-
- sync, mode = self._get_supported_sync_and_mode(
- volume_src.system_id, rep_type)
-
- in_params = {'ElementName': name,
- 'SyncType': sync,
- #'Mode': mode,
- 'SourceElement': src_cim_vol_path,
- 'WaitForCopyState': dmtf.COPY_STATE_SYNC}
-
- else:
- # Check for older support via storage configuration service
-
- method = 'CreateReplica'
-
- # Check for storage configuration service
- cim_rs = self._c.cim_scs_of_sys_id(
- volume_src.system_id, raise_error=False)
-
- ct = Volume.REPLICATE_CLONE
- if rep_type == Volume.REPLICATE_CLONE:
- ct = dmtf.ST_CONF_CAP_COPY_TYPE_UNSYNC_ASSOC
- elif rep_type == Volume.REPLICATE_COPY:
- ct = dmtf.ST_CONF_CAP_COPY_TYPE_UNSYNC_UNASSOC
- elif rep_type == Volume.REPLICATE_MIRROR_ASYNC:
- ct = dmtf.ST_CONF_CAP_COPY_TYPE_ASYNC
- elif rep_type == Volume.REPLICATE_MIRROR_SYNC:
- ct = dmtf.ST_CONF_CAP_COPY_TYPE_SYNC
-
- in_params = {'ElementName': name,
- 'CopyType': ct,
- 'SourceElement': src_cim_vol_path}
- if cim_rs:
-
- if cim_pool_path is not None:
- in_params['TargetPool'] = cim_pool_path
-
- return self._c.invoke_method(
- method, cim_rs.path, in_params,
- out_handler=self._new_vol_from_name,
- retrieve_data=SmisCommon.JOB_RETRIEVE_VOLUME)
-
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "volume-replicate not supported")
-
- def _cim_dev_mg_path_create(self, cim_gmms_path, name, cim_vol_path,
- vol_id):
- rc = SmisCommon.SNIA_INVOKE_FAILED
- out = None
-
- in_params = {
- 'GroupName': name,
- 'Members': [cim_vol_path],
- 'Type': dmtf.MASK_GROUP_TYPE_DEV}
-
- cim_dev_mg_path = None
- try:
- cim_dev_mg_path = self._c.invoke_method_wait(
- 'CreateGroup', cim_gmms_path, in_params,
- out_key='MaskingGroup',
- expect_class='CIM_TargetMaskingGroup')
- except (LsmError, CIMError):
- cim_dev_mg_path = self._check_exist_cim_dev_mg(
- name, cim_gmms_path, cim_vol_path, vol_id)
- if cim_dev_mg_path is None:
- raise
-
- return cim_dev_mg_path
-
- def _cim_tgt_mg_path_create(self, cim_sys_path, cim_gmms_path, name,
- init_type):
- """
- Create CIM_TargetMaskingGroup
- Currently, LSM does not support target ports masking
- we will mask to all target ports.
- Return CIMInstanceName of CIM_TargetMaskingGroup
- """
- rc = SmisCommon.SNIA_INVOKE_FAILED
- out = None
-
- in_params = {
- 'GroupName': name,
- 'Type': dmtf.MASK_GROUP_TYPE_TGT}
-
- if init_type == AccessGroup.INIT_TYPE_WWPN:
- cim_fc_tgts = self._cim_fc_tgt_of(cim_sys_path)
- all_cim_fc_peps_path = []
- all_cim_fc_peps_path.extend(
- [self._cim_pep_path_of_fc_tgt(x.path) for x in cim_fc_tgts])
- in_params['Members'] = all_cim_fc_peps_path
-
- elif init_type == AccessGroup.INIT_TYPE_ISCSI_IQN:
- cim_iscsi_pgs = self._cim_iscsi_pg_of(cim_sys_path)
- in_params['Members'] = [x.path for x in cim_iscsi_pgs]
- else:
- # Already checked at the beginning of this method
- pass
-
- cim_tgt_mg_path = None
- try:
- cim_tgt_mg_path = self._c.invoke_method_wait(
- 'CreateGroup', cim_gmms_path, in_params,
- out_key='MaskingGroup', expect_class='CIM_TargetMaskingGroup')
- except (LsmError, CIMError):
- cim_tgt_mg_path = self._check_exist_cim_tgt_mg(name)
- if cim_tgt_mg_path is None:
- raise
-
- return cim_tgt_mg_path
-
- def _cim_spc_path_create(self, cim_gmms_path, cim_init_mg_path,
- cim_tgt_mg_path, cim_dev_mg_path, name):
- in_params = {
- 'ElementName': name,
- 'InitiatorMaskingGroup': cim_init_mg_path,
- 'TargetMaskingGroup': cim_tgt_mg_path,
- 'DeviceMaskingGroup': cim_dev_mg_path,
- }
-
- return self._c.invoke_method_wait(
- 'CreateMaskingView', cim_gmms_path, in_params,
- out_key='ProtocolController',
- expect_class='CIM_SCSIProtocolController')
-
- def _volume_mask_group(self, access_group, volume, flags=0):
- """
- Grant access to a volume to an group
- Use GroupMaskingMappingService.AddMembers() for Group Masking
- Use ControllerConfigurationService.ExposePaths() for Masking.
- Currently, LSM does not have a way to control which target port to
- mask.
- If CIM_TargetMaskingGroup already defined for current
- CIM_InitiatorMaskingGroup, we use that.
- If No CIM_TargetMaskingGroup exist, we create one with all possible
- target ports(all FC and FCoE port for access_group.init_type == WWPN,
- and the same to iSCSI)
- """
- cim_init_mg_path = smis_ag.lsm_ag_to_cim_init_mg_path(
- self._c, access_group)
-
- cim_inits = smis_ag.cim_init_of_cim_init_mg_path(
- self._c, cim_init_mg_path)
- if len(cim_inits) == 0:
- raise LsmError(ErrorNumber.EMPTY_ACCESS_GROUP,
- "Access group %s is empty(no member), " %
- access_group.id +
- "will not do volume_mask()")
-
- if access_group.init_type != AccessGroup.INIT_TYPE_WWPN and \
- access_group.init_type != AccessGroup.INIT_TYPE_ISCSI_IQN:
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "SMI-S plugin only support iSCSI and FC/FCoE "
- "access group volume masking, but got "
- "access group init_type: %d" %
- access_group.init_type)
-
- cim_vol_path = smis_vol.lsm_vol_to_cim_vol_path(self._c, volume)
-
- cim_gmms = self._c.cim_gmms_of_sys_id(access_group.system_id)
-
- cim_spcs_path = self._c.AssociatorNames(
- cim_init_mg_path,
- AssocClass='CIM_AssociatedInitiatorMaskingGroup',
- ResultClass='CIM_SCSIProtocolController')
-
- if len(cim_spcs_path) == 0:
- # We have to create the SPC and dev_mg now.
- cim_sys = smis_sys.cim_sys_of_sys_id(
- self._c, access_group.system_id)
-
- cim_tgt_mg_path = self._cim_tgt_mg_path_create(
- cim_sys.path, cim_gmms.path, access_group.name,
- access_group.init_type)
- cim_dev_mg_path = self._cim_dev_mg_path_create(
- cim_gmms.path, access_group.name, cim_vol_path, volume.id)
- # Done when SPC created.
- self._cim_spc_path_create(
- cim_gmms.path, cim_init_mg_path, cim_tgt_mg_path,
- cim_dev_mg_path, access_group.name)
- else:
- # CIM_InitiatorMaskingGroup might have multiple SPC when having
- # many tgt_mg. It's seldom use, but possible.
- for cim_spc_path in cim_spcs_path:
- # Check whether already masked
- cim_vols = smis_ag.cim_vols_masked_to_cim_spc_path(
- self._c, cim_spc_path, smis_vol.cim_vol_id_pros())
- for cur_cim_vol in cim_vols:
- if smis_vol.vol_id_of_cim_vol(cur_cim_vol) == volume.id:
- raise LsmError(
- ErrorNumber.NO_STATE_CHANGE,
- "Volume already masked to requested access group")
-
- # SNIA require each cim_spc only have one cim_dev_mg
- # associated
- cim_dev_mg_path = self._c.AssociatorNames(
- cim_spc_path,
- AssocClass='CIM_AssociatedDeviceMaskingGroup',
- ResultClass='CIM_DeviceMaskingGroup')[0]
- in_params = {
- 'MaskingGroup': cim_dev_mg_path,
- 'Members': [cim_vol_path],
- }
- self._c.invoke_method_wait(
- 'AddMembers', cim_gmms.path, in_params)
- return None
-
- @handle_cim_errors
- def volume_mask(self, access_group, volume, flags=0):
- """
- Grant access to a volume to an group
- """
- mask_type = smis_cap.mask_type(self._c, raise_error=True)
- # Workaround for EMC VNX/CX
- if mask_type == smis_cap.MASK_TYPE_GROUP:
- cim_sys = smis_sys.cim_sys_of_sys_id(self._c, volume.system_id)
- if cim_sys.path.classname == 'Clar_StorageSystem':
- mask_type = smis_cap.MASK_TYPE_MASK
-
- if mask_type == smis_cap.MASK_TYPE_GROUP:
- return self._volume_mask_group(access_group, volume, flags)
- return self._volume_mask_old(access_group, volume, flags)
-
- def _cim_vol_masked_to_spc(self, cim_spc_path, vol_id, property_list=None):
- """
- Check whether provided volume id is masked to cim_spc_path.
- If so, return cim_vol, or return None
- """
- if property_list is None:
- property_list = smis_vol.cim_vol_id_pros()
- else:
- property_list = merge_list(
- property_list, smis_vol.cim_vol_id_pros())
-
- masked_cim_vols = smis_ag.cim_vols_masked_to_cim_spc_path(
- self._c, cim_spc_path, property_list)
- for masked_cim_vol in masked_cim_vols:
- if smis_vol.vol_id_of_cim_vol(masked_cim_vol) == vol_id:
- return masked_cim_vol
-
- return None
-
- def _volume_mask_old(self, access_group, volume, flags):
- cim_spc_path = smis_ag.lsm_ag_to_cim_spc_path(self._c, access_group)
-
- cim_inits = smis_ag.cim_init_of_cim_spc_path(self._c, cim_spc_path)
- if len(cim_inits) == 0:
- raise LsmError(ErrorNumber.EMPTY_ACCESS_GROUP,
- "Access group %s is empty(no member), " %
- access_group.id +
- "will not do volume_mask()")
-
- # Pre-Check: Already masked
- if self._cim_vol_masked_to_spc(cim_spc_path, volume.id):
- raise LsmError(
- ErrorNumber.NO_STATE_CHANGE,
- "Volume already masked to requested access group")
-
- cim_ccs = self._c.cim_ccs_of_sys_id(volume.system_id)
-
- cim_vol_path = smis_vol.lsm_vol_to_cim_vol_path(self._c, volume)
- cim_vol = self._c.GetInstance(cim_vol_path, PropertyList=['Name'])
-
- in_params = {'LUNames': [cim_vol['Name']],
- 'ProtocolControllers': [cim_spc_path],
- 'DeviceAccesses': [dmtf.CTRL_CONF_SRV_DA_RW]}
-
- self._c.invoke_method_wait('ExposePaths', cim_ccs.path, in_params)
- return None
-
- def _volume_unmask_group(self, access_group, volume):
- """
- Use CIM_GroupMaskingMappingService.RemoveMembers() against
- CIM_DeviceMaskingGroup
- If SupportedDeviceGroupFeatures does not allow empty
- DeviceMaskingGroup in SPC, we remove SPC and DeviceMaskingGroup.
- """
- cim_sys = smis_sys.cim_sys_of_sys_id(self._c, volume.system_id)
-
- cim_gmms_cap = self._c.Associators(
- cim_sys.path,
- AssocClass='CIM_ElementCapabilities',
- ResultClass='CIM_GroupMaskingMappingCapabilities',
- PropertyList=['SupportedDeviceGroupFeatures',
- 'SupportedSynchronousActions',
- 'SupportedAsynchronousActions'])[0]
-
- flag_empty_dev_in_spc = False
-
- if dmtf.GMM_CAP_DEV_MG_ALLOW_EMPTY_W_SPC in \
- cim_gmms_cap['SupportedDeviceGroupFeatures']:
- flag_empty_dev_in_spc = True
-
- if flag_empty_dev_in_spc is False:
- if ((dmtf.GMM_CAP_DELETE_SPC not in
- cim_gmms_cap['SupportedSynchronousActions']) and
- (dmtf.GMM_CAP_DELETE_SPC not in
- cim_gmms_cap['SupportedAsynchronousActions'])):
- raise LsmError(
- ErrorNumber.NO_SUPPORT,
- "volume_unmask() not supported. It requires one of these "
- "1. support of DeleteMaskingView(). 2. allowing empty "
- "DeviceMaskingGroup in SPC. But target SMI-S provider "
- "does not support any of these")
-
- cim_vol_path = smis_vol.lsm_vol_to_cim_vol_path(self._c, volume)
- vol_cim_spcs_path = self._c.AssociatorNames(
- cim_vol_path,
- AssocClass='CIM_ProtocolControllerForUnit',
- ResultClass='CIM_SCSIProtocolController')
-
- if len(vol_cim_spcs_path) == 0:
- # Already unmasked
- raise LsmError(
- ErrorNumber.NO_STATE_CHANGE,
- "Volume is not masked to requested access group")
-
- cim_init_mg_path = smis_ag.lsm_ag_to_cim_init_mg_path(
- self._c, access_group)
- ag_cim_spcs_path = self._c.AssociatorNames(
- cim_init_mg_path,
- AssocClass='CIM_AssociatedInitiatorMaskingGroup',
- ResultClass='CIM_SCSIProtocolController')
-
- found_cim_spc_path = None
- for ag_cim_spc_path in ag_cim_spcs_path:
- for vol_cim_spc_path in vol_cim_spcs_path:
- if vol_cim_spc_path == ag_cim_spc_path:
- found_cim_spc_path = vol_cim_spc_path
- break
-
- if found_cim_spc_path is None:
- # Already unmasked
- raise LsmError(
- ErrorNumber.NO_STATE_CHANGE,
- "Volume is not masked to requested access group")
-
- # SNIA require each cim_spc only have one cim_dev_mg associated.
- cim_dev_mg_path = self._c.AssociatorNames(
- found_cim_spc_path,
- AssocClass='CIM_AssociatedDeviceMaskingGroup',
- ResultClass='CIM_DeviceMaskingGroup')[0]
-
- cim_gmms = self._c.cim_gmms_of_sys_id(volume.system_id)
-
- if flag_empty_dev_in_spc is False:
- # We have to check whether this volume is the last
- # one in the DeviceMaskingGroup, if so, we have to
- # delete the SPC
- cur_cim_vols_path = self._c.AssociatorNames(
- cim_dev_mg_path,
- AssocClass='CIM_OrderedMemberOfCollection',
- ResultClass='CIM_StorageVolume')
- if len(cur_cim_vols_path) == 1:
- # last volume, should delete SPC
- in_params = {
- 'ProtocolController': found_cim_spc_path,
- }
- self._c.invoke_method_wait(
- 'DeleteMaskingView', cim_gmms.path, in_params)
-
- in_params = {
- 'MaskingGroup': cim_dev_mg_path,
- 'Members': [cim_vol_path],
- }
- self._c.invoke_method_wait(
- 'RemoveMembers', cim_gmms.path, in_params)
-
- return None
-
- @handle_cim_errors
- def volume_unmask(self, access_group, volume, flags=0):
- mask_type = smis_cap.mask_type(self._c, raise_error=True)
- # Workaround for EMC VNX/CX
- if mask_type == smis_cap.MASK_TYPE_GROUP:
- cim_sys = smis_sys.cim_sys_of_sys_id(self._c, volume.system_id)
- if cim_sys.path.classname == 'Clar_StorageSystem':
- mask_type = smis_cap.MASK_TYPE_MASK
-
- if mask_type == smis_cap.MASK_TYPE_GROUP:
- return self._volume_unmask_group(access_group, volume)
- return self._volume_unmask_old(access_group, volume)
-
- def _volume_unmask_old(self, access_group, volume):
- cim_ccs = self._c.cim_ccs_of_sys_id(volume.system_id)
- cim_spc_path = smis_ag.lsm_ag_to_cim_spc_path(self._c, access_group)
-
- # Pre-check: not masked
- cim_vol = self._cim_vol_masked_to_spc(
- cim_spc_path, volume.id, ['Name'])
-
- if cim_vol is None:
- raise LsmError(
- ErrorNumber.NO_STATE_CHANGE,
- "Volume is not masked to requested access group")
-
- hide_params = {'LUNames': [cim_vol['Name']],
- 'ProtocolControllers': [cim_spc_path]}
-
- self._c.invoke_method_wait('HidePaths', cim_ccs.path, hide_params)
- return None
-
- def _is_access_group(self, cim_spc):
- if self._c.is_netappe():
- return True
-
- rc = True
- _SMIS_EMC_ADAPTER_ROLE_MASKING = 'MASK_VIEW'
-
- if 'EMCAdapterRole' in cim_spc:
- # Currently SNIA does not define LUN mapping.
- # EMC is using their specific way for LUN mapping which
- # expose their frontend ports as a SPC(SCSIProtocolController).
- # which we shall filter out.
- emc_adp_roles = cim_spc['EMCAdapterRole'].split(' ')
- if _SMIS_EMC_ADAPTER_ROLE_MASKING not in emc_adp_roles:
- rc = False
- return rc
-
- def _cim_spc_of(self, system_id, property_list=None):
- """
- Return a list of CIM_SCSIProtocolController.
- Following SNIA SMIS 'Masking and Mapping Profile':
- CIM_ControllerConfigurationService
- |
- | CIM_ConcreteDependency
- v
- CIM_SCSIProtocolController
- """
- cim_ccs = None
- rc_cim_spcs = []
-
- if property_list is None:
- property_list = []
-
- try:
- cim_ccs = self._c.cim_ccs_of_sys_id(system_id, raise_error=False)
- except CIMError as ce:
- error_code = tuple(ce)[0]
- if error_code == pywbem.CIM_ERR_INVALID_CLASS or \
- error_code == pywbem.CIM_ERR_INVALID_PARAMETER:
- raise LsmError(ErrorNumber.NO_SUPPORT,
- 'AccessGroup is not supported ' +
- 'by this array')
- if cim_ccs is None:
- raise LsmError(ErrorNumber.NO_SUPPORT,
- 'AccessGroup is not supported by this array')
-
- cim_spcs = self._c.Associators(
- cim_ccs.path,
- AssocClass='CIM_ConcreteDependency',
- ResultClass='CIM_SCSIProtocolController',
- PropertyList=property_list)
- for cim_spc in cim_spcs:
- if self._is_access_group(cim_spc):
- rc_cim_spcs.append(cim_spc)
- return rc_cim_spcs
-
- @handle_cim_errors
- def volumes_accessible_by_access_group(self, access_group, flags=0):
- mask_type = smis_cap.mask_type(self._c, raise_error=True)
- cim_vols = []
- cim_vol_pros = smis_vol.cim_vol_pros()
-
- # Workaround for EMC VNX/CX
- if mask_type == smis_cap.MASK_TYPE_GROUP:
- cim_sys = smis_sys.cim_sys_of_sys_id(
- self._c, access_group.system_id)
- if cim_sys.path.classname == 'Clar_StorageSystem':
- mask_type = smis_cap.MASK_TYPE_MASK
-
- if mask_type == smis_cap.MASK_TYPE_GROUP:
- cim_init_mg_path = smis_ag.lsm_ag_to_cim_init_mg_path(
- self._c, access_group)
-
- cim_spcs_path = self._c.AssociatorNames(
- cim_init_mg_path,
- AssocClass='CIM_AssociatedInitiatorMaskingGroup',
- ResultClass='CIM_SCSIProtocolController')
-
- for cim_spc_path in cim_spcs_path:
- cim_vols.extend(
- smis_ag.cim_vols_masked_to_cim_spc_path(
- self._c, cim_spc_path, cim_vol_pros))
- else:
- cim_spc_path = smis_ag.lsm_ag_to_cim_spc_path(
- self._c, access_group)
- cim_vols = smis_ag.cim_vols_masked_to_cim_spc_path(
- self._c, cim_spc_path, cim_vol_pros)
- rc = []
- for cim_vol in cim_vols:
- pool_id = smis_pool.pool_id_of_cim_vol(self._c, cim_vol.path)
- sys_id = smis_sys.sys_id_of_cim_vol(cim_vol)
- rc.append(
- smis_vol.cim_vol_to_lsm_vol(cim_vol, pool_id, sys_id))
- return rc
-
- @handle_cim_errors
- def access_groups_granted_to_volume(self, volume, flags=0):
- rc = []
- mask_type = smis_cap.mask_type(self._c, raise_error=True)
- cim_vol_path = smis_vol.lsm_vol_to_cim_vol_path(self._c, volume)
-
- # Workaround for EMC VNX/CX
- if mask_type == smis_cap.MASK_TYPE_GROUP:
- cim_sys = smis_sys.cim_sys_of_sys_id(self._c, volume.system_id)
- if cim_sys.path.classname == 'Clar_StorageSystem':
- mask_type = smis_cap.MASK_TYPE_MASK
-
- cim_spc_pros = None
- if mask_type == smis_cap.MASK_TYPE_GROUP:
- cim_spc_pros = []
- else:
- cim_spc_pros = smis_ag.cim_spc_pros()
-
- cim_spcs = self._c.Associators(
- cim_vol_path,
- AssocClass='CIM_ProtocolControllerForUnit',
- ResultClass='CIM_SCSIProtocolController',
- PropertyList=cim_spc_pros)
-
- if mask_type == smis_cap.MASK_TYPE_GROUP:
- cim_init_mg_pros = smis_ag.cim_init_mg_pros()
- for cim_spc in cim_spcs:
- cim_init_mgs = self._c.Associators(
- cim_spc.path,
- AssocClass='CIM_AssociatedInitiatorMaskingGroup',
- ResultClass='CIM_InitiatorMaskingGroup',
- PropertyList=cim_init_mg_pros)
- rc.extend(
- list(
- smis_ag.cim_init_mg_to_lsm_ag(
- self._c, x, volume.system_id)
- for x in cim_init_mgs))
- else:
- for cim_spc in cim_spcs:
- if self._is_access_group(cim_spc):
- rc.append(
- smis_ag.cim_spc_to_lsm_ag(
- self._c, cim_spc, volume.system_id))
-
- return rc
-
- def _cim_init_mg_of(self, system_id, property_list=None):
- """
- We use this association to get all CIM_InitiatorMaskingGroup:
- CIM_GroupMaskingMappingService
- |
- | CIM_ServiceAffectsElement
- v
- CIM_InitiatorMaskingGroup
- """
- if property_list is None:
- property_list = []
-
- cim_gmms = self._c.cim_gmms_of_sys_id(system_id)
-
- return self._c.Associators(
- cim_gmms.path,
- AssocClass='CIM_ServiceAffectsElement',
- ResultClass='CIM_InitiatorMaskingGroup',
- PropertyList=property_list)
-
- @handle_cim_errors
- def access_groups(self, search_key=None, search_value=None, flags=0):
- rc = []
- mask_type = smis_cap.mask_type(self._c, raise_error=True)
-
- cim_sys_pros = smis_sys.cim_sys_id_pros()
- cim_syss = smis_sys.root_cim_sys(self._c, cim_sys_pros)
-
- cim_spc_pros = smis_ag.cim_spc_pros()
- for cim_sys in cim_syss:
- if cim_sys.path.classname == 'Clar_StorageSystem':
- # Workaround for EMC VNX/CX.
- # Even they claim support of Group M&M via
- # CIM_RegisteredProfile, but actually they don't support it.
- mask_type = smis_cap.MASK_TYPE_MASK
-
- system_id = smis_sys.sys_id_of_cim_sys(cim_sys)
- if mask_type == smis_cap.MASK_TYPE_GROUP:
- cim_init_mg_pros = smis_ag.cim_init_mg_pros()
- cim_init_mgs = self._cim_init_mg_of(
- system_id, cim_init_mg_pros)
- rc.extend(
- list(
- smis_ag.cim_init_mg_to_lsm_ag(self._c, x, system_id)
- for x in cim_init_mgs))
- elif mask_type == smis_cap.MASK_TYPE_MASK:
- cim_spcs = self._cim_spc_of(system_id, cim_spc_pros)
- rc.extend(
- list(
- smis_ag.cim_spc_to_lsm_ag(self._c, cim_spc, system_id)
- for cim_spc in cim_spcs))
- else:
- raise LsmError(ErrorNumber.PLUGIN_BUG,
- "_get_cim_spc_by_id(): Got invalid mask_type: "
- "%s" % mask_type)
-
- return search_property(rc, search_key, search_value)
-
- def _ag_init_add_group(self, access_group, init_id, init_type):
- cim_sys = smis_sys.cim_sys_of_sys_id(self._c, access_group.system_id)
-
- if cim_sys.path.classname == 'Clar_StorageSystem':
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "EMC VNX/CX require WWNN defined when adding a "
- "new initiator which is not supported by LSM yet. "
- "Please do it via EMC vendor specific tools.")
-
- cim_init_mg_path = smis_ag.lsm_ag_to_cim_init_mg_path(
- self._c, access_group)
-
- exist_cim_inits = smis_ag.cim_init_of_cim_init_mg_path(
- self._c, cim_init_mg_path)
-
- # Check whether already added.
- for exist_cim_init in exist_cim_inits:
- if smis_ag.init_id_of_cim_init(exist_cim_init) == init_id:
- return copy.deepcopy(access_group)
-
- cim_init_path = smis_ag.cim_init_path_check_or_create(
- self._c, access_group.system_id, init_id, init_type)
-
- cim_gmms = self._c.cim_gmms_of_sys_id(access_group.system_id)
-
- in_params = {
- 'MaskingGroup': cim_init_mg_path,
- 'Members': [cim_init_path],
- }
-
- new_cim_init_mg_path = self._c.invoke_method_wait(
- 'AddMembers', cim_gmms.path, in_params,
- out_key='MaskingGroup', expect_class='CIM_InitiatorMaskingGroup')
- cim_init_mg_pros = smis_ag.cim_init_mg_pros()
- new_cim_init_mg = self._c.GetInstance(
- new_cim_init_mg_path, PropertyList=cim_init_mg_pros,
- LocalOnly=False)
- return smis_ag.cim_init_mg_to_lsm_ag(
- self._c, new_cim_init_mg, access_group.system_id)
-
- @handle_cim_errors
- def access_group_initiator_add(self, access_group, init_id, init_type,
- flags=0):
- init_id = smis_ag.lsm_init_id_to_snia(init_id)
- mask_type = smis_cap.mask_type(self._c, raise_error=True)
-
- if mask_type == smis_cap.MASK_TYPE_GROUP:
- return self._ag_init_add_group(access_group, init_id, init_type)
- else:
- return self._ag_init_add_old(access_group, init_id, init_type)
-
- def _ag_init_add_old(self, access_group, init_id, init_type):
- # CIM_StorageHardwareIDManagementService.CreateStorageHardwareID()
- # is mandatory since 1.4rev6
- cim_sys = smis_sys.cim_sys_of_sys_id(self._c, access_group.system_id)
-
- if cim_sys.path.classname == 'Clar_StorageSystem':
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "EMC VNX/CX require WWNN defined when adding "
- "new initiator which is not supported by LSM yet. "
- "Please do it via EMC vendor specific tools. "
- "EMC VNX does not support adding iSCSI IQN neither")
-
- cim_spc_path = smis_ag.lsm_ag_to_cim_spc_path(
- self._c, access_group)
-
- exist_cim_inits = smis_ag.cim_init_of_cim_spc_path(
- self._c, cim_spc_path)
-
- for exist_cim_init in exist_cim_inits:
- if smis_ag.init_id_of_cim_init(exist_cim_init) == init_id:
- return copy.deepcopy(access_group)
-
- # Check to see if we have this initiator already, if not we
- # create it and then add to the view.
-
- smis_ag.cim_init_path_check_or_create(
- self._c, access_group.system_id, init_id, init_type)
-
- cim_ccs = self._c.cim_ccs_of_sys_id(access_group.system_id)
-
- in_params = {'InitiatorPortIDs': [init_id],
- 'ProtocolControllers': [cim_spc_path]}
-
- cim_spc_path = self._c.invoke_method_wait(
- 'ExposePaths', cim_ccs.path, in_params,
- out_key='ProtocolControllers', flag_out_array=True,
- expect_class='CIM_SCSIProtocolController')
-
- cim_spc_pros = smis_ag.cim_spc_pros()
- cim_spc = self._c.GetInstance(
- cim_spc_path, PropertyList=cim_spc_pros, LocalOnly=False)
- return smis_ag.cim_spc_to_lsm_ag(
- self._c, cim_spc, access_group.system_id)
-
- def _ag_init_del_group(self, access_group, init_id):
- """
- Call CIM_GroupMaskingMappingService.RemoveMembers() against
- CIM_InitiatorMaskingGroup.
- """
- cim_init_mg_path = smis_ag.lsm_ag_to_cim_init_mg_path(
- self._c, access_group)
- cur_cim_inits = smis_ag.cim_init_of_cim_init_mg_path(
- self._c, cim_init_mg_path)
-
- cim_init = None
- for cur_cim_init in cur_cim_inits:
- if smis_ag.init_id_of_cim_init(cur_cim_init) == init_id:
- cim_init = cur_cim_init
- break
-
- if cim_init is None:
- raise LsmError(ErrorNumber.NO_STATE_CHANGE,
- "Initiator %s does not exist in defined "
- "access group %s" %
- (init_id, access_group.id))
-
- if len(cur_cim_inits) == 1:
- raise LsmError(ErrorNumber.LAST_INIT_IN_ACCESS_GROUP,
- "Refuse to remove last initiator from access group")
-
- cim_gmms = self._c.cim_gmms_of_sys_id(access_group.system_id)
-
- # RemoveMembers from InitiatorMaskingGroup
- in_params = {
- 'MaskingGroup': cim_init_mg_path,
- 'Members': [cim_init.path],
- }
-
- self._c.invoke_method_wait('RemoveMembers', cim_gmms.path, in_params)
-
- cim_init_mg_pros = smis_ag.cim_init_mg_pros()
- cim_init_mg = self._c.GetInstance(
- cim_init_mg_path, PropertyList=cim_init_mg_pros)
-
- return smis_ag.cim_init_mg_to_lsm_ag(
- self._c, cim_init_mg, access_group.system_id)
-
- @handle_cim_errors
- def access_group_initiator_delete(self, access_group, init_id, init_type,
- flags=0):
- if self._c.is_netappe():
- # When using HidePaths to remove initiator, the whole SPC will be
- # removed. Before we find a workaround for this, I would like to
- # have this method disabled as NO_SUPPORT.
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "SMI-S plugin does not support "
- "access_group_initiator_delete() against NetApp-E")
- init_id = smis_ag.lsm_init_id_to_snia(init_id)
- mask_type = smis_cap.mask_type(self._c, raise_error=True)
-
- if mask_type == smis_cap.MASK_TYPE_GROUP:
- return self._ag_init_del_group(access_group, init_id)
- else:
- return self._ag_init_del_old(access_group, init_id)
-
- def _ag_init_del_old(self, access_group, init_id):
- cim_spc_path = smis_ag.lsm_ag_to_cim_spc_path(self._c, access_group)
-
- cim_ccs = self._c.cim_ccs_of_sys_id(access_group.system_id)
-
- hide_params = {'InitiatorPortIDs': [init_id],
- 'ProtocolControllers': [cim_spc_path]}
- self._c.invoke_method_wait('HidePaths', cim_ccs.path, hide_params)
-
- return None
-
- @handle_cim_errors
- def job_free(self, job_id, flags=0):
- """
- Frees the resources given a job number.
- """
- cim_job = self._c.cim_job_of_job_id(job_id, ['DeleteOnCompletion'])
-
- # See if we should delete the job
- if not cim_job['DeleteOnCompletion']:
- try:
- self._c.DeleteInstance(cim_job.path)
- except CIMError:
- pass
-
- @handle_cim_errors
- def disks(self, search_key=None, search_value=None, flags=0):
- """
- return all object of data.Disk.
- We are using "Disk Drive Lite Subprofile" v1.4 of SNIA SMI-S for these
- classes to create LSM Disk:
- CIM_DiskDrive
- CIM_StorageExtent (Primordial)
- Due to 'Multiple Computer System' profile, disks might associated to
- sub ComputerSystem. To improve performance of listing disks, we will
- use EnumerateInstances(). Which means we have to filter the results
- by ourselves in case URI contain 'system=xxx'.
- """
- rc = []
- self._c.profile_check(SmisCommon.SNIA_DISK_LITE_PROFILE,
- SmisCommon.SMIS_SPEC_VER_1_4,
- raise_error=True)
- cim_disk_pros = smis_disk.cim_disk_pros()
- cim_disks = self._c.EnumerateInstances(
- 'CIM_DiskDrive', PropertyList=cim_disk_pros)
- for cim_disk in cim_disks:
- if self._c.system_list and \
- smis_disk.sys_id_of_cim_disk(cim_disk) not in \
- self._c.system_list:
- continue
-
- rc.extend([smis_disk.cim_disk_to_lsm_disk(self._c, cim_disk)])
- return search_property(rc, search_key, search_value)
-
- @staticmethod
- def _is_frontend_fc_tgt(cim_fc_tgt):
- """
- Check CIM_FCPort['UsageRestriction'] for frontend port.
- """
- dmtf_usage = cim_fc_tgt['UsageRestriction']
- if dmtf_usage == dmtf.TGT_PORT_USAGE_FRONTEND_ONLY or \
- dmtf_usage == dmtf.TGT_PORT_USAGE_UNRESTRICTED:
- return True
- return False
-
- def _cim_fc_tgt_of(self, cim_sys_path, property_list=None):
- """
- Get all CIM_FCPort (frontend only) from CIM_ComputerSystem and its
- leaf CIM_ComputerSystem
- """
- rc = []
- if property_list is None:
- property_list = ['UsageRestriction']
- else:
- property_list = merge_list(property_list, ['UsageRestriction'])
- all_cim_syss_path = [cim_sys_path]
- if smis_cap.multi_sys_is_supported(self._c):
- all_cim_syss_path.extend(
- self._leaf_cim_syss_path_of(cim_sys_path))
- for cur_cim_sys_path in all_cim_syss_path:
- cur_cim_fc_tgts = self._c.Associators(
- cur_cim_sys_path,
- AssocClass='CIM_SystemDevice',
- ResultClass='CIM_FCPort',
- PropertyList=property_list)
- for cim_fc_tgt in cur_cim_fc_tgts:
- if Smis._is_frontend_fc_tgt(cim_fc_tgt):
- rc.extend([cim_fc_tgt])
- return rc
-
- @staticmethod
- def _cim_fc_tgt_to_lsm(cim_fc_tgt, system_id):
- """
- Convert CIM_FCPort to Lsm.TargetPort
- """
- port_id = md5(cim_fc_tgt['DeviceID'])
- port_type = _lsm_tgt_port_type_of_cim_fc_tgt(cim_fc_tgt)
- # SNIA define WWPN string as upper, no splitter, 16 digits.
- # No need to check.
- wwpn = hex_string_format(cim_fc_tgt['PermanentAddress'], 16, 2)
- port_name = cim_fc_tgt['ElementName']
- plugin_data = None
- return TargetPort(port_id, port_type, wwpn, wwpn, wwpn, port_name,
- system_id, plugin_data)
-
- def _iscsi_node_name_of(self, cim_iscsi_pg_path):
- """
- CIM_iSCSIProtocolEndpoint
- |
- |
- v
- CIM_SAPAvailableForElement
- |
- |
- v
- CIM_SCSIProtocolController # iSCSI Node
-
- """
- cim_spcs = self._c.Associators(
- cim_iscsi_pg_path,
- ResultClass='CIM_SCSIProtocolController',
- AssocClass='CIM_SAPAvailableForElement',
- PropertyList=['Name', 'NameFormat'])
- cim_iscsi_nodes = []
- for cim_spc in cim_spcs:
- if cim_spc.classname == 'Clar_MappingSCSIProtocolController':
- # EMC has vendor specific class which contain identical
- # properties of SPC for iSCSI node.
- continue
- if cim_spc['NameFormat'] == dmtf.SPC_NAME_FORMAT_ISCSI:
- cim_iscsi_nodes.extend([cim_spc])
-
- if len(cim_iscsi_nodes) == 0:
- raise LsmError(ErrorNumber.PLUGIN_BUG,
- "_iscsi_node_of(): No iSCSI node "
- "CIM_SCSIProtocolController associated to %s"
- % cim_iscsi_pg_path)
- if len(cim_iscsi_nodes) > 1:
- raise LsmError(ErrorNumber.PLUGIN_BUG,
- "_iscsi_node_of(): Got two or more iSCSI node "
- "CIM_SCSIProtocolController associated to %s: %s"
- % (cim_iscsi_pg_path, cim_iscsi_nodes))
- return cim_iscsi_nodes[0]['Name']
-
- def _cim_iscsi_pg_of(self, cim_sys_path, property_list=None):
- """
- Get all CIM_iSCSIProtocolEndpoint(Target only) from CIM_ComputerSystem
- and its leaf CIM_ComputerSystem
- """
- rc = []
- if property_list is None:
- property_list = ['Role']
- else:
- property_list = merge_list(property_list, ['Role'])
- all_cim_syss_path = [cim_sys_path]
- if smis_cap.multi_sys_is_supported(self._c):
- all_cim_syss_path.extend(
- self._leaf_cim_syss_path_of(cim_sys_path))
- for cur_cim_sys_path in all_cim_syss_path:
- cur_cim_iscsi_pgs = self._c.Associators(
- cur_cim_sys_path,
- AssocClass='CIM_HostedAccessPoint',
- ResultClass='CIM_iSCSIProtocolEndpoint',
- PropertyList=property_list)
- for cim_iscsi_pg in cur_cim_iscsi_pgs:
- if cim_iscsi_pg['Role'] == dmtf.ISCSI_TGT_ROLE_TARGET:
- rc.extend([cim_iscsi_pg])
- return rc
-
- def _cim_iscsi_pg_to_lsm(self, cim_iscsi_pg, system_id):
- """
- Return a list of TargetPort CIM_iSCSIProtocolEndpoint
- Associations:
- CIM_SCSIProtocolController # iSCSI Node
- ^
- | CIM_SAPAvailableForElement
- |
- CIM_iSCSIProtocolEndpoint # iSCSI Portal Group
- |
- | CIM_BindsTo
- v
- CIM_TCPProtocolEndpoint # Need TCP port, default is 3260
- |
- | CIM_BindsTo
- v
- CIM_IPProtocolEndpoint # Need IPv4 and IPv6 address
- |
- | CIM_DeviceSAPImplementation
- v
- CIM_EthernetPort # Need MAC address (Optional)
- Assuming there is storage array support iSER
- (iSCSI over RDMA of Infinity Band),
- this method is only for iSCSI over TCP.
- """
- rc = []
- port_type = TargetPort.TYPE_ISCSI
- plugin_data = None
- cim_tcps = self._c.Associators(
- cim_iscsi_pg.path,
- ResultClass='CIM_TCPProtocolEndpoint',
- AssocClass='CIM_BindsTo',
- PropertyList=['PortNumber'])
- if len(cim_tcps) == 0:
- raise LsmError(ErrorNumber.PLUGIN_BUG,
- "_cim_iscsi_pg_to_lsm(): "
- "No CIM_TCPProtocolEndpoint associated to %s"
- % cim_iscsi_pg.path)
- iscsi_node_name = self._iscsi_node_name_of(cim_iscsi_pg.path)
-
- for cim_tcp in cim_tcps:
- tcp_port = cim_tcp['PortNumber']
- cim_ips = self._c.Associators(
- cim_tcp.path,
- ResultClass='CIM_IPProtocolEndpoint',
- AssocClass='CIM_BindsTo',
- PropertyList=['IPv4Address', 'IPv6Address', 'SystemName',
- 'EMCPortNumber', 'IPv6AddressType'])
- for cim_ip in cim_ips:
- ipv4_addr = ''
- ipv6_addr = ''
- # 'IPv4Address', 'IPv6Address' are optional in SMI-S 1.4.
- if 'IPv4Address' in cim_ip and cim_ip['IPv4Address']:
- ipv4_addr = cim_ip['IPv4Address']
- if 'IPv6Address' in cim_ip and cim_ip['IPv6Address']:
- ipv6_addr = cim_ip['IPv6Address']
- # 'IPv6AddressType' is not listed in SMI-S but in DMTF CIM
- # Schema
- # Only allow IPv6 Global Unicast Address, 6to4, and Unique
- # Local Address.
- if 'IPv6AddressType' in cim_ip and cim_ip['IPv6AddressType']:
- ipv6_addr_type = cim_ip['IPv6AddressType']
- if ipv6_addr_type != dmtf.IPV6_ADDR_TYPE_GUA and \
- ipv6_addr_type != dmtf.IPV6_ADDR_TYPE_6TO4 and \
- ipv6_addr_type != dmtf.IPV6_ADDR_TYPE_ULA:
- ipv6_addr = ''
-
- # NetApp is using this kind of IPv6 address
- # 0000:0000:0000:0000:0000:0000:0a10:29d5
- # even when IPv6 is not enabled on their array.
- # It's not a legal IPv6 address anyway. No need to do
- # vendor check.
- if ipv6_addr[0:29] == '0000:0000:0000:0000:0000:0000':
- ipv6_addr = ''
-
- if ipv4_addr is None and ipv6_addr is None:
- continue
- cim_eths = self._c.Associators(
- cim_ip.path,
- ResultClass='CIM_EthernetPort',
- AssocClass='CIM_DeviceSAPImplementation',
- PropertyList=['PermanentAddress', 'ElementName'])
- nics = []
- # NetApp ONTAP cluster-mode show one IP bonded to multiple
- # ethernet,
- # Not sure it's their BUG or real ethernet channel bonding.
- # Waiting reply.
- if len(cim_eths) == 0:
- nics = [('', '')]
- else:
- for cim_eth in cim_eths:
- mac_addr = ''
- port_name = ''
- if 'PermanentAddress' in cim_eth and \
- cim_eth["PermanentAddress"]:
- mac_addr = cim_eth["PermanentAddress"]
- # 'ElementName' is optional in CIM_EthernetPort
- if 'ElementName' in cim_eth and cim_eth["ElementName"]:
- port_name = cim_eth['ElementName']
- nics.extend([(mac_addr, port_name)])
- for nic in nics:
- mac_address = nic[0]
- port_name = nic[1]
- if mac_address:
- # Convert to lsm require form
- mac_address = hex_string_format(mac_address, 12, 2)
-
- if ipv4_addr:
- network_address = "%s:%s" % (ipv4_addr, tcp_port)
- port_id = md5("%s:%s:%s" % (mac_address,
- network_address,
- iscsi_node_name))
- rc.extend(
- [TargetPort(port_id, port_type, iscsi_node_name,
- network_address, mac_address,
- port_name, system_id, plugin_data)])
- if ipv6_addr:
- # DMTF or SNIA did defined the IPv6 string format.
- # we just guess here.
- if len(ipv6_addr) == 39:
- ipv6_addr = ipv6_addr.replace(':', '')
- if len(ipv6_addr) == 32:
- ipv6_addr = hex_string_format(
- ipv6_addr, 32, 4)
-
- network_address = "[%s]:%s" % (ipv6_addr, tcp_port)
- port_id = md5("%s:%s:%s" % (mac_address,
- network_address,
- iscsi_node_name))
- rc.extend(
- [TargetPort(port_id, port_type, iscsi_node_name,
- network_address, mac_address,
- port_name, system_id, plugin_data)])
- return rc
-
- def _leaf_cim_syss_path_of(self, cim_sys_path):
- """
- Return a list of CIMInstanceName of leaf CIM_ComputerSystem
- """
- max_loop_count = 10 # There is no storage array need 10 layer of
- # Computer
- loop_counter = max_loop_count
- rc = []
- leaf_cim_syss_path = []
- try:
- leaf_cim_syss_path = self._c.AssociatorNames(
- cim_sys_path,
- ResultClass='CIM_ComputerSystem',
- AssocClass='CIM_ComponentCS',
- Role='GroupComponent',
- ResultRole='PartComponent')
- except CIMError as ce:
- error_code = tuple(ce)[0]
- if error_code == pywbem.CIM_ERR_INVALID_CLASS or \
- error_code == pywbem.CIM_ERR_NOT_SUPPORTED:
- return []
-
- if len(leaf_cim_syss_path) > 0:
- rc = leaf_cim_syss_path
- for cim_sys_path in leaf_cim_syss_path:
- rc.extend(self._leaf_cim_syss_path_of(cim_sys_path))
-
- return rc
-
- @handle_cim_errors
- def target_ports(self, search_key=None, search_value=None, flags=0):
- rc = []
-
- cim_fc_tgt_pros = ['UsageRestriction', 'ElementName', 'SystemName',
- 'PermanentAddress', 'PortDiscriminator',
- 'LinkTechnology', 'DeviceID']
-
- cim_syss = smis_sys.root_cim_sys(
- self._c, property_list=smis_sys.cim_sys_id_pros())
- for cim_sys in cim_syss:
- system_id = smis_sys.sys_id_of_cim_sys(cim_sys)
- flag_fc_support = smis_cap.fc_tgt_is_supported(self._c)
- flag_iscsi_support = smis_cap.iscsi_tgt_is_supported(self._c)
-
- # Assuming: if one system does not support target_ports(),
- # all systems from the same provider will not support
- # target_ports().
- if flag_fc_support is False and flag_iscsi_support is False:
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "Target SMI-S provider does not support any of"
- "these profiles: '%s %s', '%s %s'"
- % (SmisCommon.SMIS_SPEC_VER_1_4,
- SmisCommon.SNIA_FC_TGT_PORT_PROFILE,
- SmisCommon.SMIS_SPEC_VER_1_4,
- SmisCommon.SNIA_ISCSI_TGT_PORT_PROFILE))
-
- if flag_fc_support:
- # CIM_FCPort might be not belong to root cim_sys
- # In that case, CIM_FCPort['SystemName'] will not be
- # the name of root CIM_ComputerSystem.
- cim_fc_tgt_pros = ['UsageRestriction', 'ElementName',
- 'SystemName', 'PermanentAddress',
- 'PortDiscriminator', 'LinkTechnology',
- 'DeviceID']
- cim_fc_tgts = self._cim_fc_tgt_of(cim_sys.path,
- cim_fc_tgt_pros)
- rc.extend(
- list(
- Smis._cim_fc_tgt_to_lsm(x, system_id)
- for x in cim_fc_tgts))
-
- if flag_iscsi_support:
- cim_iscsi_pgs = self._cim_iscsi_pg_of(cim_sys.path)
- for cim_iscsi_pg in cim_iscsi_pgs:
- rc.extend(
- self._cim_iscsi_pg_to_lsm(cim_iscsi_pg, system_id))
-
- # NetApp is sharing CIM_TCPProtocolEndpoint which
- # cause duplicate TargetPort. It's a long story, they heard my
- # bug report.
- if len(cim_syss) >= 1 and \
- cim_syss[0].classname == 'ONTAP_StorageSystem':
- id_list = []
- new_rc = []
- # We keep the original list order by not using dict.values()
- for lsm_tp in rc:
- if lsm_tp.id not in id_list:
- id_list.extend([lsm_tp.id])
- new_rc.extend([lsm_tp])
- rc = new_rc
-
- return search_property(rc, search_key, search_value)
-
- def _cim_pep_path_of_fc_tgt(self, cim_fc_tgt_path):
- """
- Return CIMInstanceName of CIM_SCSIProtocolEndpoint of CIM_FCPort
- In 1.4r6, it's one-to-one map.
- """
- return self._c.AssociatorNames(
- cim_fc_tgt_path,
- AssocClass='CIM_DeviceSAPImplementation',
- ResultClass='CIM_SCSIProtocolEndpoint')[0]
-
- def _check_exist_cim_tgt_mg(self, name):
- """
- We should do more checks[1] in stead of use it directly.
- But considering EMC VMAX is the only support vendor, make it quick
- and works could be priority 1.
- We can improve this for any bug report.
-
- [1] At least check whether CIM_TargetMaskingGroup is already used
- by other SPC.
- """
- cim_tgt_mgs = self._c.EnumerateInstances(
- 'CIM_TargetMaskingGroup',
- PropertyList=['ElementName'])
- for cim_tgt_mg in cim_tgt_mgs:
- if cim_tgt_mg['ElementName'] == name:
- return cim_tgt_mg.path
-
- return None
-
- def _check_exist_cim_dev_mg(self, name, cim_gmms_path, cim_vol_path,
- vol_id):
- """
- This is buggy check, but it works on EMC VMAX which is only supported
- platform of Group Masking and Mapping.
- When found CIM_DeviceMaskingGroup, make sure cim_vol is included.
- """
- cim_dev_mgs = self._c.EnumerateInstances(
- 'CIM_DeviceMaskingGroup',
- PropertyList=['ElementName'])
- cim_dev_mg = None
- for tmp_cim_dev_mg in cim_dev_mgs:
- if tmp_cim_dev_mg['ElementName'] == name:
- cim_dev_mg = tmp_cim_dev_mg
- break
- if cim_dev_mg:
- # Check whether cim_vol included.
- cim_vol_pros = smis_vol.cim_vol_id_pros()
- cim_vols = self._c.Associators(
- cim_dev_mg.path,
- AssocClass='CIM_OrderedMemberOfCollection',
- ResultClass='CIM_StorageVolume',
- PropertyList=cim_vol_pros)
- for cim_vol in cim_vols:
- if smis_vol.vol_id_of_cim_vol(cim_vol) == vol_id:
- return cim_dev_mg.path
-
- # We should add this volume to found DeviceMaskingGroup
- in_params = {
- 'MaskingGroup': cim_dev_mg.path,
- 'Members': [cim_vol_path],
- }
- self._c.invoke_method_wait('AddMembers', cim_gmms_path, in_params)
- return cim_dev_mg.path
-
- return None
-
- @handle_cim_errors
- def access_group_create(self, name, init_id, init_type, system,
- flags=0):
- """
- Using 1.5.0 'Group Masking and Mapping' profile.
- Actually, only EMC VMAX/DMX support this now(July 2014).
- Steps:
- 0. Check exist SPC of init_id for duplication call and
- conflict.
- 1. Create CIM_InitiatorMaskingGroup
- """
- org_init_id = init_id
- init_id = smis_ag.lsm_init_id_to_snia(init_id)
-
- self._c.profile_check(SmisCommon.SNIA_GROUP_MASK_PROFILE,
- SmisCommon.SMIS_SPEC_VER_1_5,
- raise_error=True)
-
- if init_type != AccessGroup.INIT_TYPE_WWPN and \
- init_type != AccessGroup.INIT_TYPE_ISCSI_IQN:
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "SMI-S plugin only support creating FC/FCoE WWPN "
- "and iSCSI AccessGroup")
-
- cim_sys = smis_sys.cim_sys_of_sys_id(self._c, system.id)
- if cim_sys.path.classname == 'Clar_StorageSystem':
- # EMC VNX/CX does not support Group M&M, which incorrectly exposed
- # in CIM_RegisteredProfile
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "access_group_create() is not supported by "
- "EMC VNX/CX which lacks the support of SNIA 1.5+ "
- "Group Masking and Mapping profile")
-
- flag_fc_support = smis_cap.fc_tgt_is_supported(self._c)
- flag_iscsi_support = smis_cap.iscsi_tgt_is_supported(self._c)
-
- if init_type == AccessGroup.INIT_TYPE_WWPN and not flag_fc_support:
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "Target SMI-S provider does not support "
- "FC target port, which not allow creating "
- "WWPN access group")
-
- if init_type == AccessGroup.INIT_TYPE_ISCSI_IQN and \
- not flag_iscsi_support:
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "Target SMI-S provider does not support "
- "iSCSI target port, which not allow creating "
- "iSCSI IQN access group")
-
- cim_init_path = smis_ag.cim_init_path_check_or_create(
- self._c, system.id, init_id, init_type)
-
- # Create CIM_InitiatorMaskingGroup
- cim_gmms = self._c.cim_gmms_of_sys_id(system.id)
-
- in_params = {'GroupName': name,
- 'Members': [cim_init_path],
- 'Type': dmtf.MASK_GROUP_TYPE_INIT}
-
- cim_init_mg_pros = smis_ag.cim_init_mg_pros()
-
- try:
- cim_init_mg_path = self._c.invoke_method_wait(
- 'CreateGroup', cim_gmms.path, in_params,
- out_key='MaskingGroup',
- expect_class='CIM_InitiatorMaskingGroup')
- except (LsmError, CIMError):
- # Check possible failure
- # 1. Initiator already exist in other group.
- exist_cim_init_mg_paths = self._c.AssociatorNames(
- cim_init_path,
- AssocClass='CIM_MemberOfCollection',
- ResultClass='CIM_InitiatorMaskingGroup')
-
- if len(exist_cim_init_mg_paths) != 0:
- raise LsmError(ErrorNumber.EXISTS_INITIATOR,
- "Initiator %s " % org_init_id +
- "already exist in other access group")
-
- # 2. Requested name used by other group.
- exist_cim_init_mgs = self._cim_init_mg_of(
- system.id, property_list=['ElementName'])
- for exist_cim_init_mg in exist_cim_init_mgs:
- if exist_cim_init_mg['ElementName'] == name:
- raise LsmError(ErrorNumber.NAME_CONFLICT,
- "Requested name %s is used by " % name +
- "another access group")
- raise
-
- cim_init_mg = self._c.GetInstance(
- cim_init_mg_path, PropertyList=cim_init_mg_pros)
- return smis_ag.cim_init_mg_to_lsm_ag(self._c, cim_init_mg, system.id)
-
- @handle_cim_errors
- def access_group_delete(self, access_group, flags=0):
- self._c.profile_check(
- SmisCommon.SNIA_GROUP_MASK_PROFILE, SmisCommon.SMIS_SPEC_VER_1_5,
- raise_error=True)
-
- cim_init_mg_path = smis_ag.lsm_ag_to_cim_init_mg_path(
- self._c, access_group)
-
- # Check whether still have volume masked.
- cim_spcs_path = self._c.AssociatorNames(
- cim_init_mg_path,
- AssocClass='CIM_AssociatedInitiatorMaskingGroup',
- ResultClass='CIM_SCSIProtocolController')
-
- for cim_spc_path in cim_spcs_path:
- if len(self._c.AssociatorNames(
- cim_spc_path,
- AssocClass='CIM_ProtocolControllerForUnit',
- ResultClass='CIM_StorageVolume')) >= 1:
- raise LsmError(ErrorNumber.IS_MASKED,
- "Access Group %s has volume masked" %
- access_group.id)
-
- cim_gmms = self._c.cim_gmms_of_sys_id(access_group.system_id)
-
- in_params = {
- 'MaskingGroup': cim_init_mg_path,
- 'Force': True,
- }
-
- self._c.invoke_method_wait('DeleteGroup', cim_gmms.path, in_params)
- return None
diff --git a/plugin/smispy/smis_ag.py b/plugin/smispy/smis_ag.py
deleted file mode 100644
index 5ac1d20..0000000
--- a/plugin/smispy/smis_ag.py
+++ /dev/null
@@ -1,285 +0,0 @@
-## 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: Gris Ge <***@redhat.com>
-
-"""
-This module intend to provide independent methods for lsm.AccessGroup and
-volume masking/unmasking.
-"""
-
-from pywbem import CIMError, CIM_ERR_NOT_FOUND
-
-from lsm import AccessGroup, md5, LsmError, ErrorNumber
-
-from lsm.plugin.smispy.smis_common import SmisCommon
-from lsm.plugin.smispy import dmtf
-from lsm.plugin.smispy.utils import cim_path_to_path_str, path_str_to_cim_path
-
-_CIM_INIT_PROS = ['StorageID', 'IDType']
-
-
-def _init_id_and_type_of(cim_inits):
- """
- Retrieve AccessGroup.init_ids and AccessGroup.init_type from
- a list of CIM_StorageHardwareID.
- """
- init_ids = []
- init_type = AccessGroup.INIT_TYPE_UNKNOWN
- init_types = []
- for cim_init in cim_inits:
- if cim_init['IDType'] == dmtf.ID_TYPE_WWPN:
- init_ids.append(init_id_of_cim_init(cim_init))
- init_types.append(AccessGroup.INIT_TYPE_WWPN)
- if cim_init['IDType'] == dmtf.ID_TYPE_ISCSI:
- init_ids.append(init_id_of_cim_init(cim_init))
- init_types.append(AccessGroup.INIT_TYPE_ISCSI_IQN)
- # Skip if not a iscsi initiator IQN or WWPN.
- continue
-
- init_type_dict = {}
- for cur_init_type in init_types:
- init_type_dict[cur_init_type] = 1
-
- if len(init_type_dict) == 1:
- init_type = init_types[0]
- elif len(init_type_dict) == 2:
- init_type = AccessGroup.INIT_TYPE_ISCSI_WWPN_MIXED
- return (init_ids, init_type)
-
-
-def cim_spc_pros():
- """
- Return the property of CIM_SCSIProtocolController required to generate
- lsm.AccessGroup
- 'EMCAdapterRole' is for EMC VNX only.
- """
- return ['DeviceID', 'ElementName', 'StorageID', 'EMCAdapterRole',
- 'SystemName']
-
-
-def cim_init_mg_pros():
- """
- Return the property of CIM_InitiatorMaskingGroup required to generate
- lsm.AccessGroup
- """
- return ['ElementName', 'InstanceID']
-
-
-def cim_init_of_cim_spc_path(smis_common, cim_spc_path):
- """
- Return a list of CIM_StorageHardwareID associated to cim_spc.
- Only contain ['StorageID', 'IDType'] property.
- Two ways to get StorageHardwareID from SCSIProtocolController:
- * Method A (defined in SNIA SMIS 1.6):
- CIM_SCSIProtocolController
- |
- | CIM_AssociatedPrivilege
- v
- CIM_StorageHardwareID
-
- * Method B (defined in SNIA SMIS 1.3, 1.4, 1.5 and 1.6):
- CIM_SCSIProtocolController
- |
- | CIM_AuthorizedTarget
- v
- CIM_AuthorizedPrivilege
- |
- | CIM_AuthorizedSubject
- v
- CIM_StorageHardwareID
- """
- cim_inits = []
- if smis_common.profile_check(SmisCommon.SNIA_MASK_PROFILE,
- SmisCommon.SMIS_SPEC_VER_1_6,
- raise_error=False):
- try:
- cim_inits = smis_common.Associators(
- cim_spc_path,
- AssocClass='CIM_AssociatedPrivilege',
- ResultClass='CIM_StorageHardwareID',
- PropertyList=_CIM_INIT_PROS)
- except CIMError as cim_error:
- if cim_error[0] == CIM_ERR_NOT_FOUND:
- pass
- else:
- raise
-
- if len(cim_inits) == 0:
- cim_aps_path = smis_common.AssociatorNames(
- cim_spc_path,
- AssocClass='CIM_AuthorizedTarget',
- ResultClass='CIM_AuthorizedPrivilege')
-
- for cim_ap_path in cim_aps_path:
- cim_inits.extend(smis_common.Associators(
- cim_ap_path,
- AssocClass='CIM_AuthorizedSubject',
- ResultClass='CIM_StorageHardwareID',
- PropertyList=_CIM_INIT_PROS))
- return cim_inits
-
-
-def cim_spc_to_lsm_ag(smis_common, cim_spc, system_id):
- """
- Convert CIM_SCSIProtocolController to lsm.AccessGroup
- """
- ag_id = md5(cim_spc['DeviceID'])
- ag_name = cim_spc['ElementName']
- cim_inits = cim_init_of_cim_spc_path(smis_common, cim_spc.path)
- (init_ids, init_type) = _init_id_and_type_of(cim_inits)
- plugin_data = cim_path_to_path_str(cim_spc.path)
- return AccessGroup(
- ag_id, ag_name, init_ids, init_type, system_id, plugin_data)
-
-
-def cim_init_of_cim_init_mg_path(smis_common, cim_init_mg_path):
- """
- Use this association to get a list of CIM_StorageHardwareID:
- CIM_InitiatorMaskingGroup
- |
- | CIM_MemberOfCollection
- v
- CIM_StorageHardwareID
- Only contain ['StorageID', 'IDType'] property.
- """
- return smis_common.Associators(
- cim_init_mg_path,
- AssocClass='CIM_MemberOfCollection',
- ResultClass='CIM_StorageHardwareID',
- PropertyList=_CIM_INIT_PROS)
-
-
-def cim_init_mg_to_lsm_ag(smis_common, cim_init_mg, system_id):
- """
- Convert CIM_InitiatorMaskingGroup to lsm.AccessGroup
- """
- ag_name = cim_init_mg['ElementName']
- ag_id = md5(cim_init_mg['InstanceID'])
- cim_inits = cim_init_of_cim_init_mg_path(smis_common, cim_init_mg.path)
- (init_ids, init_type) = _init_id_and_type_of(cim_inits)
- plugin_data = cim_path_to_path_str(cim_init_mg.path)
- return AccessGroup(
- ag_id, ag_name, init_ids, init_type, system_id, plugin_data)
-
-
-def lsm_ag_to_cim_spc_path(smis_common, lsm_ag):
- """
- Convert lsm.AccessGroup to CIMInstanceName of CIM_SCSIProtocolController
- using lsm.AccessGroup.plugin_data.
- This method does not check whether plugin_data is cim_spc or cim_init_mg,
- caller should make sure that.
- """
- if not lsm_ag.plugin_data:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "Got lsm.AccessGroup instance with empty plugin_data")
- if smis_common.system_list and \
- lsm_ag.system_id not in smis_common.system_list:
- raise LsmError(
- ErrorNumber.NOT_FOUND_SYSTEM,
- "System filtered in URI")
-
- return path_str_to_cim_path(lsm_ag.plugin_data)
-
-
-def lsm_ag_to_cim_init_mg_path(smis_common, lsm_ag):
- """
- Convert lsm.AccessGroup to CIMInstanceName of CIM_InitiatorMaskingGroup
- using lsm.AccessGroup.plugin_data.
- This method does not check whether plugin_data is cim_spc or cim_init_mg,
- caller should make sure that.
- """
- return lsm_ag_to_cim_spc_path(smis_common, lsm_ag)
-
-
-def init_id_of_cim_init(cim_init):
- """
- Return CIM_StorageHardwareID['StorageID']
- """
- if 'StorageID' in cim_init:
- return cim_init['StorageID']
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "init_id_of_cim_init() got cim_init without 'StorageID' %s: %s" %
- (cim_init.path, cim_init.items()))
-
-
-def lsm_init_id_to_snia(lsm_init_id):
- """
- If lsm_init_id is a WWPN, convert it to SNIA format:
- [0-9A-F]{16}
- If not, return original directly.
- """
- val, init_type, init_id = AccessGroup.initiator_id_verify(lsm_init_id)
- if val and init_type == AccessGroup.INIT_TYPE_WWPN:
- return lsm_init_id.replace(':', '').upper()
- return lsm_init_id
-
-
-def cim_init_path_check_or_create(smis_common, system_id, init_id, init_type):
- """
- Check whether CIM_StorageHardwareID exists, if not, create new one.
- """
- cim_inits = smis_common.EnumerateInstances(
- 'CIM_StorageHardwareID',
- PropertyList=_CIM_INIT_PROS)
-
- if len(cim_inits):
- for cim_init in cim_inits:
- if init_id_of_cim_init(cim_init) == init_id:
- return cim_init.path
-
- # Create new one
- dmtf_id_type = None
- if init_type == AccessGroup.INIT_TYPE_WWPN:
- dmtf_id_type = dmtf.ID_TYPE_WWPN
- elif init_type == AccessGroup.INIT_TYPE_ISCSI_IQN:
- dmtf_id_type = dmtf.ID_TYPE_ISCSI
- else:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "cim_init_path_check_or_create(): Got invalid init_type: %d" %
- init_type)
-
- cim_hwms = smis_common.cim_hwms_of_sys_id(system_id)
- in_params = {
- 'StorageID': init_id,
- 'IDType': dmtf_id_type,
- }
- return smis_common.invoke_method_wait(
- 'CreateStorageHardwareID', cim_hwms.path, in_params,
- out_key='HardwareID', expect_class='CIM_StorageHardwareID')
-
-
-def cim_vols_masked_to_cim_spc_path(smis_common, cim_spc_path,
- property_list=None):
- """
- Use this association to find out masked volume for certain cim_spc:
- CIM_SCSIProtocolController
- |
- | CIM_ProtocolControllerForUnit
- v
- CIM_StorageVolume
- Return a list of CIMInstance
- """
- if property_list is None:
- property_list = []
-
- return smis_common.Associators(
- cim_spc_path,
- AssocClass='CIM_ProtocolControllerForUnit',
- ResultClass='CIM_StorageVolume',
- PropertyList=property_list)
diff --git a/plugin/smispy/smis_cap.py b/plugin/smispy/smis_cap.py
deleted file mode 100644
index 23a3449..0000000
--- a/plugin/smispy/smis_cap.py
+++ /dev/null
@@ -1,372 +0,0 @@
-# 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
-# USA
-
-from lsm import Capabilities, LsmError, ErrorNumber
-import dmtf
-from smis_common import SmisCommon
-
-MASK_TYPE_NO_SUPPORT = 0
-MASK_TYPE_MASK = 1
-MASK_TYPE_GROUP = 2
-
-
-def _rs_supported_capabilities(smis_common, system_id, cap):
- """
- Interrogate the supported features of the replication service
- """
- cim_rs = smis_common.cim_rs_of_sys_id(system_id, raise_error=False)
- if cim_rs:
- rs_cap = smis_common.Associators(
- cim_rs.path,
- AssocClass='CIM_ElementCapabilities',
- ResultClass='CIM_ReplicationServiceCapabilities',
- PropertyList=['SupportedReplicationTypes',
- 'SupportedAsynchronousActions',
- 'SupportedSynchronousActions'])[0]
-
- s_rt = rs_cap['SupportedReplicationTypes']
- async_actions = rs_cap['SupportedAsynchronousActions']
- sync_actions = rs_cap['SupportedSynchronousActions']
-
- if dmtf.REPLICA_CAP_ACTION_CREATE_ELEMENT in async_actions or \
- dmtf.REPLICA_CAP_ACTION_CREATE_ELEMENT in sync_actions:
- cap.set(Capabilities.VOLUME_REPLICATE)
- else:
- return
-
- if dmtf.REPLICA_CAP_TYPE_SYNC_SNAPSHOT_LOCAL in s_rt or \
- dmtf.REPLICA_CAP_TYPE_ASYNC_SNAPSHOT_LOCAL in s_rt:
- cap.set(Capabilities.VOLUME_REPLICATE_CLONE)
-
- if dmtf.REPLICA_CAP_TYPE_SYNC_CLONE_LOCAL in s_rt or \
- dmtf.REPLICA_CAP_TYPE_ASYNC_CLONE_LOCAL in s_rt:
- cap.set(Capabilities.VOLUME_REPLICATE_COPY)
- else:
- # Try older storage configuration service
-
- cim_scs = smis_common.cim_scs_of_sys_id(system_id, raise_error=False)
-
- if cim_scs:
- cim_sc_cap = smis_common.Associators(
- cim_scs.path,
- AssocClass='CIM_ElementCapabilities',
- ResultClass='CIM_StorageConfigurationCapabilities',
- PropertyList=['SupportedCopyTypes'])[0]
-
- if cim_sc_cap is not None and 'SupportedCopyTypes' in cim_sc_cap:
- sct = cim_sc_cap['SupportedCopyTypes']
-
- if sct and len(sct):
- cap.set(Capabilities.VOLUME_REPLICATE)
-
- if dmtf.ST_CONF_CAP_COPY_TYPE_UNSYNC_ASSOC in sct:
- cap.set(Capabilities.VOLUME_REPLICATE_CLONE)
-
- if dmtf.ST_CONF_CAP_COPY_TYPE_UNSYNC_UNASSOC in sct:
- cap.set(Capabilities.VOLUME_REPLICATE_COPY)
-
-
-def _bsp_cap_set(smis_common, system_id, cap):
- """
- Set capabilities for these methods:
- volumes()
- volume_create()
- volume_resize()
- volume_delete()
- """
- # CIM_StorageConfigurationService is optional.
- cim_scs = smis_common.cim_scs_of_sys_id(system_id, raise_error=False)
-
- if cim_scs is None:
- return
-
- # These methods are mandatory for CIM_StorageConfigurationService:
- # CreateOrModifyElementFromStoragePool()
- # ReturnToStoragePool()
- # But SNIA never defined which function of
- # CreateOrModifyElementFromStoragePool() is mandatory.
- # Hence we check CIM_StorageConfigurationCapabilities
- # which is mandatory if CIM_StorageConfigurationService is supported.
- cim_scs_cap = smis_common.Associators(
- cim_scs.path,
- AssocClass='CIM_ElementCapabilities',
- ResultClass='CIM_StorageConfigurationCapabilities',
- PropertyList=['SupportedAsynchronousActions',
- 'SupportedSynchronousActions',
- 'SupportedStorageElementTypes'])[0]
-
- element_types = cim_scs_cap['SupportedStorageElementTypes']
- sup_actions = []
-
- if 'SupportedSynchronousActions' in cim_scs_cap:
- if cim_scs_cap['SupportedSynchronousActions']:
- sup_actions.extend(cim_scs_cap['SupportedSynchronousActions'])
-
- if 'SupportedAsynchronousActions' in cim_scs_cap:
- if cim_scs_cap['SupportedAsynchronousActions']:
- sup_actions.extend(cim_scs_cap['SupportedAsynchronousActions'])
-
- if dmtf.SCS_CAP_SUP_ST_VOLUME in element_types or \
- dmtf.SCS_CAP_SUP_THIN_ST_VOLUME in element_types:
- cap.set(Capabilities.VOLUMES)
- if dmtf.SCS_CAP_SUP_THIN_ST_VOLUME in element_types:
- cap.set(Capabilities.VOLUME_THIN)
-
- if dmtf.SCS_CAP_VOLUME_CREATE in sup_actions:
- cap.set(Capabilities.VOLUME_CREATE)
-
- if dmtf.SCS_CAP_VOLUME_DELETE in sup_actions:
- cap.set(Capabilities.VOLUME_DELETE)
-
- if dmtf.SCS_CAP_VOLUME_MODIFY in sup_actions:
- cap.set(Capabilities.VOLUME_RESIZE)
-
- return
-
-
-def _disk_cap_set(smis_common, cim_sys_path, cap):
- if not smis_common.profile_check(SmisCommon.SNIA_DISK_LITE_PROFILE,
- SmisCommon.SMIS_SPEC_VER_1_4,
- raise_error=False):
- return
-
- cap.set(Capabilities.DISKS)
- return
-
-
-def _group_mask_map_cap_set(smis_common, cim_sys_path, cap):
- """
- We set caps for these methods recording to 1.5+ Group M&M profile:
- access_groups()
- access_groups_granted_to_volume()
- volumes_accessible_by_access_group()
- access_group_initiator_add()
- access_group_initiator_delete()
- volume_mask()
- volume_unmask()
- access_group_create()
- access_group_delete()
- """
- # These are mandatory in SNIA SMI-S.
- # We are not in the position of SNIA SMI-S certification.
- cap.set(Capabilities.ACCESS_GROUPS)
- cap.set(Capabilities.ACCESS_GROUPS_GRANTED_TO_VOLUME)
- cap.set(Capabilities.VOLUMES_ACCESSIBLE_BY_ACCESS_GROUP)
- cap.set(Capabilities.VOLUME_MASK)
- if fc_tgt_is_supported(smis_common):
- cap.set(Capabilities.ACCESS_GROUP_INITIATOR_ADD_WWPN)
- cap.set(Capabilities.ACCESS_GROUP_CREATE_WWPN)
- if iscsi_tgt_is_supported(smis_common):
- cap.set(Capabilities.ACCESS_GROUP_INITIATOR_ADD_ISCSI_IQN)
- cap.set(Capabilities.ACCESS_GROUP_CREATE_ISCSI_IQN)
-
- # RemoveMembers is also mandatory
- cap.set(Capabilities.ACCESS_GROUP_INITIATOR_DELETE)
-
- cim_gmm_cap_pros = [
- 'SupportedAsynchronousActions',
- 'SupportedSynchronousActions',
- 'SupportedDeviceGroupFeatures']
-
- cim_gmm_cap = smis_common.Associators(
- cim_sys_path,
- AssocClass='CIM_ElementCapabilities',
- ResultClass='CIM_GroupMaskingMappingCapabilities',
- PropertyList=cim_gmm_cap_pros)[0]
-
- # if empty dev group in spc is allowed, RemoveMembers() is enough
- # to do volume_unmask(). RemoveMembers() is mandatory.
- if dmtf.GMM_CAP_DEV_MG_ALLOW_EMPTY_W_SPC in \
- cim_gmm_cap['SupportedDeviceGroupFeatures']:
- cap.set(Capabilities.VOLUME_UNMASK)
-
- # DeleteMaskingView() is optional, this is required by volume_unmask()
- # when empty dev group in spc not allowed.
- elif ((dmtf.GMM_CAP_DELETE_SPC in
- cim_gmm_cap['SupportedSynchronousActions']) or
- (dmtf.GMM_CAP_DELETE_SPC in
- cim_gmm_cap['SupportedAsynchronousActions'])):
- cap.set(Capabilities.VOLUME_UNMASK)
-
- # DeleteGroup is optional, this is required by access_group_delete()
- if ((dmtf.GMM_CAP_DELETE_GROUP in
- cim_gmm_cap['SupportedSynchronousActions']) or
- (dmtf.GMM_CAP_DELETE_GROUP in
- cim_gmm_cap['SupportedAsynchronousActions'])):
- cap.set(Capabilities.ACCESS_GROUP_DELETE)
- return None
-
-
-def _mask_map_cap_set(smis_common, cim_sys_path, cap):
- """
- In SNIA SMI-S 1.4rev6 'Masking and Mapping' profile:
- CIM_ControllerConfigurationService is mandatory
- and it's ExposePaths() and HidePaths() are mandatory
- """
- if not smis_common.profile_check(SmisCommon.SNIA_MASK_PROFILE,
- SmisCommon.SMIS_SPEC_VER_1_4,
- raise_error=False):
- return
-
- cap.set(Capabilities.ACCESS_GROUPS)
- cap.set(Capabilities.VOLUME_MASK)
- cap.set(Capabilities.VOLUME_UNMASK)
- cap.set(Capabilities.ACCESS_GROUP_INITIATOR_DELETE)
- cap.set(Capabilities.ACCESS_GROUPS_GRANTED_TO_VOLUME)
- cap.set(Capabilities.VOLUMES_ACCESSIBLE_BY_ACCESS_GROUP)
-
- # EMC VNX does not support CreateStorageHardwareID for iSCSI
- # and require WWNN for WWPN. Hence both are not supported.
- if cim_sys_path.classname == 'Clar_StorageSystem':
- return
-
- if fc_tgt_is_supported(smis_common):
- cap.set(Capabilities.ACCESS_GROUP_INITIATOR_ADD_WWPN)
- if iscsi_tgt_is_supported(smis_common):
- cap.set(Capabilities.ACCESS_GROUP_INITIATOR_ADD_ISCSI_IQN)
- return
-
-
-def _tgt_cap_set(smis_common, cim_sys_path, cap):
-
- # LSI MegaRAID actually not support FC Target and iSCSI target,
- # They expose empty list of CIM_FCPort
- if cim_sys_path.classname == 'LSIESG_MegaRAIDHBA':
- return
-
- flag_fc_support = fc_tgt_is_supported(smis_common)
- flag_iscsi_support = smis_common.profile_check(
- SmisCommon.SNIA_ISCSI_TGT_PORT_PROFILE,
- SmisCommon.SMIS_SPEC_VER_1_4,
- raise_error=False)
-
- if flag_fc_support or flag_iscsi_support:
- cap.set(Capabilities.TARGET_PORTS)
- return
-
-
-def mask_type(smis_common, raise_error=False):
- """
- Return MASK_TYPE_NO_SUPPORT, MASK_TYPE_MASK or MASK_TYPE_GROUP
- if 'Group Masking and Mapping' profile is supported, return
- MASK_TYPE_GROUP
-
- If raise_error == False, just return MASK_TYPE_NO_SUPPORT
- or, raise NO_SUPPORT error.
- """
- if smis_common.profile_check(SmisCommon.SNIA_GROUP_MASK_PROFILE,
- SmisCommon.SMIS_SPEC_VER_1_5,
- raise_error=False):
- return MASK_TYPE_GROUP
- if smis_common.profile_check(SmisCommon.SNIA_MASK_PROFILE,
- SmisCommon.SMIS_SPEC_VER_1_4,
- raise_error=False):
- return MASK_TYPE_MASK
- if raise_error:
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "Target SMI-S provider does not support "
- "%s version %s or %s version %s" %
- (SmisCommon.SNIA_MASK_PROFILE,
- SmisCommon.SMIS_SPEC_VER_1_4,
- SmisCommon.SNIA_GROUP_MASK_PROFILE,
- SmisCommon.SMIS_SPEC_VER_1_5))
- return MASK_TYPE_NO_SUPPORT
-
-
-def fc_tgt_is_supported(smis_common):
- """
- Return True if FC Target Port 1.4+ profile is supported.
- """
- flag_fc_support = smis_common.profile_check(
- SmisCommon.SNIA_FC_TGT_PORT_PROFILE,
- SmisCommon.SMIS_SPEC_VER_1_4,
- raise_error=False)
- # One more check for NetApp Typo:
- # NetApp: 'FC Target Port'
- # SMI-S: 'FC Target Ports'
- # Bug reported.
- if not flag_fc_support:
- flag_fc_support = smis_common.profile_check(
- 'FC Target Port',
- SmisCommon.SMIS_SPEC_VER_1_4,
- raise_error=False)
- if flag_fc_support:
- return True
- else:
- return False
-
-
-def iscsi_tgt_is_supported(smis_common):
- """
- Return True if FC Target Port 1.4+ profile is supported.
- We use CIM_iSCSIProtocolEndpoint as it's a start point we are
- using in our code of target_ports().
- """
- if smis_common.profile_check(SmisCommon.SNIA_ISCSI_TGT_PORT_PROFILE,
- SmisCommon.SMIS_SPEC_VER_1_4,
- raise_error=False):
- return True
- return False
-
-
-def multi_sys_is_supported(smis_common):
- """
- Return True if Multiple ComputerSystem 1.4+ profile is supported.
- Return False else.
- """
- flag_multi_sys_support = smis_common.profile_check(
- SmisCommon.SNIA_MULTI_SYS_PROFILE,
- SmisCommon.SMIS_SPEC_VER_1_4,
- raise_error=False)
- if flag_multi_sys_support:
- return True
- else:
- return False
-
-
-def get(smis_common, cim_sys, system):
- cap = Capabilities()
-
- if smis_common.is_netappe():
- _rs_supported_capabilities(smis_common, system.id, cap)
-
- #TODO We need to investigate why our interrogation code doesn't
- #work.
- #The array is telling us one thing, but when we try to use it, it
- #doesn't work
- return cap
-
- # 'Block Services Package' profile
- _bsp_cap_set(smis_common, system.id, cap)
-
- # 'Disk Drive Lite' profile
- _disk_cap_set(smis_common, cim_sys.path, cap)
-
- # 'Masking and Mapping' and 'Group Masking and Mapping' profiles
- mt = mask_type(smis_common)
- if cim_sys.path.classname == 'Clar_StorageSystem':
- mt = MASK_TYPE_MASK
-
- if mask_type == MASK_TYPE_GROUP:
- _group_mask_map_cap_set(smis_common, cim_sys.path, cap)
- else:
- _mask_map_cap_set(smis_common, cim_sys.path, cap)
-
- # 'FC Target Ports' and 'iSCSI Target Ports' profiles
- _tgt_cap_set(smis_common, cim_sys.path, cap)
-
- _rs_supported_capabilities(smis_common, system.id, cap)
- return cap
diff --git a/plugin/smispy/smis_common.py b/plugin/smispy/smis_common.py
deleted file mode 100644
index 2129ac8..0000000
--- a/plugin/smispy/smis_common.py
+++ /dev/null
@@ -1,645 +0,0 @@
-# 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, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# Author: Gris Ge <***@redhat.com>
-
-# This file stores:
-# 1. Constants of SNIA SMI-S.
-# 2. Methods shared by smis_sys.py and etc:
-# * Job control
-# * Profile register
-# * WBEM actions: enumerate, associations, getinstance and etc.
-
-from pywbem import Uint16, CIMError
-import pywbem
-import traceback
-import os
-import datetime
-import time
-import sys
-
-import dmtf
-from lsm import LsmError, ErrorNumber, md5
-from utils import (merge_list)
-
-
-def _profile_register_load(wbem_conn):
- """
- Check CIM_RegisteredProfile in interop namespace.
- Return (profile_dict, root_blk_cim_rp)
- The 'profile_dict' is a dictionary like this:
- {
- # profile_name: max_version
- 'Array': 1.4,
- 'Block Service Profile': 1.4,
- }
- The 'root_blk_cim_rp' is the 'Array' profile of CIM_RegisteredProfile
- with highest version number.
- """
- profile_dict = {}
- root_blk_cim_rp = None
- namespace_check_list = dmtf.INTEROP_NAMESPACES
-
- cim_rps = []
- for namespace in namespace_check_list:
- try:
- cim_rps = wbem_conn.EnumerateInstances(
- 'CIM_RegisteredProfile',
- namespace=namespace,
- PropertyList=['RegisteredName', 'RegisteredVersion',
- 'RegisteredOrganization'],
- LocalOnly=False)
- except CIMError as e:
- if e[0] == pywbem.CIM_ERR_NOT_SUPPORTED or \
- e[0] == pywbem.CIM_ERR_INVALID_NAMESPACE or \
- e[0] == pywbem.CIM_ERR_INVALID_CLASS:
- pass
- else:
- raise
- if len(cim_rps) != 0:
- break
-
- if len(cim_rps) >= 1:
- for cim_rp in cim_rps:
- if cim_rp['RegisteredOrganization'] != \
- SmisCommon.SNIA_REG_ORG_CODE:
- continue
- profile_name = cim_rp['RegisteredName']
- profile_ver = cim_rp['RegisteredVersion']
- profile_ver_num = _profile_spec_ver_to_num(profile_ver)
- if profile_name in profile_dict.keys():
- exist_ver_num = _profile_spec_ver_to_num(
- profile_dict[profile_name])
- if exist_ver_num >= profile_ver_num:
- continue
- if profile_name == SmisCommon.SNIA_BLK_ROOT_PROFILE:
- root_blk_cim_rp = cim_rp
- profile_dict[profile_name] = profile_ver
- else:
- raise LsmError(
- ErrorNumber.NO_SUPPORT,
- "Target SMI-S provider does not support DMTF DSP1033 profile "
- "register which is mandatory for LSM")
-
- return profile_dict, root_blk_cim_rp
-
-
-def _profile_check(profile_dict, profile_name, spec_ver,
- raise_error=False):
- """
- Check whether we support certain profile at certain SNIA
- specification version.
- Profile spec version later or equal than require spec_ver will also be
- consider as found.
- Require profile_dict provided by SmisCommon.profile_register_load()
- Will raise LsmError(ErrorNumber.NO_SUPPORT, 'xxx') if raise_error
- is True when nothing found.
- """
- request_ver_num = _profile_spec_ver_to_num(spec_ver)
- if profile_name not in profile_dict.keys():
- if raise_error:
- raise LsmError(
- ErrorNumber.NO_SUPPORT,
- "SNIA SMI-S %s '%s' profile is not supported by " %
- (profile_name, spec_ver) +
- "target SMI-S provider")
- return False
-
- support_ver_num = _profile_spec_ver_to_num(profile_dict[profile_name])
- if support_ver_num < request_ver_num:
- if raise_error:
- raise LsmError(
- ErrorNumber.NO_SUPPORT,
- "SNIA SMI-S %s '%s' profile is not supported by " %
- (profile_name, spec_ver) +
- "target SMI-S provider. Only version %s is supported" %
- profile_dict[profile_name])
- return True
-
-
-def _profile_spec_ver_to_num(spec_ver_str):
- """
- Convert version string stored in CIM_RegisteredProfile to a integer.
- Example:
- "1.5.1" -> 1,005,001
- """
- tmp_list = [0, 0, 0]
- tmp_list = spec_ver_str.split(".")
- if len(tmp_list) == 2:
- tmp_list.extend([0])
- if len(tmp_list) == 3:
- return (int(tmp_list[0]) * 10 ** 6 +
- int(tmp_list[1]) * 10 ** 3 +
- int(tmp_list[2]))
- return None
-
-
-class SmisCommon(object):
- # Even many CIM_XXX_Service in DMTF shared the same return value
- # definition as SNIA do, but there is no DMTF standard motioned
- # InvokeMethod() should follow that list of return value.
- # We use SNIA definition here.
- # SNIA 1.6 rev4 Block book, BSP 5.5.3.12 Return Values section.
- SNIA_INVOKE_OK = 0
- SNIA_INVOKE_NOT_SUPPORTED = 1
- SNIA_INVOKE_FAILED = 4
- SNIA_INVOKE_ASYNC = 4096
-
- SNIA_BLK_ROOT_PROFILE = 'Array'
- SNIA_BLK_SRVS_PROFILE = 'Block Services'
- SNIA_DISK_LITE_PROFILE = 'Disk Drive Lite'
- SNIA_MULTI_SYS_PROFILE = 'Multiple Computer System'
- SNIA_MASK_PROFILE = 'Masking and Mapping'
- SNIA_GROUP_MASK_PROFILE = 'Group Masking and Mapping'
- SNIA_FC_TGT_PORT_PROFILE = 'FC Target Ports'
- SNIA_ISCSI_TGT_PORT_PROFILE = 'iSCSI Target Ports'
- SMIS_SPEC_VER_1_4 = '1.4'
- SMIS_SPEC_VER_1_5 = '1.5'
- SMIS_SPEC_VER_1_6 = '1.6'
- SNIA_REG_ORG_CODE = Uint16(11)
- _MEGARAID_NAMESPACE = 'root/LsiMr13'
- _NETAPP_E_NAMESPACE = 'root/LsiArray13'
- _PRODUCT_MEGARAID = 'LSI MegaRAID'
- _PRODUCT_NETAPP_E = 'NetApp-E'
-
- JOB_RETRIEVE_NONE = 0
- JOB_RETRIEVE_VOLUME = 1
- JOB_RETRIEVE_VOLUME_CREATE = 2
-
- IAAN_WBEM_HTTP_PORT = 5988
- IAAN_WBEM_HTTPS_PORT = 5989
-
- _INVOKE_MAX_LOOP_COUNT = 60
- _INVOKE_CHECK_INTERVAL = 5
-
- def __init__(self, url, username, password,
- namespace=dmtf.DEFAULT_NAMESPACE,
- no_ssl_verify=False, debug_path=None, system_list=None):
- self._wbem_conn = None
- self._profile_dict = {}
- self.root_blk_cim_rp = None # For root_cim_
- self._vendor_product = None # For vendor workaround codes.
- self.system_list = system_list
- self._debug_path = debug_path
-
- if namespace is None:
- namespace = dmtf.DEFAULT_NAMESPACE
-
- self._wbem_conn = pywbem.WBEMConnection(
- url, (username, password), namespace)
- if no_ssl_verify:
- try:
- self._wbem_conn = pywbem.WBEMConnection(
- url, (username, password), namespace,
- no_verification=True)
- except TypeError:
- # pywbem is not holding fix from
- # https://bugzilla.redhat.com/show_bug.cgi?id=1039801
- pass
-
- if debug_path is not None:
- self._wbem_conn.debug = True
-
- if namespace.lower() == SmisCommon._MEGARAID_NAMESPACE.lower():
- # Skip profile register check on MegaRAID for better performance.
- # MegaRAID SMI-S profile support status will not change for a while.
- self._profile_dict = {
- # Provide a fake profile support status to pass the check.
- SmisCommon.SNIA_BLK_ROOT_PROFILE: SmisCommon.SMIS_SPEC_VER_1_4,
- SmisCommon.SNIA_BLK_SRVS_PROFILE: SmisCommon.SMIS_SPEC_VER_1_4,
- SmisCommon.SNIA_DISK_LITE_PROFILE:
- SmisCommon.SMIS_SPEC_VER_1_4,
- }
- self._vendor_product = SmisCommon._PRODUCT_MEGARAID
- else:
- (self._profile_dict, self.root_blk_cim_rp) = \
- _profile_register_load(self._wbem_conn)
-
- if namespace.lower() == SmisCommon._NETAPP_E_NAMESPACE.lower():
- self._vendor_product = SmisCommon._PRODUCT_NETAPP_E
-
- # Check 'Array' 1.4 support status.
- _profile_check(
- self._profile_dict, SmisCommon.SNIA_BLK_ROOT_PROFILE,
- SmisCommon.SMIS_SPEC_VER_1_4, raise_error=True)
-
- def profile_check(self, profile_name, spec_ver, raise_error=False):
- """
- Usage:
- Check whether we support certain profile at certain SNIA
- specification version or later version.
- Will raise LsmError(ErrorNumber.NO_SUPPORT, 'xxx') if raise_error
- is True when nothing found.
- Parameter:
- profile_name # SmisCommon.SNIA_XXXX_PROFILE
- spec_ver # SmisCommon.SMIS_SPEC_VER_XXX
- raise_error # Raise LsmError if not found
- Returns:
- True
- or
- False
- """
- return _profile_check(
- self._profile_dict, profile_name, spec_ver, raise_error)
-
- def _vendor_namespace(self):
- if self.root_blk_cim_rp:
- cim_syss_path = self._wbem_conn.AssociatorNames(
- self.root_blk_cim_rp.path,
- ResultClass='CIM_ComputerSystem',
- AssocClass='CIM_ElementConformsToProfile')
- if len(cim_syss_path) == 0:
- raise LsmError(
- ErrorNumber.NO_SUPPORT,
- "Target SMI-S provider does not support any "
- "CIM_ComputerSystem for SNIA SMI-S '%s' profile" %
- SmisCommon.SNIA_BLK_ROOT_PROFILE)
- return cim_syss_path[0].namespace
- else:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "_vendor_namespace(): self.root_blk_cim_rp not set yet")
-
- def EnumerateInstances(self, ClassName, namespace=None, **params):
- if self._wbem_conn.default_namespace in dmtf.INTEROP_NAMESPACES:
- # We have to enumerate in vendor namespace
- self._wbem_conn.default_namespace = self._vendor_namespace()
- params['LocalOnly'] = False
- return self._wbem_conn.EnumerateInstances(
- ClassName, namespace, **params)
-
- def EnumerateInstanceNames(self, ClassName, namespace=None, **params):
- if self._wbem_conn.default_namespace in dmtf.INTEROP_NAMESPACES:
- # We have to enumerate in vendor namespace
- self._wbem_conn.default_namespace = self._vendor_namespace()
- params['LocalOnly'] = False
- return self._wbem_conn.EnumerateInstanceNames(
- ClassName, namespace, **params)
-
- def Associators(self, ObjectName, **params):
- return self._wbem_conn.Associators(ObjectName, **params)
-
- def AssociatorNames(self, ObjectName, **params):
- return self._wbem_conn.AssociatorNames(ObjectName, **params)
-
- def GetInstance(self, InstanceName, **params):
- params['LocalOnly'] = False
- return self._wbem_conn.GetInstance(InstanceName, **params)
-
- def DeleteInstance(self, InstanceName, **params):
- return self._wbem_conn.DeleteInstance(InstanceName, **params)
-
- def References(self, ObjectName, **params):
- return self._wbem_conn.References(ObjectName, **params)
-
- def is_megaraid(self):
- return self._vendor_product == SmisCommon._PRODUCT_MEGARAID
-
- def is_netappe(self):
- return self._vendor_product == SmisCommon._PRODUCT_NETAPP_E
-
- @staticmethod
- def cim_job_pros():
- return ['InstanceID']
-
- def cim_job_of_job_id(self, job_id, property_list=None):
- """
- Return CIM_ConcreteJob for given job_id.
- """
- if property_list is None:
- property_list = SmisCommon.cim_job_pros()
- else:
- property_list = merge_list(
- property_list, SmisCommon.cim_job_pros())
-
- cim_jobs = self.EnumerateInstances(
- 'CIM_ConcreteJob',
- PropertyList=property_list)
- real_job_id = SmisCommon.parse_job_id(job_id)[0]
- for cim_job in cim_jobs:
- if md5(cim_job['InstanceID']) == real_job_id:
- return cim_job
-
- raise LsmError(
- ErrorNumber.NOT_FOUND_JOB,
- "Job %s not found" % job_id)
-
- @staticmethod
- def _job_id_of_cim_job(cim_job, retrieve_data, method_data):
- """
- Return the MD5 has of CIM_ConcreteJob['InstanceID'] in conjunction
- with '@%s' % retrieve_data
- retrieve_data should be SmisCommon.JOB_RETRIEVE_NONE or
- SmisCommon.JOB_RETRIEVE_VOLUME or etc
- method_data is any string a method would like store for error
- handling by job_status().
- """
- return "%s@%d@%s" % (
- md5(cim_job['InstanceID']), int(retrieve_data), str(method_data))
-
- @staticmethod
- def parse_job_id(job_id):
- """
- job_id is assembled by a md5 string, retrieve_data and method_data
- This method will split it and return
- (md5_str, retrieve_data, method_data)
- """
- tmp_list = job_id.split('@', 3)
- md5_str = tmp_list[0]
- retrieve_data = SmisCommon.JOB_RETRIEVE_NONE
- method_data = None
- if len(tmp_list) == 3:
- retrieve_data = int(tmp_list[1])
- method_data = tmp_list[2]
- return (md5_str, retrieve_data, method_data)
-
- def _dump_wbem_xml(self, file_prefix):
- """
- When debugging issues with providers it's helpful to have
- the xml request/reply to give to provider developers.
- """
- try:
- if self._debug_path is not None:
- if not os.path.exists(self._debug_path):
- os.makedirs(self._debug_path)
-
- if os.path.isdir(self._debug_path):
- debug_fn = "%s_%s" % (
- file_prefix, datetime.datetime.now().isoformat())
- debug_full = os.path.join(
- self._debug_path, debug_fn)
-
- # Dump the request & reply to a file
- with open(debug_full, 'w') as d:
- d.write("REQUEST:\n%s\n\nREPLY:\n%s\n" %
- (self._wbem_conn.last_request,
- self._wbem_conn.last_reply))
- except Exception:
- # Lets not bother to try and report that we couldn't log the debug
- # data when we are most likely already in a bad spot
- pass
-
- def invoke_method(self, cmd, cim_path, in_params, out_handler=None,
- error_handler=None, retrieve_data=None,
- method_data=None):
- """
- cmd
- A string of command, example:
- 'CreateOrModifyElementFromStoragePool'
- cim_path
- the CIMInstanceName, example:
- CIM_StorageConfigurationService.path
- in_params
- A dictionary of input parameter, example:
- {'ElementName': volume_name,
- 'ElementType': dmtf_element_type,
- 'InPool': cim_pool_path,
- 'Size': pywbem.Uint64(size_bytes)}
- out_handler
- A reference to a method to parse output, example:
- self._new_vol_from_name
- error_handler
- A reference to a method to handle all exceptions.
- retrieve_data
- SmisCommon.JOB_RETRIEVE_XXX, it will be used only
- when a ASYNC job has been created.
- method_data
- A string which will be stored in job_id, it could be used by
- job_status() to do error checking.
- """
- if retrieve_data is None:
- retrieve_data = SmisCommon.JOB_RETRIEVE_NONE
- try:
- (rc, out) = self._wbem_conn.InvokeMethod(
- cmd, cim_path, **in_params)
-
- # Check to see if operation is done
- if rc == SmisCommon.SNIA_INVOKE_OK:
- if out_handler is None:
- return None, None
- else:
- return None, out_handler(out)
-
- elif rc == SmisCommon.SNIA_INVOKE_ASYNC:
- # We have an async operation
- job_id = SmisCommon._job_id_of_cim_job(
- out['Job'], retrieve_data, method_data)
- return job_id, None
- elif rc == SmisCommon.SNIA_INVOKE_NOT_SUPPORTED:
- raise LsmError(
- ErrorNumber.NO_SUPPORT,
- 'SMI-S error code indicates operation not supported')
- else:
- self._dump_wbem_xml(cmd)
- raise LsmError(ErrorNumber.PLUGIN_BUG,
- "Error: %s rc= %s" % (cmd, str(rc)))
-
- except Exception:
- exc_info = sys.exc_info()
- # Make sure to save off current exception as we could cause
- # another when trying to dump debug data.
- self._dump_wbem_xml(cmd)
- if error_handler is not None:
- error_handler(self, method_data, exc_info)
- else:
- raise
-
- def invoke_method_wait(self, cmd, cim_path, in_params,
- out_key=None, expect_class=None,
- flag_out_array=False):
- """
- InvokeMethod and wait it until done.
- Return a CIMInstanceName from out[out_key] or from cim_job:
- CIM_ConcreteJob
- |
- | CIM_AffectedJobElement
- v
- CIMInstanceName # expect_class
- If flag_out_array is True, return the first element of out[out_key].
- """
- (rc, out) = self._wbem_conn.InvokeMethod(cmd, cim_path, **in_params)
-
- try:
- if rc == SmisCommon.SNIA_INVOKE_OK:
- if out_key is None:
- return None
- if out_key in out:
- if flag_out_array:
- if len(out[out_key]) == 1:
- return out[out_key][0]
- else:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "invoke_method_wait(), output contains %d " %
- len(out[out_key]) +
- "elements: %s" % out[out_key])
- return out[out_key]
- else:
- raise LsmError(ErrorNumber.PLUGIN_BUG,
- "invoke_method_wait(), %s not exist in out %s" %
- (out_key, out.items()))
-
- elif rc == SmisCommon.SNIA_INVOKE_ASYNC:
- cim_job_path = out['Job']
- loop_counter = 0
- job_pros = ['JobState', 'ErrorDescription',
- 'OperationalStatus']
- cim_xxxs_path = []
- while(loop_counter <= SmisCommon._INVOKE_MAX_LOOP_COUNT):
- cim_job = self.GetInstance(cim_job_path,
- PropertyList=job_pros)
- job_state = cim_job['JobState']
- if job_state in (dmtf.JOB_STATE_NEW, dmtf.JOB_STATE_STARTING,
- dmtf.JOB_STATE_RUNNING):
- loop_counter += 1
- time.sleep(SmisCommon._INVOKE_CHECK_INTERVAL)
- continue
- elif job_state == dmtf.JOB_STATE_COMPLETED:
- if not SmisCommon.cim_job_completed_ok(cim_job):
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- str(cim_job['ErrorDescription']))
- if expect_class is None:
- return None
- cim_xxxs_path = self.AssociatorNames(
- cim_job.path,
- AssocClass='CIM_AffectedJobElement',
- ResultClass=expect_class)
- break
- else:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "invoke_method_wait(): Got unknown job state "
- "%d: %s" % (job_state, cim_job.items()))
-
- if loop_counter > SmisCommon._INVOKE_MAX_LOOP_COUNT:
- raise LsmError(
- ErrorNumber.TIMEOUT,
- "The job generated by %s() failed to finish in %ds" %
- (cmd,
- SmisCommon._INVOKE_CHECK_INTERVAL *
- SmisCommon._INVOKE_MAX_LOOP_COUNT))
-
- if len(cim_xxxs_path) == 1:
- return cim_xxxs_path[0]
- else:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "invoke_method_wait(): got unexpected(not 1) "
- "return from CIM_AffectedJobElement: "
- "%s, out: %s, job: %s" %
- (cim_xxxs_path, out.items(), cim_job.items()))
- else:
- self._dump_wbem_xml(cmd)
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "invoke_method_wait(): Got unexpected rc code "
- "%d, out: %s" % (rc, out.items()))
- except Exception:
- exc_info = sys.exc_info()
- # Make sure to save off current exception as we could cause
- # another when trying to dump debug data.
- self._dump_wbem_xml(cmd)
- raise exc_info[0], exc_info[1], exc_info[2]
-
- def _cim_srv_of_sys_id(self, srv_name, sys_id, raise_error):
- property_list = ['SystemName']
-
- try:
- cim_srvs = self.EnumerateInstances(
- srv_name,
- PropertyList=property_list)
- for cim_srv in cim_srvs:
- if cim_srv['SystemName'] == sys_id:
- return cim_srv
- except CIMError:
- if raise_error:
- raise
- else:
- return None
-
- if raise_error:
- raise LsmError(
- ErrorNumber.NO_SUPPORT,
- "Cannot find any '%s' for requested system ID" % srv_name)
- return None
-
- def cim_scs_of_sys_id(self, sys_id, raise_error=True):
- """
- Return a CIMInstance of CIM_StorageConfigurationService for given
- system id.
- Using 'SystemName' property as system id of a service which is defined
- by DMTF CIM_Service.
- """
- return self._cim_srv_of_sys_id(
- 'CIM_StorageConfigurationService', sys_id, raise_error)
-
- def cim_rs_of_sys_id(self, sys_id, raise_error=True):
- """
- Return a CIMInstance of CIM_ReplicationService for given system id.
- Using 'SystemName' property as system id of a service which is defined
- by DMTF CIM_Service.
- """
- return self._cim_srv_of_sys_id(
- 'CIM_ReplicationService', sys_id, raise_error)
-
- def cim_gmms_of_sys_id(self, sys_id, raise_error=True):
- """
- Return a CIMInstance of CIM_GroupMaskingMappingService for given system
- id.
- Using 'SystemName' property as system id of a service which is defined
- by DMTF CIM_Service.
- """
- return self._cim_srv_of_sys_id(
- 'CIM_GroupMaskingMappingService', sys_id, raise_error)
-
- def cim_ccs_of_sys_id(self, sys_id, raise_error=True):
- """
- Return a CIMInstance of CIM_ControllerConfigurationService for given
- system id.
- Using 'SystemName' property as system id of a service which is defined
- by DMTF CIM_Service.
- """
- return self._cim_srv_of_sys_id(
- 'CIM_ControllerConfigurationService', sys_id, raise_error)
-
- def cim_hwms_of_sys_id(self, sys_id, raise_error=True):
- """
- Return a CIMInstance of CIM_StorageHardwareIDManagementService for
- given system id.
- Using 'SystemName' property as system id of a service which is defined
- by DMTF CIM_Service.
- """
- return self._cim_srv_of_sys_id(
- 'CIM_StorageHardwareIDManagementService', sys_id, raise_error)
-
- @staticmethod
- def cim_job_completed_ok(status):
- """
- Given a concrete job instance, check the operational status. This
- is a little convoluted as different SMI-S proxies return the values in
- different positions in list :-)
- """
- rc = False
- op = status['OperationalStatus']
-
- if (len(op) > 1 and
- ((op[0] == dmtf.OP_STATUS_OK and
- op[1] == dmtf.OP_STATUS_COMPLETED) or
- (op[0] == dmtf.OP_STATUS_COMPLETED and
- op[1] == dmtf.OP_STATUS_OK))):
- rc = True
-
- return rc
diff --git a/plugin/smispy/smis_disk.py b/plugin/smispy/smis_disk.py
deleted file mode 100644
index e5bd5ea..0000000
--- a/plugin/smispy/smis_disk.py
+++ /dev/null
@@ -1,225 +0,0 @@
-## 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: Gris Ge <***@redhat.com>
-
-from lsm import Disk, md5, LsmError, ErrorNumber
-import dmtf
-from utils import merge_list
-
-
-_LSM_DISK_OP_STATUS_CONV = {
- dmtf.OP_STATUS_UNKNOWN: Disk.STATUS_UNKNOWN,
- dmtf.OP_STATUS_OK: Disk.STATUS_OK,
- dmtf.OP_STATUS_PREDICTIVE_FAILURE: Disk.STATUS_PREDICTIVE_FAILURE,
- dmtf.OP_STATUS_ERROR: Disk.STATUS_ERROR,
- dmtf.OP_STATUS_NON_RECOVERABLE_ERROR: Disk.STATUS_ERROR,
- dmtf.OP_STATUS_STARTING: Disk.STATUS_STARTING,
- dmtf.OP_STATUS_STOPPING: Disk.STATUS_STOPPING,
- dmtf.OP_STATUS_STOPPED: Disk.STATUS_STOPPED,
-}
-
-
-def _disk_status_of_cim_disk(cim_disk):
- """
- Convert CIM_DiskDrive['OperationalStatus'] to LSM
- Only return status, no status_info
- """
- if 'OperationalStatus' not in cim_disk:
- return Disk.STATUS_UNKNOWN
-
- return dmtf.op_status_list_conv(
- _LSM_DISK_OP_STATUS_CONV, cim_disk['OperationalStatus'],
- Disk.STATUS_UNKNOWN, Disk.STATUS_OTHER)[0]
-
-
-_DMTF_DISK_TYPE_2_LSM = {
- dmtf.DISK_TYPE_UNKNOWN: Disk.TYPE_UNKNOWN,
- dmtf.DISK_TYPE_OTHER: Disk.TYPE_OTHER,
- dmtf.DISK_TYPE_HDD: Disk.TYPE_HDD,
- dmtf.DISK_TYPE_SSD: Disk.TYPE_SSD,
- dmtf.DISK_TYPE_HYBRID: Disk.TYPE_HYBRID,
-}
-
-
-def _dmtf_disk_type_2_lsm_disk_type(dmtf_disk_type):
- if dmtf_disk_type in _DMTF_DISK_TYPE_2_LSM.keys():
- return _DMTF_DISK_TYPE_2_LSM[dmtf_disk_type]
- else:
- return Disk.TYPE_UNKNOWN
-
-
-def _disk_id_of_cim_disk(cim_disk):
- if 'SystemName' not in cim_disk or \
- 'DeviceID' not in cim_disk:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "_disk_id_of_cim_disk(): Got cim_disk with no "
- "SystemName or DeviceID property: %s, %s" %
- (cim_disk.path, cim_disk.items()))
-
- return md5("%s%s" % (cim_disk['SystemName'], cim_disk['DeviceID']))
-
-
-def cim_disk_pros():
- """
- Return all CIM_DiskDrive Properties needed to create a Disk object.
- The 'Type' and 'MediaType' is only for MegaRAID.
- The 'EMCInUse' is only for EMC.
- """
- return ['OperationalStatus', 'Name', 'SystemName',
- 'Caption', 'InterconnectType', 'DiskType', 'DeviceID',
- 'Type', 'MediaType', 'EMCInUse']
-
-
-def sys_id_of_cim_disk(cim_disk):
- if 'SystemName' not in cim_disk:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "sys_id_of_cim_disk(): Got cim_disk with no "
- "SystemName property: %s, %s" %
- (cim_disk.path, cim_disk.items()))
- return cim_disk['SystemName']
-
-
-def _pri_cim_ext_of_cim_disk(smis_common, cim_disk_path, property_list=None):
- """
- Usage:
- Find out the Primordial CIM_StorageExtent of CIM_DiskDrive
- In SNIA SMI-S 1.4 rev.6 Block book, section 11.1.1 'Base Model'
- quote:
- A disk drive is modeled as a single MediaAccessDevice (DiskDrive)
- That shall be linked to a single StorageExtent (representing the
- storage in the drive) by a MediaPresent association. The
- StorageExtent class represents the storage of the drive and
- contains its size.
- Parameter:
- cim_disk_path # CIM_InstanceName of CIM_DiskDrive
- property_list # a List of properties needed on returned
- # CIM_StorageExtent
- Returns:
- cim_pri_ext # The CIM_Instance of Primordial CIM_StorageExtent
- Exceptions:
- LsmError
- ErrorNumber.LSM_PLUGIN_BUG # Failed to find out pri cim_ext
- """
- if property_list is None:
- property_list = ['Primordial']
- else:
- property_list = merge_list(property_list, ['Primordial'])
-
- cim_exts = smis_common.Associators(
- cim_disk_path,
- AssocClass='CIM_MediaPresent',
- ResultClass='CIM_StorageExtent',
- PropertyList=property_list)
- cim_exts = [p for p in cim_exts if p["Primordial"]]
- if len(cim_exts) == 1:
- # As SNIA commanded, only _ONE_ Primordial CIM_StorageExtent for
- # each CIM_DiskDrive
- return cim_exts[0]
- else:
- raise LsmError(ErrorNumber.PLUGIN_BUG,
- "_pri_cim_ext_of_cim_disk(): "
- "Got unexpected count of Primordial " +
- "CIM_StorageExtent for CIM_DiskDrive: %s, %s " %
- (cim_disk_path, cim_exts))
-
-
-# LSIESG_DiskDrive['MediaType']
-# Value was retrieved from MOF file of MegaRAID SMI-S provider.
-_MEGARAID_DISK_MEDIA_TYPE_SSD = 1
-_MEGARAID_DISK_MEDIA_TYPE_SSD_FLASH = 2
-
-# LSIESG_DiskDrive['Type']
-# Value was retrieved from LSI engineer with content of LGPL2.1+ license.
-_MEGARAID_DISK_TYPE_SCSI = 1
-_MEGARAID_DISK_TYPE_SAS = 2
-_MEGARAID_DISK_TYPE_SATA = 3
-_MEGARAID_DISK_TYPE_FC = 4
-
-
-def _disk_type_megaraid(cim_disk):
- if cim_disk['MediaType'] == _MEGARAID_DISK_MEDIA_TYPE_SSD or \
- cim_disk['MediaType'] == _MEGARAID_DISK_MEDIA_TYPE_SSD_FLASH:
- return Disk.TYPE_SSD
- else:
- if int(cim_disk['Type']) == _MEGARAID_DISK_TYPE_SCSI:
- return Disk.TYPE_SCSI
- elif int(cim_disk['Type']) == _MEGARAID_DISK_TYPE_SAS:
- return Disk.TYPE_SAS
- elif int(cim_disk['Type']) == _MEGARAID_DISK_TYPE_SATA:
- return Disk.TYPE_SATA
- elif int(cim_disk['Type']) == _MEGARAID_DISK_TYPE_FC:
- return Disk.TYPE_FC
-
- return Disk.TYPE_UNKNOWN
-
-
-def cim_disk_to_lsm_disk(smis_common, cim_disk):
- """
- Convert CIM_DiskDrive to lsm.Disk.
- """
- # CIM_DiskDrive does not have disk size information.
- # We have to find out the Primordial CIM_StorageExtent for that.
- cim_ext = _pri_cim_ext_of_cim_disk(
- smis_common, cim_disk.path,
- property_list=['BlockSize', 'NumberOfBlocks'])
-
- status = _disk_status_of_cim_disk(cim_disk)
- cim_srss = smis_common.AssociatorNames(
- cim_ext.path, AssocClass='CIM_IsSpare',
- ResultClass='CIM_StorageRedundancySet')
- if len(cim_srss) >= 1:
- status |= Disk.STATUS_SPARE_DISK
-
- if 'EMCInUse' in cim_disk.keys() and cim_disk['EMCInUse'] is False:
- status |= Disk.STATUS_FREE
-
- name = ''
- block_size = Disk.BLOCK_SIZE_NOT_FOUND
- num_of_block = Disk.BLOCK_COUNT_NOT_FOUND
- disk_type = Disk.TYPE_UNKNOWN
- sys_id = sys_id_of_cim_disk(cim_disk)
-
- # These are mandatory
- # we do not check whether they follow the SNIA standard.
- if 'Name' in cim_disk:
- name = cim_disk["Name"]
- if 'BlockSize' in cim_ext:
- block_size = cim_ext['BlockSize']
- if 'NumberOfBlocks' in cim_ext:
- num_of_block = cim_ext['NumberOfBlocks']
-
- if smis_common.is_megaraid():
- disk_type = _disk_type_megaraid(cim_disk)
- else:
- # SNIA SMI-S 1.4 or even 1.6 does not define anyway to find out disk
- # type.
- # Currently, EMC is following DMTF define to do so.
- if 'InterconnectType' in cim_disk: # DMTF 2.31 CIM_DiskDrive
- disk_type = cim_disk['InterconnectType']
- if 'Caption' in cim_disk:
- # EMC VNX introduced NL_SAS disk.
- if cim_disk['Caption'] == 'NL_SAS':
- disk_type = Disk.TYPE_NL_SAS
-
- if disk_type == Disk.TYPE_UNKNOWN and 'DiskType' in cim_disk:
- disk_type = _dmtf_disk_type_2_lsm_disk_type(cim_disk['DiskType'])
-
- disk_id = _disk_id_of_cim_disk(cim_disk)
-
- return Disk(disk_id, name, disk_type, block_size, num_of_block, status,
- sys_id)
diff --git a/plugin/smispy/smis_pool.py b/plugin/smispy/smis_pool.py
deleted file mode 100644
index cb06867..0000000
--- a/plugin/smispy/smis_pool.py
+++ /dev/null
@@ -1,268 +0,0 @@
-## 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: Gris Ge <***@redhat.com>
-
-from utils import merge_list, path_str_to_cim_path, cim_path_to_path_str
-import dmtf
-from lsm import LsmError, ErrorNumber, Pool
-
-
-def cim_pools_of_cim_sys_path(smis_common, cim_sys_path, property_list=None):
- """
- Use this association to get a list of CIM_StoragePool:
- CIM_ComputerSystem
- |
- | (CIM_HostedStoragePool)
- |
- v
- CIM_StoragePool
- As 'Block Services Package' is mandatory for 'Array' profile which already
- checked by plugin_register(), we don't do any profile check here.
- Primordial pool will be eliminated from return list.
- These pools will be eliminated also:
- * Spare pool with CIM_StoragePool['Usage'] == dmtf.POOL_USAGE_SPARE
- * IBM ArrayPool(IBMTSDS_ArrayPool)
- * IBM ArraySitePool(IBMTSDS_ArraySitePool)
- """
- cim_pools = []
-
- if property_list is None:
- property_list = ['Primordial', 'Usage']
- else:
- property_list = merge_list(property_list, ['Primordial', 'Usage'])
-
- cim_pools = smis_common.Associators(
- cim_sys_path,
- AssocClass='CIM_HostedStoragePool',
- ResultClass='CIM_StoragePool',
- PropertyList=property_list)
-
- rc = []
- for cim_pool in cim_pools:
- if 'Primordial' in cim_pool and cim_pool['Primordial']:
- continue
- if 'Usage' in cim_pool and cim_pool['Usage'] == dmtf.POOL_USAGE_SPARE:
- continue
- # Skip IBM ArrayPool and ArraySitePool
- # ArrayPool is holding RAID info.
- # ArraySitePool is holding 8 disks. Predefined by array.
- # ArraySite --(1to1 map) --> Array --(1to1 map)--> Rank
-
- # By design when user get a ELEMENT_TYPE_POOL only pool,
- # user can assume he/she can allocate spaces from that pool
- # to create a new pool with ELEMENT_TYPE_VOLUME or
- # ELEMENT_TYPE_FS ability.
-
- # If we expose them out, we will have two kind of pools
- # (ArrayPool and ArraySitePool) having element_type &
- # ELEMENT_TYPE_POOL, but none of them can create a
- # ELEMENT_TYPE_VOLUME pool.
- # Only RankPool can create a ELEMENT_TYPE_VOLUME pool.
-
- # We are trying to hide the detail to provide a simple
- # abstraction.
- if cim_pool.classname == 'IBMTSDS_ArrayPool' or \
- cim_pool.classname == 'IBMTSDS_ArraySitePool':
- continue
- rc.append(cim_pool)
-
- return rc
-
-
-def cim_pool_id_pros():
- """
- Return a list of CIM_StoragePool properties required to generate
- lsm.Pool.id
- """
- return ['InstanceID']
-
-
-def pool_id_of_cim_pool(cim_pool):
- if 'InstanceID' in cim_pool:
- return cim_pool['InstanceID']
- else:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "pool_id_of_cim_pool(): Got CIM_StoragePool with no 'InstanceID' "
- "property: %s, %s" % (cim_pool.items(), cim_pool.path))
-
-
-def cim_pool_pros():
- """
- Return a list of CIM_StoragePool properties required to generate lsm.Pool.
- """
- pool_pros = cim_pool_id_pros()
- pool_pros.extend(['ElementName', 'TotalManagedSpace',
- 'RemainingManagedSpace', 'Usage',
- 'OperationalStatus'])
- return pool_pros
-
-
-def _pool_element_type(smis_common, cim_pool):
- """
- Return a set (Pool.element_type, Pool.unsupported)
- Using CIM_StorageConfigurationCapabilities
- 'SupportedStorageElementFeatures' and 'SupportedStorageElementTypes'
- property.
- For MegaRAID, just return (Pool.ELEMENT_TYPE_VOLUME, 0)
- """
- if smis_common.is_megaraid():
- return Pool.ELEMENT_TYPE_VOLUME | Pool.ELEMENT_TYPE_VOLUME_FULL, 0
-
- element_type = 0
- unsupported = 0
-
- # check whether current pool support create volume or not.
- cim_sccs = smis_common.Associators(
- cim_pool.path,
- AssocClass='CIM_ElementCapabilities',
- ResultClass='CIM_StorageConfigurationCapabilities',
- PropertyList=['SupportedStorageElementFeatures',
- 'SupportedStorageElementTypes'])
- # Associate StorageConfigurationCapabilities to StoragePool
- # is experimental in SNIA 1.6rev4, Block Book PDF Page 68.
- # Section 5.1.6 StoragePool, StorageVolume and LogicalDisk
- # Manipulation, Figure 9 - Capabilities Specific to a StoragePool
- if len(cim_sccs) == 1:
- cim_scc = cim_sccs[0]
- if 'SupportedStorageElementFeatures' in cim_scc:
- supported_features = cim_scc['SupportedStorageElementFeatures']
- supported_types = cim_scc['SupportedStorageElementTypes']
-
- if dmtf.SUPPORT_VOL_CREATE in supported_features:
- element_type = Pool.ELEMENT_TYPE_VOLUME
- if dmtf.ELEMENT_THIN_VOLUME in supported_types:
- element_type |= Pool.ELEMENT_TYPE_VOLUME_THIN
- if dmtf.ELEMENT_THICK_VOLUME in supported_types:
- element_type |= Pool.ELEMENT_TYPE_VOLUME_FULL
- if dmtf.SUPPORT_ELEMENT_EXPAND not in supported_features:
- unsupported |= Pool.UNSUPPORTED_VOLUME_GROW
- if dmtf.SUPPORT_ELEMENT_REDUCE not in supported_features:
- unsupported |= Pool.UNSUPPORTED_VOLUME_SHRINK
-
- else:
- # IBM DS 8000 does not support StorageConfigurationCapabilities
- # per pool yet. They has been informed. Before fix, use a quick
- # workaround.
- # TODO: Currently, we don't have a way to detect
- # Pool.ELEMENT_TYPE_POOL
- # but based on knowing definition of each vendor.
- if cim_pool.classname == 'IBMTSDS_VirtualPool' or \
- cim_pool.classname == 'IBMTSDS_ExtentPool':
- element_type = Pool.ELEMENT_TYPE_VOLUME
- elif cim_pool.classname == 'IBMTSDS_RankPool':
- element_type = Pool.ELEMENT_TYPE_POOL
- elif cim_pool.classname == 'LSIESG_StoragePool':
- element_type = Pool.ELEMENT_TYPE_VOLUME
-
- if 'Usage' in cim_pool:
- usage = cim_pool['Usage']
-
- if usage == dmtf.POOL_USAGE_UNRESTRICTED:
- element_type |= Pool.ELEMENT_TYPE_VOLUME
- if usage == dmtf.POOL_USAGE_RESERVED_FOR_SYSTEM or \
- usage > dmtf.POOL_USAGE_DELTA:
- element_type |= Pool.ELEMENT_TYPE_SYS_RESERVED
- if usage == dmtf.POOL_USAGE_DELTA:
- # We blitz all the other elements types for this designation
- element_type = Pool.ELEMENT_TYPE_DELTA
-
- return element_type, unsupported
-
-
-_LSM_POOL_OP_STATUS_CONV = {
- dmtf.OP_STATUS_OK: Pool.STATUS_OK,
- dmtf.OP_STATUS_ERROR: Pool.STATUS_ERROR,
- dmtf.OP_STATUS_DEGRADED: Pool.STATUS_DEGRADED,
- dmtf.OP_STATUS_NON_RECOVERABLE_ERROR: Pool.STATUS_ERROR,
- dmtf.OP_STATUS_SUPPORTING_ENTITY_IN_ERROR: Pool.STATUS_ERROR,
-}
-
-
-def _pool_status_of_cim_pool(dmtf_op_status_list):
- """
- Convert CIM_StoragePool['OperationalStatus'] to LSM
- """
- return dmtf.op_status_list_conv(
- _LSM_POOL_OP_STATUS_CONV, dmtf_op_status_list,
- Pool.STATUS_UNKNOWN, Pool.STATUS_OTHER)
-
-
-def cim_pool_to_lsm_pool(smis_common, cim_pool, system_id):
- """
- Return a Pool object base on information of cim_pool.
- Assuming cim_pool already holding correct properties.
- """
- status_info = ''
- pool_id = pool_id_of_cim_pool(cim_pool)
- name = ''
- total_space = Pool.TOTAL_SPACE_NOT_FOUND
- free_space = Pool.FREE_SPACE_NOT_FOUND
- status = Pool.STATUS_OK
- if 'ElementName' in cim_pool:
- name = cim_pool['ElementName']
- if 'TotalManagedSpace' in cim_pool:
- total_space = cim_pool['TotalManagedSpace']
- if 'RemainingManagedSpace' in cim_pool:
- free_space = cim_pool['RemainingManagedSpace']
- if 'OperationalStatus' in cim_pool:
- (status, status_info) = _pool_status_of_cim_pool(
- cim_pool['OperationalStatus'])
-
- element_type, unsupported = _pool_element_type(smis_common, cim_pool)
-
- plugin_data = cim_path_to_path_str(cim_pool.path)
-
- return Pool(pool_id, name, element_type, unsupported,
- total_space, free_space,
- status, status_info, system_id, plugin_data)
-
-
-def lsm_pool_to_cim_pool_path(smis_common, lsm_pool):
- """
- Convert lsm.Pool to CIMInstanceName of CIM_StoragePool using
- lsm.Pool.plugin_data
- """
- if not lsm_pool.plugin_data:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "Got lsm.Pool instance with empty plugin_data")
- if smis_common.system_list and \
- lsm_pool.system_id not in smis_common.system_list:
- raise LsmError(
- ErrorNumber.NOT_FOUND_SYSTEM,
- "System filtered in URI")
-
- return path_str_to_cim_path(lsm_pool.plugin_data)
-
-
-def pool_id_of_cim_vol(smis_common, cim_vol_path):
- """
- Find out the lsm.Pool.id of CIM_StorageVolume
- """
- property_list = cim_pool_id_pros()
- cim_pools = smis_common.Associators(
- cim_vol_path,
- AssocClass='CIM_AllocatedFromStoragePool',
- ResultClass='CIM_StoragePool',
- PropertyList=property_list)
- if len(cim_pools) != 1:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "pool_id_of_cim_vol(): Got unexpected count(%d) of cim_pool " %
- len(cim_pools) +
- "associated to cim_vol: %s, %s" % (cim_vol_path, cim_pools))
- return pool_id_of_cim_pool(cim_pools[0])
diff --git a/plugin/smispy/smis_sys.py b/plugin/smispy/smis_sys.py
deleted file mode 100644
index b3ebe60..0000000
--- a/plugin/smispy/smis_sys.py
+++ /dev/null
@@ -1,159 +0,0 @@
-## 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: Gris Ge <***@redhat.com>
-
-from utils import merge_list
-import dmtf
-from lsm import System, LsmError, ErrorNumber
-
-
-def cim_sys_id_pros():
- """
- Return the property of CIM_ComputerSystem required to generate
- lsm.System.id
- """
- return ['Name']
-
-
-def sys_id_of_cim_sys(cim_sys):
- if 'Name' in cim_sys:
- return cim_sys['Name']
- else:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "sys_id_of_cim_sys(): Got a CIM_ComputerSystem does not have "
- "'Name' property: %s, %s" % (cim_sys.items(), cim_sys.path))
-
-
-def sys_id_of_cim_vol(cim_vol):
- if 'SystemName' in cim_vol:
- return cim_vol['SystemName']
- else:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "sys_id_of_cim_vol(): Got a CIM_StorageVolume does not have "
- "'SystemName' property: %s, %s" % (cim_vol.items(), cim_vol.path))
-
-
-def root_cim_sys(smis_common, property_list=None):
- """
- Use this association to find out the root CIM_ComputerSystem:
- CIM_RegisteredProfile # Root Profile('Array') in interop
- |
- | CIM_ElementConformsToProfile
- v
- CIM_ComputerSystem # vendor namespace
- """
- id_pros = cim_sys_id_pros()
- if property_list is None:
- property_list = id_pros
- else:
- property_list = merge_list(property_list, id_pros)
-
- cim_syss = []
- if smis_common.is_megaraid():
- cim_syss = smis_common.EnumerateInstances(
- 'CIM_ComputerSystem', PropertyList=property_list)
- else:
- cim_syss = smis_common.Associators(
- smis_common.root_blk_cim_rp.path,
- ResultClass='CIM_ComputerSystem',
- AssocClass='CIM_ElementConformsToProfile',
- PropertyList=property_list)
-
- if len(cim_syss) == 0:
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "Current SMI-S provider does not provide "
- "the root CIM_ComputerSystem associated "
- "to 'Array' CIM_RegisteredProfile.")
-
- # System URI Filtering
- if smis_common.system_list:
- needed_cim_syss = []
- for cim_sys in cim_syss:
- if sys_id_of_cim_sys(cim_sys) in smis_common.system_list:
- needed_cim_syss.extend([cim_sys])
- return needed_cim_syss
- else:
- return cim_syss
-
-
-def cim_sys_pros():
- """
- Return a list of properties required to create a LSM System
- """
- cim_sys_properties = cim_sys_id_pros()
- cim_sys_properties.extend(['ElementName', 'OperationalStatus'])
- return cim_sys_properties
-
-
-_LSM_SYS_OP_STATUS_CONV = {
- dmtf.OP_STATUS_UNKNOWN: System.STATUS_UNKNOWN,
- dmtf.OP_STATUS_OK: System.STATUS_OK,
- dmtf.OP_STATUS_ERROR: System.STATUS_ERROR,
- dmtf.OP_STATUS_DEGRADED: System.STATUS_DEGRADED,
- dmtf.OP_STATUS_NON_RECOVERABLE_ERROR: System.STATUS_ERROR,
- dmtf.OP_STATUS_PREDICTIVE_FAILURE: System.STATUS_PREDICTIVE_FAILURE,
- dmtf.OP_STATUS_SUPPORTING_ENTITY_IN_ERROR: System.STATUS_ERROR,
-}
-
-
-def _sys_status_of_cim_sys(cim_sys):
- """
- Convert CIM_ComputerSystem['OperationalStatus']
- """
- if 'OperationalStatus' not in cim_sys:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "sys_status_of_cim_sys(): Got a CIM_ComputerSystem with no "
- "OperationalStatus: %s, %s" % (cim_sys.items(), cim_sys.path))
-
- return dmtf.op_status_list_conv(
- _LSM_SYS_OP_STATUS_CONV, cim_sys['OperationalStatus'],
- System.STATUS_UNKNOWN, System.STATUS_OTHER)
-
-
-def cim_sys_to_lsm_sys(cim_sys):
- status = System.STATUS_UNKNOWN
- status_info = ''
-
- if 'OperationalStatus' in cim_sys:
- (status, status_info) = _sys_status_of_cim_sys(cim_sys)
-
- sys_id = sys_id_of_cim_sys(cim_sys)
- sys_name = cim_sys['ElementName']
-
- return System(sys_id, sys_name, status, status_info)
-
-
-def cim_sys_of_sys_id(smis_common, sys_id, property_list=None):
- """
- Find out the CIM_ComputerSystem for given lsm.System.id using
- root_cim_sys()
- """
- id_pros = cim_sys_id_pros()
- if property_list is None:
- property_list = id_pros
- else:
- property_list = merge_list(property_list, id_pros)
-
- cim_syss = root_cim_sys(smis_common, property_list)
- for cim_sys in cim_syss:
- if sys_id_of_cim_sys(cim_sys) == sys_id:
- return cim_sys
- raise LsmError(
- ErrorNumber.NOT_FOUND_SYSTEM,
- "Not found System")
diff --git a/plugin/smispy/smis_vol.py b/plugin/smispy/smis_vol.py
deleted file mode 100644
index f8c727c..0000000
--- a/plugin/smispy/smis_vol.py
+++ /dev/null
@@ -1,245 +0,0 @@
-## 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: Gris Ge <***@redhat.com>
-
-"""
-This module intends to provide independent methods related to lsm.Volume and
-CIM_StorageVolume.
-"""
-
-import re
-import sys
-
-from lsm import md5, Volume, LsmError, ErrorNumber
-from lsm.plugin.smispy.utils import (
- merge_list, cim_path_to_path_str, path_str_to_cim_path)
-from lsm.plugin.smispy import dmtf
-
-
-def cim_vol_id_pros():
- """
- Return the property of CIM_StorageVolume required to generate
- lsm.Volume.id
- """
- return ['SystemName', 'DeviceID']
-
-
-def vol_id_of_cim_vol(cim_vol):
- """
- Get lsm.Volume.id from CIM_StorageVolume['DeviceID'] and ['SystemName']
- """
- if 'SystemName' not in cim_vol or 'DeviceID' not in cim_vol:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "vol_id_of_cim_vol(): Got cim_vol with no "
- "SystemName or DeviceID property: %s, %s" %
- (cim_vol.path, cim_vol.items()))
-
- return md5("%s%s" % (cim_vol['SystemName'], cim_vol['DeviceID']))
-
-
-def cim_vol_pros():
- """
- Return the PropertyList required for creating new lsm.Volume.
- """
- props = ['ElementName', 'NameFormat',
- 'NameNamespace', 'BlockSize', 'NumberOfBlocks', 'Name',
- 'OtherIdentifyingInfo', 'IdentifyingDescriptions', 'Usage',
- 'OtherNameFormat', 'OtherNameNamespace']
- props.extend(cim_vol_id_pros())
- return props
-
-
-def cim_vol_of_cim_pool_path(smis_common, cim_pool_path, property_list=None):
- """
- Use this association to get a list of CIM_StorageVolume:
- CIM_StoragePool
- |
- | CIM_AllocatedFromStoragePool
- |
- v
- CIM_StorageVolume
- CIM_StorageVolume['Usage'] == dmtf.VOL_USAGE_SYS_RESERVED will be filtered
- out.
- Return a list of CIM_StorageVolume.
- """
- if property_list is None:
- property_list = ['Usage']
- else:
- property_list = merge_list(property_list, ['Usage'])
-
- cim_vols = smis_common.Associators(
- cim_pool_path,
- AssocClass='CIM_AllocatedFromStoragePool',
- ResultClass='CIM_StorageVolume',
- PropertyList=property_list)
-
- needed_cim_vols = []
- for cim_vol in cim_vols:
- if 'Usage' not in cim_vol or \
- cim_vol['Usage'] != dmtf.VOL_USAGE_SYS_RESERVED:
- needed_cim_vols.append(cim_vol)
- return needed_cim_vols
-
-
-def _vpd83_in_cim_vol_name(cim_vol):
- """
- We require NAA Type 3 VPD83 address:
- Only this is allowed when storing VPD83 in cim_vol["Name"]:
- * NameFormat = NAA(9), NameNamespace = VPD83Type3(2)
- """
- if not ('NameFormat' in cim_vol and
- 'NameNamespace' in cim_vol and
- 'Name' in cim_vol):
- return None
- name_format = cim_vol['NameFormat']
- name_space = cim_vol['NameNamespace']
- name = cim_vol['Name']
- if not (name_format and name_space and name):
- return None
-
- if name_format == dmtf.VOL_NAME_FORMAT_NNA and \
- name_space == dmtf.VOL_NAME_SPACE_VPD83_TYPE3:
- return name
-
-
-def _vpd83_in_cim_vol_otherinfo(cim_vol):
- """
- IdentifyingDescriptions[] shall contain "NAA;VPD83Type3".
- Will return the vpd_83 value if found
- """
- if not ("IdentifyingDescriptions" in cim_vol and
- "OtherIdentifyingInfo" in cim_vol):
- return None
-
- id_des = cim_vol["IdentifyingDescriptions"]
- other_info = cim_vol["OtherIdentifyingInfo"]
- if not (isinstance(cim_vol["IdentifyingDescriptions"], list) and
- isinstance(cim_vol["OtherIdentifyingInfo"], list)):
- return None
-
- index = 0
- len_id_des = len(id_des)
- len_other_info = len(other_info)
- while index < min(len_id_des, len_other_info):
- if dmtf.VOL_OTHER_INFO_NAA_VPD83_TYPE3H == id_des[index]:
- return other_info[index]
- index += 1
- return None
-
-
-def _vpd83_netapp(cim_vol):
- """
- Workaround for NetApp, they use OtherNameNamespace and
- OtherNameFormat.
- """
- if 'OtherNameFormat' in cim_vol and \
- cim_vol['OtherNameFormat'] == 'NAA' and \
- 'OtherNameNamespace' in cim_vol and \
- cim_vol['OtherNameNamespace'] == 'VPD83Type3' and \
- 'OtherIdentifyingInfo' in cim_vol and \
- isinstance(cim_vol["OtherIdentifyingInfo"], list) and \
- len(cim_vol['OtherIdentifyingInfo']) == 1:
- return cim_vol['OtherIdentifyingInfo'][0]
-
-
-def _vpd83_of_cim_vol(cim_vol):
- """
- Extract VPD83 string from CIMInstanceName and convert to LSM format:
- ^6[a-f0-9]{31}$
- """
- vpd_83 = _vpd83_in_cim_vol_name(cim_vol)
- if vpd_83 is None:
- vpd_83 = _vpd83_in_cim_vol_otherinfo(cim_vol)
- if vpd_83 is None:
- vpd_83 = _vpd83_netapp(cim_vol)
-
- if vpd_83 and re.match('^6[a-fA-F0-9]{31}$', vpd_83):
- return vpd_83.lower()
- else:
- return ''
-
-
-def cim_vol_to_lsm_vol(cim_vol, pool_id, sys_id):
- """
- Takes a CIMInstance that represents a volume and returns a lsm Volume
- """
-
- # This is optional (User friendly name)
- if 'ElementName' in cim_vol:
- user_name = cim_vol["ElementName"]
- else:
- #Better fallback value?
- user_name = cim_vol['DeviceID']
-
- vpd_83 = _vpd83_of_cim_vol(cim_vol)
-
- admin_state = Volume.ADMIN_STATE_ENABLED
-
- plugin_data = cim_path_to_path_str(cim_vol.path)
-
- return Volume(
- vol_id_of_cim_vol(cim_vol), user_name, vpd_83,
- cim_vol["BlockSize"], cim_vol["NumberOfBlocks"], admin_state, sys_id,
- pool_id, plugin_data)
-
-
-def lsm_vol_to_cim_vol_path(smis_common, lsm_vol):
- """
- Convert lsm.Volume to CIMInstanceName of CIM_StorageVolume using
- lsm.Volume.plugin_data
- """
- if not lsm_vol.plugin_data:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "Got lsm.Volume instance with empty plugin_data")
- if smis_common.system_list and \
- lsm_vol.system_id not in smis_common.system_list:
- raise LsmError(
- ErrorNumber.NOT_FOUND_SYSTEM,
- "System filtered in URI")
-
- return path_str_to_cim_path(lsm_vol.plugin_data)
-
-
-def volume_name_exists(smis_common, volume_name):
- """
- Try to minimize time to search.
- :param volume_name: Volume ElementName
- :return: True if volume exists with 'name', else False
- """
- all_cim_vols = smis_common.EnumerateInstances(
- 'CIM_StorageVolume', PropertyList=['ElementName'])
- for exist_cim_vol in all_cim_vols:
- if volume_name == exist_cim_vol['ElementName']:
- return True
- return False
-
-
-def volume_create_error_handler(smis_common, method_data, exec_info=None):
- """
- When we got CIMError, we check whether we got a duplicate volume name.
- The method_data is the requested volume name.
- """
- if volume_name_exists(smis_common, method_data):
- raise LsmError(ErrorNumber.NAME_CONFLICT,
- "Volume with name '%s' already exists!" % method_data)
-
- if exec_info is None:
- (error_type, error_msg, error_trace) = sys.exc_info()
- else:
- (error_type, error_msg, error_trace) = exec_info
- raise error_type, error_msg, error_trace
diff --git a/plugin/smispy/smispy_lsmplugin b/plugin/smispy/smispy_lsmplugin
deleted file mode 100755
index b0ea003..0000000
--- a/plugin/smispy/smispy_lsmplugin
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env python2
-
-# Copyright (C) 2011-2013 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: tasleson
-
-import sys
-import syslog
-import traceback
-
-try:
- from lsm import PluginRunner
- from lsm.plugin.smispy.smis import Smis
-
- if __name__ == '__main__':
- PluginRunner(Smis, sys.argv).run()
-except Exception:
- #This should be quite rare, but when it does happen this is pretty
- #key in understanding what happened, especially when it happens when
- #running from the daemon.
- msg = str(traceback.format_exc())
- syslog.syslog(syslog.LOG_ERR, msg)
- sys.stderr.write(msg)
- sys.exit(1)
diff --git a/plugin/smispy/utils.py b/plugin/smispy/utils.py
deleted file mode 100644
index 668241f..0000000
--- a/plugin/smispy/utils.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# 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, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# Author: Gris Ge <***@redhat.com>
-
-import traceback
-from lsm import (LsmError, ErrorNumber, error)
-from pywbem import (CIMError, CIMInstanceName)
-import pywbem
-import json
-
-
-def merge_list(list_a, list_b):
- return list(set(list_a + list_b))
-
-
-def handle_cim_errors(method):
- def cim_wrapper(*args, **kwargs):
- try:
- return method(*args, **kwargs)
- except LsmError as lsm:
- raise
- except CIMError as ce:
- error_code, desc = ce
-
- if error_code == 0:
- if 'Socket error' in desc:
- if 'Errno 111' in desc:
- raise LsmError(ErrorNumber.NETWORK_CONNREFUSED,
- 'Connection refused')
- if 'Errno 113' in desc:
- raise LsmError(ErrorNumber.NETWORK_HOSTDOWN,
- 'Host is down')
- elif 'SSL error' in desc:
- raise LsmError(ErrorNumber.TRANSPORT_COMMUNICATION,
- desc)
- elif 'The web server returned a bad status line':
- raise LsmError(ErrorNumber.TRANSPORT_COMMUNICATION,
- desc)
- elif 'HTTP error' in desc:
- raise LsmError(ErrorNumber.TRANSPORT_COMMUNICATION,
- desc)
- raise LsmError(ErrorNumber.PLUGIN_BUG, desc)
- except pywbem.cim_http.AuthError as ae:
- raise LsmError(ErrorNumber.PLUGIN_AUTH_FAILED, "Unauthorized user")
- except pywbem.cim_http.Error as te:
- raise LsmError(ErrorNumber.NETWORK_ERROR, str(te))
- except Exception as e:
- error("Unexpected exception:\n" + traceback.format_exc())
- raise LsmError(ErrorNumber.PLUGIN_BUG, str(e),
- traceback.format_exc())
- return cim_wrapper
-
-
-def hex_string_format(hex_str, length, every):
- hex_str = hex_str.lower()
- return ':'.join(hex_str[i:i + every] for i in range(0, length, every))
-
-
-def cim_path_to_path_str(cim_path):
- """
- Convert CIMInstanceName to a string which could save in plugin_data
- """
- return json.dumps({
- 'classname': cim_path.classname,
- 'keybindings': dict(cim_path.keybindings),
- 'host': cim_path.host,
- 'namespace': cim_path.namespace,
- })
-
-
-def path_str_to_cim_path(path_str):
- """
- Convert a string into CIMInstanceName.
- """
- path_dict = json.loads(path_str)
- return CIMInstanceName(**path_dict)
diff --git a/plugin/targetd/__init__.py b/plugin/targetd/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/plugin/targetd/targetd.py b/plugin/targetd/targetd.py
deleted file mode 100644
index a5e0274..0000000
--- a/plugin/targetd/targetd.py
+++ /dev/null
@@ -1,996 +0,0 @@
-# Copyright (C) 2011-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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: Andy Grover <agrover at redhat com>
-# Gris Ge <***@redhat.com>
-
-import copy
-
-from lsm import (Pool, Volume, System, Capabilities,
- IStorageAreaNetwork, INfs, FileSystem, FsSnapshot, NfsExport,
- LsmError, ErrorNumber, uri_parse, md5, VERSION,
- common_urllib2_error_handler, search_property,
- AccessGroup)
-
-import urllib2
-import json
-import time
-import urlparse
-import socket
-import re
-
-DEFAULT_USER = "admin"
-DEFAULT_PORT = 18700
-PATH = "/targetrpc"
-
-# Current sector size in liblvm
-_LVM_SECTOR_SIZE = 512
-
-
-def handle_errors(method):
- def target_wrapper(*args, **kwargs):
- try:
- return method(*args, **kwargs)
- except TargetdError as te:
- raise LsmError(ErrorNumber.PLUGIN_BUG,
- "Got error %d from targetd: %s"
- % (te.errno, te.reason))
- except LsmError:
- raise
- except Exception as e:
- common_urllib2_error_handler(e)
-
- return target_wrapper
-
-
-class TargetdError(Exception):
- VOLUME_MASKED = 303
- INVALID_METHOD = 32601
- INVALID_ARGUMENT = 32602
- NAME_CONFLICT = 50
- EXISTS_INITIATOR = 52
- NO_FREE_HOST_LUN_ID = 1000
- EMPTY_ACCESS_GROUP = 511
-
- def __init__(self, errno, reason, *args, **kwargs):
- Exception.__init__(self, *args, **kwargs)
- self.errno = int(errno)
- self.reason = reason
-
-
-class TargetdStorage(IStorageAreaNetwork, INfs):
- _FAKE_AG_PREFIX = 'init.'
- _MAX_H_LUN_ID = 255
-
- def __init__(self):
- self.uri = None
- self.password = None
- self.tmo = 0
- self.rpc_id = 1
- self.host_with_port = None
- self.scheme = None
- self.url = None
- self.headers = None
- self.system = System("targetd", "targetd storage appliance",
- System.STATUS_UNKNOWN, '')
-
- @handle_errors
- def plugin_register(self, uri, password, timeout, flags=0):
- self.uri = uri_parse(uri)
- self.password = password
- self.tmo = timeout
- self._flag_ag_support = True
-
- user = self.uri.get('username', DEFAULT_USER)
- port = self.uri.get('port', DEFAULT_PORT)
-
- self.host_with_port = "%s:%s" % (self.uri['host'], port)
- if self.uri['scheme'].lower() == 'targetd+ssl':
- self.scheme = 'https'
- else:
- self.scheme = 'http'
-
- self.url = urlparse.urlunsplit(
- (self.scheme, self.host_with_port, PATH, None, None))
-
- auth = ('%s:%s' % (user, self.password)).encode('base64')[:-1]
- self.headers = {'Content-Type': 'application/json',
- 'Authorization': 'Basic %s' % (auth,)}
-
- try:
- self._jsonrequest('access_group_list')
- except TargetdError as te:
- if te.errno == TargetdError.INVALID_METHOD:
- self._flag_ag_support = False
- else:
- raise
-
- @handle_errors
- def time_out_set(self, ms, flags=0):
- self.tmo = ms
-
- @handle_errors
- def time_out_get(self, flags=0):
- return self.tmo
-
- @handle_errors
- def plugin_unregister(self, flags=0):
- pass
-
- @handle_errors
- def capabilities(self, system, flags=0):
- cap = Capabilities()
- cap.set(Capabilities.VOLUMES)
- cap.set(Capabilities.VOLUME_CREATE)
- cap.set(Capabilities.VOLUME_REPLICATE)
- cap.set(Capabilities.VOLUME_REPLICATE_COPY)
- cap.set(Capabilities.VOLUME_DELETE)
- cap.set(Capabilities.VOLUME_MASK)
- cap.set(Capabilities.VOLUME_UNMASK)
- cap.set(Capabilities.FS)
- cap.set(Capabilities.FS_CREATE)
- cap.set(Capabilities.FS_DELETE)
- cap.set(Capabilities.FS_CLONE)
- cap.set(Capabilities.FS_SNAPSHOT_CREATE)
- cap.set(Capabilities.FS_SNAPSHOT_DELETE)
- cap.set(Capabilities.FS_SNAPSHOTS)
- cap.set(Capabilities.EXPORT_AUTH)
- cap.set(Capabilities.EXPORTS)
- cap.set(Capabilities.EXPORT_FS)
- cap.set(Capabilities.EXPORT_REMOVE)
- cap.set(Capabilities.ACCESS_GROUPS)
- cap.set(Capabilities.ACCESS_GROUPS_GRANTED_TO_VOLUME)
- cap.set(Capabilities.VOLUMES_ACCESSIBLE_BY_ACCESS_GROUP)
- cap.set(Capabilities.VOLUME_ISCSI_CHAP_AUTHENTICATION)
-
- if self._flag_ag_support:
- cap.set(Capabilities.ACCESS_GROUP_CREATE_ISCSI_IQN)
- cap.set(Capabilities.ACCESS_GROUP_INITIATOR_ADD_ISCSI_IQN)
- cap.set(Capabilities.ACCESS_GROUP_INITIATOR_DELETE)
- cap.set(Capabilities.ACCESS_GROUP_DELETE)
-
- return cap
-
- @handle_errors
- def plugin_info(self, flags=0):
- return "Linux LIO target support", VERSION
-
- @handle_errors
- def systems(self, flags=0):
- # verify we're online
- self._jsonrequest("pool_list")
-
- return [self.system]
-
- @handle_errors
- def job_status(self, job_id, flags=0):
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- @handle_errors
- def job_free(self, job_id, flags=0):
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- @staticmethod
- def _uuid_to_vpd83(uuid):
- """
- Convert LVM UUID to VPD 83 Device ID.
- LIO kernel module(target_core_mod.ko) does not expose VPD83 via
- ConfigFs.
- Targetd does not expose VPD83 via its API.
- Hence we have to do the convention here base on kernel code.
- """
- # NAA IEEE Registered Extended Identifier/Designator.
- # SPC-4 rev37a 7.8.6.6.5
- vpd83 = '6'
- # Use OpenFabrics IEEE Company ID: 00 14 05
- # https://standards.ieee.org/develop/regauth/oui/oui.txt
- vpd83 += '001405'
-
- # Take all [a-f0-9] digits from UUID for VENDOR_SPECIFIC_IDENTIFIER
- # and VENDOR_SPECIFIC_IDENTIFIER_EXTENTION
- vpd83 += re.sub('[^a-f0-9]', '', uuid.lower())[:25]
-
- # Fill up with zero.
- vpd83 += '0' * (32 - len(vpd83))
-
- return vpd83
-
- @handle_errors
- def volumes(self, search_key=None, search_value=None, flags=0):
- volumes = []
- for p_name in (p['name'] for p in self._jsonrequest("pool_list") if
- p['type'] == 'block'):
- for vol in self._jsonrequest("vol_list", dict(pool=p_name)):
- vpd83 = TargetdStorage._uuid_to_vpd83(vol['uuid'])
- volumes.append(
- Volume(vol['uuid'], vol['name'], vpd83, 512,
- long(vol['size'] / 512),
- Volume.ADMIN_STATE_ENABLED,
- self.system.id, p_name))
- return search_property(volumes, search_key, search_value)
-
- @handle_errors
- def pools(self, search_key=None, search_value=None, flags=0):
- pools = []
- for pool in self._jsonrequest("pool_list"):
- if pool['name'].startswith('/'):
- et = Pool.ELEMENT_TYPE_FS
- else:
- et = Pool.ELEMENT_TYPE_VOLUME
-
- pools.append(Pool(pool['name'],
- pool['name'], et, 0, pool['size'],
- pool['free_size'], Pool.STATUS_UNKNOWN, '',
- 'targetd'))
- return search_property(pools, search_key, search_value)
-
- @staticmethod
- def _tgt_ag_to_lsm(tgt_ag, sys_id):
- return AccessGroup(
- tgt_ag['name'], tgt_ag['name'], tgt_ag['init_ids'],
- AccessGroup.INIT_TYPE_ISCSI_IQN, sys_id)
-
- @staticmethod
- def _tgt_init_to_lsm(tgt_init, sys_id):
- return AccessGroup(
- "%s%s" % (
- TargetdStorage._FAKE_AG_PREFIX, md5(tgt_init['init_id'])),
- 'N/A', [tgt_init['init_id']], AccessGroup.INIT_TYPE_ISCSI_IQN,
- sys_id)
-
- @handle_errors
- def access_groups(self, search_key=None, search_value=None, flags=0):
- rc_lsm_ags = []
-
- # For backward compatibility
- if self._flag_ag_support is True:
- tgt_inits = self._jsonrequest(
- 'initiator_list', {'standalone_only': True})
- else:
- tgt_inits = list(
- {'init_id': x}
- for x in set(
- i['initiator_wwn']
- for i in self._jsonrequest("export_list")))
-
- rc_lsm_ags.extend(
- list(
- TargetdStorage._tgt_init_to_lsm(i, self.system.id)
- for i in tgt_inits))
-
- if self._flag_ag_support is True:
- for tgt_ag in self._jsonrequest('access_group_list'):
- rc_lsm_ags.append(
- TargetdStorage._tgt_ag_to_lsm(
- tgt_ag, self.system.id))
-
- return search_property(rc_lsm_ags, search_key, search_value)
-
- def _lsm_ag_of_id(self, ag_id, lsm_error_obj=None):
- """
- Raise provided error if defined when not found.
- Return lsm.AccessGroup if found.
- """
- lsm_ags = self.access_groups()
- for lsm_ag in lsm_ags:
- if lsm_ag.id == ag_id:
- return lsm_ag
-
- if lsm_error_obj:
- raise lsm_error_obj
-
- @handle_errors
- def access_group_create(self, name, init_id, init_type, system, flags=0):
- if system.id != self.system.id:
- raise LsmError(
- ErrorNumber.NOT_FOUND_SYSTEM,
- "System %s not found" % system.id)
- if self._flag_ag_support is False:
- raise LsmError(
- ErrorNumber.NO_SUPPORT,
- "Please upgrade your targetd package to support "
- "access_group_create()")
-
- if init_type != AccessGroup.INIT_TYPE_ISCSI_IQN:
- raise LsmError(ErrorNumber.NO_SUPPORT, "Only iSCSI yet")
-
- try:
- self._jsonrequest(
- "access_group_create",
- dict(ag_name=name, init_id=init_id, init_type='iscsi'))
- except TargetdError as tgt_error:
- if tgt_error.errno == TargetdError.EXISTS_INITIATOR:
- raise LsmError(
- ErrorNumber.EXISTS_INITIATOR,
- "Initiator is already used by other access group")
- elif tgt_error.errno == TargetdError.NAME_CONFLICT:
- raise LsmError(
- ErrorNumber.NAME_CONFLICT,
- "Requested access group name is already used by other "
- "access group")
- elif tgt_error.errno == TargetdError.INVALID_ARGUMENT:
- raise LsmError(
- ErrorNumber.INVALID_ARGUMENT,
- str(tgt_error))
- else:
- raise
-
- return self._lsm_ag_of_id(
- name,
- LsmError(
- ErrorNumber.PLUGIN_BUG,
- "access_group_create(): Failed to find the newly created "
- "access group"))
-
- @handle_errors
- def access_group_initiator_add(self, access_group, init_id, init_type,
- flags=0):
- if init_type != AccessGroup.INIT_TYPE_ISCSI_IQN:
- raise LsmError(
- ErrorNumber.NO_SUPPORT, "Targetd only support iscsi")
-
- lsm_ag = self._lsm_ag_of_id(
- access_group.name,
- LsmError(
- ErrorNumber.NOT_FOUND_ACCESS_GROUP, "Access group not found"))
-
- # Pre-check for NO_STATE_CHANGE error as targetd silently pass
- # if initiator is already in requested access group.
- if init_id in lsm_ag.init_ids:
- raise LsmError(
- ErrorNumber.NO_STATE_CHANGE,
- "Requested init_id is already in defined access group")
-
- try:
- self._jsonrequest(
- "access_group_init_add",
- dict(
- ag_name=access_group.name, init_id=init_id,
- init_type='iscsi'))
- except TargetdError as tgt_error:
- if tgt_error.errno == TargetdError.EXISTS_INITIATOR:
- raise LsmError(
- ErrorNumber.EXISTS_INITIATOR,
- "Initiator is already used by other access group")
- else:
- raise
-
- return self._lsm_ag_of_id(
- access_group.name,
- LsmError(
- ErrorNumber.PLUGIN_BUG,
- "access_group_initiator_add(): "
- "Failed to find the updated access group"))
-
- @handle_errors
- def access_group_initiator_delete(self, access_group, init_id, init_type,
- flags=0):
- if init_type != AccessGroup.INIT_TYPE_ISCSI_IQN:
- raise LsmError(
- ErrorNumber.NO_SUPPORT,
- "Targetd only support iscsi")
-
- # Pre-check for NO_STATE_CHANGE as targetd sliently return
- # when init_id not in requested access_group.
- lsm_ag = self._lsm_ag_of_id(
- access_group.name,
- LsmError(
- ErrorNumber.NOT_FOUND_ACCESS_GROUP, "Access group not found"))
-
- if init_id not in lsm_ag.init_ids:
- raise LsmError(
- ErrorNumber.NO_STATE_CHANGE,
- "Requested initiator is not in defined access group")
-
- if len(lsm_ag.init_ids) == 1:
- raise LsmError(
- ErrorNumber.LAST_INIT_IN_ACCESS_GROUP,
- "Refused to remove the last initiator from access group")
-
- self._jsonrequest(
- "access_group_init_del",
- dict(
- ag_name=access_group.name,
- init_id=init_id,
- init_type='iscsi'))
-
- return self._lsm_ag_of_id(
- access_group.name,
- LsmError(
- ErrorNumber.PLUGIN_BUG,
- "access_group_initiator_delete(): "
- "Failed to find the updated access group"))
-
- @handle_errors
- def access_group_delete(self, access_group, flags=0):
- if access_group.id.startswith(TargetdStorage._FAKE_AG_PREFIX):
- raise LsmError(
- ErrorNumber.NO_SUPPORT,
- "Cannot delete old initiator simulated access group, "
- "they will be automatically deleted when no volume masked to")
-
- if self._flag_ag_support is False:
- raise LsmError(
- ErrorNumber.NO_SUPPORT,
- "Please upgrade your targetd package to support "
- "access_group_delete()")
-
- self._lsm_ag_of_id(
- access_group.id,
- LsmError(
- ErrorNumber.NOT_FOUND_ACCESS_GROUP,
- "Access group not found"))
-
- if list(m for m in self._tgt_masks() if m['ag_id'] == access_group.id):
- raise LsmError(
- ErrorNumber.IS_MASKED,
- "Cannot delete access group which has volume masked to")
-
- self._jsonrequest(
- "access_group_destroy", {'ag_name': access_group.name})
- return None
-
- def _tgt_masks(self):
- """
- Return a list of tgt_mask:
- {
- 'pool_name': pool_name,
- 'vol_name': vol_name,
- 'ag_id': lsm_ag.id,
- 'h_lun_id': h_lun_id,
- }
- """
- tgt_masks = []
- for tgt_exp in self._jsonrequest("export_list"):
- tgt_masks.append({
- 'ag_id': "%s%s" % (
- TargetdStorage._FAKE_AG_PREFIX,
- md5(tgt_exp['initiator_wwn'])),
- 'vol_name': tgt_exp['vol_name'],
- 'pool_name': tgt_exp['pool'],
- 'h_lun_id': tgt_exp['lun'],
- })
- if self._flag_ag_support:
- for tgt_ag_map in self._jsonrequest("access_group_map_list"):
- tgt_masks.append({
- 'ag_id': tgt_ag_map['ag_name'],
- 'vol_name': tgt_ag_map['vol_name'],
- 'pool_name': tgt_ag_map['pool_name'],
- 'h_lun_id': tgt_ag_map['h_lun_id'],
- })
-
- return tgt_masks
-
- def _is_masked(self, ag_id, pool_name, vol_name, tgt_masks=None):
- """
- Check whether volume is masked to certain access group.
- Return True or False
- """
- if tgt_masks is None:
- tgt_masks = self._tgt_masks()
- return list(
- m for m in tgt_masks
- if (m['vol_name'] == vol_name and
- m['pool_name'] == pool_name and
- m['ag_id'] == ag_id)
- ) != []
-
- def _lsm_vol_of_id(self, vol_id, error=None):
- try:
- return list(v for v in self.volumes() if v.id == vol_id)[0]
- except IndexError:
- if error:
- raise error
- else:
- return None
-
- @handle_errors
- def volume_mask(self, access_group, volume, flags=0):
- self._lsm_ag_of_id(
- access_group.id,
- LsmError(
- ErrorNumber.NOT_FOUND_ACCESS_GROUP, "Access group not found"))
-
- self._lsm_vol_of_id(
- volume.id,
- LsmError(
- ErrorNumber.NOT_FOUND_VOLUME, "Volume not found"))
-
- tgt_masks = self._tgt_masks()
- if self._is_masked(
- access_group.id, volume.pool_id, volume.name, tgt_masks):
- raise LsmError(
- ErrorNumber.NO_STATE_CHANGE,
- "Volume is already masked to requested access group")
-
- if access_group.id.startswith(TargetdStorage._FAKE_AG_PREFIX):
- free_h_lun_ids = (
- set(range(TargetdStorage._MAX_H_LUN_ID + 1)) -
- set([m['h_lun_id'] for m in tgt_masks]))
-
- if len(free_h_lun_ids) == 0:
- # TODO(Gris Ge): Add SYSTEM_LIMIT error into API
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "System limit: targetd only allows %s LUN masked" %
- TargetdStorage._MAX_H_LUN_ID)
-
- h_lun_id = free_h_lun_ids.pop()
-
- self._jsonrequest(
- "export_create",
- {
- 'pool': volume.pool_id,
- 'vol': volume.name,
- 'initiator_wwn': access_group.init_ids[0],
- 'lun': h_lun_id
- })
- else:
- try:
- self._jsonrequest(
- 'access_group_map_create',
- {
- 'pool_name': volume.pool_id,
- 'vol_name': volume.name,
- 'ag_name': access_group.id,
- })
- except TargetdError as tgt_error:
- if tgt_error.errno == TargetdError.NO_FREE_HOST_LUN_ID:
- # TODO(Gris Ge): Add SYSTEM_LIMIT error into API
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "System limit: targetd only allows %s LUN masked" %
- TargetdStorage._MAX_H_LUN_ID)
- elif tgt_error.errno == TargetdError.EMPTY_ACCESS_GROUP:
- raise LsmError(
- ErrorNumber.NOT_FOUND_ACCESS_GROUP,
- "Access group not found")
- else:
- raise
-
- return None
-
- @handle_errors
- def volume_unmask(self, volume, access_group, flags=0):
- self._lsm_ag_of_id(
- access_group.id,
- LsmError(
- ErrorNumber.NOT_FOUND_ACCESS_GROUP, "Access group not found"))
-
- self._lsm_vol_of_id(
- volume.id,
- LsmError(
- ErrorNumber.NOT_FOUND_VOLUME, "Volume not found"))
-
- # Pre-check if already unmasked
- if not self._is_masked(access_group.id, volume.pool_id, volume.name):
- raise LsmError(ErrorNumber.NO_STATE_CHANGE,
- "Volume is not masked to requested access group")
-
- if access_group.id.startswith(TargetdStorage._FAKE_AG_PREFIX):
- self._jsonrequest("export_destroy",
- dict(pool=volume.pool_id,
- vol=volume.name,
- initiator_wwn=access_group.init_ids[0]))
- else:
- self._jsonrequest(
- "access_group_map_destroy",
- {
- 'pool_name': volume.pool_id,
- 'vol_name': volume.name,
- 'ag_name': access_group.id,
- })
-
- return None
-
- @handle_errors
- def volumes_accessible_by_access_group(self, access_group, flags=0):
- tgt_masks = self._tgt_masks()
-
- vol_infos = list(
- [m['vol_name'], m['pool_name']]
- for m in tgt_masks
- if m['ag_id'] == access_group.id)
-
- if len(vol_infos) == 0:
- return []
-
- rc_lsm_vols = []
- return list(
- lsm_vol
- for lsm_vol in self.volumes(flags=flags)
- if [lsm_vol.name, lsm_vol.pool_id] in vol_infos)
-
- @handle_errors
- def access_groups_granted_to_volume(self, volume, flags=0):
- tgt_masks = self._tgt_masks()
- ag_ids = list(
- m['ag_id']
- for m in tgt_masks
- if (m['vol_name'] == volume.name and
- m['pool_name'] == volume.pool_id))
-
- lsm_ags = self.access_groups(flags=flags)
- return [x for x in lsm_ags if x.id in ag_ids]
-
- def _get_volume(self, pool_id, volume_name):
- vol = [v for v in self._jsonrequest("vol_list", dict(pool=pool_id))
- if v['name'] == volume_name][0]
-
- vpd83 = TargetdStorage._uuid_to_vpd83(vol['uuid'])
- return Volume(vol['uuid'], vol['name'], vpd83, 512,
- vol['size'] / 512,
- Volume.ADMIN_STATE_ENABLED,
- self.system.id,
- pool_id)
-
- def _get_fs(self, pool_id, fs_name):
- fs = self.fs()
- for f in fs:
- if f.name == fs_name and f.pool_id == pool_id:
- return f
- return None
-
- def _get_ss(self, fs, ss_name):
- ss = self.fs_snapshots(fs)
- for s in ss:
- if s.name == ss_name:
- return s
- return None
-
- @handle_errors
- def volume_create(self, pool, volume_name, size_bytes, provisioning,
- flags=0):
- if provisioning != Volume.PROVISION_DEFAULT:
- raise LsmError(ErrorNumber.INVALID_ARGUMENT,
- "Unsupported provisioning")
-
- # Make sure size_bytes round up with _LVM_SECTOR_SIZE
- if size_bytes:
- remainder = size_bytes % _LVM_SECTOR_SIZE
- if remainder:
- size_bytes = size_bytes + _LVM_SECTOR_SIZE - remainder
- else:
- size_bytes = _LVM_SECTOR_SIZE
-
- self._jsonrequest("vol_create", dict(pool=pool.id,
- name=volume_name,
- size=size_bytes))
-
- return None, self._get_volume(pool.id, volume_name)
-
- @handle_errors
- def volume_delete(self, volume, flags=0):
- try:
- self._jsonrequest("vol_destroy",
- dict(pool=volume.pool_id, name=volume.name))
- except TargetdError as te:
- if te.errno == TargetdError.VOLUME_MASKED:
- raise LsmError(ErrorNumber.IS_MASKED,
- "Volume is masked to access group")
- raise
-
- @handle_errors
- def volume_replicate(self, pool, rep_type, volume_src, name, flags=0):
- if rep_type != Volume.REPLICATE_COPY:
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- #pool id is optional, use volume src as default
- pool_id = volume_src.pool_id
- if pool:
- pool_id = pool.id
-
- self._jsonrequest("vol_copy",
- dict(pool=pool_id, vol_orig=volume_src.name,
- vol_new=name))
-
- return None, self._get_volume(pool_id, name)
-
- @handle_errors
- def iscsi_chap_auth(self, init_id, in_user, in_password, out_user,
- out_password, flags=0):
- self._jsonrequest("initiator_set_auth",
- dict(initiator_wwn=init_id,
- in_user=in_user,
- in_pass=in_password,
- out_user=out_user,
- out_pass=out_password))
-
- return None
-
- @handle_errors
- def fs(self, search_key=None, search_value=None, flags=0):
- rc = []
- for fs in self._jsonrequest("fs_list"):
- #self, id, name, total_space, free_space, pool_id, system_id
- rc.append(FileSystem(fs['uuid'], fs['name'], fs['total_space'],
- fs['free_space'], fs['pool'], self.system.id))
- return search_property(rc, search_key, search_value)
-
- @handle_errors
- def fs_delete(self, fs, flags=0):
- self._jsonrequest("fs_destroy", dict(uuid=fs.id))
-
- @handle_errors
- def fs_create(self, pool, name, size_bytes, flags=0):
- self._jsonrequest("fs_create", dict(pool_name=pool.id, name=name,
- size_bytes=size_bytes))
-
- return None, self._get_fs(pool.name, name)
-
- @handle_errors
- def fs_clone(self, src_fs, dest_fs_name, snapshot=None, flags=0):
-
- ss_id = None
- if snapshot:
- ss_id = snapshot.id
-
- self._jsonrequest("fs_clone", dict(fs_uuid=src_fs.id,
- dest_fs_name=dest_fs_name,
- snapshot_id=ss_id))
-
- return None, self._get_fs(src_fs.pool_id, dest_fs_name)
-
- @handle_errors
- def fs_snapshots(self, fs, flags=0):
- rc = []
- for ss in self._jsonrequest("ss_list", dict(fs_uuid=fs.id)):
- #id, name, timestamp
- rc.append(FsSnapshot(ss['uuid'], ss['name'], ss['timestamp']))
- return rc
-
- @handle_errors
- def fs_snapshot_create(self, fs, snapshot_name, flags=0):
-
- self._jsonrequest("fs_snapshot", dict(fs_uuid=fs.id,
- dest_ss_name=snapshot_name))
-
- return None, self._get_ss(fs, snapshot_name)
-
- @handle_errors
- def fs_snapshot_delete(self, fs, snapshot, flags=0):
- self._jsonrequest("fs_snapshot_delete", dict(fs_uuid=fs.id,
- ss_uuid=snapshot.id))
-
- @handle_errors
- def export_auth(self, flags=0):
- exports = self._jsonrequest("nfs_export_auth_list")
- return exports
-
- @staticmethod
- def _get_value(options, key):
- for o in options:
- if '=' in o:
- k, v = o.split('=')
- if k == key:
- return v
- return None
-
- @staticmethod
- def _option_string(nfs_options):
- cpy = copy.copy(nfs_options)
- if 'ro' in cpy:
- cpy.remove('ro')
- if 'rw' in cpy:
- cpy.remove('rw')
- if 'no_root_squash' in cpy:
- cpy.remove('no_root_squash')
- if 'root_squash' in cpy:
- cpy.remove('root_squash')
-
- cpy.sort()
- s = ','.join(cpy)
- return s
-
- @staticmethod
- def _calculate_export_md5(export_path, options):
- opts = TargetdStorage._option_string(options)
- return md5(export_path + opts)
-
- @handle_errors
- def exports(self, search_key=None, search_value=None, flags=0):
- tmp_exports = {}
- exports = []
- fs_full_paths = {}
- all_nfs_exports = self._jsonrequest("nfs_export_list")
- nfs_exports = []
-
- #Remove those that are not of FS origin
- fs_list = self._jsonrequest("fs_list")
- for f in fs_list:
- fs_full_paths[f['full_path']] = f
-
- for export in all_nfs_exports:
- if export['path'] in fs_full_paths:
- nfs_exports.append(export)
-
- #Collect like exports to minimize results
- for export in nfs_exports:
- key = export['path'] + \
- TargetdStorage._option_string(export['options'])
- if key in tmp_exports:
- tmp_exports[key].append(export)
- else:
- tmp_exports[key] = [export]
-
- #Walk through the options
- for le in tmp_exports.values():
- export_id = ""
- root = []
- rw = []
- ro = []
- sec = None
- anonuid = NfsExport.ANON_UID_GID_NA
- anongid = NfsExport.ANON_UID_GID_NA
-
- options = None
-
- for export in le:
-
- host = export['host']
- export_id += host
- export_id += export['path']
- export_id += fs_full_paths[export['path']]['uuid']
-
- options = export['options']
-
- if 'rw' in options:
- rw.append(host)
-
- if 'ro' in options:
- ro.append(host)
-
- sec = TargetdStorage._get_value(options, 'sec')
- if sec is None:
- sec = 'sys'
-
- if 'no_root_squash' in options:
- root.append(host)
-
- uid = TargetdStorage._get_value(options, 'anonuid')
- if uid is not None:
- anonuid = uid
- gid = TargetdStorage._get_value(options, 'anongid')
- if gid is not None:
- anongid = gid
-
- exports.append(
- NfsExport(TargetdStorage._calculate_export_md5(export['path'],
- options),
- fs_full_paths[export['path']]['uuid'],
- export['path'], sec, root, rw, ro, anonuid, anongid,
- TargetdStorage._option_string(options)))
-
- return search_property(exports, search_key, search_value)
-
- def _get_fs_path(self, fs_id):
- for fs in self._jsonrequest("fs_list"):
- if fs_id == fs['uuid']:
- return fs['full_path']
- return None
-
- @handle_errors
- def export_fs(
- self, fs_id, export_path, root_list, rw_list, ro_list,
- anon_uid=NfsExport.ANON_UID_GID_NA,
- anon_gid=NfsExport.ANON_UID_GID_NA,
- auth_type=None, options=None, flags=0):
-
- if export_path is not None:
- raise LsmError(ErrorNumber.INVALID_ARGUMENT,
- 'export_path required to be None')
-
- base_opts = []
-
- if anon_uid is not None:
- base_opts.append('anonuid=%s' % str(anon_uid))
-
- if anon_gid is not None:
- base_opts.append('anongid=%s' % str(anon_gid))
-
- if auth_type is not None:
- base_opts.append('sec=%s' % str(auth_type))
-
- fs_path = self._get_fs_path(fs_id)
- if fs_path is None:
- raise LsmError(ErrorNumber.NOT_FOUND_FS, "File system not found")
-
- for host in rw_list:
- tmp_opts = copy.copy(base_opts)
- if host in root_list:
- tmp_opts.append('no_root_squash')
-
- tmp_opts.append('rw')
-
- self._jsonrequest("nfs_export_add",
- dict(host=host, path=fs_path,
- export_path=None, options=tmp_opts))
-
- for host in ro_list:
- tmp_opts = copy.copy(base_opts)
- if host in root_list:
- tmp_opts.append('no_root_squash')
-
- tmp_opts.append('ro')
-
- self._jsonrequest("nfs_export_add",
- dict(host=host, path=fs_path,
- export_path=None, options=tmp_opts))
-
- #Kind of a pain to determine which export was newly created as it
- #could get merged into an existing record, doh!
- #Make sure fs_id's match and that one of the hosts is in the
- #record.
- exports = self.exports()
- h = []
- h.extend(rw_list)
- h.extend(ro_list)
- for host in exports:
- if host.fs_id == fs_id:
- l = []
- l.extend(host.ro)
- l.extend(host.rw)
- for host_entry in h:
- if host_entry in l:
- return host
-
- raise LsmError(ErrorNumber.PLUGIN_BUG, "Failed to create export")
-
- @handle_errors
- def export_remove(self, export, flags=0):
-
- for host in export.rw:
- params = dict(host=host, path=export.export_path)
- self._jsonrequest("nfs_export_remove", params)
-
- for host in export.ro:
- params = dict(host=host, path=export.export_path)
- self._jsonrequest("nfs_export_remove", params)
-
- def _jsonrequest(self, method, params=None):
- data = json.dumps(dict(id=self.rpc_id, method=method,
- params=params, jsonrpc="2.0"))
- self.rpc_id += 1
-
- try:
- request = urllib2.Request(self.url, data, self.headers)
- response_obj = urllib2.urlopen(request)
- except socket.error:
- raise LsmError(ErrorNumber.NETWORK_ERROR,
- "Unable to connect to targetd, uri right?")
-
- response_data = response_obj.read()
- response = json.loads(response_data)
- if response.get('error', None) is None:
- return response.get('result')
- else:
- if response['error']['code'] <= 0:
- #error_text = "%s:%s" % (str(response['error']['code']),
- # response['error'].get('message', ''))
-
- raise TargetdError(abs(int(response['error']['code'])),
- response['error'].get('message', ''))
- else: # +code is async execution id
- #Async completion, polling for results
- async_code = response['error']['code']
- while True:
- time.sleep(1)
- results = self._jsonrequest('async_list')
- status = results.get(str(async_code), None)
- if status:
- if status[0]:
- raise LsmError(
- ErrorNumber.PLUGIN_BUG,
- "%d has error %d" % (async_code, status[0]))
diff --git a/plugin/targetd/targetd_lsmplugin b/plugin/targetd/targetd_lsmplugin
deleted file mode 100755
index 3a75334..0000000
--- a/plugin/targetd/targetd_lsmplugin
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env python2
-
-# Copyright (C) 2011-2013 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: Andy Grover <agrover at redhat com>
-
-import sys
-import syslog
-import traceback
-
-try:
- from lsm import PluginRunner
- from lsm.plugin.targetd.targetd import TargetdStorage
-
- if __name__ == '__main__':
- PluginRunner(TargetdStorage, sys.argv).run()
-except Exception:
- #This should be quite rare, but when it does happen this is pretty
- #key in understanding what happened, especially when it happens when
- #running from the daemon.
- msg = str(traceback.format_exc())
- syslog.syslog(syslog.LOG_ERR, msg)
- sys.stderr.write(msg)
- sys.exit(1)
diff --git a/python_binding/Makefile.am b/python_binding/Makefile.am
deleted file mode 100644
index 8b0581a..0000000
--- a/python_binding/Makefile.am
+++ /dev/null
@@ -1,17 +0,0 @@
-
-lsmdir = $(pythondir)/lsm
-externaldir = $(lsmdir)/external
-
-lsm_PYTHON = \
- lsm/__init__.py \
- lsm/_client.py \
- lsm/_common.py \
- lsm/_data.py \
- lsm/_transport.py \
- lsm/version.py \
- lsm/_iplugin.py \
- lsm/_pluginrunner.py
-
-external_PYTHON = \
- lsm/external/__init__.py \
- lsm/external/xmltodict.py
diff --git a/python_binding/lsm/__init__.py b/python_binding/lsm/__init__.py
deleted file mode 100644
index fb1cdbd..0000000
--- a/python_binding/lsm/__init__.py
+++ /dev/null
@@ -1,15 +0,0 @@
-__all__ = []
-
-from version import VERSION
-
-from _common import error, info, LsmError, ErrorNumber, \
- JobStatus, uri_parse, md5, Proxy, size_bytes_2_size_human, \
- common_urllib2_error_handler, size_human_2_size_bytes
-from _data import (Disk, Volume, Pool, System, FileSystem, FsSnapshot,
- NfsExport, BlockRange, AccessGroup, TargetPort,
- Capabilities)
-from _iplugin import IPlugin, IStorageAreaNetwork, INetworkAttachedStorage, \
- INfs
-
-from _client import Client
-from _pluginrunner import PluginRunner, search_property
diff --git a/python_binding/lsm/_client.py b/python_binding/lsm/_client.py
deleted file mode 100644
index a641b1d..0000000
--- a/python_binding/lsm/_client.py
+++ /dev/null
@@ -1,1076 +0,0 @@
-# Copyright (C) 2011-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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: tasleson
-
-import os
-from lsm import (Volume, NfsExport, Capabilities, Pool, System,
- Disk, AccessGroup, FileSystem, FsSnapshot,
- uri_parse, LsmError, ErrorNumber,
- INetworkAttachedStorage, TargetPort)
-
-from _common import return_requires as _return_requires
-from _common import UDS_PATH as _UDS_PATH
-from _transport import TransPort as _TransPort
-from _data import IData as _IData
-
-
-## Removes self for the hash d
-# @param d Hash to remove self from
-# @returns d with hash removed.
-def _del_self(d):
- """
- Used to remove the self key from the dict d. Self is included when calling
- the function locals() in a class method.
- """
- del d['self']
- return d
-
-
-def _check_search_key(search_key, supported_keys):
- if search_key and search_key not in supported_keys:
- raise LsmError(ErrorNumber.UNSUPPORTED_SEARCH_KEY,
- "Unsupported search_key: '%s'" % search_key)
- return
-
-
-## Descriptive exception about daemon not running.
-def _raise_no_daemon():
- raise LsmError(ErrorNumber.DAEMON_NOT_RUNNING,
- "The libStorageMgmt daemon is not running (process "
- "name lsmd), try 'service libstoragemgmt start'")
-
-
-## Main client class for library.
-# ** IMPORTANT **
-# Theory of operation for methods in this class.
-# We are using the name of the method and the name of the parameters and
-# using python introspection abilities to translate them to the method and
-# parameter names. Makes the code compact, but you will break things if the
-# IPlugin class does not match the method names and parameters here!
-class Client(INetworkAttachedStorage):
-
- ##
- # Used for default flag value
- #
- FLAG_RSVD = 0
-
- """
- Client side class used for managing storage that utilises RPC mechanism.
- """
- ## Method added so that the interface for the client RPC and the plug-in
- ## itself match.
- def plugin_register(self, uri, plain_text_password, timeout_ms, flags=0):
- raise RuntimeError("Do not call directly!")
-
- ## Called when we are ready to initialize the plug-in.
- # @param self The this pointer
- # @param uri The uniform resource identifier
- # @param plain_text_password Password as plain text
- # @param timeout_ms The timeout in ms
- # @param flags Reserved for future use, must be zero.
- # @returns None
- def __start(self, uri, password, timeout, flags=0):
- """
- Instruct the plug-in to get ready
- """
- self._tp.rpc('plugin_register', _del_self(locals()))
-
- ## Checks to see if any unix domain sockets exist in the base directory
- # and opens a socket to one to see if the server is actually there.
- # @param self The this pointer
- # @returns True if daemon appears to be present, else false.
- @staticmethod
- def _check_daemon_exists():
- uds_path = Client._plugin_uds_path()
- if os.path.exists(uds_path):
- for root, sub_folders, files in os.walk(uds_path):
- for filename in files:
- uds = os.path.join(root, filename)
-
- try:
- #This operation will work if the daemon is available
- s = _TransPort.get_socket(uds)
- s.close()
- return True
- except LsmError:
- pass
- else:
- #Base directory is not present?
- pass
- return False
-
- @staticmethod
- def _plugin_uds_path():
- rc = _UDS_PATH
-
- if 'LSM_UDS_PATH' in os.environ:
- rc = os.environ['LSM_UDS_PATH']
-
- return rc
-
- ## Class constructor
- # @param self The this pointer
- # @param uri The uniform resource identifier
- # @param plain_text_password Password as plain text (Optional)
- # @param timeout_ms The timeout in ms
- # @param flags Reserved for future use, must be zero.
- # @returns None
- def __init__(self, uri, plain_text_password=None, timeout_ms=30000,
- flags=0):
- self._uri = uri
- self._password = plain_text_password
- self._timeout = timeout_ms
- self._uds_path = Client._plugin_uds_path()
-
- u = uri_parse(uri, ['scheme'])
-
- scheme = u['scheme']
- if "+" in scheme:
- (plug, proto) = scheme.split("+")
- scheme = plug
-
- self.plugin_path = os.path.join(self._uds_path, scheme)
-
- if os.path.exists(self.plugin_path):
- self._tp = _TransPort(_TransPort.get_socket(self.plugin_path))
- else:
- #At this point we don't know if the user specified an incorrect
- #plug-in in the URI or the daemon isn't started. We will check
- #the directory for other unix domain sockets.
- if Client._check_daemon_exists():
- raise LsmError(ErrorNumber.PLUGIN_NOT_EXIST,
- "Plug-in %s not found!" % self.plugin_path)
- else:
- _raise_no_daemon()
-
- self.__start(uri, plain_text_password, timeout_ms, flags)
-
- ## Synonym for close.
- @_return_requires(None)
- def plugin_unregister(self, flags=FLAG_RSVD):
- """
- Synonym for close.
- """
- self.close(flags)
-
- ## Does an orderly plugin_unregister of the plug-in
- # @param self The this pointer
- # @param flags Reserved for future use, must be zero.
- @_return_requires(None)
- def close(self, flags=FLAG_RSVD):
- """
- Does an orderly plugin_unregister of the plug-in
- """
- self._tp.rpc('plugin_unregister', _del_self(locals()))
- self._tp.close()
- self._tp = None
-
- ## Retrieves all the available plug-ins
- @staticmethod
- @_return_requires([unicode])
- def available_plugins(field_sep=':', flags=FLAG_RSVD):
- """
- Retrieves all the available plug-ins
-
- Return list of strings of available plug-ins with the
- "desc<sep>version"
- """
- rc = []
-
- if not Client._check_daemon_exists():
- _raise_no_daemon()
-
- uds_path = Client._plugin_uds_path()
-
- for root, sub_folders, files in os.walk(uds_path):
- for filename in files:
- uds = os.path.join(root, filename)
- tp = _TransPort(_TransPort.get_socket(uds))
- i, v = tp.rpc('plugin_info', dict(flags=Client.FLAG_RSVD))
- rc.append("%s%s%s" % (i, field_sep, v))
- tp.close()
-
- return rc
-
- ## Sets the timeout for the plug-in
- # @param self The this pointer
- # @param ms Time-out in ms
- # @param flags Reserved for future use, must be zero.
- @_return_requires(None)
- def time_out_set(self, ms, flags=FLAG_RSVD):
- """
- Sets any time-outs for the plug-in (ms)
-
- Return None on success, else LsmError exception
- """
- return self._tp.rpc('time_out_set', _del_self(locals()))
-
- ## Retrieves the current time-out value.
- # @param self The this pointer
- # @param flags Reserved for future use, must be zero.
- # @returns Time-out value
- @_return_requires(int)
- def time_out_get(self, flags=FLAG_RSVD):
- """
- Retrieves the current time-out
-
- Return time-out in ms, else raise LsmError
- """
- return self._tp.rpc('time_out_get', _del_self(locals()))
-
- ## Retrieves the status of the specified job id.
- # @param self The this pointer
- # @param job_id The job identifier
- # @param flags Reserved for future use, must be zero.
- # @returns A tuple ( status (enumeration), percent_complete,
- # completed item)
- @_return_requires(int, int, _IData)
- def job_status(self, job_id, flags=FLAG_RSVD):
- """
- Returns the stats of the given job.
-
- Returns a tuple ( status (enumeration), percent_complete,
- completed item).
- else LsmError exception.
- """
- return self._tp.rpc('job_status', _del_self(locals()))
-
- ## Frees the resources for the specified job id.
- # @param self The this pointer
- # @param job_id Job id in which to release resource for
- # @param flags Reserved for future use, must be zero.
- @_return_requires(None)
- def job_free(self, job_id, flags=FLAG_RSVD):
- """
- Frees resources for a given job number.
-
- Returns None on success, else raises an LsmError
- """
- return self._tp.rpc('job_free', _del_self(locals()))
-
- ## Gets the capabilities of the array.
- # @param self The this pointer
- # @param system The system of interest
- # @param flags Reserved for future use, must be zero.
- # @returns Capability object
- @_return_requires(Capabilities)
- def capabilities(self, system, flags=FLAG_RSVD):
- """
- Fetches the capabilities of the array
-
- Returns a capability object, see data,py for details.
- """
- return self._tp.rpc('capabilities', _del_self(locals()))
-
- ## Gets information about the plug-in
- # @param self The this pointer
- # @param flags Reserved for future use
- # @returns Tuple (description, version)
- @_return_requires(unicode, unicode)
- def plugin_info(self, flags=FLAG_RSVD):
- """
- Returns a description and version of plug-in
- """
- return self._tp.rpc('plugin_info', _del_self(locals()))
-
- ## Returns an array of pool objects.
- # @param self The this pointer
- # @param search_key Search key
- # @param search_value Search value
- # @param flags Reserved for future use, must be zero.
- # @returns An array of pool objects.
- @_return_requires([Pool])
- def pools(self, search_key=None, search_value=None, flags=FLAG_RSVD):
- """
- Returns an array of pool objects. Pools are used in both block and
- file system interfaces, thus the reason they are in the base class.
- """
- _check_search_key(search_key, Pool.SUPPORTED_SEARCH_KEYS)
- return self._tp.rpc('pools', _del_self(locals()))
-
- ## Returns an array of system objects.
- # @param self The this pointer
- # @param flags Reserved for future use, must be zero.
- # @returns An array of system objects.
- @_return_requires([System])
- def systems(self, flags=FLAG_RSVD):
- """
- Returns an array of system objects. System information is used to
- distinguish resources from on storage array to another when the plug=in
- supports the ability to have more than one array managed by it
- """
- return self._tp.rpc('systems', _del_self(locals()))
-
- ## Register a user/password for the specified initiator for CHAP
- # authentication.
- # Note: If you pass an empty user and password the expected behavior is to
- # remove any authentication for the specified initiator.
- # @param self The this pointer
- # @param init_id The initiator ID
- # @param in_user User for inbound CHAP
- # @param in_password Password for inbound CHAP
- # @param out_user Outbound username
- # @param out_password Outbound password
- # @param flags Reserved for future use, must be zero.
- # @returns None on success, throws LsmError on errors.
- @_return_requires(None)
- def iscsi_chap_auth(self, init_id, in_user, in_password,
- out_user, out_password, flags=FLAG_RSVD):
- """
- Register a user/password for the specified initiator for CHAP
- authentication.
- """
- AccessGroup.initiator_id_verify(init_id,
- AccessGroup.INIT_TYPE_ISCSI_IQN,
- raise_exception=True)
- return self._tp.rpc('iscsi_chap_auth', _del_self(locals()))
-
- ## Returns an array of volume objects
- # @param self The this pointer
- # @param search_key Search key to use
- # @param search_value Search value
- # @param flags Reserved for future use, must be zero.
- # @returns An array of volume objects.
- @_return_requires([Volume])
- def volumes(self, search_key=None, search_value=None, flags=FLAG_RSVD):
- """
- Returns an array of volume objects
- """
- _check_search_key(search_key, Volume.SUPPORTED_SEARCH_KEYS)
- return self._tp.rpc('volumes', _del_self(locals()))
-
- ## Creates a volume
- # @param self The this pointer
- # @param pool The pool object to allocate storage from
- # @param volume_name The human text name for the volume
- # @param size_bytes Size of the volume in bytes
- # @param provisioning How the volume is to be provisioned
- # @param flags Reserved for future use, must be zero.
- # @returns A tuple (job_id, new volume), when one is None the other is
- # valid.
- @_return_requires(unicode, Volume)
- def volume_create(self, pool, volume_name, size_bytes, provisioning,
- flags=FLAG_RSVD):
- """
- Creates a volume, given a pool, volume name, size and provisioning
-
- returns a tuple (job_id, new volume)
- Note: Tuple return values are mutually exclusive, when one
- is None the other must be valid.
- """
- return self._tp.rpc('volume_create', _del_self(locals()))
-
- ## Re-sizes a volume
- # @param self The this pointer
- # @param volume The volume object to re-size
- # @param new_size_bytes Size of the volume in bytes
- # @param flags Reserved for future use, must be zero.
- # @returns A tuple (job_id, new re-sized volume), when one is
- # None the other is valid.
- @_return_requires(unicode, Volume)
- def volume_resize(self, volume, new_size_bytes, flags=FLAG_RSVD):
- """
- Re-sizes a volume.
-
- Returns a tuple (job_id, re-sized_volume)
- Note: Tuple return values are mutually exclusive, when one
- is None the other must be valid.
- """
- return self._tp.rpc('volume_resize', _del_self(locals()))
-
- ## Replicates a volume from the specified pool.
- # @param self The this pointer
- # @param pool The pool to re-size from
- # @param rep_type Replication type
- # (enumeration,see common.data.Volume)
- # @param volume_src The volume to replicate
- # @param name Human readable name of replicated volume
- # @param flags Reserved for future use, must be zero.
- # @returns A tuple (job_id, new replicated volume), when one is
- # None the other is valid.
- @_return_requires(unicode, Volume)
- def volume_replicate(self, pool, rep_type, volume_src, name,
- flags=FLAG_RSVD):
- """
- Replicates a volume from the specified pool.
-
- Returns a tuple (job_id, replicated volume)
- Note: Tuple return values are mutually exclusive, when one
- is None the other must be valid.
- """
- return self._tp.rpc('volume_replicate', _del_self(locals()))
-
- ## Size of a replicated block.
- # @param self The this pointer
- # @param system The system to request the rep. block range size from
- # @param flags Reserved for future use, must be zero
- # @returns Size of the replicated block in bytes
- @_return_requires(int)
- def volume_replicate_range_block_size(self, system, flags=FLAG_RSVD):
- """
- Returns the size of a replicated block in bytes.
- """
- return self._tp.rpc('volume_replicate_range_block_size',
- _del_self(locals()))
-
- ## Replicates a portion of a volume to itself or another volume.
- # @param self The this pointer
- # @param rep_type Replication type
- # (enumeration, see common.data.Volume)
- # @param volume_src The volume src to replicate from
- # @param volume_dest The volume dest to replicate to
- # @param ranges An array of Block range objects
- # @see lsm.common.data.BlockRange
- # @param flags Reserved for future use, must be zero.
- # @returns Job id or None when completed, else raises LsmError on errors.
- @_return_requires(unicode)
- def volume_replicate_range(self, rep_type, volume_src, volume_dest, ranges,
- flags=FLAG_RSVD):
- """
- Replicates a portion of a volume to itself or another volume. The src,
- dest and number of blocks values change with vendor, call
- volume_replicate_range_block_size to get block unit size.
-
- Returns Job id or None when completed, else raises LsmError on errors.
- """
- return self._tp.rpc('volume_replicate_range', _del_self(locals()))
-
- ## Deletes a volume
- # @param self The this pointer
- # @param volume The volume object which represents the volume to delete
- # @param flags Reserved for future use, must be zero.
- # @returns None on success, else job id. Raises LsmError on errors.
- @_return_requires(unicode)
- def volume_delete(self, volume, flags=FLAG_RSVD):
- """
- Deletes a volume.
-
- Returns None on success, else job id
- """
- return self._tp.rpc('volume_delete', _del_self(locals()))
-
- ## Makes a volume online and available to the host.
- # @param self The this pointer
- # @param volume The volume to place online
- # @param flags Reserved for future use, must be zero.
- # @returns None on success, else raises LsmError
- @_return_requires(None)
- def volume_enable(self, volume, flags=FLAG_RSVD):
- """
- Makes a volume available to the host
-
- returns None on success, else raises LsmError on errors.
- """
- return self._tp.rpc('volume_enable', _del_self(locals()))
-
- ## Takes a volume offline
- # @param self The this pointer
- # @param volume The volume object
- # @param flags Reserved for future use, must be zero.
- # @returns None on success, else raises LsmError on errors.
- @_return_requires(None)
- def volume_disable(self, volume, flags=FLAG_RSVD):
- """
- Makes a volume unavailable to the host
-
- returns None on success, else raises LsmError on errors.
- """
- return self._tp.rpc('volume_disable', _del_self(locals()))
-
- ## Returns an array of disk objects
- # @param self The this pointer
- # @param search_key Search Key
- # @param search_value Search value
- # @param flags When equal to DISK.FLAG_RETRIEVE_FULL_INFO
- # returned objects will contain optional data.
- # If not defined, only the mandatory properties will
- # be returned.
- # @returns An array of disk objects.
- @_return_requires([Disk])
- def disks(self, search_key=None, search_value=None, flags=FLAG_RSVD):
- """
- Returns an array of disk objects
- """
- _check_search_key(search_key, Disk.SUPPORTED_SEARCH_KEYS)
- return self._tp.rpc('disks', _del_self(locals()))
-
- ## Access control for allowing an access group to access a volume
- # @param self The this pointer
- # @param access_group The access group
- # @param volume The volume to grant access to
- # @param flags Reserved for future use, must be zero.
- # @returns None on success, throws LsmError on errors.
- @_return_requires(None)
- def volume_mask(self, access_group, volume, flags=FLAG_RSVD):
- """
- Allows an access group to access a volume.
- """
- return self._tp.rpc('volume_mask', _del_self(locals()))
-
- ## Revokes access to a volume to initiators in an access group
- # @param self The this pointer
- # @param access_group The access group
- # @param volume The volume to grant access to
- # @param flags Reserved for future use, must be zero.
- # @returns None on success, throws LsmError on errors.
- @_return_requires(None)
- def volume_unmask(self, access_group, volume, flags=FLAG_RSVD):
- """
- Revokes access for an access group for a volume
- """
- return self._tp.rpc('volume_unmask', _del_self(locals()))
-
- ## Returns a list of access group objects
- # @param self The this pointer
- # @param search_key Search Key
- # @param search_value Search value
- # @param flags Reserved for future use, must be zero.
- # @returns List of access groups
- @_return_requires([AccessGroup])
- def access_groups(self, search_key=None, search_value=None,
- flags=FLAG_RSVD):
- """
- Returns a list of access groups
- """
- _check_search_key(search_key, AccessGroup.SUPPORTED_SEARCH_KEYS)
- return self._tp.rpc('access_groups', _del_self(locals()))
-
- ## Creates an access a group with the specified initiator in it.
- # @param self The this pointer
- # @param name The initiator group name
- # @param init_id Initiator id
- # @param init_type Type of initiator (Enumeration)
- # @param system Which system to create this group on
- # @param flags Reserved for future use, must be zero.
- # @returns AccessGroup on success, else raises LsmError
- @_return_requires(AccessGroup)
- def access_group_create(self, name, init_id, init_type, system,
- flags=FLAG_RSVD):
- """
- Creates an access group and add the specified initiator id,
- init_type and desired access.
- """
- init_type, init_id = AccessGroup.initiator_id_verify(
- init_id, init_type, raise_exception=True)[1:]
- return self._tp.rpc('access_group_create', _del_self(locals()))
-
- ## Deletes an access group.
- # @param self The this pointer
- # @param access_group The access group to delete
- # @param flags Reserved for future use, must be zero.
- # @returns None on success, throws LsmError on errors.
- @_return_requires(None)
- def access_group_delete(self, access_group, flags=FLAG_RSVD):
- """
- Deletes an access group
- """
- return self._tp.rpc('access_group_delete', _del_self(locals()))
-
- ## Adds an initiator to an access group
- # @param self The this pointer
- # @param access_group Group to add initiator to
- # @param init_id Initiators id
- # @param init_type Initiator id type (enumeration)
- # @param flags Reserved for future use, must be zero.
- # @returns None on success, throws LsmError on errors.
- @_return_requires(AccessGroup)
- def access_group_initiator_add(self, access_group, init_id, init_type,
- flags=FLAG_RSVD):
- """
- Adds an initiator to an access group
- """
- init_type, init_id = AccessGroup.initiator_id_verify(
- init_id, init_type, raise_exception=True)[1:]
- return self._tp.rpc('access_group_initiator_add', _del_self(locals()))
-
- ## Deletes an initiator from an access group
- # @param self The this pointer
- # @param access_group The access group to remove initiator from
- # @param init_id The initiator to remove from the group
- # @param init_type Initiator id type (enumeration)
- # @param flags Reserved for future use, must be zero.
- # @returns None on success, throws LsmError on errors.
- @_return_requires(AccessGroup)
- def access_group_initiator_delete(self, access_group, init_id, init_type,
- flags=FLAG_RSVD):
- """
- Deletes an initiator from an access group
- """
- init_id = AccessGroup.initiator_id_verify(init_id, None,
- raise_exception=True)[2]
- return self._tp.rpc('access_group_initiator_delete',
- _del_self(locals()))
-
- ## Returns the list of volumes that access group has access to.
- # @param self The this pointer
- # @param access_group The access group to list volumes for
- # @param flags Reserved for future use, must be zero.
- # @returns list of volumes
- @_return_requires([Volume])
- def volumes_accessible_by_access_group(self, access_group,
- flags=FLAG_RSVD):
- """
- Returns the list of volumes that access group has access to.
- """
- return self._tp.rpc('volumes_accessible_by_access_group',
- _del_self(locals()))
-
- ##Returns the list of access groups that have access to the specified
- #volume.
- # @param self The this pointer
- # @param volume The volume to list access groups for
- # @param flags Reserved for future use, must be zero.
- # @returns list of access groups
- @_return_requires([AccessGroup])
- def access_groups_granted_to_volume(self, volume, flags=FLAG_RSVD):
- """
- Returns the list of access groups that have access to the specified
- volume.
- """
- return self._tp.rpc('access_groups_granted_to_volume',
- _del_self(locals()))
-
- ## Checks to see if a volume has child dependencies.
- # @param self The this pointer
- # @param volume The volume to check
- # @param flags Reserved for future use, must be zero.
- # @returns True or False
- @_return_requires(bool)
- def volume_child_dependency(self, volume, flags=FLAG_RSVD):
- """
- Returns True if this volume has other volumes which are dependant on
- it. Implies that this volume cannot be deleted or possibly modified
- because it would affect its children.
- """
- return self._tp.rpc('volume_child_dependency', _del_self(locals()))
-
- ## Removes any child dependency.
- # @param self The this pointer
- # @param volume The volume to remove dependencies for
- # @param flags Reserved for future use, must be zero.
- # @returns None if complete, else job id.
- @_return_requires(unicode)
- def volume_child_dependency_rm(self, volume, flags=FLAG_RSVD):
- """
- If this volume has child dependency, this method call will fully
- replicate the blocks removing the relationship between them. This
- should return None (success) if volume_child_dependency would return
- False.
-
- Note: This operation could take a very long time depending on the size
- of the volume and the number of child dependencies.
-
- Returns None if complete else job id, raises LsmError on errors.
- """
- return self._tp.rpc('volume_child_dependency_rm', _del_self(locals()))
-
- ## Returns a list of file system objects.
- # @param self The this pointer
- # @param search_key Search Key
- # @param search_value Search value
- # @param flags Reserved for future use, must be zero.
- # @returns A list of FS objects.
- @_return_requires([FileSystem])
- def fs(self, search_key=None, search_value=None, flags=FLAG_RSVD):
- """
- Returns a list of file systems on the controller.
- """
- _check_search_key(search_key, FileSystem.SUPPORTED_SEARCH_KEYS)
- return self._tp.rpc('fs', _del_self(locals()))
-
- ## Deletes a file system
- # @param self The this pointer
- # @param fs The file system to delete
- # @param flags Reserved for future use, must be zero.
- # @returns None on success, else job id
- @_return_requires(unicode)
- def fs_delete(self, fs, flags=FLAG_RSVD):
- """
- WARNING: Destructive
-
- Deletes a file system and everything it contains
- Returns None on success, else job id
- """
- return self._tp.rpc('fs_delete', _del_self(locals()))
-
- ## Re-sizes a file system
- # @param self The this pointer
- # @param fs The file system to re-size
- # @param new_size_bytes The new size of the file system in bytes
- # @param flags Reserved for future use, must be zero.
- # @returns tuple (job_id, re-sized file system),
- # When one is None the other is valid
- @_return_requires(unicode, FileSystem)
- def fs_resize(self, fs, new_size_bytes, flags=FLAG_RSVD):
- """
- Re-size a file system
-
- Returns a tuple (job_id, re-sized file system)
- Note: Tuple return values are mutually exclusive, when one
- is None the other must be valid.
- """
- return self._tp.rpc('fs_resize', _del_self(locals()))
-
- ## Creates a file system.
- # @param self The this pointer
- # @param pool The pool object to allocate space from
- # @param name The human text name for the file system
- # @param size_bytes The size of the file system in bytes
- # @param flags Reserved for future use, must be zero.
- # @returns tuple (job_id, file system),
- # When one is None the other is valid
- @_return_requires(unicode, FileSystem)
- def fs_create(self, pool, name, size_bytes, flags=FLAG_RSVD):
- """
- Creates a file system given a pool, name and size.
- Note: size is limited to 2**64 bytes
-
- Returns a tuple (job_id, file system)
- Note: Tuple return values are mutually exclusive, when one
- is None the other must be valid.
- """
- return self._tp.rpc('fs_create', _del_self(locals()))
-
- ## Clones a file system
- # @param self The this pointer
- # @param src_fs The source file system to clone
- # @param dest_fs_name The destination file system clone name
- # @param snapshot Optional, create clone from previous snapshot
- # @param flags Reserved for future use, must be zero.
- # @returns tuple (job_id, file system)
- @_return_requires(unicode, FileSystem)
- def fs_clone(self, src_fs, dest_fs_name, snapshot=None, flags=FLAG_RSVD):
- """
- Creates a thin, point in time read/writable copy of src to dest.
- Optionally uses snapshot as backing of src_fs
-
- Returns a tuple (job_id, file system)
- Note: Tuple return values are mutually exclusive, when one
- is None the other must be valid.
- """
- return self._tp.rpc('fs_clone', _del_self(locals()))
-
- ## Clones an individual file or files on the specified file system
- # @param self The this pointer
- # @param fs The file system the files are on
- # @param src_file_name The source file name
- # @param dest_file_name The dest. file name
- # @param snapshot Optional, the snapshot to base clone source
- # file from
- # @param flags Reserved for future use, must be zero.
- # @returns None on success, else job id
- @_return_requires(unicode)
- def fs_file_clone(self, fs, src_file_name, dest_file_name, snapshot=None,
- flags=FLAG_RSVD):
- """
- Creates a thinly provisioned clone of src to dest.
- Note: Source and Destination are required to be on same filesystem and
- all directories in destination path need to exist.
-
- Returns None on success, else job id
- """
- return self._tp.rpc('fs_file_clone', _del_self(locals()))
-
- ## Returns a list of snapshots
- # @param self The this pointer
- # @param fs The file system
- # @param flags Reserved for future use, must be zero.
- # @returns a list of snapshot objects.
- @_return_requires([FsSnapshot])
- def fs_snapshots(self, fs, flags=FLAG_RSVD):
- """
- Returns a list of snapshot names for the supplied file system
- """
- return self._tp.rpc('fs_snapshots', _del_self(locals()))
-
- ## Creates a snapshot (Point in time read only copy)
- # @param self The this pointer
- # @param fs The file system to snapshot
- # @param snapshot_name The human readable snapshot name
- # @param flags Reserved for future use, must be zero.
- # @returns tuple (job_id, snapshot)
- @_return_requires(unicode, FsSnapshot)
- def fs_snapshot_create(self, fs, snapshot_name, flags=FLAG_RSVD):
- """
- Snapshot is a point in time read-only copy
-
- Create a snapshot on the chosen file system.
-
- Returns a tuple (job_id, snapshot)
- Notes:
- - Snapshot name may not match what was passed in
- (depends on array implementation)
- - Tuple return values are mutually exclusive, when one
- is None the other must be valid.
- """
- return self._tp.rpc('fs_snapshot_create', _del_self(locals()))
-
- ## Deletes a snapshot
- # @param self The this pointer
- # @param fs The filesystem the snapshot it for
- # @param snapshot The specific snap shot to delete
- # @param flags Reserved for future use, must be zero.
- # @returns None on success, else job id
- @_return_requires(unicode)
- def fs_snapshot_delete(self, fs, snapshot, flags=FLAG_RSVD):
- """
- Frees the re-sources for the given snapshot on the supplied filesystem.
-
- Returns None on success else job id, LsmError exception on error
- """
- return self._tp.rpc('fs_snapshot_delete', _del_self(locals()))
-
- ## Reverts a snapshot
- # @param self The this pointer
- # @param fs The file system object to restore snapshot for
- # @param snapshot The snapshot file to restore back too
- # @param files The specific files to restore
- # @param restore_files Individual files to restore
- # @param all_files Set to True if all files should be restored
- # back
- # @param flags Reserved for future use, must be zero.
- # @return None on success, else job id
- @_return_requires(unicode)
- def fs_snapshot_restore(self, fs, snapshot, files, restore_files,
- all_files=False, flags=FLAG_RSVD):
- """
- WARNING: Destructive!
-
- Reverts a file-system or just the specified files from the snapshot.
- If a list of files is supplied but the array cannot restore just them
- then the operation will fail with an LsmError raised. If files == None
- and all_files = True then all files on the file-system are restored.
-
- Restore_file if None none must be the same length as files with each
- index in each list referring to the associated file.
-
- Returns None on success, else job id, LsmError exception on error
- """
- return self._tp.rpc('fs_snapshot_restore', _del_self(locals()))
-
- ## Checks to see if a file system has child dependencies.
- # @param fs The file system to check
- # @param files The files to check (optional)
- # @param flags Reserved for future use, must be zero.
- # @returns True or False
- @_return_requires(bool)
- def fs_child_dependency(self, fs, files, flags=FLAG_RSVD):
- """
- Returns True if the specified filesystem or specified file on this
- file system has child dependencies. This implies that this filesystem
- or specified file on this file system cannot be deleted or possibly
- modified because it would affect its children.
- """
- return self._tp.rpc('fs_child_dependency', _del_self(locals()))
-
- ## Removes child dependencies from a FS or specific file.
- # @param self The this pointer
- # @param fs The file system to remove child dependencies for
- # @param files The list of files to remove child dependencies (opt.)
- # @param flags Reserved for future use, must be zero.
- # @returns None if complete, else job id.
- @_return_requires(unicode)
- def fs_child_dependency_rm(self, fs, files, flags=FLAG_RSVD):
- """
- If this filesystem or specified file on this filesystem has child
- dependency this method will fully replicate the blocks removing the
- relationship between them. This should return None(success) if
- fs_child_dependency would return False.
-
- Note: This operation could take a very long time depending on the size
- of the filesystem and the number of child dependencies.
-
- Returns None if completed, else job id. Raises LsmError on errors.
- """
- return self._tp.rpc('fs_child_dependency_rm', _del_self(locals()))
-
- ## Returns a list of all the NFS client authentication types.
- # @param self The this pointer
- # @param flags Reserved for future use, must be zero.
- # @returns An array of client authentication types.
- @_return_requires([unicode])
- def export_auth(self, flags=FLAG_RSVD):
- """
- What types of NFS client authentication are supported.
- """
- return self._tp.rpc('export_auth', _del_self(locals()))
-
- ## Returns a list of all the exported file systems
- # @param self The this pointer
- # @param search_key Search Key
- # @param search_value Search value
- # @param flags Reserved for future use, must be zero.
- # @returns An array of export objects
- @_return_requires([NfsExport])
- def exports(self, search_key=None, search_value=None, flags=FLAG_RSVD):
- """
- Get a list of all exported file systems on the controller.
- """
- _check_search_key(search_key, NfsExport.SUPPORTED_SEARCH_KEYS)
- return self._tp.rpc('exports', _del_self(locals()))
-
- ## Exports a FS as specified in the export.
- # @param self The this pointer
- # @param fs_id The FS ID to export
- # @param export_path The export path (Set to None for array to pick)
- # @param root_list List of hosts with root access
- # @param rw_list List of hosts with read/write access
- # @param ro_list List of hosts with read only access
- # @param anon_uid UID to map to anonymous
- # @param anon_gid GID to map to anonymous
- # @param auth_type NFS client authentication type
- # @param options Options to pass to plug-in
- # @param flags Reserved for future use, must be zero.
- # @returns NfsExport on success, else raises LsmError
- @_return_requires(NfsExport)
- def export_fs(self, fs_id, export_path, root_list, rw_list, ro_list,
- anon_uid=NfsExport.ANON_UID_GID_NA,
- anon_gid=NfsExport.ANON_UID_GID_NA,
- auth_type=None, options=None, flags=FLAG_RSVD):
- """
- Exports a filesystem as specified in the arguments
- """
- return self._tp.rpc('export_fs', _del_self(locals()))
-
- ## Removes the specified export
- # @param self The this pointer
- # @param export The export to remove
- # @param flags Reserved for future use, must be zero.
- # @returns None on success, else raises LsmError
- @_return_requires(None)
- def export_remove(self, export, flags=FLAG_RSVD):
- """
- Removes the specified export
- """
- return self._tp.rpc('export_remove', _del_self(locals()))
-
- ## Returns a list of target ports
- # @param self The this pointer
- # @param search_key The key to search against
- # @param search_value The value to search for
- # @param flags Reserved for future use, must be zero
- # @returns List of target ports, else raises LsmError
- @_return_requires([TargetPort])
- def target_ports(self, search_key=None, search_value=None,
- flags=FLAG_RSVD):
- """
- Returns a list of target ports
- """
- _check_search_key(search_key, TargetPort.SUPPORTED_SEARCH_KEYS)
- return self._tp.rpc('target_ports', _del_self(locals()))
-
- ## Returns the RAID information of certain volume
- # @param self The this pointer
- # @param raid_type The RAID type of this volume
- # @param strip_size The size of strip of disk or other storage
- # extent.
- # @param disk_count The count of disks of RAID group(s) where
- # this volume allocated from.
- # @param min_io_size The preferred I/O size of random I/O.
- # @param opt_io_size The preferred I/O size of sequential I/O.
- # @returns List of target ports, else raises LsmError
- @_return_requires([int, int, int, int, int])
- def volume_raid_info(self, volume, flags=FLAG_RSVD):
- """Query the RAID information of certain volume.
-
- New in version 1.2.
-
- Query the RAID type, strip size, extents count, minimum I/O size,
- optimal I/O size of given volume.
-
- This method requires this capability:
- lsm.Capabilities.VOLUME_RAID_INFO
-
- Args:
- volume (Volume object): Volume to query
- flags (int): Reserved for future use. Should be set as
- lsm.Client.FLAG_RSVD
- Returns:
- [raid_type, strip_size, disk_count, min_io_size, opt_io_size]
-
- raid_type (int): RAID Type of requested volume.
- Could be one of these values:
- Volume.RAID_TYPE_RAID0
- Stripe
- Volume.RAID_TYPE_RAID1
- Two disks Mirror
- Volume.RAID_TYPE_RAID3
- Byte-level striping with dedicated parity
- Volume.RAID_TYPE_RAID4
- Block-level striping with dedicated parity
- Volume.RAID_TYPE_RAID5
- Block-level striping with distributed parity
- Volume.RAID_TYPE_RAID6
- Block-level striping with two distributed parities,
- aka, RAID-DP
- Volume.RAID_TYPE_RAID10
- Stripe of mirrors
- Volume.RAID_TYPE_RAID15
- Parity of mirrors
- Volume.RAID_TYPE_RAID16
- Dual parity of mirrors
- Volume.RAID_TYPE_RAID50
- Stripe of parities
- Volume.RAID_TYPE_RAID60
- Stripe of dual parities
- Volume.RAID_TYPE_RAID51
- Mirror of parities
- Volume.RAID_TYPE_RAID61
- Mirror of dual parities
- Volume.RAID_TYPE_JBOD
- Just bunch of disks, no parity, no striping.
- Volume.RAID_TYPE_UNKNOWN
- The plugin failed to detect the volume's RAID type.
- Volume.RAID_TYPE_MIXED
- This volume contains multiple RAID settings.
- Volume.RAID_TYPE_OTHER
- Vendor specific RAID type
- strip_size(int): The size of strip on each disk or other storage
- extent.
- For RAID1/JBOD, it should be set as sector size.
- If plugin failed to detect strip size, it should be set
- as Volume.STRIP_SIZE_UNKNOWN(0).
- disk_count(int): The count of disks used for assembling the RAID
- group(s) where this volume allocated from.
- For any RAID system using the slice of disk, this value
- indicate how many disk slices are used for the RAID.
- For exmaple, on LVM RAID, the 'disk_count' here indicate the
- count of PVs used for certain volume.
- Another example, on EMC VMAX, the 'disk_count' here indicate
- how many hyper volumes are used for this volume.
- For any RAID system using remote LUN for data storing, each
- remote LUN should be count as a disk.
- If the plugin failed to detect disk_count, it should be set
- as Volume.DISK_COUNT_UNKNOWN(0).
- min_io_size(int): The minimum I/O size, device preferred I/O
- size for random I/O. Any I/O size not equal to a multiple
- of this value may get significant speed penalty.
- Normally it refers to strip size of each disk(extent).
- If plugin failed to detect min_io_size, it should try these
- values in the sequence of:
- logical sector size -> physical sector size ->
- Volume.MIN_IO_SIZE_UNKNOWN(0).
- opt_io_size(int): The optimal I/O size, device preferred I/O
- size for sequential I/O. Normally it refers to RAID group
- stripe size.
- If plugin failed to detect opt_io_size, it should be set
- to Volume.OPT_IO_SIZE_UNKNOWN(0).
- Raises:
- LsmError:
- ErrorNumber.NO_SUPPORT
- No support.
- """
- return self._tp.rpc('volume_raid_info', _del_self(locals()))
diff --git a/python_binding/lsm/_common.py b/python_binding/lsm/_common.py
deleted file mode 100644
index 4c87661..0000000
--- a/python_binding/lsm/_common.py
+++ /dev/null
@@ -1,588 +0,0 @@
-# Copyright (C) 2011-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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: tasleson
-import hashlib
-
-import os
-import unittest
-import urlparse
-import re
-
-import sys
-import syslog
-import collections
-import inspect
-import urllib2
-
-import functools
-import traceback
-
-
-def default_property(name, allow_set=True, doc=None):
- """
- Creates the get/set properties for the given name. It assumes that the
- actual attribute is '_' + name
-
- TODO: Expand this with domain validation to ensure the values are correct.
- """
- attribute_name = '_' + name
-
- def getter(self):
- return getattr(self, attribute_name)
-
- def setter(self, value):
- setattr(self, attribute_name, value)
-
- prop = property(getter, setter if allow_set else None, None, doc)
-
- def decorator(cls):
- setattr(cls, name, prop)
- return cls
-
- return decorator
-
-
-def common_urllib2_error_handler(exp):
-
- if isinstance(exp, urllib2.HTTPError):
- raise LsmError(ErrorNumber.PLUGIN_AUTH_FAILED, str(exp))
- if isinstance(exp, urllib2.URLError):
- desc = str(exp)
- if 'urlopen error' in desc:
- if 'Errno 111' in desc:
- raise LsmError(ErrorNumber.NETWORK_CONNREFUSED,
- 'Connection refused')
- if 'Errno 113' in desc:
- raise LsmError(ErrorNumber.NETWORK_HOSTDOWN,
- 'Host is down')
- error("Unexpected network error:\n" + traceback.format_exc())
- raise LsmError(ErrorNumber.NETWORK_ERROR, desc)
-
- stack_trace = traceback.format_exc()
- error("Unexpected exception:\n" + stack_trace)
- raise LsmError(ErrorNumber.PLUGIN_BUG, "Unexpected exception",
- stack_trace)
-
-
-## Documentation for Proxy class.
-#
-# Class to encapsulate the actual class we want to call. When an attempt is
-# made to access an attribute that doesn't exist we will raise an LsmError
-# instead of the default keyError.
-class Proxy(object):
- """
- Used to provide an unambiguous error when a feature is not implemented.
- """
-
- ## The constructor.
- # @param self The object self
- # @param obj The object instance to wrap
- def __init__(self, obj=None):
- """
- Constructor which takes an object to wrap.
- """
- self.proxied_obj = obj
-
- ## Called each time an attribute is requested of the object
- # @param self The object self
- # @param name Name of the attribute being accessed
- # @return The result of the method
- def __getattr__(self, name):
- """
- Called each time an attribute is requested of the object
- """
- if hasattr(self.proxied_obj, name):
- return functools.partial(self._present, name)
- else:
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "Unsupported operation")
-
- ## Method which is called to invoke the actual method of interest.
- # @param self The object self
- # @param _proxy_method_name Method to invoke
- # @param args Arguments
- # @param kwargs Keyword arguments
- # @return The result of the method invocation
- def _present(self, _proxy_method_name, *args, **kwargs):
- """
- Method which is called to invoke the actual method of interest.
- """
- return getattr(self.proxied_obj, _proxy_method_name)(*args, **kwargs)
-
-# variable in client and specified on the command line for the daemon
-UDS_PATH = '/var/run/lsm/ipc'
-
-#Set to True for verbose logging
-LOG_VERBOSE = True
-
-##Constant for byte size
-SIZE_CONS = {
- 'B': 1,
- 'KiB': 2 ** 10,
- 'KB': 10 ** 3,
- 'K': 2 ** 10,
- 'k': 2 ** 10,
- 'MiB': 2 ** 20,
- 'MB': 10 ** 6,
- 'M': 2 ** 20,
- 'm': 2 ** 20,
- 'GiB': 2 ** 30,
- 'GB': 10 ** 9,
- 'G': 2 ** 30,
- 'g': 2 ** 30,
- 'TiB': 2 ** 40,
- 'TB': 10 ** 12,
- 'T': 2 ** 40,
- 't': 2 ** 40,
- 'PiB': 2 ** 50,
- 'PB': 10 ** 15,
- 'P': 2 ** 50,
- 'p': 2 ** 50,
- 'EiB': 2 ** 60,
- 'EB': 10 ** 18,
- 'E': 2 ** 60,
- 'e': 2 ** 60,
-}
-SIZE_CONS_CHK_LST = ['EiB', 'PiB', 'TiB', 'GiB', 'MiB', 'KiB']
-
-
-##Converts the size into human format.
-# @param size Size in bytes
-# @param human True|False
-# @return Human representation of size
-def sh(size, human=False):
- """
- Convert size in bytes to human readable size
- The return string will follow IEC binary prefixes, e.g. '1.9 KiB'
- For size less than 1024, we do nothing but return the int we get.
- TODO: Need a expect to handle when size is not a int. int() might do.
- """
- units = None
-
- if human:
- for key_name in SIZE_CONS_CHK_LST:
- if size >= SIZE_CONS[key_name]:
- size /= float(SIZE_CONS[key_name])
- units = key_name
- break
- if not units:
- units = "B"
- return "%.2f %s" % (size, units)
- else:
- return size
-
-
-##Converts the size into human format.
-# @param size Size in bytes
-# @return Human representation of size in IEC binary size prefixes.
-def size_bytes_2_size_human(size):
- """
- Convert integer size in bytes to human readable size.
- We are following rules of IEC binary prefixes on size:
- http://en.wikipedia.org/wiki/Gibibyte
- The biggest of unit this function supported is PiB.
- The precision is 2 which means you will get '1.99 KiB'
- """
- return sh(size, True)
-
-
-##Converts the size into human format.
-# @param size_human Human readable size string, e.g. '1.9 KiB'
-# @return Size in bytes
-def size_human_2_size_bytes(size_human):
- """
- Convert human readable size string into integer size in bytes.
- Following rules of IEC binary prefixes on size:
- http://en.wikipedia.org/wiki/Gibibyte
- Supported input size_human in these formats:
- '1.9KiB' # int(1024*1.9)
- '1 KiB' # 2**10
- '1B' # 1
- '2K' # 2*(2**10), treated as '2KiB'
- '2k' # 2*(2**10), treated as '2KiB'
- '2KB' # 2*(10**3)
- """
- regex_size_human = re.compile(r"""
- ^
- ([0-9\.]+) # 1: number
- [ \t]* # might have space between number and unit
- ([a-zA-Z]*) # 2: units
- $
- """, re.X)
- regex_match = regex_size_human.match(size_human)
- units = ''
- number = 0
- size_bytes = 0
- if regex_match:
- number = regex_match.group(1)
- units = regex_match.group(2)
- if not units:
- return int(number)
- units = units.upper()
- units = units.replace('IB', 'iB')
- if units in SIZE_CONS:
- size_bytes = SIZE_CONS[units] * float(number)
- return int(size_bytes)
-
-
-## Common method used to parse a URI.
-# @param uri The uri to parse
-# @param requires Optional list of keys that must be present in output
-# @param required_params Optional list of required parameters that
-# must be present.
-# @return A hash of the parsed values.
-def uri_parse(uri, requires=None, required_params=None):
- """
- Common uri parse method that optionally can check for what is needed
- before returning successfully.
- """
-
- rc = {}
- u = urlparse.urlparse(uri)
-
- if u.scheme:
- rc['scheme'] = u.scheme
-
- if u.netloc:
- rc['netloc'] = u.netloc
-
- if u.port:
- rc['port'] = u.port
-
- if u.hostname:
- rc['host'] = u.hostname
-
- if u.username:
- rc['username'] = u.username
- else:
- rc['username'] = None
-
- rc['parameters'] = uri_parameters(u)
-
- if requires:
- for r in requires:
- if r not in rc:
- raise LsmError(ErrorNumber.PLUGIN_BUG,
- 'uri missing \"%s\" or is in invalid form' % r)
-
- if required_params:
- for r in required_params:
- if r not in rc['parameters']:
- raise LsmError(ErrorNumber.PLUGIN_BUG,
- 'uri missing query parameter %s' % r)
- return rc
-
-
-## Parses the parameters (Query string) of the URI
-# @param uri Full uri
-# @returns hash of the query string parameters.
-def uri_parameters(uri):
- # workaround for python bug:
- # http://bugs.python.org/issue9374
- # for URL: smispy+ssl://***@emc-smi:5989?namespace=root/emc
- # Before the patch commited( RHEL 6 and Fedora 18- ):
- # '?namespace=root/emc' is saved in uri.path
- # After patched(RHEL 7 and Fedora 19+):
- # 'namespace=root/emc' is saved in uri.query
- query = ''
- if uri.query:
- query = uri.query
- elif uri.path:
- query = urlparse.urlparse('http:' + uri[2]).query
- else:
- return {}
- if query:
- return dict([part.split('=') for part in query.split('&')])
- else:
- return {}
-
-
-## Generates the md5 hex digest of passed in parameter.
-# @param t Item to generate signature on.
-# @returns md5 hex digest.
-def md5(t):
- h = hashlib.md5()
- h.update(t)
- return h.hexdigest()
-
-
-## Converts a list of arguments to string.
-# @param args Args to join
-# @return string of arguments joined together.
-def params_to_string(*args):
- return ''.join([str(e) for e in args])
-
-# Unfortunately the process name remains as 'python' so we are using argv[0] in
-# the output to allow us to determine which python exe is indeed logging to
-# syslog.
-# TODO: On newer versions of python this is no longer true, need to fix.
-
-
-## Posts a message to the syslogger.
-# @param level Logging level
-# @param prg Program name
-# @param msg Message to log.
-def post_msg(level, prg, msg):
- """
- If a message includes new lines we will create multiple syslog
- entries so that the message is readable. Otherwise it isn't very readable.
- Hopefully we won't be logging much :-)
- """
- for l in msg.split('\n'):
- if len(l):
- syslog.syslog(level, prg + ": " + l)
-
-
-def error(*msg):
- post_msg(syslog.LOG_ERR, os.path.basename(sys.argv[0]),
- params_to_string(*msg))
-
-
-def info(*msg):
- if LOG_VERBOSE:
- post_msg(syslog.LOG_INFO, os.path.basename(sys.argv[0]),
- params_to_string(*msg))
-
-
-class SocketEOF(Exception):
- """
- Exception class to indicate when we read zero bytes from a socket.
- """
- pass
-
-
-@default_property('code', 'Error code')
-@default_property('msg', 'Error message')
-@default_property('data', 'Optional error data')
-class LsmError(Exception):
- def __init__(self, code, message, data=None, *args, **kwargs):
- """
- Class represents an error.
- """
- Exception.__init__(self, *args, **kwargs)
- self._code = code
- self._msg = message
- self._data = data
-
- def __str__(self):
- error_no_str = ErrorNumber.error_number_to_str(self.code)
- if self.data is not None:
- return "%s: %s Data: %s" % \
- (error_no_str, self.msg, self.data)
- else:
- return "%s: %s " % (error_no_str, self.msg)
-
-
-def addl_error_data(domain, level, exception, debug=None, debug_data=None):
- """
- Used for gathering additional information about an error.
- """
- return {'domain': domain, 'level': level, 'exception': exception,
- 'debug': debug, 'debug_data': debug_data}
-
-
-def get_class(class_name):
- """
- Given a class name it returns the class, caller will then
- need to run the constructor to create.
- """
- parts = class_name.split('.')
- module = ".".join(parts[:-1])
- if len(module):
- m = __import__(module)
- for comp in parts[1:]:
- m = getattr(m, comp)
- else:
- m = __import__('__main__')
- m = getattr(m, class_name)
- return m
-
-
-#Note: Some of these don't make sense for python, but they do for other
-#Languages so we will be keeping them consistent even though we won't be
-#using them.
-class ErrorNumber(object):
- OK = 0
- LIB_BUG = 1
- PLUGIN_BUG = 2
- JOB_STARTED = 7
- TIMEOUT = 11
- DAEMON_NOT_RUNNING = 12
-
- NAME_CONFLICT = 50
- EXISTS_INITIATOR = 52
-
- INVALID_ARGUMENT = 101
-
- NO_STATE_CHANGE = 125
-
- NETWORK_CONNREFUSED = 140 # Host on network, but connection refused
- NETWORK_HOSTDOWN = 141 # Host unreachable on network
- NETWORK_ERROR = 142 # Generic network error
-
- NO_MEMORY = 152
- NO_SUPPORT = 153
-
- # Deletion related errors
- IS_MASKED = 160 # Volume is masked to access group.
-
- NOT_FOUND_ACCESS_GROUP = 200
- NOT_FOUND_FS = 201
- NOT_FOUND_JOB = 202
- NOT_FOUND_POOL = 203
- NOT_FOUND_FS_SS = 204
- NOT_FOUND_VOLUME = 205
- NOT_FOUND_NFS_EXPORT = 206
- NOT_FOUND_SYSTEM = 208
-
- NOT_LICENSED = 226
-
- NO_SUPPORT_ONLINE_CHANGE = 250
- NO_SUPPORT_OFFLINE_CHANGE = 251
-
- PLUGIN_AUTH_FAILED = 300 # Client supplied credential are incorrect
- PLUGIN_IPC_FAIL = 301 # Inter-process communication between client &
- # out of process plug-in encountered connection
- # errors.
-
- PLUGIN_SOCKET_PERMISSION = 307 # Incorrect permission on UNIX domain
- # socket used for IPC
- PLUGIN_NOT_EXIST = 311
-
- NOT_ENOUGH_SPACE = 350
-
- TRANSPORT_COMMUNICATION = 400
- TRANSPORT_SERIALIZATION = 401
- TRANSPORT_INVALID_ARG = 402
-
- LAST_INIT_IN_ACCESS_GROUP = 502
- # refuse to remove the last initiator from access group
-
- UNSUPPORTED_SEARCH_KEY = 510
-
- EMPTY_ACCESS_GROUP = 511 # volume_mask() will fail if access group
- # has no member/initiator.
-
- POOL_NOT_READY = 512 # Pool is not ready for create/resize/etc
-
- _LOCALS = locals()
-
- @staticmethod
- def error_number_to_str(error_no):
- for error_str in ErrorNumber._LOCALS.keys():
- if ErrorNumber._LOCALS[error_str] == error_no:
- return "%s(%d)" % (error_str, error_no)
- return "UNKNOWN_ERROR_NUMBER(%d)" % error_no
-
-
-class JobStatus(object):
- INPROGRESS = 1
- COMPLETE = 2
- ERROR = 3
-
-
-def type_compare(method_name, exp_type, act_val):
- if isinstance(exp_type, collections.Sequence):
- if not isinstance(act_val, collections.Sequence):
- raise TypeError("%s call is returning a %s, but is "
- "expecting a sequence" %
- (method_name, str(type(act_val))))
- # If the list has only one expected value we will make sure all
- # elements in the list adhere to it, otherwise we will enforce a one
- # to one check against the expected types.
- if len(exp_type) == 1:
- for av in act_val:
- type_compare(method_name, exp_type[0], av)
- else:
- # Expect a 1-1 type match, extras get ignored at the moment
- for exp, act in zip(exp_type, act_val):
- type_compare(method_name, exp, act)
- else:
- # A number of times a method will return None or some valid type,
- # only check on the type if the value is not None
- if exp_type != type(act_val) and act_val is not None:
- if (exp_type == unicode and type(act_val) == str):
- return
- if not inspect.isclass(exp_type) or \
- not issubclass(type(act_val), exp_type):
- raise TypeError('%s call expected: %s got: %s ' %
- (method_name, str(exp_type),
- str(type(act_val))))
-
-
-def return_requires(*types):
- """
- Decorator function that allows us to ensure that we are getting the
- correct types back from a function/method call.
-
- Note: This is normally frowned upon by the python community, but this API
- needs to be language agnostic, so making sure we have the correct types
- is quite important.
- """
- def outer(func):
- @functools.wraps(func)
- def inner(*args, **kwargs):
- r = func(*args, **kwargs)
-
- # In this case the user did something like
- # @return_requires(int, string, int)
- # in this case we require that all the args are present.
- if len(types) > 1:
- if len(r) != len(types):
- raise TypeError("%s call expected %d "
- "return values, actual = %d" %
- (func.__name__, len(types), len(r)))
-
- type_compare(func.__name__, types, r)
- elif len(types) == 1:
- # We have one return type (but it could be a sequence)
- type_compare(func.__name__, types[0], r)
-
- return r
- return inner
- return outer
-
-
-class TestCommon(unittest.TestCase):
- def setUp(self):
- pass
-
- def test_simple(self):
-
- try:
- raise SocketEOF()
- except SocketEOF as e:
- self.assertTrue(isinstance(e, SocketEOF))
-
- try:
- raise LsmError(10, 'Message', 'Data')
- except LsmError as e:
- self.assertTrue(e.code == 10 and e.msg == 'Message' and
- e.data == 'Data')
-
- ed = addl_error_data('domain', 'level', 'exception', 'debug',
- 'debug_data')
- self.assertTrue(ed['domain'] == 'domain' and ed['level'] == 'level'
- and ed['debug'] == 'debug'
- and ed['exception'] == 'exception'
- and ed['debug_data'] == 'debug_data')
-
- def tearDown(self):
- pass
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/python_binding/lsm/_data.py b/python_binding/lsm/_data.py
deleted file mode 100644
index 23681dd..0000000
--- a/python_binding/lsm/_data.py
+++ /dev/null
@@ -1,817 +0,0 @@
-# Copyright (C) 2011-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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: tasleson
-# Gris Ge <***@redhat.com>
-
-from abc import ABCMeta as _ABCMeta
-import re
-
-try:
- import simplejson as json
-except ImportError:
- import json
-
-from json.decoder import WHITESPACE
-from _common import get_class, default_property, ErrorNumber, LsmError
-
-
-class DataEncoder(json.JSONEncoder):
- """
- Custom json encoder for objects derived form ILsmData
- """
-
- def default(self, my_class):
- if not isinstance(my_class, IData):
- raise ValueError('incorrect class type:' + str(type(my_class)))
- else:
- return my_class._to_dict()
-
-
-class DataDecoder(json.JSONDecoder):
- """
- Custom json decoder for objects derived from ILsmData
- """
-
- @staticmethod
- def __process_dict(d):
- """
- Processes a dictionary
- """
- rc = {}
-
- if 'class' in d:
- rc = IData._factory(d)
- else:
- for (k, v) in d.iteritems():
- rc[k] = DataDecoder.__decode(v)
-
- return rc
-
- @staticmethod
- def __process_list(l):
- """
- Processes a list
- """
- rc = []
- for elem, value in enumerate(l):
- if type(value) is list:
- rc.append(DataDecoder.__process_list(value))
- elif type(value) is dict:
- rc.append(DataDecoder.__process_dict(value))
- else:
- rc.append(value)
- return rc
-
- @staticmethod
- def __decode(e):
- """
- Decodes the parsed json
- """
- if type(e) is dict:
- return DataDecoder.__process_dict(e)
- elif type(e) is list:
- return DataDecoder.__process_list(e)
- else:
- return e
-
- def decode(self, json_string, _w=WHITESPACE.match):
- return DataDecoder.__decode(json.loads(json_string))
-
-
-class IData(object):
- """
- Base class functionality of serializable
- classes.
- """
- __metaclass__ = _ABCMeta
-
- def _to_dict(self):
- """
- Represent the class as a dictionary
- """
- rc = {'class': self.__class__.__name__}
-
- #If one of the attributes is another IData we will
- #process that too, is there a better way to handle this?
- for (k, v) in self.__dict__.items():
- if isinstance(v, IData):
- rc[k[1:]] = v._to_dict()
- else:
- rc[k[1:]] = v
-
- return rc
-
- @staticmethod
- def _factory(d):
- """
- Factory for creating the appropriate class given a dictionary.
- This only works for objects that inherit from IData
- """
- if 'class' in d:
- class_name = d['class']
- del d['class']
- c = get_class(__name__ + '.' + class_name)
-
- #If any of the parameters are themselves an IData process them
- for k, v in d.items():
- if isinstance(v, dict) and 'class' in v:
- d['_' + k] = IData._factory(d.pop(k))
- else:
- d['_' + k] = d.pop(k)
-
- return c(**d)
-
- def __str__(self):
- """
- Used for human string representation.
- """
- return str(self._to_dict())
-
-
-@default_property('id', doc="Unique identifier")
-@default_property('name', doc="Disk name (aka. vendor)")
-@default_property('disk_type', doc="Enumerated type of disk")
-@default_property('block_size', doc="Size of each block")
-@default_property('num_of_blocks', doc="Total number of blocks")
-@default_property('status', doc="Enumerated status")
-@default_property('system_id', doc="System identifier")
-@default_property("plugin_data", doc="Private plugin data")
-class Disk(IData):
- """
- Represents a disk.
- """
- SUPPORTED_SEARCH_KEYS = ['id', 'system_id']
-
- # We use '-1' to indicate we failed to get the requested number.
- # For example, when block found is undetectable, we use '-1' instead of
- # confusing 0.
- BLOCK_COUNT_NOT_FOUND = -1
- BLOCK_SIZE_NOT_FOUND = -1
-
- TYPE_UNKNOWN = 0
- TYPE_OTHER = 1
- TYPE_ATA = 3 # IDE disk which is seldomly used.
- TYPE_SATA = 4
- TYPE_SAS = 5
- TYPE_FC = 6
- TYPE_SOP = 7 # SCSI over PCIe(SSD)
- TYPE_SCSI = 8
- TYPE_LUN = 9 # Remote LUN was treated as a disk.
-
- # Due to complesity of disk types, we are defining these beside DMTF
- # standards:
- TYPE_NL_SAS = 51 # Near-Line SAS==SATA disk + SAS port.
-
- # in DMTF CIM 2.34.0+ CIM_DiskDrive['DiskType'], they also defined
- # SSD and HYBRID disk type. We use it as faillback.
- TYPE_HDD = 52 # Normal HDD
- TYPE_SSD = 53 # Solid State Drive
- TYPE_HYBRID = 54 # uses a combination of HDD and SSD
-
- STATUS_UNKNOWN = 1 << 0
- STATUS_OK = 1 << 1
- STATUS_OTHER = 1 << 2
- STATUS_PREDICTIVE_FAILURE = 1 << 3
- STATUS_ERROR = 1 << 4
- STATUS_REMOVED = 1 << 5
- STATUS_STARTING = 1 << 6
- STATUS_STOPPING = 1 << 7
- STATUS_STOPPED = 1 << 8
- STATUS_INITIALIZING = 1 << 9
- STATUS_MAINTENANCE_MODE = 1 << 10
- # In maintenance for bad sector scan, integerity check and etc
- # It might be combined with STATUS_OK or
- # STATUS_STOPPED for online maintenance or offline maintenance.
- STATUS_SPARE_DISK = 1 << 11
- # Indicate disk is a spare disk.
- STATUS_RECONSTRUCT = 1 << 12
- # Indicate disk is reconstructing data.
- STATUS_FREE = 1 << 13
- # New in version 1.2, indicate the whole disk is not holding any data or
- # acting as a dedicate spare disk.
- # This disk could be assigned as a dedicated spare disk or used for
- # creating pool.
- # If any spare disk(like those on NetApp ONTAP) does not require
- # any explicit action when assigning to pool, it should be treated as
- # free disk and marked as STATUS_FREE|STATUS_SPARE_DISK.
-
- def __init__(self, _id, _name, _disk_type, _block_size, _num_of_blocks,
- _status, _system_id, _plugin_data=None):
- self._id = _id
- self._name = _name
- self._disk_type = _disk_type
- self._block_size = _block_size
- self._num_of_blocks = _num_of_blocks
- self._status = _status
- self._system_id = _system_id
- self._plugin_data = _plugin_data
-
- @property
- def size_bytes(self):
- """
- Disk size in bytes.
- """
- return self.block_size * self.num_of_blocks
-
- def __str__(self):
- return self.name
-
-
-# Lets do this once outside of the class to minimize the number of
-# times it needs to be compiled.
-_vol_regex_vpd83 = re.compile('^[0-9a-f]{32}$')
-
-
-@default_property('id', doc="Unique identifier")
-@default_property('name', doc="User given name")
-@default_property('vpd83', doc="Vital product page 0x83 identifier")
-@default_property('block_size', doc="Volume block size")
-@default_property('num_of_blocks', doc="Number of blocks")
-@default_property('admin_state', doc="Enabled or disabled by administrator")
-@default_property('system_id', doc="System identifier")
-@default_property('pool_id', doc="Pool identifier")
-@default_property("plugin_data", doc="Private plugin data")
-class Volume(IData):
- """
- Represents a volume.
- """
- SUPPORTED_SEARCH_KEYS = ['id', 'system_id', 'pool_id']
-
- #Replication types
- REPLICATE_UNKNOWN = -1
- REPLICATE_CLONE = 2
- REPLICATE_COPY = 3
- REPLICATE_MIRROR_SYNC = 4
- REPLICATE_MIRROR_ASYNC = 5
-
- #Provisioning types
- PROVISION_UNKNOWN = -1
- PROVISION_THIN = 1
- PROVISION_FULL = 2
- PROVISION_DEFAULT = 3
-
- ADMIN_STATE_DISABLED = 0
- ADMIN_STATE_ENABLED = 1
-
- RAID_TYPE_UNKNOWN = -1
- # The plugin failed to detect the volume's RAID type.
- RAID_TYPE_RAID0 = 0
- # Stripe
- RAID_TYPE_RAID1 = 1
- # Mirror for two disks. For 4 disks or more, they are RAID10.
- RAID_TYPE_RAID3 = 3
- # Byte-level striping with dedicated parity
- RAID_TYPE_RAID4 = 4
- # Block-level striping with dedicated parity
- RAID_TYPE_RAID5 = 5
- # Block-level striping with distributed parity
- RAID_TYPE_RAID6 = 6
- # Block-level striping with two distributed parities, aka, RAID-DP
- RAID_TYPE_RAID10 = 10
- # Stripe of mirrors
- RAID_TYPE_RAID15 = 15
- # Parity of mirrors
- RAID_TYPE_RAID16 = 16
- # Dual parity of mirrors
- RAID_TYPE_RAID50 = 50
- # Stripe of parities
- RAID_TYPE_RAID60 = 60
- # Stripe of dual parities
- RAID_TYPE_RAID51 = 51
- # Mirror of parities
- RAID_TYPE_RAID61 = 61
- # Mirror of dual parities
- RAID_TYPE_JBOD = 20
- # Just bunch of disks, no parity, no striping.
- RAID_TYPE_MIXED = 21
- # This volume contains multiple RAID settings.
- RAID_TYPE_OTHER = 22
- # Vendor specific RAID type
-
- STRIP_SIZE_UNKNOWN = 0
- DISK_COUNT_UNKNOWN = 0
- MIN_IO_SIZE_UNKNOWN = 0
- OPT_IO_SIZE_UNKNOWN = 0
-
- def __init__(self, _id, _name, _vpd83, _block_size, _num_of_blocks,
- _admin_state, _system_id, _pool_id, _plugin_data=None):
- self._id = _id # Identifier
- self._name = _name # Human recognisable name
- if _vpd83 and not Volume.vpd83_verify(_vpd83):
- raise LsmError(ErrorNumber.INVALID_ARGUMENT,
- "Incorrect format of VPD 0x83 string: '%s', "
- "expecting 32 lower case hex characters" %
- _vpd83)
- self._vpd83 = _vpd83 # SCSI page 83 unique ID
- self._block_size = _block_size # Block size
- self._num_of_blocks = _num_of_blocks # Number of blocks
- self._admin_state = _admin_state # enable or disabled by admin
- self._system_id = _system_id # System id this volume belongs
- self._pool_id = _pool_id # Pool id this volume belongs
- self._plugin_data = _plugin_data
-
- @property
- def size_bytes(self):
- """
- Volume size in bytes.
- """
- return self.block_size * self.num_of_blocks
-
- def __str__(self):
- return self.name
-
- @staticmethod
- def vpd83_verify(vpd):
- """
- Returns True if string is valid vpd 0x83 representation
- """
- if vpd and _vol_regex_vpd83.match(vpd):
- return True
- return False
-
-
-@default_property('id', doc="Unique identifier")
-@default_property('name', doc="User defined system name")
-@default_property('status', doc="Enumerated status of system")
-@default_property('status_info', doc="Detail status information of system")
-@default_property("plugin_data", doc="Private plugin data")
-class System(IData):
- STATUS_UNKNOWN = 1 << 0
- STATUS_OK = 1 << 1
- STATUS_ERROR = 1 << 2
- STATUS_DEGRADED = 1 << 3
- STATUS_PREDICTIVE_FAILURE = 1 << 4
- STATUS_OTHER = 1 << 5
-
- def __init__(self, _id, _name, _status, _status_info, _plugin_data=None):
- self._id = _id
- self._name = _name
- self._status = _status
- self._status_info = _status_info
- self._plugin_data = _plugin_data
-
-
-@default_property('id', doc="Unique identifier")
-@default_property('name', doc="User supplied name")
-@default_property('total_space', doc="Total space in bytes")
-@default_property('free_space', doc="Free space in bytes")
-@default_property('status', doc="Enumerated status")
-@default_property('status_info', doc="Text explaining status")
-@default_property('system_id', doc="System identifier")
-@default_property("plugin_data", doc="Plug-in private data")
-@default_property("element_type", doc="What pool can be used for")
-@default_property("unsupported_actions",
- doc="What cannot be done with this pool")
-class Pool(IData):
- """
- Pool specific information
- """
- SUPPORTED_SEARCH_KEYS = ['id', 'system_id']
-
- TOTAL_SPACE_NOT_FOUND = -1
- FREE_SPACE_NOT_FOUND = -1
-
- # Element Type indicate what kind of element could this pool create:
- # * Another Pool
- # * Volume (aka, LUN)
- # * System Reserved Pool.
- ELEMENT_TYPE_POOL = 1 << 1
- ELEMENT_TYPE_VOLUME = 1 << 2
- ELEMENT_TYPE_FS = 1 << 3
- ELEMENT_TYPE_DELTA = 1 << 4
- ELEMENT_TYPE_VOLUME_FULL = 1 << 5
- ELEMENT_TYPE_VOLUME_THIN = 1 << 6
- ELEMENT_TYPE_SYS_RESERVED = 1 << 10 # Reserved for system use
-
- # Unsupported actions, what pool cannot be used for
- UNSUPPORTED_VOLUME_GROW = 1 << 0
- UNSUPPORTED_VOLUME_SHRINK = 1 << 1
-
- # Pool status could be any combination of these status.
- STATUS_UNKNOWN = 1 << 0
- STATUS_OK = 1 << 1
- STATUS_OTHER = 1 << 2
- STATUS_DEGRADED = 1 << 4
- STATUS_ERROR = 1 << 5
- STATUS_STOPPED = 1 << 9
- STATUS_RECONSTRUCTING = 1 << 12
- STATUS_VERIFYING = 1 << 13
- STATUS_INITIALIZING = 1 << 14
- STATUS_GROWING = 1 << 15
-
- def __init__(self, _id, _name, _element_type, _unsupported_actions,
- _total_space, _free_space,
- _status, _status_info, _system_id, _plugin_data=None):
- self._id = _id # Identifier
- self._name = _name # Human recognisable name
- self._element_type = _element_type # What pool can be used to create
- self._unsupported_actions = _unsupported_actions # What pool cannot be
- # used for
- self._total_space = _total_space # Total size
- self._free_space = _free_space # Free space available
- self._status = _status # Status of pool.
- self._status_info = _status_info # Additional status text of pool
- self._system_id = _system_id # System id this pool belongs
- self._plugin_data = _plugin_data # Plugin private data
-
-
-@default_property('id', doc="Unique identifier")
-@default_property('name', doc="File system name")
-@default_property('total_space', doc="Total space in bytes")
-@default_property('free_space', doc="Free space available")
-@default_property('pool_id', doc="What pool the file system resides on")
-@default_property('system_id', doc="System ID")
-@default_property("plugin_data", "Private plugin data")
-class FileSystem(IData):
- SUPPORTED_SEARCH_KEYS = ['id', 'system_id', 'pool_id']
-
- def __init__(self, _id, _name, _total_space, _free_space, _pool_id,
- _system_id, _plugin_data=None):
- self._id = _id
- self._name = _name
- self._total_space = _total_space
- self._free_space = _free_space
- self._pool_id = _pool_id
- self._system_id = _system_id
- self._plugin_data = _plugin_data
-
-
-@default_property('id', doc="Unique identifier")
-@default_property('name', doc="Snapshot name")
-@default_property('ts', doc="Time stamp the snapshot was created")
-@default_property("plugin_data", "Private plugin data")
-class FsSnapshot(IData):
-
- def __init__(self, _id, _name, _ts, _plugin_data=None):
- self._id = _id
- self._name = _name
- self._ts = int(_ts)
- self._plugin_data = _plugin_data
-
-
-@default_property('id', doc="Unique identifier")
-@default_property('fs_id', doc="Filesystem that is exported")
-@default_property('export_path', doc="Export path")
-@default_property('auth', doc="Authentication type")
-@default_property('root', doc="List of hosts with no_root_squash")
-@default_property('rw', doc="List of hosts with Read & Write privileges")
-@default_property('ro', doc="List of hosts with Read only privileges")
-@default_property('anonuid', doc="UID for anonymous user id")
-@default_property('anongid', doc="GID for anonymous group id")
-@default_property('options', doc="String containing advanced options")
-@default_property('plugin_data', doc="Plugin private data")
-class NfsExport(IData):
- SUPPORTED_SEARCH_KEYS = ['id', 'fs_id']
- ANON_UID_GID_NA = -1
- ANON_UID_GID_ERROR = -2
-
- def __init__(self, _id, _fs_id, _export_path, _auth, _root, _rw, _ro,
- _anonuid, _anongid, _options, _plugin_data=None):
- assert (_fs_id is not None)
- assert (_export_path is not None)
-
- self._id = _id
- self._fs_id = _fs_id # File system exported
- self._export_path = _export_path # Export path
- self._auth = _auth # Authentication type
- self._root = _root # List of hosts with no_root_squash
- self._rw = _rw # List of hosts with read/write
- self._ro = _ro # List of hosts with read/only
- self._anonuid = _anonuid # uid for anonymous user id
- self._anongid = _anongid # gid for anonymous group id
- self._options = _options # NFS options
- self._plugin_data = _plugin_data
-
-
-@default_property('src_block', doc="Source logical block address")
-@default_property('dest_block', doc="Destination logical block address")
-@default_property('block_count', doc="Number of blocks")
-class BlockRange(IData):
- def __init__(self, _src_block, _dest_block, _block_count):
- self._src_block = _src_block
- self._dest_block = _dest_block
- self._block_count = _block_count
-
-
-@default_property('id', doc="Unique instance identifier")
-@default_property('name', doc="Access group name")
-@default_property('init_ids', doc="List of initiator IDs")
-@default_property('init_type', doc="Initiator type")
-@default_property('system_id', doc="System identifier")
-@default_property('plugin_data', doc="Plugin private data")
-class AccessGroup(IData):
- SUPPORTED_SEARCH_KEYS = ['id', 'system_id']
-
- INIT_TYPE_UNKNOWN = 0
- INIT_TYPE_OTHER = 1
- INIT_TYPE_WWPN = 2
- INIT_TYPE_ISCSI_IQN = 5
- INIT_TYPE_ISCSI_WWPN_MIXED = 7
-
- def __init__(self, _id, _name, _init_ids, _init_type, _system_id,
- _plugin_data=None):
- self._id = _id
- self._name = _name # AccessGroup name
- self._init_ids = AccessGroup._standardize_init_list(_init_ids)
- # A list of Initiator ID strings.
- self._init_type = _init_type
- self._system_id = _system_id # System id this group belongs
- self._plugin_data = _plugin_data
-
- @staticmethod
- def _standardize_init_list(init_ids):
- rc = []
- for i in init_ids:
- valid, init_type, init_id = AccessGroup.initiator_id_verify(i)
-
- if valid:
- rc.append(init_id)
- else:
- raise LsmError(LsmError.ErrorNumber.INVALID_ARGUMENT,
- "Invalid initiator ID %s" % i)
- return rc
-
- _regex_wwpn = re.compile(r"""
- ^(0x|0X)?([0-9A-Fa-f]{2})
- (([\.:\-])?[0-9A-Fa-f]{2}){7}$
- """, re.X)
-
- @staticmethod
- def initiator_id_verify(init_id, init_type=None, raise_exception=False):
- """
- Public method which can be used to verify an initiator id
- :param init_id:
- :param init_type:
- :param raise_exception: Will throw a LsmError INVALID_ARGUMENT if
- not a valid initiator address
- :return:(Bool, init_type, init_id) Note: init_id will be returned in
- normalized format if it's a WWPN
- """
- if init_id.startswith('iqn') or init_id.startswith('eui') or\
- init_id.startswith('naa'):
-
- if init_type is None or \
- init_type == AccessGroup.INIT_TYPE_ISCSI_IQN:
- return True, AccessGroup.INIT_TYPE_ISCSI_IQN, init_id
- if AccessGroup._regex_wwpn.match(str(init_id)):
- if init_type is None or \
- init_type == AccessGroup.INIT_TYPE_WWPN:
- return True, AccessGroup.INIT_TYPE_WWPN, \
- AccessGroup._wwpn_to_lsm_type(init_id)
-
- if raise_exception:
- raise LsmError(ErrorNumber.INVALID_ARGUMENT,
- "Initiator id '%s' is invalid" % init_id)
-
- return False, None, None
-
- @staticmethod
- def _wwpn_to_lsm_type(wwpn, raise_error=True):
- """
- Conver provided WWPN string into LSM standarded one:
-
- LSM WWPN format:
- ^(?:[0-9a-f]{2}:){7}[0-9a-f]{2}$
- LSM WWPN Example:
- 10:00:00:00:c9:95:2f:de
-
- Acceptable WWPN format is:
- ^[0x|0X]{0,1}(:?[0-9A-Fa-f]{2}[\.\-:]{0,1}){7}[0-9A-Fa-f]{2}$
- Acceptable WWPN example:
- 10:00:00:00:c9:95:2f:de
- 10:00:00:00:C9:95:2F:DE
- 10-00-00-00-C9-95-2F-DE
- 10-00-00-00-c9-95-2f-de
- 10.00.00.00.C9.95.2F.DE
- 10.00.00.00.c9.95.2f.de
- 0x10000000c9952fde
- 0X10000000C9952FDE
- 10000000c9952fde
- 10000000C9952FDE
- Return the LSM WWPN
- Return None if raise_error is False and not a valid WWPN.
- """
- if AccessGroup._regex_wwpn.match(str(wwpn)):
- s = str(wwpn)
- s = s.lower()
- s = re.sub(r'0x', '', s)
- s = re.sub(r'[^0-9a-f]', '', s)
- s = ":".join(re.findall(r'..', s))
- return s
- if raise_error:
- raise LsmError(ErrorNumber.INVALID_ARGUMENT,
- "Invalid WWPN Initiator: %s" % wwpn)
- return None
-
-
-@default_property('id', doc="Unique instance identifier")
-@default_property('port_type', doc="Target port type")
-@default_property('service_address', doc="Target port service address")
-@default_property('network_address', doc="Target port network address")
-@default_property('physical_address', doc="Target port physical address")
-@default_property('physical_name', doc="Target port physical port name")
-@default_property('system_id', doc="System identifier")
-@default_property('plugin_data', doc="Plugin private data")
-class TargetPort(IData):
- SUPPORTED_SEARCH_KEYS = ['id', 'system_id']
-
- TYPE_OTHER = 1
- TYPE_FC = 2
- TYPE_FCOE = 3
- TYPE_ISCSI = 4
-
- def __init__(self, _id, _port_type, _service_address,
- _network_address, _physical_address, _physical_name,
- _system_id, _plugin_data=None):
- self._id = _id
- self._port_type = _port_type
- self._service_address = _service_address
- # service_address:
- # The address used by upper layer like FC and iSCSI:
- # FC and FCoE: WWPN
- # iSCSI: IQN
- # String. Lower case, split with : every two digits if WWPN.
- self._network_address = _network_address
- # network_address:
- # The address used by network layer like FC and TCP/IP:
- # FC/FCoE: WWPN
- # iSCSI: IPv4:Port
- # [IPv6]:Port
- # String. Lower case, split with : every two digits if WWPN.
- self._physical_address = _physical_address
- # physical_address:
- # The address used by physical layer like FC-0 and MAC:
- # FC: WWPN
- # FCoE: WWPN
- # iSCSI: MAC
- # String. Lower case, split with : every two digits.
- self._physical_name = _physical_name
- # physical_name
- # The name of physical port. Administrator could use this name to
- # locate the port on storage system.
- # String.
- self._system_id = _system_id
- self._plugin_data = _plugin_data
-
-
-class Capabilities(IData):
- UNSUPPORTED = 0
- SUPPORTED = 1
-
- _NUM = 512 # Indicate the maximum capability integer
-
- _CAP_NUM_BEGIN = 20 # Indicate the first capability integer
-
- #Block operations
- VOLUMES = 20
- VOLUME_CREATE = 21
- VOLUME_RESIZE = 22
-
- VOLUME_REPLICATE = 23
- VOLUME_REPLICATE_CLONE = 24
- VOLUME_REPLICATE_COPY = 25
- VOLUME_REPLICATE_MIRROR_ASYNC = 26
- VOLUME_REPLICATE_MIRROR_SYNC = 27
-
- VOLUME_COPY_RANGE_BLOCK_SIZE = 28
- VOLUME_COPY_RANGE = 29
- VOLUME_COPY_RANGE_CLONE = 30
- VOLUME_COPY_RANGE_COPY = 31
-
- VOLUME_DELETE = 33
-
- VOLUME_ENABLE = 34
- VOLUME_DISABLE = 35
-
- VOLUME_MASK = 36
- VOLUME_UNMASK = 37
- ACCESS_GROUPS = 38
- ACCESS_GROUP_CREATE_WWPN = 39
- ACCESS_GROUP_DELETE = 40
- ACCESS_GROUP_INITIATOR_ADD_WWPN = 41
- # For empty access group, this indicate it can add WWPN into it.
- ACCESS_GROUP_INITIATOR_DELETE = 42
-
- VOLUMES_ACCESSIBLE_BY_ACCESS_GROUP = 43
- ACCESS_GROUPS_GRANTED_TO_VOLUME = 44
-
- VOLUME_CHILD_DEPENDENCY = 45
- VOLUME_CHILD_DEPENDENCY_RM = 46
-
- ACCESS_GROUP_CREATE_ISCSI_IQN = 47
- ACCESS_GROUP_INITIATOR_ADD_ISCSI_IQN = 48
- # For empty access group, this indicate it can add iSCSI IQN into it.
-
- VOLUME_ISCSI_CHAP_AUTHENTICATION = 53
-
- VOLUME_RAID_INFO = 54
-
- VOLUME_THIN = 55
-
- #File system
- FS = 100
- FS_DELETE = 101
- FS_RESIZE = 102
- FS_CREATE = 103
- FS_CLONE = 104
- FILE_CLONE = 105
- FS_SNAPSHOTS = 106
- FS_SNAPSHOT_CREATE = 107
- FS_SNAPSHOT_DELETE = 109
- FS_SNAPSHOT_RESTORE = 110
- FS_SNAPSHOT_RESTORE_SPECIFIC_FILES = 111
- FS_CHILD_DEPENDENCY = 112
- FS_CHILD_DEPENDENCY_RM = 113
- FS_CHILD_DEPENDENCY_RM_SPECIFIC_FILES = 114
-
- #NFS
- EXPORT_AUTH = 120
- EXPORTS = 121
- EXPORT_FS = 122
- EXPORT_REMOVE = 123
- EXPORT_CUSTOM_PATH = 124
-
- POOLS_QUICK_SEARCH = 210
- VOLUMES_QUICK_SEARCH = 211
- DISKS_QUICK_SEARCH = 212
- ACCESS_GROUPS_QUICK_SEARCH = 213
- FS_QUICK_SEARCH = 214
- NFS_EXPORTS_QUICK_SEARCH = 215
- TARGET_PORTS = 216
- TARGET_PORTS_QUICK_SEARCH = 217
-
- DISKS = 220
-
- def _to_dict(self):
- return {'class': self.__class__.__name__,
- 'cap': ''.join(['%02x' % b for b in self._cap])}
-
- def __init__(self, _cap=None):
- if _cap is not None:
- self._cap = bytearray(_cap.decode('hex'))
- else:
- self._cap = bytearray(Capabilities._NUM)
-
- def supported(self, capability):
- return self.get(capability) == Capabilities.SUPPORTED
-
- def get(self, capability):
- if capability >= len(self._cap):
- return Capabilities.UNSUPPORTED
- return self._cap[capability]
-
- @staticmethod
- def _lsm_cap_to_str_dict():
- """
- Return a dict containing all valid capability:
- integer => string name
- """
- lsm_cap_to_str_conv = dict()
- for c_str, c_int in Capabilities.__dict__.items():
- if type(c_str) == str and type(c_int) == int and \
- c_str[0] != '_' and \
- Capabilities._CAP_NUM_BEGIN <= c_int <= Capabilities._NUM:
- lsm_cap_to_str_conv[c_int] = c_str
- return lsm_cap_to_str_conv
-
- def get_supported(self, all_cap=False):
- """
- Returns a hash of the supported capabilities in the form
- constant, name
- """
- all_caps = Capabilities._lsm_cap_to_str_dict()
-
- if all_cap:
- return all_caps
-
- rc = {}
- for i in all_caps.keys():
- if self._cap[i] == Capabilities.SUPPORTED:
- if i in all_caps:
- rc[i] = all_caps[i]
- return rc
-
- def set(self, capability, value=SUPPORTED):
- self._cap[capability] = value
-
- def enable_all(self):
- for i in range(len(self._cap)):
- self._cap[i] = Capabilities.SUPPORTED
-
-
-if __name__ == '__main__':
- #TODO Need some unit tests that encode/decode all the types with nested
- pass
diff --git a/python_binding/lsm/_iplugin.py b/python_binding/lsm/_iplugin.py
deleted file mode 100644
index a612ba4..0000000
--- a/python_binding/lsm/_iplugin.py
+++ /dev/null
@@ -1,481 +0,0 @@
-# Copyright (C) 2011-2013 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: tasleson
-
-from abc import ABCMeta as _ABCMeta
-from abc import abstractmethod as _abstractmethod
-from lsm import LsmError, ErrorNumber
-
-
-class IPlugin(object):
- """
- Plug-in interface that all plug-ins must implement for basic
- operation.
- """
- __metaclass__ = _ABCMeta
-
- @_abstractmethod
- def plugin_register(self, uri, password, timeout, flags=0):
- """
- Method first called to setup the plug-in (except for plugin_info)
-
- This would be the place to make a connection to the array.
-
- Returns None on success, else LsmError exception
- """
- pass
-
- @_abstractmethod
- def time_out_set(self, ms, flags=0):
- """
- Sets any time-outs for the plug-in (ms)
-
- Returns None on success, else LsmError exception
- """
- pass
-
- @_abstractmethod
- def time_out_get(self, flags=0):
- """
- Retrieves the current time-out
-
- Returns time-out in ms, else raise LsmError
- """
- pass
-
- @_abstractmethod
- def plugin_unregister(self, flags=0):
- """
- Called when the client wants to finish up or the socket goes eof.
- Plug-in should clean up all resources. Note: In the case where
- the socket goes EOF and the plugin_unregister runs into errors the
- exception(s) will not be delivered to the client!
-
- Returns None on success, else LsmError exception
- """
- pass
-
- @_abstractmethod
- def job_status(self, job_id, flags=0):
- """
- Returns the stats of the given job.
-
- Returns a tuple ( status (enumeration), percent_complete,
- completed item).
- else LsmError exception.
- """
- pass
-
- @_abstractmethod
- def job_free(self, job_id, flags=0):
- """
- Frees resources for a given job.
-
- Returns None on success, else raises an LsmError
- """
- pass
-
- @_abstractmethod
- def capabilities(self, system, flags=0):
- """
- Returns the capabilities for the selected system, raises LsmError
- """
- pass
-
- @_abstractmethod
- def plugin_info(self, flags=0):
- """
- Returns the description and version for plug-in, raises LsmError
-
- Note: Make sure plugin can handle this call before plugin_register is
- called.
- """
- pass
-
- @_abstractmethod
- def pools(self, search_key=None, search_value=None, flags=0):
- """
- Returns an array of pool objects. Pools are used in both block and
- file system interfaces, thus the reason they are in the base class.
-
- Raises LsmError on error
- """
- pass
-
- @_abstractmethod
- def systems(self, flags=0):
- """
- Returns an array of system objects. System information is used to
- distinguish resources from on storage array to another when the plug=in
- supports the ability to have more than one array managed by it
-
- Raises LsmError on error
- """
- pass
-
-
-class IStorageAreaNetwork(IPlugin):
-
- def volumes(self, search_key=None, search_value=None, flags=0):
- """
- Returns an array of volume objects
-
- Raises LsmError on error
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def volume_create(self, pool, volume_name, size_bytes, provisioning,
- flags=0):
- """
- Creates a volume, given a pool, volume name, size and provisioning
-
- Returns a tuple (job_id, new volume)
- Note: Tuple return values are mutually exclusive, when one
- is None the other must be valid.
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def volume_delete(self, volume, flags=0):
- """
- Deletes a volume.
-
- Returns Job id or None if completed, else raises LsmError on errors.
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def volume_resize(self, volume, new_size_bytes, flags=0):
- """
- Re-sizes a volume.
-
- Returns a tuple (job_id, re-sized_volume)
- Note: Tuple return values are mutually exclusive, when one
- is None the other must be valid.
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def volume_replicate(self, pool, rep_type, volume_src, name, flags=0):
- """
- Replicates a volume from the specified pool. In this library, to
- replicate means to create a new volume which is a copy of the source.
-
- Returns a tuple (job_id, replicated volume)
- Note: Tuple return values are mutually exclusive, when one
- is None the other must be valid.
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def volume_replicate_range_block_size(self, system, flags=0):
- """
- Returns the number of bytes per block for volume_replicate_range
- call. Callers of volume_replicate_range need to use this when
- calculating start and block lengths.
-
- Note: bytes per block may not match volume blocksize.
-
- Returns bytes per block, Raises LsmError on error
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def volume_replicate_range(self, rep_type, volume_src, volume_dest, ranges,
- flags=0):
- """
- Replicates a portion of a volume to itself or another volume. The src,
- dest and number of blocks values change with vendor, call
- volume_replicate_range_block_size to get block unit size.
-
- Returns Job id or None if completed, else raises LsmError on errors.
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def volume_enable(self, volume, flags=0):
- """
- Makes a volume available to the host
-
- Returns None on success, else raises LsmError on errors.
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def volume_disable(self, volume, flags=0):
- """
- Makes a volume unavailable to the host
-
- Returns None on success, else raises LsmError on errors.
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def iscsi_chap_auth(self, init_id, in_user, in_password, out_user,
- out_password, flags):
- """
- Register a user/password for the specified initiator for CHAP
- authentication. in_user & in_password are for inbound CHAP, out_user &
- out_password are for outbound CHAP.
-
- Note: Setting in_user, in_password or out_user, out_password to None
- will disable authentication.
-
- Raises LsmError on error
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def volume_mask(self, access_group, volume, flags=0):
- """
- Allows an access group to access a volume.
-
- Returns None on success, else raises LsmError on errors.
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def volume_unmask(self, access_group, volume, flags=0):
- """
- Revokes access for an access group for a volume
-
- Returns None on success, else raises LsmError on errors.
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def access_groups(self, search_key=None, search_value=None, flags=0):
- """
- Returns a list of access groups, raises LsmError on errors.
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def access_group_create(self, name, init_id, init_type, system,
- flags=0):
- """
- Returns a list of access groups, raises LsmError on errors.
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def access_group_delete(self, access_group, flags=0):
- """
- Deletes an access group, Raises LsmError on error
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def access_group_initiator_add(self, access_group, init_id, init_type,
- flags=0):
- """
- Adds an initiator to an access group, Raises LsmError on error
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def access_group_initiator_delete(self, access_group, init_id, init_type,
- flags=0):
- """
- Deletes an initiator from an access group, Raises LsmError on error
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def volumes_accessible_by_access_group(self, access_group, flags=0):
- """
- Returns the list of volumes that access group has access to.
- Raises LsmError on error
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def access_groups_granted_to_volume(self, volume, flags=0):
- """
- Returns the list of access groups that have access to the specified,
- Raises LsmError on error
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def volume_child_dependency(self, volume, flags=0):
- """
- Returns True if this volume has other volumes which are dependant on
- it. Implies that this volume cannot be deleted or possibly modified
- because it would affect its children.
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def volume_child_dependency_rm(self, volume, flags=0):
- """
- If this volume has child dependency, this method call will fully
- replicate the blocks removing the relationship between them. This
- should return None (success) if volume_child_dependency would return
- False.
-
- Note: This operation could take a very long time depending on the size
- of the volume and the number of child dependencies.
-
- Returns None if complete else job id, raises LsmError on errors.
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def target_ports(self, search_key=None, search_value=None, flags=0):
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
-
-class INetworkAttachedStorage(IPlugin):
- """
- Class the represents Network attached storage (Common NFS/CIFS operations)
- """
- def fs(self, search_key=None, search_value=None, flags=0):
- """
- Returns a list of file systems on the controller. Raises LsmError on
- errors.
- """
- pass
-
- def fs_delete(self, fs, flags=0):
- """
- WARNING: Destructive
-
- Deletes a file system and everything it contains
- Returns None on success, else job id
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def fs_resize(self, fs, new_size_bytes, flags=0):
- """
- Re-size a file system
-
- Returns a tuple (job_id, re-sized file system)
- Note: Tuple return values are mutually exclusive, when one
- is None the other must be valid.
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def fs_create(self, pool, name, size_bytes, flags=0):
- """
- Creates a file system given a pool, name and size.
- Note: size is limited to 2**64 bytes so max size of a single volume
- at this time is 16 Exabytes
-
- Returns a tuple (job_id, file system)
- Note: Tuple return values are mutually exclusive, when one
- is None the other must be valid.
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def fs_clone(self, src_fs, dest_fs_name, snapshot=None, flags=0):
- """
- Creates a thin, point in time read/writable copy of src to dest.
- Optionally uses snapshot as backing of src_fs
-
- Returns a tuple (job_id, file system)
- Note: Tuple return values are mutually exclusive, when one
- is None the other must be valid.
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def fs_file_clone(self, fs, src_file_name, dest_file_name, snapshot=None,
- flags=0):
- """
- Creates a thinly provisioned clone of src to dest.
- Note: Source and Destination are required to be on same filesystem
-
- Returns Job id or None if completed, else raises LsmError on errors.
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def fs_snapshots(self, fs, flags=0):
- """
- Returns a list of snapshots for the supplied file system,
- Raises LsmError on error
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def fs_snapshot_create(self, fs, snapshot_name, flags=0):
- """
- Snapshot is a point in time read-only copy
-
- Create a snapshot on the chosen file system
-
- Returns a tuple (job_id, snap shot created)
- Note: Tuple return values are mutually exclusive, when one
- is None the other must be valid.
-
- Note: Snapshot name may not match
- what was passed in (depends on array implementation)
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def fs_snapshot_delete(self, fs, snapshot, flags=0):
- """
- Frees the re-sources for the given snapshot on the supplied filesystem.
-
- Returns Job id or None if completed, else raises LsmError on errors.
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def fs_snapshot_restore(self, fs, snapshot, files, restore_files,
- all_files=False, flags=0):
- """
- WARNING: Destructive!
-
- Reverts a file-system or just the specified files from the snapshot.
- If a list of files is supplied but the array cannot restore just them
- then the operation will fail with an LsmError raised.
- If files == None and all_files = True then all files on the
- file-system are restored.
-
- Restore_file if not None must be the same length as files with each
- index in each list referring to the associated file.
-
- Returns None on success, else job id, LsmError exception on error
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def fs_child_dependency(self, fs, files, flags=0):
- """
- Returns True if the specified filesystem or specified file on this
- file system has child dependencies. This implies that this filesystem
- or specified file on this file system cannot be deleted or possibly
- modified because it would affect its children.
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def fs_child_dependency_rm(self, fs, files, flags=0):
- """
- If this filesystem or specified file on this filesystem has child
- dependency this method will fully replicate the blocks removing the
- relationship between them. This should return None(success) if
- fs_child_dependency would return False.
-
- Note: This operation could take a very long time depending on the size
- of the filesystem and the number of child dependencies.
-
- Returns Job id or None if completed, else raises LsmError on errors.
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
-
-class INfs(INetworkAttachedStorage):
- def export_auth(self, flags=0):
- """
- Returns the types of authentication that are available for NFS
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def exports(self, search_key=None, search_value=None, flags=0):
- """
- Get a list of all exported file systems on the controller.
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def export_fs(self, fs_id, export_path, root_list, rw_list, ro_list,
- anon_uid, anon_gid, auth_type, options, flags=0):
- """
- Exports a filesystem as specified in the export
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- def export_remove(self, export, flags=0):
- """
- Removes the specified export
- """
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
diff --git a/python_binding/lsm/_pluginrunner.py b/python_binding/lsm/_pluginrunner.py
deleted file mode 100644
index a6d095c..0000000
--- a/python_binding/lsm/_pluginrunner.py
+++ /dev/null
@@ -1,153 +0,0 @@
-# Copyright (C) 2011-2013 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: tasleson
-
-import socket
-import traceback
-import sys
-from _common import SocketEOF as _SocketEOF
-from lsm import LsmError, error, ErrorNumber
-import _transport
-from lsm.lsmcli import cmd_line_wrapper
-
-
-def search_property(lsm_objs, search_key, search_value):
- """
- This method does not check whether lsm_obj contain requested property.
- The method caller should do the check.
- """
- if search_key is None:
- return lsm_objs
- return list(lsm_obj for lsm_obj in lsm_objs
- if getattr(lsm_obj, search_key) == search_value)
-
-
-class PluginRunner(object):
- """
- Plug-in side common code which uses the passed in plugin to do meaningful
- work.
- """
-
- @staticmethod
- def _is_number(val):
- """
- Returns True if val is an integer.
- """
- try:
- int(val)
- return True
- except ValueError:
- return False
-
- def __init__(self, plugin, args):
- self.cmdline = False
- if len(args) == 2 and PluginRunner._is_number(args[1]):
- try:
- fd = int(args[1])
- self.tp = _transport.TransPort(
- socket.fromfd(fd, socket.AF_UNIX, socket.SOCK_STREAM))
-
- #At this point we can return errors to the client, so we can
- #inform the client if the plug-in fails to create itself
- try:
- self.plugin = plugin()
- except Exception as e:
- exception_info = sys.exc_info()
-
- self.tp.send_error(0, -32099,
- 'Error instantiating plug-in ' + str(e))
- raise exception_info[1], None, exception_info[2]
-
- except Exception:
- error(traceback.format_exc())
- error('Plug-in exiting.')
- sys.exit(2)
-
- else:
- self.cmdline = True
- cmd_line_wrapper(plugin)
-
- def run(self):
- #Don't need to invoke this when running stand alone as a cmdline
- if self.cmdline:
- return
-
- need_shutdown = False
- msg_id = 0
-
- try:
- while True:
- try:
- #result = None
-
- msg = self.tp.read_req()
-
- method = msg['method']
- msg_id = msg['id']
- params = msg['params']
-
- #Check to see if this plug-in implements this operation
- #if not return the expected error.
- if hasattr(self.plugin, method):
- if params is None:
- result = getattr(self.plugin, method)()
- else:
- result = getattr(self.plugin, method)(
- **msg['params'])
- else:
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "Unsupported operation")
-
- self.tp.send_resp(result)
-
- if method == 'plugin_register':
- need_shutdown = True
-
- if method == 'plugin_unregister':
- #This is a graceful plugin_unregister
- need_shutdown = False
- self.tp.close()
- break
-
- except ValueError as ve:
- error(traceback.format_exc())
- self.tp.send_error(msg_id, -32700, str(ve))
- except AttributeError as ae:
- error(traceback.format_exc())
- self.tp.send_error(msg_id, -32601, str(ae))
- except LsmError as lsm_err:
- self.tp.send_error(msg_id, lsm_err.code, lsm_err.msg,
- lsm_err.data)
- except _SocketEOF:
- #Client went away and didn't meet our expectations for protocol,
- #this error message should not be seen as it shouldn't be occuring.
- if need_shutdown:
- error('Client went away, exiting plug-in')
- except Exception:
- error("Unhandled exception in plug-in!\n" + traceback.format_exc())
-
- try:
- self.tp.send_error(msg_id, ErrorNumber.PLUGIN_BUG,
- "Unhandled exception in plug-in",
- str(traceback.format_exc()))
- except Exception:
- pass
-
- finally:
- if need_shutdown:
- #Client wasn't nice, we will allow plug-in to cleanup
- self.plugin.plugin_unregister()
- sys.exit(2)
diff --git a/python_binding/lsm/_transport.py b/python_binding/lsm/_transport.py
deleted file mode 100644
index 5d6a6ec..0000000
--- a/python_binding/lsm/_transport.py
+++ /dev/null
@@ -1,271 +0,0 @@
-# Copyright (C) 2011-2013 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: tasleson
-
-import json
-import socket
-import string
-import os
-from _common import SocketEOF as _SocketEOF
-from _common import LsmError, ErrorNumber
-from _data import DataDecoder as _DataDecoder, DataEncoder as _DataEncoder
-import unittest
-import threading
-
-
-class TransPort(object):
- """
- Provides wire serialization by using json. Loosely conforms to json-rpc,
- however a length header was added so that we would have the ability to use
- non sax like json parsers, which are more abundant.
-
- <Zero padded 10 digit number [1..2**32] for the length followed by
- valid json.
-
- Notes:
- id field (json-rpc) is present but currently not being used.
- This is available to be expanded on later.
- """
-
- HDR_LEN = 10
-
- def _read_all(self, l):
- """
- Reads l number of bytes before returning. Will raise a SocketEOF
- if socket returns zero bytes (i.e. socket no longer connected)
- """
-
- if l < 1:
- raise ValueError("Trying to read less than 1 byte!")
-
- data = ""
- while len(data) < l:
- r = self.s.recv(l - len(data))
- if not r:
- raise _SocketEOF()
- data += r
-
- return data
-
- def _send_msg(self, msg):
- """
- Sends the json formatted message by pre-appending the length
- first.
- """
-
- if msg is None or len(msg) < 1:
- raise ValueError("Msg argument empty")
-
- #Note: Don't catch io exceptions at this level!
- s = string.zfill(len(msg), self.HDR_LEN) + msg
- #common.Info("SEND: ", msg)
- self.s.sendall(s)
-
- def _recv_msg(self):
- """
- Reads header first to get the length and then the remaining
- bytes of the message.
- """
- try:
- l = self._read_all(self.HDR_LEN)
- msg = self._read_all(int(l))
- #common.Info("RECV: ", msg)
- except socket.error as e:
- raise LsmError(ErrorNumber.TRANSPORT_COMMUNICATION,
- "Error while reading a message from the plug-in",
- str(e))
- return msg
-
- def __init__(self, socket_descriptor):
- self.s = socket_descriptor
-
- @staticmethod
- def get_socket(path):
- """
- Returns a connected socket from the passed in path.
- """
- try:
- s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
-
- if os.path.exists(path):
- if os.access(path, os.R_OK | os.W_OK):
- s.connect(path)
- else:
- raise LsmError(ErrorNumber.PLUGIN_SOCKET_PERMISSION,
- "Permissions are incorrect for IPC "
- "socket file")
- else:
- raise LsmError(ErrorNumber.PLUGIN_NOT_EXIST,
- "Plug-in appears to not exist")
- except socket.error:
- #self, code, message, data=None, *args, **kwargs
- raise LsmError(ErrorNumber.PLUGIN_IPC_FAIL,
- "Unable to connect to lsmd, daemon started?")
- return s
-
- def close(self):
- """
- Closes the transport and the underlying socket
- """
- self.s.close()
-
- def send_req(self, method, args):
- """
- Sends a request given a method and arguments.
- Note: arguments must be in the form that can be automatically
- serialized to json
- """
- try:
- msg = {'method': method, 'id': 100, 'params': args}
- data = json.dumps(msg, cls=_DataEncoder)
- self._send_msg(data)
- except socket.error as se:
- raise LsmError(ErrorNumber.TRANSPORT_COMMUNICATION,
- "Error while sending a message to the plug-in",
- str(se))
-
- def read_req(self):
- """
- Reads a message and returns the parsed version of it.
- """
- data = self._recv_msg()
- if len(data):
- #common.Info(str(data))
- return json.loads(data, cls=_DataDecoder)
-
- def rpc(self, method, args):
- """
- Sends a request and waits for a response.
- """
- self.send_req(method, args)
- (reply, msg_id) = self.read_resp()
- assert msg_id == 100
- return reply
-
- def send_error(self, msg_id, error_code, msg, data=None):
- """
- Used to transmit an error.
- """
- e = {'id': msg_id, 'error': {'code': error_code, 'message': msg,
- 'data': data}}
- self._send_msg(json.dumps(e, cls=_DataEncoder))
-
- def send_resp(self, result, msg_id=100):
- """
- Used to transmit a response
- """
- r = {'id': msg_id, 'result': result}
- self._send_msg(json.dumps(r, cls=_DataEncoder))
-
- def read_resp(self):
- data = self._recv_msg()
- resp = json.loads(data, cls=_DataDecoder)
-
- if 'result' in resp:
- return resp['result'], resp['id']
- else:
- e = resp['error']
- raise LsmError(**e)
-
-
-def _server(s):
- """
- Test echo server for test case.
- """
- srv = TransPort(s)
-
- msg = srv.read_req()
-
- try:
- while msg['method'] != 'done':
-
- if msg['method'] == 'error':
- srv.send_error(
- msg['id'],
- msg['params']['errorcode'],
- msg['params']['errormsg'])
- else:
- srv.send_resp(msg['params'])
- msg = srv.read_req()
- srv.send_resp(msg['params'])
- finally:
- s.close()
-
-
-class _TestTransport(unittest.TestCase):
- def setUp(self):
- (self.c, self.s) = socket.socketpair(
- socket.AF_UNIX, socket.SOCK_STREAM)
-
- self.client = TransPort(self.c)
-
- self.server = threading.Thread(target=_server, args=(self.s,))
- self.server.start()
-
- def test_simple(self):
- tc = ['0', ' ', ' ', '{}:""', "Some text message", 'DEADBEEF']
-
- for t in tc:
- self.client.send_req('test', t)
- reply, msg_id = self.client.read_resp()
- self.assertTrue(msg_id == 100)
- self.assertTrue(reply == t)
-
- def test_exceptions(self):
-
- e_msg = 'Test error message'
- e_code = 100
-
- self.client.send_req('error', {'errorcode': e_code, 'errormsg': e_msg})
- self.assertRaises(LsmError, self.client.read_resp)
-
- try:
- self.client.send_req('error', {'errorcode': e_code,
- 'errormsg': e_msg})
- self.client.read_resp()
- except LsmError as e:
- self.assertTrue(e.code == e_code)
- self.assertTrue(e.msg == e_msg)
-
- def test_slow(self):
-
- #Try to test the receiver getting small chunks to read
- #in a loop
- for l in range(1, 4096, 10):
-
- payload = "x" * l
- msg = {'method': 'drip', 'id': 100, 'params': payload}
- data = json.dumps(msg, cls=_DataEncoder)
-
- wire = string.zfill(len(data), TransPort.HDR_LEN) + data
-
- self.assertTrue(len(msg) >= 1)
-
- for i in wire:
- self.c.send(i)
-
- reply, msg_id = self.client.read_resp()
- self.assertTrue(payload == reply)
-
- def tearDown(self):
- self.client.send_req("done", None)
- resp, msg_id = self.client.read_resp()
- self.assertTrue(resp is None)
- self.server.join()
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/python_binding/lsm/external/__init__.py b/python_binding/lsm/external/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/python_binding/lsm/external/xmltodict.py b/python_binding/lsm/external/xmltodict.py
deleted file mode 100644
index 80fbf55..0000000
--- a/python_binding/lsm/external/xmltodict.py
+++ /dev/null
@@ -1,147 +0,0 @@
-# This code taken from recipe
-# http://code.activestate.com/recipes/
-# 573463-converting-xml-to-dictionary-and-back/
-# Modified slightly to remove namespace and number of other small details
-# Licensed: PSF
-
-from xml.etree import ElementTree
-
-
-def _ns(tag):
- return tag[tag.find('}') + 1:]
-
-
-class XmlDictObject(dict):
- """
- Adds object like functionality to the standard dictionary.
- """
- def __init__(self, initdict=None):
- if initdict is None:
- initdict = {}
- dict.__init__(self, initdict)
-
- def __getattr__(self, item):
- return self.__getitem__(item)
-
- def __setattr__(self, item, value):
- self.__setitem__(item, value)
-
- def __str__(self):
- if '_text' in self:
- return self.__getitem__('_text')
- else:
- return ''
-
- @staticmethod
- def wrap(x):
- """
- Static method to wrap a dictionary recursively as an XmlDictObject
- """
- if isinstance(x, dict):
- return XmlDictObject(
- (k, XmlDictObject.wrap(v)) for (k, v) in x.iteritems())
- elif isinstance(x, list):
- return [XmlDictObject.wrap(v) for v in x]
- else:
- return x
-
- @staticmethod
- def _un_wrap(x):
- if isinstance(x, dict):
- return dict(
- (k, XmlDictObject._un_wrap(v)) for (k, v) in x.iteritems())
- elif isinstance(x, list):
- return [XmlDictObject._un_wrap(v) for v in x]
- else:
- return x
-
- def un_wrap(self):
- """
- Recursively converts an XmlDictObject to a standard dictionary and
- returns the result.
- """
- return XmlDictObject._un_wrap(self)
-
-
-def _convert_dict_to_xml_recurse(parent, dictitem):
- assert isinstance(dictitem, dict)
-
- if isinstance(dictitem, dict):
- for (tag, child) in dictitem.iteritems():
- if str(tag) == '_text':
- parent.text = str(child)
- elif isinstance(child, list):
- # iterate through the array and convert
- for listchild in child:
- elem = ElementTree.Element(tag)
- parent.append(elem)
- _convert_dict_to_xml_recurse(elem, listchild)
- else:
- elem = ElementTree.Element(tag)
- parent.append(elem)
- _convert_dict_to_xml_recurse(elem, child)
- else:
- parent.text = str(dictitem)
-
-
-def convert_dict_to_xml(xmldict):
- """
- Converts a dictionary to an XML ElementTree Element
- """
- roottag = xmldict.keys()[0]
- root = ElementTree.Element(roottag)
- _convert_dict_to_xml_recurse(root, xmldict[roottag])
- return root
-
-
-def _convert_xml_to_dict_recurse(node, dictclass):
- nodedict = dictclass()
-
- if len(node.items()) > 0:
- # if we have attributes, set them
- if'attrib' in nodedict:
- nodedict['attrib'].update(dict(node.items()))
- else:
- nodedict['attrib'] = {}
- nodedict['attrib'].update(dict(node.items()))
- #We get a collision so attributes get their own hash!
- #nodedict.update(dict(node.items()))
-
- for child in node:
- # recursively add the element's children
- newitem = _convert_xml_to_dict_recurse(child, dictclass)
- if _ns(child.tag) in nodedict:
- # found duplicate tag, force a list
- if isinstance(nodedict[_ns(child.tag)], list):
- # append to existing list
- nodedict[_ns(child.tag)].append(newitem)
- else:
- # convert to list
- nodedict[_ns(child.tag)] = [nodedict[_ns(child.tag)], newitem]
- else:
- # only one, directly set the dictionary
- nodedict[_ns(child.tag)] = newitem
-
- if node.text is None:
- text = None
- else:
- text = node.text.strip()
-
- if len(nodedict) > 0:
- # if we have a dictionary add the text as a dictionary value
- # (if there is any)
- if text is not None and len(text) > 0:
- nodedict['_text'] = text
- else:
- # if we don't have child nodes or attributes, just set the text
- nodedict = text
-
- return nodedict
-
-
-def convert_xml_to_dict(root, dictclass=XmlDictObject):
- """
- Converts an ElementTree Element to a dictionary
- """
- return dictclass(
- {_ns(root.tag): _convert_xml_to_dict_recurse(root, dictclass)})
diff --git a/python_binding/lsm/version.py.in b/python_binding/lsm/version.py.in
deleted file mode 100644
index dc2333e..0000000
--- a/python_binding/lsm/version.py.in
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (C) 2011-2013 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: tasleson
-
-#To be filled in by autoconf
-VERSION = "@VERSION@"
diff --git a/test/Makefile.am b/test/Makefile.am
deleted file mode 100644
index 872e8e0..0000000
--- a/test/Makefile.am
+++ /dev/null
@@ -1,13 +0,0 @@
-AM_CPPFLAGS = \
- -I$(top_srcdir)/c_binding/include \
- -***@srcdir@/c_binding/include \
- $(LIBXML_CFLAGS)
-
-EXTRA_DIST=cmdtest.py runtests.sh plugin_test.py
-
-TESTS = runtests.sh
-
-check_PROGRAMS = tester
-tester_CFLAGS = $(LIBCHECK_CFLAGS)
-tester_LDADD = ../c_binding/libstoragemgmt.la $(LIBCHECK_LIBS)
-tester_SOURCES = tester.c
diff --git a/test/cmdtest.py b/test/cmdtest.py
deleted file mode 100755
index e80e027..0000000
--- a/test/cmdtest.py
+++ /dev/null
@@ -1,753 +0,0 @@
-#!/usr/bin/env python2
-
-# Copyright (C) 2011-2014 Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program 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 General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-# USA.
-#
-# Author: tasleson
-
-#Description: Query array capabilities and run very basic operational tests.
-#
-# Note: This file is GPL copyright and not LGPL because:
-# 1. It is used to test the library, not provide functionality for it.
-# 2. It uses a function copied from anaconda library which is GPLv2 or later,
-# thus this code must be GPL as well.
-
-import random
-import string
-import sys
-import hashlib
-import os
-from subprocess import Popen, PIPE
-from optparse import OptionParser
-
-(OP_SYS, OP_POOL, OP_VOL, OP_FS, OP_EXPORTS, OP_SS) = \
- ('SYSTEMS', 'POOLS', 'VOLUMES', 'FS', 'EXPORTS',
- 'SNAPSHOTS')
-
-(ID, NAME) = (0, 1)
-(POOL_TOTAL, POOL_FREE, POOL_SYSTEM) = (2, 3, 4)
-(VOL_VPD, VOL_BS, VOL_BLOCKS, VOL_STATUS, VOL_SIZE) = (2, 3, 4, 5, 6)
-(INIT_TYPE) = 2
-(FS_TOTAL, FS_FREE, FS_POOL_ID) = (2, 3, 4)
-
-(SYS_STATUS,) = (2,)
-
-iqn = ['iqn.1994-05.com.domain:01.89bd01', 'iqn.1994-05.com.domain:01.89bd02']
-
-cmd = "lsmcli"
-
-sep = ","
-test_pool_name = 'lsm_test_aggr'
-test_fs_pool_id = ''
-test_disk_id = 'DISK_ID_00000'
-
-CUR_SYS_ID = None
-
-code_coverage = bool(os.getenv('LSM_PYTHON_COVERAGE', False))
-
-
-def random_iqn():
- """Logic taken from anaconda library"""
-
- s = "iqn.1994-05.com.domain:01."
- m = hashlib.md5()
- u = os.uname()
- for i in u:
- m.update(i)
- dig = m.hexdigest()
-
- for i in range(0, 6):
- s += dig[random.randrange(0, 32)]
- return s
-
-
-def rs(l):
- """
- Generate a random string
- """
- return 'lsm_' + ''.join(
- random.choice(string.ascii_uppercase) for x in range(l))
-
-
-def call(command, expected_rc=0):
- """
- Call an executable and return a tuple of exitcode, stdout, stderr
- """
-
- if code_coverage:
- actual_command = ['coverage', 'run', '-o']
- actual_command.extend(command)
- else:
- actual_command = command
-
- print actual_command, 'EXPECTED Exit [%d]' % expected_rc
-
- process = Popen(actual_command, stdout=PIPE, stderr=PIPE)
- out = process.communicate()
-
- if process.returncode != expected_rc:
- raise RuntimeError("exit code != %s, actual= %s, stdout= %s, "
- "stderr= %s" % (expected_rc, process.returncode,
- out[0], out[1]))
- return process.returncode, out[0], out[1]
-
-
-def parse(out):
- rc = []
- for line in out.split('\n'):
- elem = line.split(sep)
- cleaned_elem = []
- for e in elem:
- e = e.strip()
- cleaned_elem.append(e)
-
- if len(cleaned_elem) > 1:
- rc.append(cleaned_elem)
- return rc
-
-
-def parse_key_value(out):
- rc = []
- for line in out.split('\n'):
- elem = line.split(sep)
- if len(elem) > 1:
- item = dict()
-
- for i in range(0, len(elem), 2):
- key = elem[i].strip()
- value = elem[i + 1].strip()
- item[key] = value
-
- rc.append(item)
- return rc
-
-
-def parse_display(op):
- rc = []
- out = call([cmd, '-t' + sep, 'list', '--type', op])[1]
- for line in out.split('\n'):
- elem = line.split(sep)
- if len(elem) > 1:
- rc.append(list(d.strip() for d in elem))
- return rc
-
-
-def name_to_id(op, name):
- out = parse_display(op)
-
- for i in out:
- if i[NAME] == name:
- return i[ID]
- return None
-
-
-def create_volume(pool):
- out = call([cmd, '-t' + sep, 'volume-create', '--name', rs(12), '--size',
- '30M', '--pool', pool, '--provisioning', 'DEFAULT'])[1]
- r = parse(out)
- return r[0][ID]
-
-
-def volume_delete(vol_id):
- call([cmd, '-t' + sep, '-f', 'volume-delete', '--vol', vol_id])
-
-
-def fs_create(pool_id):
- out = call([cmd, '-t' + sep, 'fs-create', '--name', rs(12), '--size',
- '500M', '--pool', pool_id])[1]
- r = parse(out)
- return r[0][ID]
-
-
-def export_fs(fs_id):
- out = call([cmd, '-t' + sep,
- 'fs-export',
- '--fs', fs_id,
- '--rw-host', '192.168.0.1',
- '--root-host', '192.168.0.1', '--script'])[1]
-
- r = parse_key_value(out)
- return r[0]['ID']
-
-
-def un_export_fs(export_id):
- call([cmd, 'fs-unexport', '--export', export_id])
-
-
-def delete_fs(fs_id):
- call([cmd, '-t' + sep, '-f', 'fs-delete', '--fs', fs_id])
-
-
-def access_group_create(init_id, system_id):
- out = call([cmd, '-t' + sep, 'access-group-create', '--name', rs(8),
- '--init', init_id, '--sys', system_id])[1]
- r = parse(out)
- return r[0][ID]
-
-
-def access_group_initiator_add(group, initiator):
- call([cmd, 'access-group-add', '--ag', group, '--init', initiator])
-
-
-def access_group_remove_init(group, initiator):
- call([cmd, 'access-group-remove', '--ag', group, '--init', initiator])
-
-
-def access_group_delete(group_id):
- call([cmd, '-t' + sep, 'access-group-delete', '--ag', group_id])
-
-
-def volume_mask(group, volume_id):
- call([cmd, 'volume-mask', '--ag', group, '--vol', volume_id])
-
-
-def volume_unmask(group, volume_id):
- call([cmd, 'volume-unmask', '--ag', group, '--vol', volume_id])
-
-
-def volumes_accessible_by_access_group(ag_id):
- call([cmd, 'list', '--type', 'volumes', '--ag', ag_id])
-
-
-def access_groups_granted_to_volume(vol_id):
- call([cmd, 'list', '--type', 'access_groups', '--vol', vol_id])
-
-
-def resize_vol(vol_id):
- call([cmd, '-t' + sep, '-f',
- 'volume-resize',
- '--vol', vol_id,
- '--size', '60M'])
- call([cmd, '-t' + sep, '-f',
- 'volume-resize',
- '--vol', vol_id,
- '--size', '100M'])
- #Some devices cannot re-size down...
- #call([cmd, '--volume-resize', id, '--size', '30M' , '-t'+sep ])
-
-
-def resize_fs(fs_id):
- call([cmd, '-t' + sep, '-f',
- 'fs-resize',
- '--fs', fs_id,
- '--size', '1G'])
- call([cmd, '-t' + sep, '-f',
- 'fs-resize',
- '--fs', fs_id,
- '--size', '750M'])
- call([cmd, '-t' + sep, '-f',
- 'fs-resize',
- '--fs', fs_id,
- '--size', '300M'])
-
-
-def map_init(init, volume):
- call([cmd, '-t' + sep, 'access-grant', '--init', init, '--vol', volume,
- '--access', 'RW'])
-
-
-def unmap(init, volume):
- call([cmd, 'access-revoke', '--init', init, '--vol', volume])
-
-
-def clone_fs(fs_id):
- # TODO Change to --source_id instead of --source_name ?
- out = call([cmd, '-t' + sep, 'fs-clone', '--src-fs', fs_id,
- '--dst-name', 'cloned_' + rs(8)])[1]
- r = parse(out)
- return r[0][ID]
-
-
-def fs_child_dependancy(fs_id):
- call([cmd, 'fs-dependants', '--fs', fs_id])
-
-
-def fs_child_dependancy_rm(fs_id):
- call([cmd, 'fs-dependants-rm', '--fs', fs_id])
-
-
-def clone_file(fs_id):
- # TODO Make this work outside of the simulator
- call([cmd, 'file-clone', '--fs', fs_id, '--src', 'foo', '--dst', 'bar'])
-
-
-def create_ss(fs_id):
- out = call([cmd, '-t' + sep, 'fs-snap-create', '--name', rs(12), '--fs',
- fs_id])[1]
- r = parse(out)
- return r[0][ID]
-
-
-def delete_ss(fs_id, ss_id):
- call([cmd, '-f', 'fs-snap-delete', '--snap', ss_id, '--fs', fs_id])
-
-
-def restore_ss(snapshot_id, fs_id):
- call([cmd, '-f', 'fs-snap-restore', '--snap', snapshot_id, '--fs', fs_id])
-
-
-def volume_replicate(source_id, vol_type, pool=None):
- out = call([cmd,
- '-t' + sep,
- 'volume-replicate',
- '--vol', source_id,
- '--rep-type', vol_type,
- '--name', 'lun_' + vol_type + '_' + rs(12)])[1]
- r = parse(out)
- return r[0][ID]
-
-
-def volume_replicate_range_bs(system_id):
- """
- Returns the replicated range block size.
- """
- out = call([cmd,
- 'volume-replicate-range-block-size',
- '--sys', system_id])[1]
- return int(out)
-
-
-def volume_replicate_range(vol_id, dest_vol_id, rep_type, src_start,
- dest_start, count):
- out = call(
- [cmd, '-f', 'volume-replicate-range',
- '--src-vol', vol_id,
- '--rep-type', rep_type,
- '--dst-vol', dest_vol_id,
- '--src-start', str(src_start),
- '--dst-start', str(dest_start),
- '--count', str(count)])
-
-
-def volume_child_dependency(vol_id):
- call([cmd, 'volume-dependants', '--vol', vol_id])
-
-
-def volume_child_dependency_rm(vol_id):
- call([cmd, 'volume-dependants-rm', '--vol', vol_id])
-
-
-def get_systems():
- out = call([cmd, '-t' + sep, 'list', '--type', 'SYSTEMS'])[1]
- system_list = parse(out)
- return system_list
-
-
-def initiator_chap(initiator):
- call([cmd, 'iscsi-chap',
- '--init', initiator])
- call([cmd, 'iscsi-chap',
- '--init', initiator,
- '--in-user', "foo",
- '--in-pass', "bar"])
- call([cmd, 'iscsi-chap',
- '--init', initiator, '--in-user', "foo",
- '--in-pass', "bar", '--out-user', "foo",
- '--out-pass', "bar"])
-
-
-def capabilities(system_id):
- """
- Return a hash table of key:bool where key is supported operation
- """
- rc = {}
- out = call([cmd, '-t' + sep, 'capabilities', '--sys', system_id])[1]
- results = parse(out)
-
- for r in results:
- rc[r[0]] = True if r[1] == 'SUPPORTED' else False
- return rc
-
-
-def get_existing_fs(system_id):
- out = call([cmd, '-t' + sep, 'list', '--type', 'FS', ])[1]
- results = parse(out)
-
- if len(results) > 0:
- return results[0][ID]
- return None
-
-
-def numbers():
- vols = []
- test_pool_id = name_to_id(OP_POOL, test_pool_name)
-
- for i in range(10):
- vols.append(create_volume(test_pool_id))
-
- for i in vols:
- volume_delete(i)
-
-
-def display_check(display_list, system_id):
- s = [x for x in display_list if x != 'SNAPSHOTS']
- for p in s:
- call([cmd, 'list', '--type', p])
- call([cmd, '-H', 'list', '--type', p, ])
- call([cmd, '-H', '-t' + sep, 'list', '--type', p])
-
- if 'SNAPSHOTS' in display_list:
- fs_id = get_existing_fs(system_id)
- if fs_id:
- call([cmd, 'list', '--type', 'SNAPSHOTS', '--fs', fs_id])
-
- if 'POOLS' in display_list:
- call([cmd, '-H', '-t' + sep, 'list', '--type', 'POOLS'])
-
-
-def test_display(cap, system_id):
- """
- Crank through supported display operations making sure we get good
- status for each of them
- """
- to_test = ['SYSTEMS', 'POOLS']
-
- if cap['VOLUMES']:
- to_test.append('VOLUMES')
-
- if cap['FS']:
- to_test.append("FS")
-
- if cap['EXPORTS']:
- to_test.append("EXPORTS")
-
- if cap['ACCESS_GROUPS']:
- to_test.append("ACCESS_GROUPS")
-
- if cap['FS_SNAPSHOTS']:
- to_test.append('SNAPSHOTS')
-
- if cap['EXPORT_AUTH']:
- to_test.append('NFS_CLIENT_AUTH')
-
- if cap['EXPORTS']:
- to_test.append('EXPORTS')
-
- display_check(to_test, system_id)
-
-
-def test_block_creation(cap, system_id):
- vol_src = None
- test_pool_id = name_to_id(OP_POOL, test_pool_name)
-
- # Fail early if no pool is available
- if test_pool_id is None:
- print 'Pool %s is not available!' % test_pool_name
- exit(10)
-
- if cap['VOLUME_CREATE']:
- vol_src = create_volume(test_pool_id)
-
- if cap['VOLUME_RESIZE']:
- resize_vol(vol_src)
-
- if cap['VOLUME_REPLICATE'] and cap['VOLUME_DELETE']:
- if cap['VOLUME_REPLICATE_CLONE']:
- clone = volume_replicate(vol_src, 'CLONE', test_pool_id)
- volume_delete(clone)
-
- if cap['VOLUME_REPLICATE_COPY']:
- copy = volume_replicate(vol_src, 'COPY', test_pool_id)
- volume_delete(copy)
-
- if cap['VOLUME_REPLICATE_MIRROR_ASYNC']:
- m = volume_replicate(vol_src, 'MIRROR_ASYNC', test_pool_id)
- volume_delete(m)
-
- if cap['VOLUME_REPLICATE_MIRROR_SYNC']:
- m = volume_replicate(vol_src, 'MIRROR_SYNC', test_pool_id)
- volume_delete(m)
-
- if cap['VOLUME_COPY_RANGE_BLOCK_SIZE']:
- size = volume_replicate_range_bs(system_id)
- print 'sub volume replication block size is=', size
-
- if cap['VOLUME_COPY_RANGE']:
- if cap['VOLUME_COPY_RANGE_CLONE']:
- volume_replicate_range(vol_src, vol_src, "CLONE",
- 0, 10000, 100)
-
- if cap['VOLUME_COPY_RANGE_COPY']:
- volume_replicate_range(vol_src, vol_src, "COPY",
- 0, 10000, 100)
-
- if cap['VOLUME_CHILD_DEPENDENCY']:
- volume_child_dependency(vol_src)
-
- if cap['VOLUME_CHILD_DEPENDENCY_RM']:
- volume_child_dependency_rm(vol_src)
-
- if cap['VOLUME_DELETE']:
- volume_delete(vol_src)
-
-
-def test_fs_creation(cap, system_id):
-
- if test_fs_pool_id:
- pool_id = test_fs_pool_id
- else:
- pool_id = name_to_id(OP_POOL, test_pool_name)
-
- if cap['FS_CREATE']:
- fs_id = fs_create(pool_id)
-
- if cap['FS_RESIZE']:
- resize_fs(fs_id)
-
- if cap['FS_DELETE']:
- delete_fs(fs_id)
-
- if cap['FS_CLONE']:
- fs_id = fs_create(pool_id)
- clone = clone_fs(fs_id)
- test_display(cap, system_id)
- delete_fs(clone)
- delete_fs(fs_id)
-
- if cap['FILE_CLONE']:
- fs_id = fs_create(pool_id)
- clone_file(fs_id)
- test_display(cap, system_id)
- delete_fs(fs_id)
-
- if cap['FS_SNAPSHOT_CREATE'] and cap['FS_CREATE'] and cap['FS_DELETE'] \
- and cap['FS_SNAPSHOT_DELETE']:
- #Snapshot create/delete
- fs_id = fs_create(pool_id)
- ss = create_ss(fs_id)
- test_display(cap, system_id)
- restore_ss(ss, fs_id)
- delete_ss(fs_id, ss)
- delete_fs(fs_id)
-
- if cap['FS_CHILD_DEPENDENCY']:
- fs_id = fs_create(pool_id)
- fs_child_dependancy(fs_id)
- delete_fs(fs_id)
-
- if cap['FS_CHILD_DEPENDENCY_RM']:
- fs_id = fs_create(pool_id)
- clone_fs(fs_id)
- fs_child_dependancy_rm(fs_id)
- delete_fs(fs_id)
-
-
-def test_nfs(cap, system_id):
- if test_fs_pool_id:
- pool_id = test_fs_pool_id
- else:
- pool_id = name_to_id(OP_POOL, test_pool_name)
-
- if cap['FS_CREATE'] and cap['EXPORT_FS'] and cap['EXPORT_REMOVE']:
- fs_id = fs_create(pool_id)
- export_id = export_fs(fs_id)
- test_display(cap, system_id)
- un_export_fs(export_id)
- delete_fs(fs_id)
-
-
-def test_mapping(cap, system_id):
- pool_id = name_to_id(OP_POOL, test_pool_name)
- iqn1 = random_iqn()
- iqn2 = random_iqn()
-
- if cap['ACCESS_GROUP_CREATE_ISCSI_IQN']:
- ag_id = access_group_create(iqn1, system_id)
-
- if cap['VOLUME_ISCSI_CHAP_AUTHENTICATION']:
- initiator_chap(iqn1)
-
- if cap['ACCESS_GROUP_INITIATOR_ADD_ISCSI_IQN']:
- access_group_initiator_add(ag_id, iqn2)
-
- if cap['VOLUME_MASK'] and cap['VOLUME_UNMASK']:
- vol_id = create_volume(pool_id)
- volume_mask(ag_id, vol_id)
-
- test_display(cap, system_id)
-
- if cap['VOLUMES_ACCESSIBLE_BY_ACCESS_GROUP']:
- volumes_accessible_by_access_group(ag_id)
-
- if cap['ACCESS_GROUPS_GRANTED_TO_VOLUME']:
- access_groups_granted_to_volume(vol_id)
-
- if cap['VOLUME_UNMASK']:
- volume_unmask(ag_id, vol_id)
-
- if cap['VOLUME_DELETE']:
- volume_delete(vol_id)
-
- if cap['ACCESS_GROUP_INITIATOR_DELETE']:
- access_group_remove_init(ag_id, iqn1)
-
- if cap['ACCESS_GROUP_DELETE']:
- access_group_delete(ag_id)
-
-
-def test_nfs_operations(cap, system_id):
- pass
-
-
-def test_plugin_info(cap, system_id):
- out = call([cmd, 'plugin-info', ])[1]
- out = call([cmd, '-t' + sep, 'plugin-info', ])[1]
-
-
-def test_plugin_list(cap, system_id):
- out = call([cmd, 'list', '--type', 'PLUGINS'])[1]
- out = call([cmd, '-t' + sep, 'list', '--type', 'PLUGINS'])[1]
-
-
-def test_error_paths(cap, system_id):
-
- # Generate bad argument exception
- call([cmd, 'list', '--type', 'SNAPSHOTS'], 2)
- call([cmd, 'list', '--type', 'SNAPSHOTS', '--fs', 'DOES_NOT_EXIST'], 2)
-
-
-def create_all(cap, system_id):
- test_plugin_info(cap, system_id)
- test_block_creation(cap, system_id)
- test_fs_creation(cap, system_id)
- test_nfs(cap, system_id)
-
-
-def search_test(cap, system_id):
- print "\nTesting query with search ID\n"
- sys_id_filter = "--sys='%s'" % system_id
- if test_fs_pool_id:
- pool_id = test_fs_pool_id
- else:
- pool_id = name_to_id(OP_POOL, test_pool_name)
- pool_id_filter = "--pool='%s'" % pool_id
-
- vol_id = create_volume(pool_id)
- vol_id_filter = "--vol='%s'" % vol_id
-
- disk_id_filter = "--disk='%s'" % test_disk_id
-
- ag_id = access_group_create(random_iqn(), system_id)
- ag_id_filter = "--ag='%s'" % ag_id
-
- fs_id = fs_create(pool_id)
- fs_id_filter = "--fs='%s'" % fs_id
-
- nfs_export_id = export_fs(fs_id)
- nfs_export_id_filter = "--nfs-export='%s'" % nfs_export_id
-
- all_filters = [sys_id_filter, pool_id_filter, vol_id_filter,
- disk_id_filter, ag_id_filter, fs_id_filter,
- nfs_export_id_filter]
-
- supported = {
- 'pools': [sys_id_filter, pool_id_filter],
- 'volumes': [sys_id_filter, pool_id_filter, vol_id_filter,
- ag_id_filter],
- 'disks': [sys_id_filter, disk_id_filter],
- 'access_groups': [sys_id_filter, ag_id_filter, vol_id_filter],
- 'fs': [sys_id_filter, pool_id_filter, fs_id_filter],
- 'exports': [fs_id_filter, nfs_export_id_filter],
- }
- for resouce_type in supported.keys():
- for cur_filter in all_filters:
- if cur_filter in supported[resouce_type]:
- call([cmd, 'list', '--type', resouce_type, cur_filter])
- else:
- call([cmd, 'list', '--type', resouce_type, cur_filter], 2)
-
- un_export_fs(nfs_export_id)
- delete_fs(fs_id)
- access_group_delete(ag_id)
- volume_delete(vol_id)
- return
-
-def volume_raid_info_test(cap, system_id):
- if cap['VOLUME_RAID_INFO'] and cap['VOLUME_CREATE']:
- test_pool_id = name_to_id(OP_POOL, test_pool_name)
-
- if test_pool_id is None:
- print 'Pool %s is not available!' % test_pool_name
- exit(10)
-
- vol_id = create_volume(test_pool_id)
- out = call([cmd, '-t' + sep, 'volume-raid-info', '--vol', vol_id])[1]
- r = parse(out)
- if len(r[0]) != 6:
- print "volume-raid-info got expected output: %s" % out
- exit(10)
- if r[0][0] != vol_id:
- print "volume-raid-info output volume ID is not requested " \
- "volume ID %s" % out
- exit(10)
- return
-
-def run_all_tests(cap, system_id):
- test_display(cap, system_id)
- test_plugin_list(cap, system_id)
-
- test_error_paths(cap, system_id)
- create_all(cap, system_id)
-
- test_mapping(cap, system_id)
-
- search_test(cap, system_id)
-
- volume_raid_info_test(cap, system_id)
-
-if __name__ == "__main__":
- parser = OptionParser()
- parser.add_option("-c", "--command", action="store", type="string",
- dest="cmd", help="specific command line to test")
- parser.add_option("-p", "--pool", action="store", dest="pool_name",
- default='lsm_test_aggr',
- help="pool name to use for testing")
-
- parser.add_option("-f", "--fspool", action="store", dest="fs_pool_id",
- default='',
- help="fs pool id to use for testing")
-
- parser.description = "lsmcli command line test tool"
-
- (options, args) = parser.parse_args()
-
- if options.cmd is None:
- print 'Please specify which lsmcli to test using -c or --command'
- sys.exit(1)
- else:
- cmd = options.cmd
- test_pool_name = options.pool_name
-
- if options.fs_pool_id:
- test_fs_pool_id = options.fs_pool_id
-
- #Theory of testing.
- # For each system that is available to us:
- # Query capabilities
- # Query all supported query operations (should have more to query)
- #
- # Create objects of every supported type
- # Query all supported query operations
- # (should have more to query),
- # run though different options making sure nothing explodes!
- #
- # Try calling un-supported operations and expect them to fail
- systems = get_systems()
-
- for system in systems:
- c = capabilities(system[ID])
- run_all_tests(c, system[ID])
diff --git a/test/plugin_test.py b/test/plugin_test.py
deleted file mode 100755
index 69a45b7..0000000
--- a/test/plugin_test.py
+++ /dev/null
@@ -1,1348 +0,0 @@
-#!/usr/bin/env python2
-
-# Copyright (C) 2013-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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import lsm
-import functools
-import time
-import random
-import string
-import traceback
-import unittest
-import argparse
-import collections
-import atexit
-import sys
-import re
-import os
-import tempfile
-from lsm import LsmError, ErrorNumber
-from lsm import Capabilities as Cap
-
-results = {}
-stats = {}
-
-
-MIN_POOL_SIZE = 4096
-MIN_OBJECT_SIZE = 512
-
-
-def mb_in_bytes(mib):
- return 1024 * 1024 * mib
-
-
-def record_result(method):
- def recorder(*args, **kwargs):
- try:
- result = method(*args, **kwargs)
- results[method.__name__] = dict(rc=True, msg=None)
- return result
- except Exception as e:
- results[method.__name__] = dict(rc=False,
- stack_trace=traceback.format_exc(),
- msg=str(e))
- return recorder
-
-
-def update_stats(method_name, duration, number_results):
- if method_name in stats:
- stats[method_name]["count"] += 1
- else:
- stats[method_name] = dict(count=1, total_time=0, number_items=0)
-
- stats[method_name]["total_time"] += duration
-
- if number_results > 0:
- stats[method_name]["number_items"] += number_results
-
-
-def rs(component, l=4):
- """
- Generate a random string
- """
- rp = ''.join(random.choice(string.ascii_uppercase) for x in range(l))
-
- if component is not None:
- return 'lsm_%s_%s' % (component, rp)
- return rp
-
-
-def r_fcpn():
- """
- Generate a random 16 character hex number
- """
- rnd_fcpn = '%016x' % random.randrange(2 ** 64)
- return ':'.join(rnd_fcpn[i:i + 2] for i in range(0, len(rnd_fcpn), 2))
-
-
-class Duration(object):
- def __init__(self):
- self.start = 0
- self.end = 0
-
- def __enter__(self):
- self.start = time.time()
- return self
-
- def __exit__(self, *ignore):
- self.end = time.time()
-
- def amount(self):
- return self.end - self.start
-
-
-def supported(cap, capability):
- for c in capability:
- if not cap.supported(c):
- return False
- return True
-
-
-class TestProxy(object):
-
- # Errors that we are forcing to occur
- not_logging = [lsm.ErrorNumber.NO_SUPPORT,
- lsm.ErrorNumber.NAME_CONFLICT,
- lsm.ErrorNumber.NO_STATE_CHANGE,
- lsm.ErrorNumber.IS_MASKED,
- lsm.ErrorNumber.EXISTS_INITIATOR]
-
- # Hash of all calls that can be async
- async_calls = {'volume_create': (unicode, lsm.Volume),
- 'volume_resize': (unicode, lsm.Volume),
- 'volume_replicate': (unicode, lsm.Volume),
- 'volume_replicate_range': (unicode,),
- 'volume_delete': (unicode,),
- 'volume_child_dependency_rm': (unicode,),
- 'fs_delete': (unicode,),
- 'fs_resize': (unicode, lsm.FileSystem),
- 'fs_create': (unicode, lsm.FileSystem),
- 'fs_clone': (unicode, lsm.FileSystem),
- 'fs_file_clone': (unicode,),
- 'fs_snapshot_create': (unicode, lsm.FsSnapshot),
- 'fs_snapshot_delete': (unicode,),
- 'fs_snapshot_restore': (unicode,),
- 'fs_child_dependency_rm': (unicode,)}
-
- ## The constructor.
- # @param self The object self
- # @param obj The object instance to wrap
- def __init__(self, obj=None):
- """
- Constructor which takes an object to wrap.
- """
- self.o = obj
-
- ## Called each time an attribute is requested of the object
- # @param self The object self
- # @param name Name of the attribute being accessed
- # @return The result of the method
- def __getattr__(self, name):
- """
- Called each time an attribute is requested of the object
- """
- if hasattr(self.o, name):
- return functools.partial(self.present, name)
- else:
- raise AttributeError("No such method %s" % name)
-
- @staticmethod
- def log_result(method, v):
- if method not in results:
- results[method] = []
-
- results[method].append(v)
-
- ## Method which is called to invoke the actual method of interest.
- #
- # The intentions of this method is this:
- # - Invoke the method just like it normally would without this
- # so signature in & out is identical
- # - Collect results of the method call
- # - Collect stats on the execution time of call
- #
- # @param self The object self
- # @param _proxy_method_name Method to invoke
- # @param args Arguments
- # @param kwargs Keyword arguments
- # @return The result of the method invocation
- def present(self, _proxy_method_name, *args, **kwargs):
- """
- Method which is called to invoke the actual method of interest.
- """
- rc = None
- job_possible = _proxy_method_name in TestProxy.async_calls
-
- # Timer block
- with Duration() as method_time:
- try:
- rc = getattr(self.o, _proxy_method_name)(*args, **kwargs)
- TestProxy.log_result(_proxy_method_name,
- dict(rc=True, stack_trace=None, msg=None))
- except lsm.LsmError as le:
- # We are forcing some types of error, for these we won't log
- # but will allow the test case asserts to check to make sure
- # we actually got them.
- if le.code not in self.not_logging:
- TestProxy.log_result(
- _proxy_method_name,
- dict(rc=False,
- stack_trace=traceback.format_exc(),
- msg=str(le)))
- raise
-
- # If the job can do async, we will block looping on it.
- if job_possible and rc is not None:
- # Note: Some return a single unicode or None,
- # others return a tuple (job, object)
- if type(rc) != tuple and type(rc) != list:
- rc = (rc, None)
- rc = self.wait_for_it(_proxy_method_name, *rc)
-
- # Fix up return value to match what it would normally be
- if job_possible:
- if 2 == len(TestProxy.async_calls[_proxy_method_name]):
- rc = (None, rc)
-
- # We don't care about time per operation when there is only one
- # possible.
- if not job_possible and isinstance(rc, collections.Sequence) \
- and len(rc) > 2:
- num_results = len(rc)
- else:
- num_results = 0
-
- update_stats(_proxy_method_name, method_time.amount(), num_results)
- return rc
-
- def wait_for_it(self, msg, job, item):
- if not job:
- return item
- else:
- while True:
- (s, percent, i) = self.job_status(job)
-
- if s == lsm.JobStatus.INPROGRESS:
- time.sleep(0.25)
- elif s == lsm.JobStatus.COMPLETE:
- self.job_free(job)
- return i
- else:
- raise Exception(msg + " job error code= " + str(s))
-
-
-def check_type(value, *expected):
- assert type(value) in expected, "type expected (%s), type actual (%s)" % \
- (str(type(value)), str(expected))
-
-
-class TestPlugin(unittest.TestCase):
- """
- Anything that starts with test_ will be run as a separate unit test with
- the setUp and tearDown methods called before and after respectively
- """
-
- URI = 'sim://'
- PASSWORD = None
-
- def _object_size(self, pool):
- return mb_in_bytes(MIN_OBJECT_SIZE)
-
- def setUp(self):
- for skip_test_case in TestPlugin.SKIP_TEST_CASES:
- if self.id().endswith(skip_test_case):
- self.skipTest("Tested has been skiped as requested")
-
- self.c = TestProxy(lsm.Client(TestPlugin.URI, TestPlugin.PASSWORD))
-
- self.systems = self.c.systems()
- self.pools = self.c.pools()
-
- self.pool_by_sys_id = {}
-
- for s in self.systems:
- self.pool_by_sys_id[s.id] = [p for p in self.pools if
- p.system_id == s.id]
-
- # TODO Store what exists, so that we don't remove it
-
- def _get_pool_by_usage(self, system_id, element_type,
- unsupported_features=0):
- largest_free = 0
- rc = None
-
- for p in self.pool_by_sys_id[system_id]:
- # If the pool matches our criteria and min size we will consider
- # it, but we will select the one with the most free space for
- # testing and one that support volume expansion
- if p.element_type & element_type and \
- p.free_space > mb_in_bytes(MIN_POOL_SIZE) and \
- (not p.unsupported_actions & unsupported_features):
- if p.free_space > largest_free:
- largest_free = p.free_space
- rc = p
- return rc
-
- def tearDown(self):
- # TODO Walk the array looking for stuff we have created and remove it
- # What should we do if an array supports a create operation, but not
- # the corresponding remove?
- self.c.close()
-
- def test_plugin_info(self):
- (desc, version) = self.c.plugin_info()
- self.assertTrue(desc is not None and len(desc) > 0)
- self.assertTrue(version is not None and len(version) > 0)
-
- def test_timeout(self):
- tmo = 40000
- self.c.time_out_set(tmo)
- self.assertEquals(self.c.time_out_get(), tmo)
-
- def test_systems_list(self):
- arrays = self.c.systems()
- self.assertTrue(len(arrays) > 0, "We need at least one array for "
- "testing!")
-
- def test_pools_list(self):
- pools_list = self.c.pools()
- self.assertTrue(len(pools_list) > 0, "We need at least 1 pool to test")
-
- @staticmethod
- def _vpd_correct(vpd):
- if vpd and re.match('^[a-f0-9]{32}$', vpd):
- return True
- return False
-
- def _find_or_create_volumes(self):
- """
- Find existing volumes, if not found, try to create one.
- Return (volumes, flag_created)
- If 'flag_created' is True, then returned volumes is newly created.
- """
- volumes = self.c.volumes()
- flag_created = False
- if len(self.c.volumes()) == 0:
- for s in self.systems:
- cap = self.c.capabilities(s)
- if supported(cap, [Cap.VOLUME_CREATE, Cap.VOLUME_DELETE]):
- self._volume_create(s.id)
- flag_created = True
- break
- volumes = self.c.volumes()
-
- return volumes, flag_created
-
- def test_volume_list(self):
- (volumes, flag_created) = self._find_or_create_volumes()
- self.assertTrue(len(volumes) > 0, "We need at least 1 volume to test")
-
- if flag_created:
- self._volume_delete(volumes[0])
-
- def test_volume_vpd83(self):
- (volumes, flag_created) = self._find_or_create_volumes()
- self.assertTrue(len(volumes) > 0, "We need at least 1 volume to test")
- for v in volumes:
- self.assertTrue(TestPlugin._vpd_correct(v.vpd83),
- "VPD is not as expected '%s' for volume id: '%s'" %
- (v.vpd83, v.id))
- if flag_created:
- self._volume_delete(volumes[0])
-
- def test_disks_list(self):
- for s in self.systems:
- cap = self.c.capabilities(s)
- if supported(cap, [Cap.DISKS]):
- disks = self.c.disks()
- self.assertTrue(len(disks) > 0,
- "We need at least 1 disk to test")
-
- def _volume_create(self, system_id,
- element_type=lsm.Pool.ELEMENT_TYPE_VOLUME,
- unsupported_features=0):
- if system_id in self.pool_by_sys_id:
- p = self._get_pool_by_usage(system_id, element_type,
- unsupported_features)
-
- self.assertTrue(p is not None, "Unable to find a suitable pool")
-
- if p:
- vol_size = self._object_size(p)
-
- vol = self.c.volume_create(p, rs('v'), vol_size,
- lsm.Volume.PROVISION_DEFAULT)[1]
-
- self.assertTrue(self._volume_exists(vol.id), p.id)
- self.assertTrue(vol.pool_id == p.id)
- return vol, p
-
- def _fs_create(self, system_id):
- if system_id in self.pool_by_sys_id:
- fs = None
- pool = self._get_pool_by_usage(system_id,
- lsm.Pool.ELEMENT_TYPE_FS)
-
- self.assertTrue(pool is not None, "Unable to find a suitable pool "
- "for fs creation")
-
- if pool is not None:
- fs_size = self._object_size(pool)
- fs = self.c.fs_create(pool, rs('fs'), fs_size)[1]
- self.assertTrue(self._fs_exists(fs.id))
-
- self.assertTrue(fs is not None)
- self.assertTrue(pool is not None)
-
- return fs, pool
-
- def _volume_delete(self, volume):
- self.c.volume_delete(volume)
- self.assertFalse(self._volume_exists(volume.id))
-
- def _fs_delete(self, fs):
- self.c.fs_delete(fs)
- self.assertFalse(self._fs_exists(fs.id))
-
- def _fs_snapshot_delete(self, fs, ss):
- self.c.fs_snapshot_delete(fs, ss)
- self.assertFalse(self._fs_snapshot_exists(fs, ss.id))
-
- def _volume_exists(self, volume_id, pool_id=None):
- volumes = self.c.volumes()
-
- for v in volumes:
- if v.id == volume_id:
- if pool_id is not None:
- if v.pool_id == pool_id:
- return True
- else:
- return False
-
- return True
-
- return False
-
- def _fs_exists(self, fs_id):
- fs = self.c.fs()
-
- for f in fs:
- if f.id == fs_id:
- return True
-
- return False
-
- def _fs_snapshot_exists(self, fs, ss_id):
- snapshots = self.c.fs_snapshots(fs)
-
- for s in snapshots:
- if s.id == ss_id:
- return True
-
- return False
-
- def test_volume_create_delete(self):
- if self.pool_by_sys_id:
- for s in self.systems:
- vol = None
- cap = self.c.capabilities(s)
- if supported(cap, [Cap.VOLUME_CREATE]):
- vol = self._volume_create(s.id)[0]
- self.assertTrue(vol is not None)
-
- if vol is not None and \
- supported(cap, [Cap.VOLUME_DELETE]):
- self._volume_delete(vol)
-
- def test_volume_resize(self):
- if self.pool_by_sys_id:
- for s in self.systems:
- cap = self.c.capabilities(s)
-
- # We need to make sure that the pool supports volume grow.
- unsupported = lsm.Pool.UNSUPPORTED_VOLUME_GROW
-
- if supported(cap, [Cap.VOLUME_CREATE,
- Cap.VOLUME_DELETE,
- Cap.VOLUME_RESIZE]):
- vol = self._volume_create(
- s.id,
- unsupported_features=unsupported)[0]
- vol_resize = self.c.volume_resize(
- vol, vol.size_bytes + mb_in_bytes(16))[1]
- self.assertTrue(vol.size_bytes < vol_resize.size_bytes)
- self.assertTrue(vol.id == vol_resize.id,
- "Expecting re-sized volume to refer to "
- "same volume. Expected %s, got %s" %
- (vol.id, vol_resize.id))
- if vol.id == vol_resize.id:
- self._volume_delete(vol_resize)
- else:
- # Delete the original
- self._volume_delete(vol)
-
- def _replicate_test(self, capability, replication_type):
- if self.pool_by_sys_id:
- for s in self.systems:
- cap = self.c.capabilities(s)
-
- if supported(cap, [Cap.VOLUME_CREATE,
- Cap.VOLUME_DELETE]):
- vol, pool = self._volume_create(s.id)
-
- # For the moment lets allow the array to pick the pool
- # to supply the backing store for the replicate
- if supported(cap, [capability]):
- volume_clone = self.c.volume_replicate(
- None, replication_type, vol,
- rs('v_c_'))[1]
-
- self.assertTrue(volume_clone is not None)
- self.assertTrue(self._volume_exists(volume_clone.id))
-
- if volume_clone is not None:
- # Lets test for creating a clone with an
- # existing name
- error_num = None
- try:
- volume_clone_dupe_name = \
- self.c.volume_replicate(
- None, replication_type, vol,
- volume_clone.name)[1]
- except LsmError as le:
- error_num = le.code
-
- self.assertTrue(error_num ==
- ErrorNumber.NAME_CONFLICT)
-
- self._volume_delete(volume_clone)
-
- self._volume_delete(vol)
-
- def test_volume_replication(self):
- self._replicate_test(Cap.VOLUME_REPLICATE_CLONE,
- lsm.Volume.REPLICATE_CLONE)
-
- self._replicate_test(Cap.VOLUME_REPLICATE_COPY,
- lsm.Volume.REPLICATE_COPY)
-
- self._replicate_test(Cap.VOLUME_REPLICATE_MIRROR_ASYNC,
- lsm.Volume.REPLICATE_MIRROR_ASYNC)
-
- self._replicate_test(Cap.VOLUME_REPLICATE_MIRROR_SYNC,
- lsm.Volume.REPLICATE_MIRROR_SYNC)
-
- def test_volume_replicate_range_block_size(self):
- for s in self.systems:
- cap = self.c.capabilities(s)
-
- if supported(cap, [Cap.VOLUME_COPY_RANGE_BLOCK_SIZE]):
- size = self.c.volume_replicate_range_block_size(s)
- self.assertTrue(size > 0)
- else:
- self.assertRaises(lsm.LsmError,
- self.c.volume_replicate_range_block_size, s)
-
- def test_replication_range(self):
- if self.pool_by_sys_id:
- for s in self.systems:
- cap = self.c.capabilities(s)
-
- if supported(cap,
- [Cap.VOLUME_COPY_RANGE_BLOCK_SIZE,
- Cap.VOLUME_CREATE,
- Cap.VOLUME_DELETE,
- Cap.VOLUME_COPY_RANGE]):
-
- size = self.c.volume_replicate_range_block_size(s)
-
- vol, pool = self._volume_create(s.id)
-
- br = lsm.BlockRange(0, size, size)
-
- if supported(
- cap, [Cap.VOLUME_COPY_RANGE_CLONE]):
- self.c.volume_replicate_range(
- lsm.Volume.REPLICATE_CLONE, vol, vol, [br])
- else:
- self.assertRaises(
- lsm.LsmError,
- self.c.volume_replicate_range,
- lsm.Volume.REPLICATE_CLONE, vol, vol, [br])
-
- br = lsm.BlockRange(size * 2, size, size)
-
- if supported(
- cap, [Cap.VOLUME_COPY_RANGE_COPY]):
- self.c.volume_replicate_range(
- lsm.Volume.REPLICATE_COPY, vol, vol, [br])
- else:
- self.assertRaises(
- lsm.LsmError,
- self.c.volume_replicate_range,
- lsm.Volume.REPLICATE_COPY, vol, vol, [br])
-
- self._volume_delete(vol)
-
- def test_fs_creation_deletion(self):
- for s in self.systems:
- cap = self.c.capabilities(s)
-
- if supported(cap, [Cap.FS_CREATE]):
- fs, pool = self._fs_create(s.id)
-
- if fs is not None:
- if supported(cap, [Cap.FS_DELETE]):
- self._fs_delete(fs)
-
- def test_fs_resize(self):
- for s in self.systems:
- cap = self.c.capabilities(s)
-
- if supported(cap, [Cap.FS_CREATE]):
- fs, pool = self._fs_create(s.id)
-
- if fs is not None:
- if supported(cap, [Cap.FS_RESIZE]):
- fs_size = fs.total_space + mb_in_bytes(16)
- fs_resized = self.c.fs_resize(fs, fs_size)[1]
- self.assertTrue(fs_resized.total_space)
-
- if supported(cap, [Cap.FS_DELETE]):
- self._fs_delete(fs)
-
- def test_fs_clone(self):
- for s in self.systems:
- cap = self.c.capabilities(s)
-
- if supported(cap, [Cap.FS_CREATE,
- Cap.FS_CLONE]):
- fs, pool = self._fs_create(s.id)
-
- if fs is not None:
- fs_clone = self.c.fs_clone(fs, rs('fs_c'))[1]
-
- if supported(cap, [Cap.FS_DELETE]):
- self._fs_delete(fs_clone)
- self._fs_delete(fs)
-
- def test_fs_snapshot(self):
- for s in self.systems:
- cap = self.c.capabilities(s)
-
- if supported(cap, [Cap.FS_CREATE,
- Cap.FS_SNAPSHOT_CREATE]):
-
- fs, pool = self._fs_create(s.id)
-
- if fs is not None:
- ss = self.c.fs_snapshot_create(fs, rs('ss'))[1]
- self.assertTrue(self._fs_snapshot_exists(fs, ss.id))
-
- if supported(cap, [Cap.FS_SNAPSHOT_RESTORE]):
- self.c.fs_snapshot_restore(fs, ss, None, None, True)
-
- # Delete snapshot
- if supported(cap, [Cap.FS_SNAPSHOT_DELETE]):
- self._fs_snapshot_delete(fs, ss)
-
- def test_target_ports(self):
- for s in self.systems:
- cap = self.c.capabilities(s)
-
- if supported(cap, [Cap.TARGET_PORTS]):
- ports = self.c.target_ports()
-
- for p in ports:
- self.assertTrue(p.id is not None)
- self.assertTrue(p.port_type is not None)
- self.assertTrue(p.service_address is not None)
- self.assertTrue(p.network_address is not None)
- self.assertTrue(p.physical_address is not None)
- self.assertTrue(p.physical_name is not None)
- self.assertTrue(p.system_id is not None)
-
- def _masking_state(self, cap, ag, vol, masked):
- if supported(cap,
- [Cap.
- VOLUMES_ACCESSIBLE_BY_ACCESS_GROUP]):
- vol_masked = \
- self.c.volumes_accessible_by_access_group(ag)
-
- match = [x for x in vol_masked if x.id == vol.id]
-
- if masked:
- self.assertTrue(len(match) == 1)
- else:
- self.assertTrue(len(match) == 0)
-
- if supported(cap,
- [Cap.
- ACCESS_GROUPS_GRANTED_TO_VOLUME]):
- ag_masked = \
- self.c.access_groups_granted_to_volume(vol)
-
- match = [x for x in ag_masked if x.id == ag.id]
-
- if masked:
- self.assertTrue(len(match) == 1)
- else:
- self.assertTrue(len(match) == 0)
-
- def test_mask_unmask(self):
- for s in self.systems:
- ag_created = None
- cap = self.c.capabilities(s)
-
- if supported(cap, [Cap.ACCESS_GROUPS,
- Cap.VOLUME_MASK,
- Cap.VOLUME_UNMASK,
- Cap.VOLUME_CREATE,
- Cap.VOLUME_DELETE]):
-
- if supported(cap, [Cap.ACCESS_GROUP_CREATE_ISCSI_IQN]):
- ag_name = rs("ag")
- ag_iqn = 'iqn.1994-05.com.domain:01.' + rs(None, 6)
-
- ag_created = self.c.access_group_create(
- ag_name, ag_iqn, lsm.AccessGroup.INIT_TYPE_ISCSI_IQN,
- s)
-
- # Make sure we have an access group to test with, many
- # smi-s providers don't provide functionality to create them!
- ag_list = self.c.access_groups('system_id', s.id)
- if len(ag_list):
- vol = self._volume_create(s.id)[0]
- self.assertTrue(vol is not None)
-
- chose_ag = ag_created
-
- if chose_ag is None:
- for ag in ag_list:
- if len(ag.init_ids) >= 1:
- chose_ag = ag
- break
-
- if chose_ag is None:
- raise Exception("No access group with 1+ member "
- "found, cannot do volume mask test")
-
- if vol is not None and chose_ag is not None:
- self.c.volume_mask(chose_ag, vol)
- self._masking_state(cap, chose_ag, vol, True)
-
- # Test duplicate call for NO_STATE_CHANGE error
- flag_dup_error_found = False
- try:
- self.c.volume_mask(chose_ag, vol)
- except LsmError as lsm_error:
- self.assertTrue(
- lsm_error.code == ErrorNumber.NO_STATE_CHANGE)
- flag_dup_error_found = True
- self.assertTrue(flag_dup_error_found)
-
- self.c.volume_unmask(chose_ag, vol)
- self._masking_state(cap, chose_ag, vol, False)
-
- # Test duplicate call for NO_STATE_CHANGE error
- flag_dup_error_found = False
- try:
- self.c.volume_unmask(chose_ag, vol)
- except LsmError as lsm_error:
- self.assertTrue(
- lsm_error.code == ErrorNumber.NO_STATE_CHANGE)
- flag_dup_error_found = True
- self.assertTrue(flag_dup_error_found)
-
- if vol:
- self._volume_delete(vol)
-
- if ag_created:
- self.c.access_group_delete(ag_created)
- ag_created = None
-
- def _create_access_group(self, cap, name, s, init_type):
- ag_created = None
-
- if init_type == lsm.AccessGroup.INIT_TYPE_ISCSI_IQN:
- ag_created = self.c.access_group_create(
- name,
- 'iqn.1994-05.com.domain:01.' + rs(None, 6),
- lsm.AccessGroup.INIT_TYPE_ISCSI_IQN, s)
-
- elif init_type == lsm.AccessGroup.INIT_TYPE_WWPN:
- ag_created = self.c.access_group_create(
- name,
- r_fcpn(),
- lsm.AccessGroup.INIT_TYPE_WWPN, s)
-
- self.assertTrue(ag_created is not None)
-
- if ag_created is not None:
- ag_list = self.c.access_groups()
- match = [x for x in ag_list if x.id == ag_created.id]
- self.assertTrue(len(match) == 1, "Newly created access group %s "
- "not in the access group listing"
- % (ag_created.name))
-
- return ag_created
-
- def _delete_access_group(self, ag):
- self.c.access_group_delete(ag)
- ag_list = self.c.access_groups()
- match = [x for x in ag_list if x.id == ag.id]
- self.assertTrue(len(match) == 0, "Expected access group that was "
- "deleted to not show up in the "
- "access group list!")
-
- def _test_ag_create_dup(self, lsm_ag, lsm_system):
- """
- Test NAME_CONFLICT and EXISTS_INITIATOR of access_group_create().
- """
- flag_got_expected_error = False
- new_init_id = None
- if lsm_ag.init_type == lsm.AccessGroup.INIT_TYPE_ISCSI_IQN:
- new_init_id = 'iqn.1994-05.com.domain:01.' + rs(None, 6)
- else:
- new_init_id = r_fcpn()
- try:
- self.c.access_group_create(
- lsm_ag.name, new_init_id, lsm_ag.init_type, lsm_system)
- except LsmError as lsm_error:
- self.assertTrue(lsm_error.code == ErrorNumber.NAME_CONFLICT)
- flag_got_expected_error = True
-
- self.assertTrue(flag_got_expected_error)
-
- flag_got_expected_error = False
- try:
- self.c.access_group_create(
- rs('ag'), lsm_ag.init_ids[0], lsm_ag.init_type, lsm_system)
- except LsmError as lsm_error:
- self.assertTrue(lsm_error.code == ErrorNumber.EXISTS_INITIATOR)
- flag_got_expected_error = True
-
- self.assertTrue(flag_got_expected_error)
-
- def _test_ag_create_delete(self, cap, s):
- ag = None
- if supported(cap, [Cap.ACCESS_GROUPS,
- Cap.ACCESS_GROUP_CREATE_ISCSI_IQN]):
- ag = self._create_access_group(
- cap, rs('ag'), s, lsm.AccessGroup.INIT_TYPE_ISCSI_IQN)
- if ag is not None and \
- supported(cap, [Cap.ACCESS_GROUP_DELETE]):
- self._test_ag_create_dup(ag, s)
- self._delete_access_group(ag)
-
- if supported(cap, [Cap.ACCESS_GROUPS,
- Cap.ACCESS_GROUP_CREATE_WWPN]):
- ag = self._create_access_group(
- cap, rs('ag'), s, lsm.AccessGroup.INIT_TYPE_WWPN)
- if ag is not None and \
- supported(cap, [Cap.ACCESS_GROUP_DELETE]):
- self._test_ag_create_dup(ag, s)
- self._delete_access_group(ag)
-
- def test_iscsi_chap(self):
- ag = None
-
- for s in self.systems:
- cap = self.c.capabilities(s)
-
- if supported(cap, [Cap.ACCESS_GROUPS,
- Cap.ACCESS_GROUP_CREATE_ISCSI_IQN,
- Cap.VOLUME_ISCSI_CHAP_AUTHENTICATION]):
- ag = self._create_access_group(
- cap, rs('ag'), s, lsm.AccessGroup.INIT_TYPE_ISCSI_IQN)
-
- self.c.iscsi_chap_auth(ag.init_ids[0], 'foo', rs(None, 12),
- None, None)
-
- if ag is not None and \
- supported(cap, [Cap.ACCESS_GROUP_DELETE]):
- self._test_ag_create_dup(ag, s)
- self._delete_access_group(ag)
-
- def test_access_group_create_delete(self):
- for s in self.systems:
- cap = self.c.capabilities(s)
- self._test_ag_create_delete(cap, s)
-
- def test_access_group_list(self):
- for s in self.systems:
- cap = self.c.capabilities(s)
-
- if supported(cap, [Cap.ACCESS_GROUPS]):
- ag_list = self.c.access_groups('system_id', s.id)
- if len(ag_list) == 0:
- self._test_ag_create_delete(cap, s)
- else:
- self.assertTrue(len(ag_list) > 0,
- "Need at least 1 access group for testing "
- "and no support exists for creation of "
- "access groups for this system")
-
- def _ag_init_add(self, ag):
- t = None
- t_id = ''
-
- if ag.init_type == lsm.AccessGroup.INIT_TYPE_ISCSI_IQN:
- t_id = 'iqn.1994-05.com.domain:01.89bd02'
- t = lsm.AccessGroup.INIT_TYPE_ISCSI_IQN
- else:
- # We will try FC PN
- t_id = r_fcpn()
- t = lsm.AccessGroup.INIT_TYPE_WWPN
-
- self.c.access_group_initiator_add(ag, t_id, t)
-
- ag_after = self.c.access_groups('id', ag.id)[0]
- match = [x for x in ag_after.init_ids if x == t_id]
- self.assertTrue(len(match) == 1)
- return t_id
-
- def _ag_init_delete(self, ag, init_id, init_type):
- self.c.access_group_initiator_delete(ag, init_id, init_type)
- ag_after = self.c.access_groups('id', ag.id)[0]
- match = [x for x in ag_after.init_ids if x == init_id]
- self.assertTrue(len(match) == 0)
-
- def test_access_group_initiator_add_delete(self):
- usable_ag_types = [lsm.AccessGroup.INIT_TYPE_WWPN,
- lsm.AccessGroup.INIT_TYPE_ISCSI_IQN]
-
- for s in self.systems:
- ag_to_delete = None
-
- cap = self.c.capabilities(s)
- if supported(cap, [Cap.ACCESS_GROUPS]):
- ag_list = self.c.access_groups('system_id', s.id)
-
- if supported(cap, [Cap.ACCESS_GROUP_CREATE_WWPN])\
- or supported(cap, [Cap.ACCESS_GROUP_CREATE_ISCSI_IQN]):
-
- if supported(
- cap, [Cap.ACCESS_GROUP_CREATE_ISCSI_IQN,
- Cap.ACCESS_GROUP_DELETE]):
- ag_to_delete = self._create_access_group(
- cap, rs('ag'), s,
- lsm.AccessGroup.INIT_TYPE_ISCSI_IQN)
- ag_list = self.c.access_groups('system_id', s.id)
-
- if supported(cap,
- [Cap.
- ACCESS_GROUP_INITIATOR_ADD_ISCSI_IQN]):
-
- init_id = self._ag_init_add(ag_to_delete)
-
- if supported(
- cap, [Cap.ACCESS_GROUP_INITIATOR_DELETE]):
- self._ag_init_delete(
- ag_to_delete, init_id,
- lsm.AccessGroup.INIT_TYPE_ISCSI_IQN)
-
- if supported(
- cap, [Cap.ACCESS_GROUP_CREATE_WWPN,
- Cap.ACCESS_GROUP_DELETE]):
- ag_to_delete = self._create_access_group(
- cap, rs('ag'), s, lsm.AccessGroup.INIT_TYPE_WWPN)
- ag_list = self.c.access_groups('system_id', s.id)
-
- if ag_to_delete is not None:
- self._delete_access_group(ag_to_delete)
- else:
- if len(ag_list):
- # Try and find an initiator group that has a usable
- # access group type instead of unknown or other...
- ag = ag_list[0]
- for a_tmp in ag_list:
- if a_tmp.init_type in usable_ag_types:
- ag = a_tmp
- break
-
- if supported(cap, [Cap.
- ACCESS_GROUP_INITIATOR_ADD_WWPN]):
- init_id = self._ag_init_add(ag)
- if supported(
- cap, [Cap.ACCESS_GROUP_INITIATOR_DELETE]):
- self._ag_init_delete(
- ag, init_id,
- lsm.AccessGroup.INIT_TYPE_WWPN)
-
- if supported(
- cap,
- [Cap.ACCESS_GROUP_INITIATOR_ADD_ISCSI_IQN]):
- init_id = self._ag_init_add(ag)
- if supported(cap,
- [Cap.ACCESS_GROUP_INITIATOR_DELETE]):
- self._ag_init_delete(
- ag, init_id,
- lsm.AccessGroup.INIT_TYPE_ISCSI_IQN)
-
- def test_duplicate_volume_name(self):
- if self.pool_by_sys_id:
- for s in self.systems:
- vol = None
- cap = self.c.capabilities(s)
- if supported(cap, [Cap.VOLUME_CREATE]):
- vol, pool = self._volume_create(s.id)
- self.assertTrue(vol is not None)
-
- # Try to create another with same name
- try:
- vol_dupe = self.c.volume_create(
- pool, vol.name, vol.size_bytes,
- lsm.Volume.PROVISION_DEFAULT)[1]
- except LsmError as le:
- self.assertTrue(le.code == ErrorNumber.NAME_CONFLICT)
-
- if vol is not None and \
- supported(cap, [Cap.VOLUME_DELETE]):
- self._volume_delete(vol)
-
- def test_duplicate_access_group_name(self):
- for s in self.systems:
- ag_to_delete = None
-
- ag_type = None
- ag_name = rs('ag_dupe')
-
- cap = self.c.capabilities(s)
- if supported(cap, [Cap.ACCESS_GROUPS,
- Cap.ACCESS_GROUP_DELETE]):
- ag_list = self.c.access_groups('system_id', s.id)
-
- if supported(
- cap, [Cap.ACCESS_GROUP_CREATE_ISCSI_IQN]):
- ag_type = lsm.AccessGroup.INIT_TYPE_ISCSI_IQN
-
- elif supported(cap,
- [Cap.ACCESS_GROUP_CREATE_WWPN]):
- ag_type = lsm.AccessGroup.INIT_TYPE_WWPN
-
- else:
- return
-
- ag_created = self._create_access_group(
- cap, ag_name, s, ag_type)
-
- if ag_created is not None:
- # Try to create a duplicate
- got_exception = False
- try:
- ag_dupe = self._create_access_group(
- cap, ag_name, s, ag_type)
- except LsmError as le:
- got_exception = True
- self.assertTrue(le.code == ErrorNumber.NAME_CONFLICT)
-
- self.assertTrue(got_exception)
-
- self._delete_access_group(ag_created)
-
- def test_ag_vol_delete_with_vol_masked(self):
- for s in self.systems:
- cap = self.c.capabilities(s)
- if supported(cap, [Cap.ACCESS_GROUPS,
- Cap.ACCESS_GROUP_CREATE_ISCSI_IQN,
- Cap.ACCESS_GROUP_DELETE,
- Cap.VOLUME_UNMASK,
- Cap.VOLUME_CREATE,
- Cap.VOLUME_DELETE,
- Cap.VOLUME_MASK,
- Cap.VOLUME_UNMASK]):
-
- ag_name = rs("ag")
- ag_iqn = 'iqn.1994-05.com.domain:01.' + rs(None, 6)
-
- ag = self.c.access_group_create(
- ag_name, ag_iqn, lsm.AccessGroup.INIT_TYPE_ISCSI_IQN, s)
-
- pool = self._get_pool_by_usage(s.id,
- lsm.Pool.ELEMENT_TYPE_VOLUME)
- if ag and pool:
- vol_size = self._object_size(pool)
-
- vol = self.c.volume_create(
- pool, rs('v'), vol_size,
- lsm.Volume.PROVISION_DEFAULT)[1]
-
- if vol:
- got_exception = False
- self.c.volume_mask(ag, vol)
-
- # Try to delete the access group
-
- try:
- self.c.access_group_delete(ag)
- except LsmError as le:
- if le.code == lsm.ErrorNumber.IS_MASKED:
- got_exception = True
- self.assertTrue(le.code ==
- lsm.ErrorNumber.IS_MASKED)
-
- self.assertTrue(got_exception)
-
- # Try to delete the volume
- got_exception = False
- try:
- self.c.volume_delete(vol)
- except LsmError as le:
- if le.code == lsm.ErrorNumber.IS_MASKED:
- got_exception = True
- self.assertTrue(le.code ==
- lsm.ErrorNumber.IS_MASKED)
-
- self.assertTrue(got_exception)
-
- # Clean up
- self.c.volume_unmask(ag, vol)
- self.c.volume_delete(vol)
-
- self.c.access_group_delete(ag)
-
- def test_volume_vpd83_verify(self):
-
- failing = [None,
- "012345678901234567890123456789AB",
- "012345678901234567890123456789ax",
- "012345678901234567890123456789ag",
- "1234567890123456789012345abcdef",
- "01234567890123456789012345abcdefa"]
-
- for f in failing:
- self.assertFalse(lsm.Volume.vpd83_verify(f))
-
- self.assertTrue(
- lsm.Volume.vpd83_verify("01234567890123456789012345abcdef"))
-
- def test_available_plugins(self):
- plugins = self.c.available_plugins(':')
- self.assertTrue(plugins is not None)
- self.assertTrue(len(plugins) > 0)
- self.assertTrue(':' in plugins[0])
-
- def test_volume_enable_disable(self):
- for s in self.systems:
- cap = self.c.capabilities(s)
-
- if supported(cap, [Cap.VOLUME_CREATE, Cap.VOLUME_DELETE,
- Cap.VOLUME_ENABLE, Cap.VOLUME_DISABLE]):
- vol, pool = self._volume_create(s.id)
-
- self.c.volume_disable(vol)
- self.c.volume_enable(vol)
-
- self._volume_delete(vol)
-
- def test_daemon_not_running(self):
- current = None
- got_exception = False
- # Force a ErrorNumber.DAEMON_NOT_RUNNING
- if 'LSM_UDS_PATH' in os.environ:
- current = os.environ['LSM_UDS_PATH']
-
- tmp_dir = tempfile.mkdtemp()
- os.environ['LSM_UDS_PATH'] = tmp_dir
-
- try:
- tmp_c = lsm.Client(TestPlugin.URI, TestPlugin.PASSWORD)
- except LsmError as expected_error:
- got_exception = True
- self.assertTrue(expected_error.code ==
- ErrorNumber.DAEMON_NOT_RUNNING,
- 'Actual error %d' % (expected_error.code))
-
- self.assertTrue(got_exception)
-
- os.rmdir(tmp_dir)
-
- if current:
- os.environ['LSM_UDS_PATH'] = current
- else:
- del os.environ['LSM_UDS_PATH']
-
- def test_non_existent_plugin(self):
- got_exception = False
- try:
- uri = "%s://***@host" % rs(None, 6)
-
- tmp_c = lsm.Client(uri, TestPlugin.PASSWORD)
- except LsmError as expected_error:
- got_exception = True
- self.assertTrue(expected_error.code ==
- ErrorNumber.PLUGIN_NOT_EXIST,
- 'Actual error %d' % (expected_error.code))
-
- self.assertTrue(got_exception)
-
- def test_volume_depends(self):
- for s in self.systems:
- cap = self.c.capabilities(s)
-
- if supported(cap, [Cap.VOLUME_CREATE, Cap.VOLUME_DELETE,
- Cap.VOLUME_CHILD_DEPENDENCY,
- Cap.VOLUME_CHILD_DEPENDENCY_RM]) and \
- (supported(cap, [Cap.VOLUME_REPLICATE_COPY]) or
- supported(cap, [Cap.VOLUME_REPLICATE_CLONE])):
- vol, pol = self._volume_create(s.id)
-
- if supported(cap, [Cap.VOLUME_REPLICATE_CLONE]):
- vol_child = self.c.volume_replicate(
- None,
- lsm.Volume.REPLICATE_CLONE,
- vol,
- rs('v_tc_'))[1]
- else:
- vol_child = self.c.volume_replicate(
- None,
- lsm.Volume.REPLICATE_COPY,
- vol,
- rs('v_fc_'))[1]
-
- self.assertTrue(vol_child is not None)
-
- if self.c.volume_child_dependency(vol):
- self.c.volume_child_dependency_rm(vol)
- else:
- self.assertTrue(self.c.volume_child_dependency_rm(vol)
- is None)
-
- self._volume_delete(vol)
-
- if vol_child:
- self._volume_delete(vol_child)
-
- def test_fs_depends(self):
- for s in self.systems:
- cap = self.c.capabilities(s)
-
- if supported(cap, [Cap.FS_CREATE, Cap.FS_DELETE,
- Cap.FS_CHILD_DEPENDENCY,
- Cap.FS_CHILD_DEPENDENCY_RM,
- Cap.FS_CLONE]):
- fs, pol = self._fs_create(s.id)
- fs_child = self.c.fs_clone(fs, rs('fs_c_'))[1]
- self.assertTrue(fs_child is not None)
-
- if self.c.fs_child_dependency(fs, None):
- self.c.fs_child_dependency_rm(fs, None)
- else:
- self.assertTrue(self.c.fs_child_dependency_rm(fs, None)
- is None)
-
- self._fs_delete(fs)
- if fs_child:
- self._fs_delete(fs_child)
-
- def test_nfs_auth_types(self):
- for s in self.systems:
- cap = self.c.capabilities(s)
-
- if supported(cap, [Cap.EXPORT_AUTH]):
- auth_types = self.c.export_auth()
- self.assertTrue(auth_types is not None)
-
- def test_export_list(self):
- for s in self.systems:
- cap = self.c.capabilities(s)
-
- if supported(cap, [Cap.EXPORTS]):
- exports = self.c.exports()
- # TODO verify export values
-
- def test_create_delete_exports(self):
- for s in self.systems:
- cap = self.c.capabilities(s)
-
- if supported(cap, [Cap.FS_CREATE, Cap.EXPORTS, Cap.EXPORT_FS,
- Cap.EXPORT_REMOVE]):
- fs, pool = self._fs_create(s.id)
-
- if supported(cap, [Cap.EXPORT_CUSTOM_PATH]):
- path = "/mnt/%s" % rs(None, 6)
- exp = self.c.export_fs(fs.id, path, [], [],
- ['192.168.2.1'])
- else:
- exp = self.c.export_fs(fs.id, None, [], [],
- ['192.168.2.1'])
- self.c.export_remove(exp)
- self._fs_delete(fs)
-
-
-def dump_results():
- """
- unittest.main exits when done so we need to register this handler to
- get our results out.
-
- If PyYAML is available we will output detailed results, else we will
- output nothing. The detailed output results of what we called,
- how it finished and how long it took.
- """
- try:
- import yaml
- sys.stdout.write(yaml.dump(dict(methods_called=results, stats=stats)))
- except ImportError:
- sys.stdout.write("NOTICE: Install PyYAML for detailed test results\n")
-
-
-def add_our_params():
- """
- There are probably easier ways to extend unittest, but this seems
- easiest at the moment if we want to retain the default behavior and
- introduce a couple of parameters.
- """
- unittest.TestProgram.USAGE += """\
-
-Options libStorageMgmt:
- --password 'Array password'
- --uri 'Array URI'
- --skip 'Test case to skip. Repeatable argument'
- """
-
-
-if __name__ == "__main__":
- atexit.register(dump_results)
- add_our_params()
-
- parser = argparse.ArgumentParser(add_help=False)
- parser.add_argument('--password', default=None)
- parser.add_argument('--uri')
- parser.add_argument('--skip', action='append')
- options, other_args = parser.parse_known_args()
-
- if options.uri:
- TestPlugin.URI = options.uri
- elif os.getenv('LSM_TEST_URI'):
- TestPlugin.URI = os.getenv('LSM_TEST_URI')
- else:
- TestPlugin.URI = 'sim://'
-
- if options.password:
- TestPlugin.PASSWORD = options.password
- elif os.getenv('LSM_TEST_PASSWORD'):
- TestPlugin.PASSWORD = os.getenv('LSM_TEST_PASSWORD')
-
- if options.skip:
- if hasattr(unittest.TestCase, 'skipTest') is False:
- raise Exception(
- "Current python version is too old to support 'skipTest'")
- TestPlugin.SKIP_TEST_CASES = options.skip
- else:
- TestPlugin.SKIP_TEST_CASES = []
-
- unittest.main(argv=sys.argv[:1] + other_args)
diff --git a/test/runtests.sh b/test/runtests.sh
deleted file mode 100755
index 541e194..0000000
--- a/test/runtests.sh
+++ /dev/null
@@ -1,179 +0,0 @@
-#!/bin/bash
-
-# Copyright (C) 2011-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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: tasleson
-#
-# Unit test case driver
-
-# Make sure these are available in the envirnoment before we start lsmd
-export G_SLICE=always-malloc
-export G_DEBUG=gc-friendly
-export CK_DEFAULT_TIMEOUT=600
-export CK_FORK=no
-
-rundir=$RANDOM
-base=/tmp/$rundir
-
-LSMD_PID=65535
-
-export LSM_TEST_RUNDIR=$rundir
-export LSM_UDS_PATH=$base/lsm/ipc/
-
-LSMD_TMP_LOG_FILE="$base/lsmd.log"
-
-cleanup() {
- #Clean up the daemon if it is running
- if [ $LSMD_PID -ne 65535 ]
- then
- kill -s KILL $LSMD_PID
- fi
-
- cat $LSMD_TMP_LOG_FILE
- if [ -e $LSM_UDS_PATH ]
- then
- rm -rf $base
- fi
-
- if [ -e $rootdir/_build ]
- then
- rm $lsm_py_folder/lsm/plugin
- rm $lsm_py_folder/lsm/lsmcli
- chmod -w $lsm_py_folder/lsm
- fi
-}
-
-good() {
- echo "executing: $1"
- eval $1
- ec=$?
- if [ $ec -ne 0 ]; then
- echo "Fail exit[$ec]: $1"
- cleanup
- exit 1
- fi
-}
-
-# Add a signal handler to clean-up
-trap "cleanup; exit 1" INT
-
-# Unset these as they can cause the test case to fail
-# specifically the password one, but remove both.
-unset LSMCLI_PASSWORD
-unset LSMCLI_URI
-
-#Put us in a consistent spot
-cd "$(dirname "$0")"
-
-#Get base root directory
-testdir=`pwd`
-rootdir=${testdir%/*}
-
-#Are we running within distcheck?
-c_unit=$rootdir/test/tester
-LSMD_DAEMON=$rootdir/daemon/lsmd
-shared_libs=$rootdir/c_binding/.libs/
-bin_plugin=$rootdir/plugin/simc/.libs/
-lsm_py_folder=$rootdir/python_binding
-lsm_plugin_py_folder=$rootdir/plugin
-lsmcli_py_folder=$rootdir/tools/lsmcli
-
-if [ -e $rootdir/_build ]
-then
- c_unit=$rootdir/_build/test/tester
- LSMD_DAEMON=$rootdir/_build/daemon/lsmd
- shared_libs=$rootdir/_build/c_binding/.libs/
- bin_plugin=$rootdir/_build/plugin/simc/.libs/
- # In distcheck, all folder is read only(except _build and _inst).
- # which prevent us from linking plugin and lsmcli into python/lsm folder.
- chmod +w $rootdir/python_binding/lsm
-fi
-
-#With a distcheck you cannot muck with the source file system, so we will copy
-#plugins somewhere else.
-plugins=$base/plugins
-
-#Export needed vars
-export PYTHONPATH=$lsm_py_folder
-export LD_LIBRARY_PATH=$base/lib
-export LSM_SIM_DATA="$base/lsm_sim_data"
-
-echo "testdir= $testdir"
-echo "rootdir= $rootdir"
-echo "c_unit= $c_unit"
-
-#Create the directory for the unix domain sockets
-good "mkdir -p $LSM_UDS_PATH"
-good "mkdir -p $plugins"
-good "mkdir -p $LD_LIBRARY_PATH"
-
-#Copy shared libraries
-good "cp $shared_libs/*.so.* $LD_LIBRARY_PATH"
-
-#Link plugin folder as python/lsm/plugin folder
-if [ ! -L "$lsm_py_folder/lsm/plugin" ];then
- good "ln -s $lsm_plugin_py_folder $lsm_py_folder/lsm/"
-fi
-
-#Link lsmcli folder as python/lsm/lsmcli folder
-if [ ! -L "$lsm_py_folder/lsm/lsmcli" ];then
- good "ln -s $lsmcli_py_folder $lsm_py_folder/lsm/"
-fi
-
-#Copy plugins to one directory.
-good "find $rootdir/ \( ! -regex '.*/\..*' \) -type f -name \*_lsmplugin -exec cp {} $plugins \;"
-
-#Copy the actual binary, not the shell script pointing to binary otherwise
-#valgrind does not work.
-good "cp $bin_plugin/*_lsmplugin $plugins"
-good "ls -lh $plugins"
-
-#Check to make sure that constants are correct
-good "perl ../tools/utility/check_const.pl"
-
-#Start daemon
-$LSMD_DAEMON \
- --plugindir $plugins \
- --socketdir $LSM_UDS_PATH \
- -d >$LSMD_TMP_LOG_FILE &
-
-# Let the daemon get settled before running the tests
-sleep 2
-
-LSMD_PID=$(ps aux | grep $LSM_UDS_PATH | grep -v grep | awk '{print $2}')
-
-#Run C unit test
-if [ -z "$LSM_VALGRIND" ]; then
- good "$c_unit"
-else
- good "valgrind --leak-check=full --show-reachable=no --log-file=/tmp/leaking_client $rootdir/test/.libs/tester"
-fi
-
-#Run cmdline against the simulator if we are not checking for leaks
-if [ -z "$LSM_VALGRIND" ]; then
- export LSMCLI_URI='sim://'
- good "$rootdir/test/cmdtest.py -c $plugins/sim_lsmplugin"
- good "$rootdir/test/cmdtest.py -c $rootdir/tools/lsmcli/lsmcli"
-
- #Run the plug-in test against the python simulator
- good "$rootdir/test/plugin_test.py -v --uri sim://"
-fi
-
-#Run the plug-in test against the C simulator"
-good "$rootdir/test/plugin_test.py -v --uri simc://"
-
-#Pretend we were never here
-cleanup
diff --git a/test/tester.c b/test/tester.c
deleted file mode 100644
index 1622a75..0000000
--- a/test/tester.c
+++ /dev/null
@@ -1,2953 +0,0 @@
-/*
- * Copyright (C) 2011-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 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <check.h>
-#include <unistd.h>
-#include <time.h>
-#include <libstoragemgmt/libstoragemgmt.h>
-#include <libstoragemgmt/libstoragemgmt_plug_interface.h>
-
-const char URI[] = "sim://localhost/?statefile=/tmp/%d/lsm_sim_%s";
-const char SYSTEM_NAME[] = "LSM simulated storage plug-in";
-const char SYSTEM_ID[] = "sim-01";
-const char *ISCSI_HOST[2] = { "iqn.1994-05.com.domain:01.89bd01",
- "iqn.1994-05.com.domain:01.89bd02" };
-
-static int which_plugin = 0;
-
-#define POLL_SLEEP 50000
-
-lsm_connect *c = NULL;
-
-char *error(lsm_error_ptr e)
-{
- static char eb[1024];
- memset(eb, 0, sizeof(eb));
-
- if( e != NULL ) {
- snprintf(eb, sizeof(eb), "Error msg= %s - exception %s - debug %s",
- lsm_error_message_get(e),
- lsm_error_exception_get(e), lsm_error_debug_get(e));
- lsm_error_free(e);
- e = NULL;
- } else {
- snprintf(eb, sizeof(eb), "No addl. error info.");
- }
- return eb;
-}
-
-/**
- * Macro for calls which we expect success.
- * @param variable Where the result of the call is placed
- * @param func Name of function
- * @param ... Function parameters
- */
-#define G(variable, func, ...) \
-variable = func(__VA_ARGS__); \
-fail_unless( LSM_ERR_OK == variable, "call:%s rc = %d %s (which %d)", #func, \
- variable, error(lsm_error_last_get(c)), which_plugin);
-
-/**
- * Macro for calls which we expect failure.
- * @param variable Where the result of the call is placed
- * @param func Name of function
- * @param ... Function parameters
- */
-#define F(variable, func, ...) \
-variable = func(__VA_ARGS__); \
-fail_unless( LSM_ERR_OK != variable, "call:%s rc = %d %s (which %d)", #func, \
- variable, error(lsm_error_last_get(c)), which_plugin);
-
-/**
-* Generates a random string in the buffer with specified length.
-* Note: This function should not produce repeating sequences or duplicates
-* regardless if it's used repeatedly in the same function in the same process
-* or different forked processes.
-* @param buff Buffer to write the random string to
-* @param len Length of the random string
-*/
-void generate_random(char *buff, uint32_t len)
-{
- uint32_t i = 0;
- static int seed = 0;
- static int pid = 0;
-
- /* Re-seed the random number generator at least once per unique process */
- if( (!seed || !pid) || (pid != getpid()) ) {
- seed = time(NULL);
- pid = getpid();
- srandom(seed + pid);
- }
-
- if( buff && (len > 1) ) {
- for(i = 0; i < (len - 1); ++i) {
- buff[i] = 97 + rand()%26;
- }
- buff[len-1] = '\0';
- }
-}
-
-char *plugin_to_use()
-{
- char *uri_to_use = "sim://";
-
- if( which_plugin == 1 ) {
- uri_to_use = "simc://";
- } else {
- char *rundir = getenv("LSM_TEST_RUNDIR");
-
- /* The python plug-in keeps state, but the unit tests don't expect this
- * create a new random file for the state to keep things new.
- */
-
- if( rundir ) {
- int rdir = atoi(rundir);
- static char fn[128];
- static char name[32];
- generate_random(name, sizeof(name));
- snprintf(fn, sizeof(fn), URI, rdir, name);
- uri_to_use = fn;
- } else {
- printf("Missing LSM_TEST_RUNDIR, expect test failures!\n");
- }
- }
- printf("URI = %s\n", uri_to_use);
- return uri_to_use;
-}
-
-lsm_pool *get_test_pool(lsm_connect *c)
-{
- lsm_pool **pools = NULL;
- uint32_t count = 0;
- lsm_pool *test_pool = NULL;
- int rc = 0;
-
- G(rc, lsm_pool_list, c, NULL, NULL, &pools, &count, LSM_CLIENT_FLAG_RSVD);
-
- if( LSM_ERR_OK == rc ) {
- uint32_t i = 0;
- for(i = 0; i < count; ++i ) {
- if(strcmp(lsm_pool_name_get(pools[i]), "lsm_test_aggr") == 0 ) {
- test_pool = lsm_pool_record_copy(pools[i]);
- G(rc, lsm_pool_record_array_free, pools, count);
- break;
- }
- }
- }
- return test_pool;
-}
-
-void dump_error(lsm_error_ptr e)
-{
- int rc = 0;
- if (e != NULL) {
- printf("Error msg= %s - exception %s - debug %s\n",
- lsm_error_message_get(e),
- lsm_error_exception_get(e), lsm_error_debug_get(e));
-
- G(rc, lsm_error_free, e);
- e = NULL;
- } else {
- printf("No additional error information!\n");
- }
-}
-
-void setup(void)
-{
- /*
- * Note: Do not use any error reporting functions in this function
- */
-
- lsm_error_ptr e = NULL;
-
- int rc = lsm_connect_password(plugin_to_use(), NULL, &c, 30000, &e,
- LSM_CLIENT_FLAG_RSVD);
-
- if( LSM_ERR_OK == rc ) {
- if( getenv("LSM_DEBUG_PLUGIN") ) {
- printf("Attach debugger to plug-in, press <return> when ready...");
- getchar();
- }
- }
-}
-
-void teardown(void)
-{
- /*
- * Note: Do not use any error reporting functions in this function
- */
-
- if( c ) {
- lsm_connect_close(c, LSM_CLIENT_FLAG_RSVD);
- c = NULL;
- }
-}
-
-void wait_for_job(lsm_connect *c, char **job_id)
-{
- lsm_job_status status;
- uint8_t pc = 0;
- int rc = 0;
-
- do {
- G(rc, lsm_job_status_get, c, *job_id, &status, &pc, LSM_CLIENT_FLAG_RSVD);
- printf("GENERIC: Job %s in progress, %d done, status = %d\n", *job_id,
- pc, status);
- usleep(POLL_SLEEP);
-
- } while( status == LSM_JOB_INPROGRESS );
-
- G(rc, lsm_job_free, c, job_id, LSM_CLIENT_FLAG_RSVD);
-
- fail_unless( LSM_JOB_COMPLETE == status);
- fail_unless( 100 == pc);
- fail_unless( job_id != NULL );
-}
-
-lsm_volume *wait_for_job_vol(lsm_connect *c, char **job_id)
-{
- lsm_job_status status;
- lsm_volume *vol = NULL;
- uint8_t pc = 0;
- int rc = 0;
-
- do {
- G(rc, lsm_job_status_volume_get, c, *job_id, &status, &pc, &vol,
- LSM_CLIENT_FLAG_RSVD);
- printf("VOLUME: Job %s in progress, %d done, status = %d\n",
- *job_id, pc, status);
- usleep(POLL_SLEEP);
-
- } while( rc == LSM_ERR_OK && status == LSM_JOB_INPROGRESS );
-
- printf("Volume complete: Job %s percent %d done, status = %d, rc=%d\n",
- *job_id, pc, status, rc);
-
- G(rc, lsm_job_free, c, job_id, LSM_CLIENT_FLAG_RSVD);
-
- fail_unless( LSM_JOB_COMPLETE == status);
- fail_unless( 100 == pc);
-
- return vol;
-}
-
-lsm_pool *wait_for_job_pool(lsm_connect *c, char **job_id)
-{
- lsm_job_status status;
- lsm_pool *pool = NULL;
- uint8_t pc = 0;
- int rc = 0;
-
- do {
- G(rc, lsm_job_status_pool_get, c, *job_id, &status, &pc, &pool,
- LSM_CLIENT_FLAG_RSVD);
- printf("POOL: Job %s in progress, %d done, status = %d\n", *job_id, pc,
- status);
- usleep(POLL_SLEEP);
-
- } while( status == LSM_JOB_INPROGRESS );
-
- G(rc, lsm_job_free, c, job_id, LSM_CLIENT_FLAG_RSVD);
-
- fail_unless( LSM_JOB_COMPLETE == status);
- fail_unless( 100 == pc);
-
- return pool;
-}
-
-lsm_fs *wait_for_job_fs(lsm_connect *c, char **job_id)
-{
- lsm_job_status status;
- lsm_fs *fs = NULL;
- uint8_t pc = 0;
- int rc = 0;
-
- do {
- G(rc, lsm_job_status_fs_get, c, *job_id, &status, &pc, &fs,
- LSM_CLIENT_FLAG_RSVD);
- printf("FS: Job %s in progress, %d done, status = %d\n", *job_id, pc,
- status);
- usleep(POLL_SLEEP);
-
- } while( status == LSM_JOB_INPROGRESS );
-
- G(rc, lsm_job_free, c, job_id, LSM_CLIENT_FLAG_RSVD);
- fail_unless( LSM_JOB_COMPLETE == status);
- fail_unless( 100 == pc);
-
- return fs;
-}
-
-lsm_fs_ss *wait_for_job_ss(lsm_connect *c, char **job_id)
-{
- lsm_job_status status;
- lsm_fs_ss *ss = NULL;
- uint8_t pc = 0;
- int rc = 0;
-
- do {
- G(rc, lsm_job_status_ss_get, c, *job_id, &status, &pc, &ss,
- LSM_CLIENT_FLAG_RSVD);
- printf("SS: Job %s in progress, %d done, status = %d\n",
- *job_id, pc, status);
- usleep(POLL_SLEEP);
-
- } while( status == LSM_JOB_INPROGRESS );
-
- G(rc, lsm_job_free, c, job_id, LSM_CLIENT_FLAG_RSVD);
-
- fail_unless( LSM_JOB_COMPLETE == status);
- fail_unless( 100 == pc);
-
- return ss;
-}
-
-int compare_string_lists(lsm_string_list *l, lsm_string_list *r)
-{
- if( l && r) {
- int i = 0;
-
- if( l == r ) {
- return 0;
- }
-
- if( lsm_string_list_size(l) != lsm_string_list_size(r) ) {
- return 1;
- }
-
- for( i = 0; i < lsm_string_list_size(l); ++i ) {
- if( strcmp(lsm_string_list_elem_get(l, i),
- lsm_string_list_elem_get(r, i)) != 0) {
- return 1;
- }
- }
- return 0;
- }
- return 1;
-}
-
-void create_volumes(lsm_connect *c, lsm_pool *p, int num)
-{
- int i;
-
- for( i = 0; i < num; ++i ) {
- lsm_volume *n = NULL;
- char *job = NULL;
- char name[32];
-
- memset(name, 0, sizeof(name));
- snprintf(name, sizeof(name), "test %d", i);
-
- int vc = lsm_volume_create(c, p, name, 20000000,
- LSM_VOLUME_PROVISION_DEFAULT, &n, &job, LSM_CLIENT_FLAG_RSVD);
-
- fail_unless( vc == LSM_ERR_OK || vc == LSM_ERR_JOB_STARTED,
- "lsmVolumeCreate %d (%s)", vc, error(lsm_error_last_get(c)));
-
- if( LSM_ERR_JOB_STARTED == vc ) {
- n = wait_for_job_vol(c, &job);
- } else {
- fail_unless(LSM_ERR_OK == vc);
- }
-
- G(vc, lsm_volume_record_free, n);
- n = NULL;
- }
-}
-
-lsm_system *get_system(lsm_connect *c)
-{
- lsm_system *rc_sys = NULL;
- lsm_system **sys=NULL;
- uint32_t count = 0;
- int rc = 0;
-
- G(rc, lsm_system_list, c, &sys, &count, LSM_CLIENT_FLAG_RSVD);
-
- if( LSM_ERR_OK == rc && count) {
- rc_sys = lsm_system_record_copy(sys[0]);
- G(rc, lsm_system_record_array_free, sys, count);
- }
- return rc_sys;
-}
-
-START_TEST(test_smoke_test)
-{
- uint32_t i = 0;
- int rc = 0;
-
- lsm_pool *selectedPool = NULL;
- uint32_t poolCount = 0;
-
- uint32_t set_tmo = 31123;
- uint32_t tmo = 0;
-
- //Set timeout.
- G(rc, lsm_connect_timeout_set, c, set_tmo, LSM_CLIENT_FLAG_RSVD);
-
- //Get time-out.
- G(rc, lsm_connect_timeout_get, c, &tmo, LSM_CLIENT_FLAG_RSVD);
-
- fail_unless( set_tmo == tmo, " %u != %u", set_tmo, tmo );
-
- lsm_pool **pools = NULL;
- uint32_t count = 0;
- int poolToUse = -1;
-
- //Get pool list
- G(rc, lsm_pool_list, c, NULL, NULL, &pools, &poolCount, LSM_CLIENT_FLAG_RSVD);
-
- //Check pool count
- count = poolCount;
- fail_unless(count == 4, "We are expecting 4 pools from simulator");
-
- //Dump pools and select a pool to use for testing.
- for (i = 0; i < count; ++i) {
- printf("Id= %s, name=%s, capacity= %"PRIu64 ", remaining= %"PRIu64" "
- "system %s\n",
- lsm_pool_id_get(pools[i]),
- lsm_pool_name_get(pools[i]),
- lsm_pool_total_space_get(pools[i]),
- lsm_pool_free_space_get(pools[i]),
- lsm_pool_system_id_get(pools[i]));
-
- fail_unless( strcmp(lsm_pool_system_id_get(pools[i]), SYSTEM_ID) == 0,
- "Expecting system id of %s, got %s",
- SYSTEM_ID, lsm_pool_system_id_get(pools[i]));
-
- fail_unless(lsm_pool_status_get(pools[i]) == LSM_POOL_STATUS_OK,
- "%"PRIu64, lsm_pool_status_get(pools[i]));
-
- if (lsm_pool_free_space_get(pools[i]) > 20000000) {
- poolToUse = i;
- }
- }
-
- if (poolToUse != -1) {
- lsm_volume *n = NULL;
- char *job = NULL;
-
- selectedPool = pools[poolToUse];
-
- int vc = lsm_volume_create(c, pools[poolToUse], "test", 20000000,
- LSM_VOLUME_PROVISION_DEFAULT, &n, &job, LSM_CLIENT_FLAG_RSVD);
-
- fail_unless( vc == LSM_ERR_OK || vc == LSM_ERR_JOB_STARTED,
- "lsmVolumeCreate %d (%s)", vc, error(lsm_error_last_get(c)));
-
- if( LSM_ERR_JOB_STARTED == vc ) {
- n = wait_for_job_vol(c, &job);
-
- fail_unless( n != NULL);
- }
-
- uint8_t dependants = 10;
- int child_depends = 0;
- G(child_depends, lsm_volume_child_dependency, c, n, &dependants,
- LSM_CLIENT_FLAG_RSVD);
- fail_unless(dependants == 0);
-
- child_depends = lsm_volume_child_dependency_delete(c, n, &job, LSM_CLIENT_FLAG_RSVD);
- if( LSM_ERR_JOB_STARTED == child_depends ) {
- wait_for_job(c, &job);
- } else if ( LSM_ERR_NO_STATE_CHANGE != child_depends) {
- fail_unless(LSM_ERR_OK == child_depends, "rc = %d", child_depends);
- fail_unless(NULL == job);
- }
-
-
- lsm_block_range **range = lsm_block_range_record_array_alloc(3);
- fail_unless(NULL != range);
-
-
- uint32_t bs = 0;
- lsm_system * system = get_system(c);
-
- int rep_bs = 0;
- G(rep_bs, lsm_volume_replicate_range_block_size, c, system, &bs,
- LSM_CLIENT_FLAG_RSVD);
- fail_unless(512 == bs);
-
- lsm_system_record_free(system);
-
- int rep_i = 0;
-
- for(rep_i = 0; rep_i < 3; ++rep_i) {
- range[rep_i] = lsm_block_range_record_alloc((rep_i * 1000),
- ((rep_i + 100) * 10000), 10);
-
- lsm_block_range *copy = lsm_block_range_record_copy(range[rep_i]);
-
- fail_unless( lsm_block_range_source_start_get(range[rep_i]) ==
- lsm_block_range_source_start_get(copy));
-
- fail_unless( lsm_block_range_dest_start_get(range[rep_i]) ==
- lsm_block_range_dest_start_get(copy));
-
- fail_unless ( lsm_block_range_block_count_get(range[rep_i]) ==
- lsm_block_range_block_count_get( copy ));
-
- G(rc, lsm_block_range_record_free, copy);
- copy = NULL;
-
- }
-
- int rep_range = lsm_volume_replicate_range(c, LSM_VOLUME_REPLICATE_CLONE,
- n, n, range, 3, &job, LSM_CLIENT_FLAG_RSVD);
-
- if( LSM_ERR_JOB_STARTED == rep_range ) {
- wait_for_job(c, &job);
- } else {
-
- if( LSM_ERR_OK != rep_range ) {
- dump_error(lsm_error_last_get(c));
- }
-
- fail_unless(LSM_ERR_OK == rep_range);
- }
-
- G(rc, lsm_block_range_record_array_free, range, 3);
-
- int online = 0;
- G(online, lsm_volume_disable, c, n, LSM_CLIENT_FLAG_RSVD);
-
- G(online, lsm_volume_enable, c, n, LSM_CLIENT_FLAG_RSVD);
-
- char *jobDel = NULL;
- int delRc = lsm_volume_delete(c, n, &jobDel, LSM_CLIENT_FLAG_RSVD);
-
- fail_unless( delRc == LSM_ERR_OK || delRc == LSM_ERR_JOB_STARTED,
- "lsm_volume_delete %d (%s)", rc, error(lsm_error_last_get(c)));
-
- if( LSM_ERR_JOB_STARTED == delRc ) {
- wait_for_job_vol(c, &jobDel);
- }
-
- G(rc, lsm_volume_record_free, n);
- }
-
- //Create some volumes for testing.
- create_volumes(c, selectedPool, 3);
-
- lsm_volume **volumes = NULL;
- count = 0;
- /* Get a list of volumes */
- G(rc, lsm_volume_list, c, NULL, NULL, &volumes, &count, LSM_CLIENT_FLAG_RSVD);
-
- for (i = 0; i < count; ++i) {
- printf("%s - %s - %s - %"PRIu64" - %"PRIu64" - %x\n",
- lsm_volume_id_get(volumes[i]),
- lsm_volume_name_get(volumes[i]),
- lsm_volume_vpd83_get(volumes[i]),
- lsm_volume_block_size_get(volumes[i]),
- lsm_volume_number_of_blocks_get(volumes[i]),
- lsm_volume_admin_state_get(volumes[i]));
- }
-
- if( count ) {
-
- lsm_volume *rep = NULL;
- char *job = NULL;
-
- //Try a re-size then a snapshot
- lsm_volume *resized = NULL;
- char *resizeJob = NULL;
-
- int resizeRc = lsm_volume_resize(c, volumes[0],
- ((lsm_volume_number_of_blocks_get(volumes[0]) *
- lsm_volume_block_size_get(volumes[0])) * 2), &resized, &resizeJob, LSM_CLIENT_FLAG_RSVD);
-
- fail_unless(resizeRc == LSM_ERR_OK || resizeRc == LSM_ERR_JOB_STARTED,
- "lsmVolumeResize %d (%s)", resizeRc,
- error(lsm_error_last_get(c)));
-
- if( LSM_ERR_JOB_STARTED == resizeRc ) {
- resized = wait_for_job_vol(c, &resizeJob);
- }
-
- G(rc, lsm_volume_record_free, resized);
-
- //Lets create a clone of one.
- int repRc = lsm_volume_replicate(c, NULL, //Pool is optional
- LSM_VOLUME_REPLICATE_CLONE,
- volumes[0], "CLONE1",
- &rep, &job, LSM_CLIENT_FLAG_RSVD);
-
- fail_unless(repRc == LSM_ERR_OK || repRc == LSM_ERR_JOB_STARTED,
- "lsmVolumeReplicate %d (%s)", repRc,
- error(lsm_error_last_get(c)));
-
- if( LSM_ERR_JOB_STARTED == repRc ) {
- rep = wait_for_job_vol(c, &job);
- }
-
- G(rc, lsm_volume_record_free, rep);
-
- G(rc, lsm_volume_record_array_free, volumes, count);
-
- if (pools) {
- G(rc, lsm_pool_record_array_free, pools, poolCount);
- }
- }
-}
-
-END_TEST
-
-
-START_TEST(test_access_groups)
-{
- lsm_access_group **groups = NULL;
- lsm_access_group *group = NULL;
- uint32_t count = 0;
- uint32_t i = 0;
- lsm_string_list *init_list = NULL;
- lsm_system *system = NULL;
- int rc = 0;
-
- fail_unless(c!=NULL);
-
-
- system = get_system(c);
-
- G(rc, lsm_access_group_list, c, NULL, NULL, &groups, &count, LSM_CLIENT_FLAG_RSVD);
- fail_unless(count == 0, "Expect 0 access groups, got %"PRIu32, count);
- fail_unless(groups == NULL);
-
- G(rc, lsm_access_group_create, c, "test_access_groups",
- "iqn.1994-05.com.domain:01.89bd01",
- LSM_ACCESS_GROUP_INIT_TYPE_ISCSI_IQN, system,
- &group, LSM_CLIENT_FLAG_RSVD);
-
- if( LSM_ERR_OK == rc ) {
- lsm_string_list *init_list = lsm_access_group_initiator_id_get(group);
- lsm_string_list *init_copy = NULL;
-
- fail_unless(lsm_string_list_size(init_list) == 1);
-
- init_copy = lsm_string_list_copy(init_list);
- lsm_access_group_initiator_id_set(group, init_copy);
-
- printf("%s - %s - %s\n", lsm_access_group_id_get(group),
- lsm_access_group_name_get(group),
- lsm_access_group_system_id_get(group));
-
- fail_unless(NULL != lsm_access_group_id_get(group));
- fail_unless(NULL != lsm_access_group_name_get(group));
- fail_unless(NULL != lsm_access_group_system_id_get(group));
-
- lsm_access_group *copy = lsm_access_group_record_copy(group);
- if( copy ) {
- fail_unless( strcmp(lsm_access_group_id_get(group), lsm_access_group_id_get(copy)) == 0);
- fail_unless( strcmp(lsm_access_group_name_get(group), lsm_access_group_name_get(copy)) == 0) ;
- fail_unless( strcmp(lsm_access_group_system_id_get(group), lsm_access_group_system_id_get(copy)) == 0);
-
- G(rc, lsm_access_group_record_free, copy);
- copy = NULL;
- }
-
- G(rc, lsm_string_list_free, init_copy);
- init_copy = NULL;
- }
-
- G(rc, lsm_access_group_list, c, NULL, NULL, &groups, &count, LSM_CLIENT_FLAG_RSVD);
- fail_unless( 1 == count );
- G(rc, lsm_access_group_record_array_free, groups, count);
- groups = NULL;
- count = 0;
- //char *job = NULL;
- lsm_access_group *updated = NULL;
-
- rc = lsm_access_group_initiator_add(c, group, "iqn.1994-05.com.domain:01.89bd02",
- LSM_ACCESS_GROUP_INIT_TYPE_ISCSI_IQN,
- &updated, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_OK == rc, "Expected success on lsmAccessGroupInitiatorAdd %d %d", rc, which_plugin);
-
- G(rc, lsm_access_group_list, c, NULL, NULL, &groups, &count, LSM_CLIENT_FLAG_RSVD);
- fail_unless( 1 == count );
-
- fail_unless( updated != NULL );
- lsm_access_group_record_free(updated);
- updated = NULL;
-
- if( count ) {
- init_list = lsm_access_group_initiator_id_get(groups[0]);
- fail_unless( lsm_string_list_size(init_list) == 2,
- "Expecting 2 initiators, current num = %d\n",
- lsm_string_list_size(init_list) );
- for( i = 0; i < lsm_string_list_size(init_list) - 1; ++i) {
- printf("%d = %s\n", i, lsm_string_list_elem_get(init_list, i));
-
- printf("Deleting initiator %s from group!\n",
- lsm_string_list_elem_get(init_list, i));
-
- G(rc, lsm_access_group_initiator_delete, c, groups[0],
- lsm_string_list_elem_get(init_list, i),
- LSM_ACCESS_GROUP_INIT_TYPE_ISCSI_IQN, &updated,
- LSM_CLIENT_FLAG_RSVD)
-
- fail_unless(updated != NULL);
- lsm_access_group_record_free(updated);
- updated = NULL;
- }
- init_list = NULL;
- }
-
- if( group ) {
- G(rc, lsm_access_group_record_free, group);
- group = NULL;
- }
-
- G(rc, lsm_access_group_record_array_free, groups, count);
- groups = NULL;
- count = 0;
-
- G(rc, lsm_access_group_list, c, NULL, NULL, &groups, &count, LSM_CLIENT_FLAG_RSVD);
- fail_unless( LSM_ERR_OK == rc);
- fail_unless( 1 == count );
-
- if( count ) {
- init_list = lsm_access_group_initiator_id_get(groups[0]);
- fail_unless( init_list != NULL);
- fail_unless( lsm_string_list_size(init_list) == 1, "%d",
- lsm_string_list_size(init_list));
- init_list = NULL;
- G(rc, lsm_access_group_record_array_free, groups, count);
- groups = NULL;
- count = 0;
- }
-
- G(rc, lsm_system_record_free, system);
- system = NULL;
-}
-END_TEST
-
-START_TEST(test_access_groups_grant_revoke)
-{
- fail_unless(c!=NULL);
- lsm_access_group *group = NULL;
- int rc = 0;
- lsm_pool *pool = get_test_pool(c);
- char *job = NULL;
- lsm_volume *n = NULL;
- lsm_system *system = NULL;
-
- fail_unless(pool != NULL);
- system = get_system(c);
-
- G(rc, lsm_access_group_create, c, "test_access_groups_grant_revoke",
- ISCSI_HOST[0],
- LSM_ACCESS_GROUP_INIT_TYPE_ISCSI_IQN,
- system,
- &group, LSM_CLIENT_FLAG_RSVD);
-
-
- int vc = lsm_volume_create(c, pool, "volume_grant_test", 20000000,
- LSM_VOLUME_PROVISION_DEFAULT, &n, &job, LSM_CLIENT_FLAG_RSVD);
-
- fail_unless( vc == LSM_ERR_OK || vc == LSM_ERR_JOB_STARTED,
- "lsmVolumeCreate %d (%s)", vc, error(lsm_error_last_get(c)));
-
- if( LSM_ERR_JOB_STARTED == vc ) {
- n = wait_for_job_vol(c, &job);
- }
-
- fail_unless(n != NULL);
-
- rc = lsm_volume_mask(c, group, n, LSM_CLIENT_FLAG_RSVD);
- if( LSM_ERR_JOB_STARTED == rc ) {
- wait_for_job(c, &job);
- } else {
- fail_unless(LSM_ERR_OK == rc, "rc = %d, plug-in = %d", rc, which_plugin);
- }
-
- lsm_volume **volumes = NULL;
- uint32_t v_count = 0;
- G(rc, lsm_volumes_accessible_by_access_group, c, group, &volumes, &v_count,
- LSM_CLIENT_FLAG_RSVD);
- fail_unless(v_count == 1);
-
- if( v_count >= 1 ) {
- fail_unless(strcmp(lsm_volume_id_get(volumes[0]), lsm_volume_id_get(n)) == 0);
- G(rc, lsm_volume_record_array_free, volumes, v_count);
- }
-
- lsm_access_group **groups;
- uint32_t g_count = 0;
- G(rc, lsm_access_groups_granted_to_volume, c, n, &groups, &g_count,
- LSM_CLIENT_FLAG_RSVD);
- fail_unless(g_count == 1);
-
-
- if( g_count >= 1 ) {
- fail_unless(strcmp(lsm_access_group_id_get(groups[0]), lsm_access_group_id_get(group)) == 0);
- G(rc, lsm_access_group_record_array_free, groups, g_count);
- }
-
- rc = lsm_volume_unmask(c, group, n, LSM_CLIENT_FLAG_RSVD);
- if( LSM_ERR_JOB_STARTED == rc ) {
- wait_for_job(c, &job);
- } else {
- fail_unless(LSM_ERR_OK == rc, "rc = %d, which_plugin=%d",
- rc, which_plugin);
- }
-
- G(rc, lsm_access_group_delete, c, group, LSM_CLIENT_FLAG_RSVD);
- G(rc, lsm_access_group_record_free, group);
-
- G(rc, lsm_volume_record_free, n);
- G(rc, lsm_pool_record_free, pool);
-
- G(rc, lsm_system_record_free, system);
-}
-END_TEST
-
-START_TEST(test_fs)
-{
- fail_unless(c!=NULL);
-
- lsm_fs **fs_list = NULL;
- int rc = 0;
- uint32_t fs_count = 0;
- lsm_fs *nfs = NULL;
- lsm_fs *resized_fs = NULL;
- char *job = NULL;
- uint64_t fs_free_space = 0;
-
- lsm_pool *test_pool = get_test_pool(c);
-
- G(rc, lsm_fs_list, c, NULL, NULL, &fs_list, &fs_count, LSM_CLIENT_FLAG_RSVD);
- fail_unless(0 == fs_count);
-
- rc = lsm_fs_create(c, test_pool, "C_unit_test", 50000000, &nfs, &job, LSM_CLIENT_FLAG_RSVD);
-
- if( LSM_ERR_JOB_STARTED == rc ) {
- fail_unless(NULL == nfs);
-
- nfs = wait_for_job_fs(c, &job);
- } else {
- fail_unless(LSM_ERR_OK == rc);
- }
-
- fail_unless(NULL != nfs);
-
- fs_free_space = lsm_fs_free_space_get(nfs);
- fail_unless(fs_free_space != 0);
-
- lsm_fs *cloned_fs = NULL;
- rc = lsm_fs_clone(c, nfs, "cloned_fs", NULL, &cloned_fs, &job, LSM_CLIENT_FLAG_RSVD);
- if( LSM_ERR_JOB_STARTED == rc ) {
- fail_unless(NULL == cloned_fs);
- cloned_fs = wait_for_job_fs(c, &job);
-
- rc = lsm_fs_record_free(cloned_fs);
- cloned_fs = NULL;
- fail_unless(LSM_ERR_OK == rc, "rc= %d", rc);
- } else {
- fail_unless(LSM_ERR_OK == rc, "rc= %d", rc);
- }
-
- rc = lsm_fs_file_clone(c, nfs, "src/file.txt", "dest/file.txt", NULL, &job, LSM_CLIENT_FLAG_RSVD);
- if( LSM_ERR_JOB_STARTED == rc ) {
- wait_for_job(c, &job);
- } else {
- fail_unless(LSM_ERR_OK == rc);
- }
-
-
- G(rc, lsm_fs_list, c, NULL, NULL, &fs_list, &fs_count, LSM_CLIENT_FLAG_RSVD);
- fail_unless(2 == fs_count, "fs_count = %d", fs_count);
- G(rc, lsm_fs_record_array_free, fs_list, fs_count);
- fs_list = NULL;
- fs_count = 0;
-
- rc = lsm_fs_resize(c,nfs, 100000000, &resized_fs, &job, LSM_CLIENT_FLAG_RSVD);
-
- if( LSM_ERR_JOB_STARTED == rc ) {
- fail_unless(NULL == resized_fs);
- resized_fs = wait_for_job_fs(c, &job);
- }
-
- if ( which_plugin == 0 ){
-
- uint8_t yes_no = 10;
- G(rc, lsm_fs_child_dependency, c, nfs, NULL, &yes_no,
- LSM_CLIENT_FLAG_RSVD);
- fail_unless( yes_no != 0);
-
- rc = lsm_fs_child_dependency_delete(
- c, nfs, NULL, &job, LSM_CLIENT_FLAG_RSVD);
- if( LSM_ERR_JOB_STARTED == rc ) {
- fail_unless(NULL != job);
- wait_for_job(c, &job);
- } else {
- fail_unless( LSM_ERR_OK == rc);
- }
- }
-
- rc = lsm_fs_delete(c, resized_fs, &job, LSM_CLIENT_FLAG_RSVD);
-
- if( LSM_ERR_JOB_STARTED == rc ) {
- wait_for_job(c, &job);
- } else {
- fail_unless(LSM_ERR_OK == rc);
- }
-
- G(rc, lsm_fs_record_free, resized_fs);
- G(rc, lsm_fs_record_free, nfs);
- G(rc, lsm_pool_record_free, test_pool);
-}
-END_TEST
-
-START_TEST(test_ss)
-{
- fail_unless(c != NULL);
- lsm_fs_ss **ss_list = NULL;
- uint32_t ss_count = 0;
- char *job = NULL;
- lsm_fs *fs = NULL;
- lsm_fs_ss *ss = NULL;
-
-
- lsm_pool *test_pool = get_test_pool(c);
-
- int rc = lsm_fs_create(c, test_pool, "test_fs", 100000000, &fs, &job,
- LSM_CLIENT_FLAG_RSVD);
-
- if( LSM_ERR_JOB_STARTED == rc ) {
- fs = wait_for_job_fs(c, &job);
- }
-
- fail_unless(fs != NULL);
-
- G(rc, lsm_pool_record_free, test_pool);
- test_pool = NULL;
-
-
- G(rc, lsm_fs_ss_list, c, fs, &ss_list, &ss_count, LSM_CLIENT_FLAG_RSVD);
- fail_unless( NULL == ss_list);
- fail_unless( 0 == ss_count );
-
-
- rc = lsm_fs_ss_create(c, fs, "test_snap", &ss, &job, LSM_CLIENT_FLAG_RSVD);
- if( LSM_ERR_JOB_STARTED == rc ) {
- printf("Waiting for snap to create!\n");
- ss = wait_for_job_ss(c, &job);
- } else {
- fail_unless(LSM_ERR_OK == rc);
- }
-
- fail_unless( NULL != ss);
-
- G(rc, lsm_fs_ss_list, c, fs, &ss_list, &ss_count, LSM_CLIENT_FLAG_RSVD);
- fail_unless( NULL != ss_list);
- fail_unless( 1 == ss_count );
-
- lsm_string_list *files = lsm_string_list_alloc(1);
- if(files) {
- G(rc, lsm_string_list_elem_set, files, 0, "some/file/name.txt");
- }
-
- rc = lsm_fs_ss_restore(c, fs, ss, files, files, 0, &job, LSM_CLIENT_FLAG_RSVD);
- if( LSM_ERR_JOB_STARTED == rc ) {
- printf("Waiting for lsm_fs_ss_restore!\n");
- wait_for_job(c, &job);
- } else {
- fail_unless(LSM_ERR_OK == rc);
- }
-
- G(rc, lsm_string_list_free, files);
-
- rc = lsm_fs_ss_delete(c, fs, ss, &job, LSM_CLIENT_FLAG_RSVD);
- if( LSM_ERR_JOB_STARTED == rc ) {
- wait_for_job(c, &job);
- }
-
- G(rc, lsm_fs_ss_record_array_free, ss_list, ss_count);
- G(rc, lsm_fs_record_free, fs);
- G(rc, lsm_fs_ss_record_free, ss);
-
-}
-END_TEST
-
-START_TEST(test_systems)
-{
- uint32_t count = 0;
- lsm_system **sys=NULL;
- const char *id = NULL;
- const char *name = NULL;
- uint32_t status = 0;
- int rc = 0;
-
- fail_unless(c!=NULL);
-
- G(rc, lsm_system_list, c, &sys, &count, LSM_CLIENT_FLAG_RSVD);
- fail_unless(count == 1);
-
- if( count ) {
- id = lsm_system_id_get(sys[0]);
- fail_unless(id != NULL);
- fail_unless(strcmp(id, SYSTEM_ID) == 0, "%s", id);
-
- name = lsm_system_name_get(sys[0]);
- fail_unless(name != NULL);
- fail_unless(strcmp(name, SYSTEM_NAME) == 0);
-
- status = lsm_system_status_get(sys[0]);
- fail_unless(status == LSM_SYSTEM_STATUS_OK, "status = %x", status);
- }
-
- G(rc, lsm_system_record_array_free, sys, count);
-}
-END_TEST
-
-#define COMPARE_STR_FUNC(func, l, r) \
- rc = strcmp(func(l), func(r)); \
- if( rc ) \
- return rc;\
-
-#define COMPARE_NUMBER_FUNC(func, l, r)\
- if( func(l) != func(r) ) \
- return 1;\
-
-
-static int compare_disks(lsm_disk *l, lsm_disk *r)
-{
- int rc;
- if( l && r ) {
- COMPARE_STR_FUNC(lsm_disk_id_get, l, r);
- COMPARE_STR_FUNC(lsm_disk_name_get, l, r);
- COMPARE_STR_FUNC(lsm_disk_system_id_get, l, r);
- COMPARE_NUMBER_FUNC(lsm_disk_type_get, l, r);
- COMPARE_NUMBER_FUNC(lsm_disk_number_of_blocks_get, l, r);
- COMPARE_NUMBER_FUNC(lsm_disk_block_size_get, l, r);
- COMPARE_NUMBER_FUNC(lsm_disk_status_get, l, r);
- return 0;
- }
- return 1;
-}
-
-START_TEST(test_disks)
-{
- uint32_t count = 0;
- lsm_disk **d = NULL;
- const char *id;
- const char *name;
- const char *system_id;
- int i = 0;
-
- fail_unless(c!=NULL);
-
- int rc = lsm_disk_list(c, NULL, NULL, &d, &count, 0);
-
- if( LSM_ERR_OK == rc ) {
- fail_unless(LSM_ERR_OK == rc, "%d", rc);
- fail_unless(count >= 1);
-
- for( i = 0; i < count; ++i ) {
- lsm_disk *d_copy = lsm_disk_record_copy( d[i] );
- fail_unless( d_copy != NULL );
- if( d_copy ) {
- fail_unless(compare_disks(d[i], d_copy) == 0);
- lsm_disk_record_free(d_copy);
- d_copy = NULL;
- }
-
- id = lsm_disk_id_get(d[i]);
- fail_unless(id != NULL && strlen(id) > 0);
-
- name = lsm_disk_name_get(d[i]);
- fail_unless(id != NULL && strlen(name) > 0);
-
- system_id = lsm_disk_system_id_get(d[i]);
- fail_unless(id != NULL && strlen(system_id) > 0);
- fail_unless(strcmp(system_id, SYSTEM_ID) == 0, "%s", id);
-
- fail_unless( lsm_disk_type_get(d[i]) >= 1 );
- fail_unless( lsm_disk_number_of_blocks_get(d[i]) >= 1);
- fail_unless( lsm_disk_block_size_get(d[i]) >= 1);
- fail_unless( lsm_disk_status_get(d[i]) >= 1);
-
- }
- lsm_disk_record_array_free(d, count);
- } else {
- fail_unless(d == NULL);
- fail_unless(count == 0);
- }
-}
-END_TEST
-
-START_TEST(test_nfs_exports)
-{
- fail_unless(c != NULL);
- int rc = 0;
-
- lsm_pool *test_pool = get_test_pool(c);
- lsm_fs *nfs = NULL;
- char *job = NULL;
-
- fail_unless(NULL != test_pool);
-
- if( test_pool ) {
- rc = lsm_fs_create(c, test_pool, "C_unit_test_nfs_export", 50000000,
- &nfs, &job, LSM_CLIENT_FLAG_RSVD);
-
- if( LSM_ERR_JOB_STARTED == rc ) {
- nfs = wait_for_job_fs(c, &job);
- } else {
- fail_unless(LSM_ERR_OK == rc, "RC = %d", rc);
- }
-
- fail_unless(nfs != NULL);
- lsm_nfs_export **exports = NULL;
- uint32_t count = 0;
-
- G(rc, lsm_pool_record_free, test_pool);
- test_pool = NULL;
-
-
- if( nfs ) {
- G(rc, lsm_nfs_list, c, NULL, NULL, &exports, &count, LSM_CLIENT_FLAG_RSVD);
- fail_unless(count == 0);
- fail_unless(NULL == exports);
-
-
- lsm_string_list *access = lsm_string_list_alloc(1);
- fail_unless(NULL != access);
-
- G(rc, lsm_string_list_elem_set, access, 0, "192.168.2.29");
-
- lsm_nfs_export *e = NULL;
-
- G(rc, lsm_nfs_export_fs, c, lsm_fs_id_get(nfs), NULL, access,
- access, NULL, ANON_UID_GID_NA,
- ANON_UID_GID_NA, NULL, NULL, &e,
- LSM_CLIENT_FLAG_RSVD);
-
- G(rc, lsm_nfs_export_record_free, e);
- e=NULL;
-
- G(rc, lsm_string_list_free, access);
- access = NULL;
-
- G(rc, lsm_nfs_list, c, NULL, NULL, &exports, &count, LSM_CLIENT_FLAG_RSVD);
- fail_unless( exports != NULL);
- fail_unless( count == 1 );
-
- if( count ) {
- G(rc, lsm_nfs_export_delete, c, exports[0], LSM_CLIENT_FLAG_RSVD);
- G(rc, lsm_nfs_export_record_array_free, exports, count);
- exports = NULL;
-
- G(rc, lsm_nfs_list, c, NULL, NULL, &exports, &count,
- LSM_CLIENT_FLAG_RSVD);
-
- fail_unless(count == 0);
- fail_unless(NULL == exports);
- }
-
-
- G(rc, lsm_fs_record_free, nfs);
- nfs = NULL;
- }
- }
-}
-END_TEST
-
-struct bad_record
-{
- uint32_t m;
-};
-
-
-START_TEST(test_volume_methods)
-{
- lsm_volume *v = NULL;
- lsm_pool *test_pool = NULL;
- char *job = NULL;
-
- int rc = 0;
-
- fail_unless(c != NULL);
-
- test_pool = get_test_pool(c);
-
- if( test_pool ) {
- rc = lsm_volume_create(c, test_pool, "lsm_volume_method_test",
- 10000000, LSM_VOLUME_PROVISION_DEFAULT,
- &v, &job, LSM_CLIENT_FLAG_RSVD);
-
- if( LSM_ERR_JOB_STARTED == rc ) {
- v = wait_for_job_vol(c, &job);
- } else {
- fail_unless(LSM_ERR_OK == rc, "rc %d", rc);
- }
-
- if ( v ) {
- fail_unless( strcmp(lsm_volume_pool_id_get(v),
- lsm_pool_id_get(test_pool)) == 0 );
-
- rc = lsm_volume_delete(c, v, &job, LSM_CLIENT_FLAG_RSVD);
- if( LSM_ERR_JOB_STARTED == rc ) {
- wait_for_job(c, &job);
- } else {
- fail_unless(LSM_ERR_OK == rc, "rc %d", rc);
- }
-
- G(rc, lsm_volume_record_free, v);
- v = NULL;
- }
-
- G(rc, lsm_pool_record_free, test_pool);
- test_pool = NULL;
- }
-}
-END_TEST
-
-START_TEST(test_invalid_input)
-{
- fail_unless(c != NULL);
- int rc = 0;
-
- struct bad_record bad;
- bad.m = 0xA0A0A0A0;
-
- printf("Testing arguments\n");
-
- lsm_pool *test_pool = get_test_pool(c);
-
- lsm_connect *test_connect = NULL;
- lsm_error_ptr test_error = NULL;
-
- rc = lsm_connect_password(NULL, NULL, NULL, 20000, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc %d", rc);
-
- rc = lsm_connect_password("INVALID_URI:\\yep", NULL, &test_connect, 20000,
- &test_error, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc %d", rc);
-
-
- rc = lsm_connect_close((lsm_connect *)&bad, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- rc = lsm_connect_close((lsm_connect *)NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
-
-
- rc = lsm_job_status_get(c, NULL, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- char *job = NULL;
- rc = lsm_job_status_get(c, job, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- lsm_job_status status;
-
-
- rc = lsm_job_status_get(c, job, &status, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- uint8_t percent_complete;
- rc = lsm_job_status_get(c, "NO_SUCH_JOB", &status, &percent_complete, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_NOT_FOUND_JOB == rc, "rc %d", rc);
-
- /* lsmJobStatusVolumeGet */
- lsm_volume *vol = NULL;
- rc = lsm_job_status_volume_get(c, NULL, NULL, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- rc = lsm_job_status_volume_get(c, NULL, NULL, NULL, &vol, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- rc = lsm_job_status_volume_get(c, job, NULL, NULL, &vol, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- rc = lsm_job_status_volume_get(c, job, &status, NULL, &vol, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- rc = lsm_job_status_volume_get(c, "NO_SUCH_JOB", &status, &percent_complete, &vol, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_NOT_FOUND_JOB == rc, "rc %d", rc);
-
- /* lsmJobStatusFsGet */
- lsm_fs *fs = NULL;
-
- rc = lsm_job_status_fs_get(c, NULL, NULL, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- rc = lsm_job_status_fs_get(c, NULL, NULL, NULL, &fs, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- rc = lsm_job_status_fs_get(c, job, NULL, NULL, &fs, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- rc = lsm_job_status_fs_get(c, job, &status, NULL, &fs, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- rc = lsm_job_status_fs_get(c, "NO_SUCH_JOB", &status, &percent_complete, &fs, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_NOT_FOUND_JOB == rc, "rc %d", rc);
-
- /* lsmJobStatusFsGet */
- lsm_fs_ss *ss = (lsm_fs_ss *)&bad;
-
- rc = lsm_job_status_ss_get(c, NULL, NULL, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- rc = lsm_job_status_ss_get(c, NULL, NULL, NULL, &ss, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- ss = NULL;
-
- rc = lsm_job_status_ss_get(c, job, NULL, NULL, &ss, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- rc = lsm_job_status_ss_get(c, job, &status, NULL, &ss, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- rc = lsm_job_status_ss_get(c, "NO_SUCH_JOB", &status, &percent_complete, &ss, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_NOT_FOUND_JOB == rc, "rc %d", rc);
-
-
- /* lsmJobFree */
- char *bogus_job = strdup("NO_SUCH_JOB");
- rc = lsm_job_free(c, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- rc = lsm_job_free(c, &bogus_job, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_NOT_FOUND_JOB == rc, "rc %d", rc);
-
- fail_unless(bogus_job != NULL, "Expected bogus job to != NULL!");
- free(bogus_job);
-
-
- /* lsm_disk_list */
- uint32_t count = 0;
- lsm_disk **disks = NULL;
-
- rc = lsm_disk_list(c, NULL, NULL, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d, rc");
-
- rc = lsm_disk_list(c, "bogus_key", NULL, &disks, &count, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d, rc");
-
- rc = lsm_disk_list(c, "bogus_key", "nope", &disks, &count, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_UNSUPPORTED_SEARCH_KEY == rc, "rc %d, rc");
-
- /* lsmPoolList */
- rc = lsm_pool_list(c, NULL, NULL, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- lsm_pool **pools = NULL;
- rc = lsm_pool_list(c, NULL, NULL, &pools, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- rc = lsm_pool_list(c, NULL, NULL, NULL, &count, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- pools = (lsm_pool **)&bad;
- rc = lsm_pool_list(c, NULL, NULL, &pools, &count, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- pools = NULL;
- rc = lsm_pool_list(c, "bogus_key", "nope", &pools, &count, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_UNSUPPORTED_SEARCH_KEY == rc, "rc %d", rc);
-
- rc = lsm_pool_list(c, "bogus_key", NULL, &pools, &count, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- /* lsmVolumeList */
- rc = lsm_volume_list(c, NULL, NULL, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- lsm_volume **vols = NULL;
- rc = lsm_volume_list(c, NULL, NULL, &vols, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- rc = lsm_volume_list(c, NULL, NULL, NULL, &count, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- vols = (lsm_volume **)&bad;
- rc = lsm_volume_list(c, NULL, NULL, &vols, &count, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- vols = NULL;
- rc = lsm_volume_list(c, "bogus_key", "nope", &vols, &count, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_UNSUPPORTED_SEARCH_KEY == rc, "rc %d", rc);
-
- rc = lsm_volume_list(c, "bogus_key", NULL, &vols, &count, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- /* lsmVolumeCreate */
- lsm_volume *new_vol = NULL;
- job = NULL;
-
- rc = lsm_volume_create(c, NULL, NULL, 0, 0, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- rc = lsm_volume_create(c, (lsm_pool *)&bad, "BAD_POOL", 10000000,
- LSM_VOLUME_PROVISION_DEFAULT, &new_vol, &job, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- rc = lsm_volume_create(c, test_pool, "", 10000000, LSM_VOLUME_PROVISION_DEFAULT,
- &new_vol, &job, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- rc = lsm_volume_create(c, test_pool, "ARG_TESTING", 10000000, LSM_VOLUME_PROVISION_DEFAULT,
- NULL, &job, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- rc = lsm_volume_create(c, test_pool, "ARG_TESTING", 10000000, LSM_VOLUME_PROVISION_DEFAULT,
- &new_vol, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- job = "NOT_NULL";
- rc = lsm_volume_create(c, test_pool, "ARG_TESTING", 10000000, LSM_VOLUME_PROVISION_DEFAULT,
- &new_vol, &job, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- job = NULL;
- rc = lsm_volume_create(c, test_pool, "ARG_TESTING", 10000000, LSM_VOLUME_PROVISION_DEFAULT,
- &new_vol, &job, LSM_CLIENT_FLAG_RSVD);
-
- if( LSM_ERR_JOB_STARTED == rc ) {
- new_vol = wait_for_job_vol(c, &job);
- } else {
- fail_unless(LSM_ERR_OK == rc, "rc %d", rc);
- }
-
- /* lsmVolumeResize */
- rc = lsm_volume_resize(c, NULL, 0, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
-
- lsm_volume *resized = (lsm_volume *)&bad;
- rc = lsm_volume_resize(c, new_vol, 20000000, &resized, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- resized = NULL;
- rc = lsm_volume_resize(c, new_vol, 20000000, &resized, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- rc = lsm_volume_resize(c, new_vol, lsm_volume_number_of_blocks_get(new_vol) *
- lsm_volume_block_size_get(new_vol),
- &resized, &job, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_NO_STATE_CHANGE == rc, "rc = %d", rc);
-
- rc = lsm_volume_resize(c, new_vol, 20000000, &resized, &job, LSM_CLIENT_FLAG_RSVD);
-
- if( LSM_ERR_JOB_STARTED == rc ) {
- resized = wait_for_job_vol(c, &job);
- } else {
- fail_unless(LSM_ERR_OK == rc, "rc %d", rc);
- }
-
- /* lsmVolumeDelete */
- rc = lsm_volume_delete(c, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- rc = lsm_volume_delete(c, resized, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc %d", rc);
-
- rc = lsm_volume_delete(c, resized, &job, LSM_CLIENT_FLAG_RSVD);
- if( LSM_ERR_JOB_STARTED == rc ) {
- wait_for_job(c, &job);
- } else {
- fail_unless(LSM_ERR_OK == rc, "rc %d", rc);
- }
-
- /* lsmStorageCapabilities * */
- lsm_system **sys = NULL;
- uint32_t num_systems = 0;
- rc = lsm_system_list(c, &sys, &num_systems, LSM_CLIENT_FLAG_RSVD );
-
- fail_unless(LSM_ERR_OK == rc, "rc %d", rc);
- fail_unless( sys != NULL);
- fail_unless( num_systems >= 1, "num_systems %d", num_systems);
-
-
- rc = lsm_capabilities(c, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT, "rc %d", rc);
-
- if( num_systems ) {
- rc = lsm_capabilities(c, sys[0], NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT, "rc %d", rc);
- }
-
- /* lsmVolumeReplicate */
- lsm_volume *cloned = NULL;
- rc = lsm_volume_replicate(c, (lsm_pool *)&bad, 0, NULL, NULL, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_volume_replicate(c, test_pool, LSM_VOLUME_REPLICATE_CLONE, NULL,
- "cloned", &cloned, &job, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_volume_replicate(c, test_pool, LSM_VOLUME_REPLICATE_CLONE, new_vol,
- "", &cloned, &job, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_volume_replicate(c, test_pool, LSM_VOLUME_REPLICATE_CLONE, new_vol,
- "cloned", NULL, &job, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_volume_replicate(c, test_pool, LSM_VOLUME_REPLICATE_CLONE, new_vol,
- "cloned", &cloned, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
-
- /* lsmVolumeReplicateRangeBlockSize */
- rc = lsm_volume_replicate_range_block_size(c, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- /* lsmVolumeReplicateRange */
- rc = lsm_volume_replicate_range(c, LSM_VOLUME_REPLICATE_CLONE, NULL, NULL,
- NULL, 0, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_volume_replicate_range(c, LSM_VOLUME_REPLICATE_CLONE, new_vol,
- NULL, NULL, 0, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_volume_replicate_range(c, LSM_VOLUME_REPLICATE_CLONE, new_vol, new_vol,
- NULL, 1, &job, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
-
- rc = lsm_volume_enable(c, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_volume_disable(c, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
-
- /* lsmAccessGroupCreate */
- lsm_access_group *ag = NULL;
- lsm_system *system = NULL;
- system = get_system(c);
-
- rc = lsm_access_group_create(c, NULL, NULL, 0, system, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_access_group_create(c, "my_group", ISCSI_HOST[0], LSM_ACCESS_GROUP_INIT_TYPE_OTHER,
- NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
-
- rc = lsm_access_group_create(c, "my_group", ISCSI_HOST[0], LSM_ACCESS_GROUP_INIT_TYPE_OTHER,
- system, &ag, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_OK, "rc = %d", rc);
- fail_unless(ag != NULL);
-
-
- /* lsmAccessGroupDel */
- rc = lsm_access_group_delete(c, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- /* lsmAccessGroupInitiatorAdd */
- rc = lsm_access_group_initiator_add(c, NULL, NULL, 0, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
-
- rc = lsm_access_group_initiator_delete(c, NULL, NULL, 0, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_access_group_initiator_delete(c, ag, NULL,
- LSM_ACCESS_GROUP_INIT_TYPE_OTHER, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
-
-
- rc = lsm_volume_mask(c, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_volume_mask(c, ag, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_volume_unmask(c, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_volume_unmask(c, ag, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
-
- /* lsmVolumesAccessibleByAccessGroup */
- rc = lsm_volumes_accessible_by_access_group(c, NULL, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_volumes_accessible_by_access_group(c, ag, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- /* lsmAccessGroupsGrantedToVolume */
- rc = lsm_access_groups_granted_to_volume(c, NULL, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_access_groups_granted_to_volume(c, new_vol, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- /* lsmVolumeChildDependency */
- rc = lsm_volume_child_dependency(c, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_volume_child_dependency(c, new_vol, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- /*lsmVolumeChildDependencyDelete*/
- rc = lsm_volume_child_dependency_delete(c, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_volume_child_dependency_delete(c, new_vol, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- /* lsmSystemList */
- lsm_system **systems = NULL;
- rc = lsm_system_list(c, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
-
- rc = lsm_system_list(c, &systems, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- /* lsmFsList */
- rc = lsm_fs_list(c, NULL, NULL, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- lsm_fs **fsl = NULL;
- rc = lsm_fs_list(c, NULL, NULL, &fsl, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_fs_list(c, "bogus_key", "nope", &fsl, &count, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_UNSUPPORTED_SEARCH_KEY, "rc = %d", rc);
-
- /*lsmFsCreate*/
- rc = lsm_fs_create(c, NULL, NULL, 0, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_fs_create(c, test_pool, NULL, 0, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- lsm_fs *arg_fs = NULL;
- rc = lsm_fs_create(c, test_pool, "argument_fs", 10000000, &arg_fs, &job,
- LSM_CLIENT_FLAG_RSVD);
-
- if( LSM_ERR_JOB_STARTED == rc ) {
- arg_fs = wait_for_job_fs(c, &job);
- } else {
- fail_unless(LSM_ERR_OK == rc, "rc = %d", rc);
- }
-
- /* lsmFsDelete */
- rc = lsm_fs_delete(c, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_fs_delete(c, arg_fs, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- /* lsmFsResize */
- rc = lsm_fs_resize(c, NULL, 0, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_fs_resize(c, arg_fs, 0, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- /* lsmFsClone */
- rc = lsm_fs_clone(c, NULL, NULL, NULL, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_fs_clone(c, arg_fs, NULL, NULL, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
-
- /*lsmFsFileClone*/
- rc = lsm_fs_file_clone(c, NULL, NULL, NULL, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_fs_file_clone(c, arg_fs, NULL, NULL, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
-
- rc = lsm_fs_child_dependency(c, NULL, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- lsm_string_list *badf = (lsm_string_list *)&bad;
- rc = lsm_fs_child_dependency(c, arg_fs, badf, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- lsm_string_list *f = lsm_string_list_alloc(1);
- rc = lsm_fs_child_dependency(c, arg_fs, f, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- /*lsmFsChildDependencyDelete*/
- rc = lsm_fs_child_dependency_delete(c, NULL, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_fs_child_dependency_delete(c, arg_fs, badf, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_fs_child_dependency_delete(c, arg_fs, f, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
-
-
- rc = lsm_fs_ss_list(c, NULL, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
-
- rc = lsm_fs_ss_list(c, arg_fs, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
-
- rc = lsm_fs_ss_create(c, NULL, NULL, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_fs_ss_create(c, arg_fs, NULL, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- lsm_fs_ss *arg_ss = NULL;
-
- rc = lsm_fs_ss_create(c, arg_fs, "arg_snapshot", &arg_ss, &job,
- LSM_CLIENT_FLAG_RSVD);
-
- if( LSM_ERR_JOB_STARTED == rc ) {
- arg_ss = wait_for_job_ss(c, &job);
- } else {
- fail_unless(rc == LSM_ERR_OK, "rc = %d", rc);
- }
-
- rc = lsm_fs_ss_delete(c, NULL, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_fs_ss_delete(c, arg_fs, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_fs_ss_delete(c, arg_fs, arg_ss, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
-
- rc = lsm_fs_ss_restore(c, NULL, NULL, NULL, NULL, 0, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_fs_ss_restore(c, arg_fs, NULL, NULL, NULL, 0, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_fs_ss_restore(c, arg_fs, arg_ss, badf, NULL, 0, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_fs_ss_restore(c, arg_fs, arg_ss, badf, badf, 0, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_fs_ss_restore(c, arg_fs, arg_ss, f, f, 0, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_nfs_list(c, NULL, NULL, NULL, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
-
- rc = lsm_access_group_record_free(ag);
- ag = NULL;
- fail_unless(LSM_ERR_OK == rc, "%d", rc);
-
- rc = lsm_fs_ss_record_free(arg_ss);
- fail_unless(LSM_ERR_OK == rc, "%d", rc);
- arg_ss = NULL;
-
- rc = lsm_fs_record_free(arg_fs);
- fail_unless(LSM_ERR_OK == rc, "%d", rc);
- arg_fs = NULL;
-
- rc = lsm_nfs_export_fs(c, NULL, NULL, NULL, NULL, NULL, 0,0,NULL, NULL, NULL,
- LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_nfs_export_fs(c, NULL, NULL, badf, NULL, NULL, 0,0,NULL, NULL, NULL,
- LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_nfs_export_fs(c, NULL, NULL, f, badf, NULL, 0,0,NULL, NULL, NULL,
- LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_nfs_export_fs(c, NULL, NULL, f, f, badf, 0,0,NULL, NULL, NULL,
- LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
-
- rc = lsm_nfs_export_fs(c, NULL, NULL, f, f, f, 0,0, NULL, NULL, NULL,
- LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
- rc = lsm_nfs_export_delete(c, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT, "rc = %d", rc);
-
-
- rc = lsm_volume_record_free(new_vol);
- new_vol = NULL;
- fail_unless(rc == LSM_ERR_OK, "rc = %d", rc);
-
- rc = lsm_volume_record_free(resized);
- resized = NULL;
- fail_unless(rc == LSM_ERR_OK, "rc = %d", rc);
-
- rc = lsm_system_record_array_free(sys, num_systems);
- fail_unless(LSM_ERR_OK == rc, "%d", rc);
-
- rc = lsm_pool_record_free(test_pool);
- fail_unless(LSM_ERR_OK == rc, "%d", rc);
-
- G(rc, lsm_system_record_free, system );
- system = NULL;
- G(rc, lsm_string_list_free, f);
- f = NULL;
-
-}
-END_TEST
-
-static void cap_test( lsm_storage_capabilities *cap, lsm_capability_type t)
-{
- lsm_capability_value_type supported;
- supported = lsm_capability_get(cap, t);
-
- fail_unless ( lsm_capability_supported(cap, t) != 0,
- "lsm_capability_supported returned unsupported");
- fail_unless( supported == LSM_CAP_SUPPORTED,
- "supported = %d for %d", supported, t);
-}
-
-START_TEST(test_capabilities)
-{
- int rc = 0;
-
- lsm_system **sys = NULL;
- uint32_t sys_count = 0;
- lsm_storage_capabilities *cap = NULL;
-
- G(rc, lsm_system_list, c, &sys, &sys_count, LSM_CLIENT_FLAG_RSVD);
- fail_unless( sys_count >= 1, "count = %d", sys_count);
-
- if( sys_count > 0 ) {
- G(rc, lsm_capabilities, c, sys[0], &cap, LSM_CLIENT_FLAG_RSVD);
-
- if( LSM_ERR_OK == rc ) {
- cap_test(cap, LSM_CAP_VOLUMES);
- cap_test(cap, LSM_CAP_VOLUME_CREATE);
- cap_test(cap, LSM_CAP_VOLUME_RESIZE);
- cap_test(cap, LSM_CAP_VOLUME_REPLICATE);
- cap_test(cap, LSM_CAP_VOLUME_REPLICATE_CLONE);
- cap_test(cap, LSM_CAP_VOLUME_REPLICATE_COPY);
- cap_test(cap, LSM_CAP_VOLUME_REPLICATE_MIRROR_ASYNC);
- cap_test(cap, LSM_CAP_VOLUME_REPLICATE_MIRROR_SYNC);
- cap_test(cap, LSM_CAP_VOLUME_COPY_RANGE_BLOCK_SIZE);
- cap_test(cap, LSM_CAP_VOLUME_COPY_RANGE);
- cap_test(cap, LSM_CAP_VOLUME_COPY_RANGE_CLONE);
- cap_test(cap, LSM_CAP_VOLUME_COPY_RANGE_COPY);
- cap_test(cap, LSM_CAP_VOLUME_DELETE);
- cap_test(cap, LSM_CAP_VOLUME_ENABLE);
- cap_test(cap, LSM_CAP_VOLUME_DISABLE);
- cap_test(cap, LSM_CAP_VOLUME_MASK);
- cap_test(cap, LSM_CAP_VOLUME_UNMASK);
- cap_test(cap, LSM_CAP_ACCESS_GROUPS);
- cap_test(cap, LSM_CAP_ACCESS_GROUP_CREATE_WWPN);
- cap_test(cap, LSM_CAP_ACCESS_GROUP_INITIATOR_ADD_WWPN);
- cap_test(cap, LSM_CAP_ACCESS_GROUP_INITIATOR_DELETE);
- cap_test(cap, LSM_CAP_VOLUMES_ACCESSIBLE_BY_ACCESS_GROUP);
- cap_test(cap, LSM_CAP_ACCESS_GROUPS_GRANTED_TO_VOLUME);
- cap_test(cap, LSM_CAP_VOLUME_CHILD_DEPENDENCY);
- cap_test(cap, LSM_CAP_VOLUME_CHILD_DEPENDENCY_RM);
- cap_test(cap, LSM_CAP_FS);
- cap_test(cap, LSM_CAP_FS_DELETE);
- cap_test(cap, LSM_CAP_FS_RESIZE);
- cap_test(cap, LSM_CAP_FS_CREATE);
- cap_test(cap, LSM_CAP_FS_CLONE);
- cap_test(cap, LSM_CAP_FILE_CLONE);
- cap_test(cap, LSM_CAP_FS_SNAPSHOTS);
- cap_test(cap, LSM_CAP_FS_SNAPSHOT_CREATE);
- cap_test(cap, LSM_CAP_FS_SNAPSHOT_DELETE);
- cap_test(cap, LSM_CAP_FS_SNAPSHOT_RESTORE);
- cap_test(cap, LSM_CAP_FS_SNAPSHOT_RESTORE_SPECIFIC_FILES);
- cap_test(cap, LSM_CAP_FS_CHILD_DEPENDENCY);
- cap_test(cap, LSM_CAP_FS_CHILD_DEPENDENCY_RM);
- cap_test(cap, LSM_CAP_FS_CHILD_DEPENDENCY_RM_SPECIFIC_FILES );
- cap_test(cap, LSM_CAP_EXPORT_AUTH);
- cap_test(cap, LSM_CAP_EXPORTS);
- cap_test(cap, LSM_CAP_EXPORT_FS);
- cap_test(cap, LSM_CAP_EXPORT_REMOVE);
-
-
- G(rc, lsm_capability_record_free, cap);
- cap = NULL;
- }
-
- G(rc, lsm_system_record_array_free, sys, sys_count);
- }
-}
-END_TEST
-
-START_TEST(test_iscsi_auth_in)
-{
- lsm_access_group *group = NULL;
- lsm_system *system = NULL;
- int rc = 0;
-
- system = get_system(c);
- printf("get_system() OK\n");
-
- G(rc, lsm_access_group_create, c, "ISCSI_AUTH", ISCSI_HOST[0],
- LSM_ACCESS_GROUP_INIT_TYPE_ISCSI_IQN, system, &group,
- LSM_CLIENT_FLAG_RSVD);
- printf("lsm_access_group_create() OK\n");
-
- fail_unless(LSM_ERR_OK == rc, "rc = %d", rc);
- G(rc, lsm_system_record_free, system);
- printf("lsm_system_record_free() OK\n");
-
- system = NULL;
-
- if( LSM_ERR_OK == rc ) {
-
- rc = lsm_iscsi_chap_auth(
- c, ISCSI_HOST[0], "username", "secret", NULL, NULL,
- LSM_CLIENT_FLAG_RSVD);
-
- fail_unless(LSM_ERR_OK == rc, "rc = %d", rc);
-
- rc = lsm_access_group_delete(c, group, LSM_CLIENT_FLAG_RSVD);
-
- fail_unless(LSM_ERR_OK == rc );
-
- lsm_access_group_record_free(group);
- group = NULL;
- }
-}
-END_TEST
-
-START_TEST(test_plugin_info)
-{
- char *desc = NULL;
- char *version = NULL;
- int rc = 0;
-
- G(rc, lsm_plugin_info_get, c, &desc, &version, LSM_CLIENT_FLAG_RSVD);
-
- if( LSM_ERR_OK == rc ) {
- printf("Desc: (%s), Version: (%s)\n", desc, version);
- free(desc);
- free(version);
- }
-
- rc = lsm_plugin_info_get(NULL, &desc, &version, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc = %d", rc);
-
- rc = lsm_plugin_info_get(c, NULL, &version, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc = %d", rc);
-
- rc = lsm_plugin_info_get(c, &desc, NULL, LSM_CLIENT_FLAG_RSVD);
- fail_unless(LSM_ERR_INVALID_ARGUMENT == rc, "rc = %d", rc);
-}
-END_TEST
-
-START_TEST(test_get_available_plugins)
-{
- int i = 0;
- int num = 0;
- lsm_string_list *plugins = NULL;
- int rc = 0;
-
- G(rc, lsm_available_plugins_list, ":", &plugins, 0);
-
- num = lsm_string_list_size(plugins);
- for( i = 0; i < num; i++) {
- const char *info = lsm_string_list_elem_get(plugins, i);
- fail_unless(strlen(info) > 0);
- printf("%s\n", info);
- }
-
- G(rc, lsm_string_list_free, plugins);
- plugins = NULL;
-}
-END_TEST
-
-START_TEST(test_error_reporting)
-{
- uint8_t d[4] = {0x00, 0x01, 0x02, 0x03};
- char msg[] = "Testing Errors";
- char exception[] = "Exception text";
- char debug_msg[] = "Debug message";
- void *debug_data = NULL;
- uint32_t debug_size = 0;
-
- lsm_error_ptr e = lsm_error_create(LSM_ERR_LIB_BUG, msg,
- exception, debug_msg,
- d, sizeof(d));
-
- fail_unless(e != NULL);
-
- if( e ) {
- fail_unless(LSM_ERR_LIB_BUG == lsm_error_number_get(e));
- fail_unless(strcmp(msg, lsm_error_message_get(e)) == 0);
- fail_unless(strcmp(exception, lsm_error_exception_get(e)) == 0);
- fail_unless(strcmp(debug_msg, lsm_error_debug_get(e)) == 0);
- debug_data = lsm_error_debug_data_get(e, &debug_size);
- fail_unless(debug_data != NULL);
- fail_unless(debug_size == sizeof(d));
- fail_unless(memcmp(d, debug_data, debug_size) == 0);
- fail_unless( LSM_ERR_OK == lsm_error_free(e) );
- }
-}
-END_TEST
-
-START_TEST(test_capability)
-{
- int rc;
- int i;
- lsm_capability_type expected_present[] = {
- LSM_CAP_VOLUMES,
- LSM_CAP_VOLUME_CREATE,
- LSM_CAP_VOLUME_RESIZE,
- LSM_CAP_VOLUME_REPLICATE,
- LSM_CAP_VOLUME_REPLICATE_CLONE,
- LSM_CAP_VOLUME_REPLICATE_COPY,
- LSM_CAP_VOLUME_REPLICATE_MIRROR_ASYNC,
- LSM_CAP_VOLUME_REPLICATE_MIRROR_SYNC,
- LSM_CAP_VOLUME_COPY_RANGE_BLOCK_SIZE,
- LSM_CAP_VOLUME_COPY_RANGE,
- LSM_CAP_VOLUME_COPY_RANGE_CLONE,
- LSM_CAP_VOLUME_COPY_RANGE_COPY,
- LSM_CAP_VOLUME_DELETE,
- LSM_CAP_VOLUME_ENABLE,
- LSM_CAP_VOLUME_DISABLE,
- LSM_CAP_VOLUME_MASK,
- LSM_CAP_VOLUME_UNMASK,
- LSM_CAP_ACCESS_GROUPS,
- LSM_CAP_ACCESS_GROUP_CREATE_WWPN,
- LSM_CAP_ACCESS_GROUP_INITIATOR_ADD_WWPN,
- LSM_CAP_ACCESS_GROUP_INITIATOR_DELETE,
- LSM_CAP_VOLUMES_ACCESSIBLE_BY_ACCESS_GROUP,
- LSM_CAP_ACCESS_GROUPS_GRANTED_TO_VOLUME,
- LSM_CAP_VOLUME_CHILD_DEPENDENCY,
- LSM_CAP_VOLUME_CHILD_DEPENDENCY_RM,
- LSM_CAP_FS,
- LSM_CAP_FS_DELETE,
- LSM_CAP_FS_RESIZE,
- LSM_CAP_FS_CREATE,
- LSM_CAP_FS_CLONE,
- LSM_CAP_FILE_CLONE,
- LSM_CAP_FS_SNAPSHOTS,
- LSM_CAP_FS_SNAPSHOT_CREATE,
- LSM_CAP_FS_SNAPSHOT_DELETE,
- LSM_CAP_FS_SNAPSHOT_RESTORE,
- LSM_CAP_FS_SNAPSHOT_RESTORE_SPECIFIC_FILES,
- LSM_CAP_FS_CHILD_DEPENDENCY,
- LSM_CAP_FS_CHILD_DEPENDENCY_RM,
- LSM_CAP_FS_CHILD_DEPENDENCY_RM_SPECIFIC_FILES,
- LSM_CAP_EXPORT_AUTH,
- LSM_CAP_EXPORTS,
- LSM_CAP_EXPORT_FS,
- LSM_CAP_EXPORT_REMOVE};
-
- lsm_capability_type expected_absent[] = {
- };
-
-
- lsm_storage_capabilities *cap = lsm_capability_record_alloc(NULL);
-
- fail_unless(cap != NULL);
-
- if( cap ) {
- G(rc, lsm_capability_set_n, cap, LSM_CAP_SUPPORTED,
- LSM_CAP_VOLUMES,
- LSM_CAP_VOLUME_CREATE,
- LSM_CAP_VOLUME_RESIZE,
- LSM_CAP_VOLUME_REPLICATE,
- LSM_CAP_VOLUME_REPLICATE_CLONE,
- LSM_CAP_VOLUME_REPLICATE_COPY,
- LSM_CAP_VOLUME_REPLICATE_MIRROR_ASYNC,
- LSM_CAP_VOLUME_REPLICATE_MIRROR_SYNC,
- LSM_CAP_VOLUME_COPY_RANGE_BLOCK_SIZE,
- LSM_CAP_VOLUME_COPY_RANGE,
- LSM_CAP_VOLUME_COPY_RANGE_CLONE,
- LSM_CAP_VOLUME_COPY_RANGE_COPY,
- LSM_CAP_VOLUME_DELETE,
- LSM_CAP_VOLUME_ENABLE,
- LSM_CAP_VOLUME_DISABLE,
- LSM_CAP_VOLUME_MASK,
- LSM_CAP_VOLUME_UNMASK,
- LSM_CAP_ACCESS_GROUPS,
- LSM_CAP_ACCESS_GROUP_CREATE_WWPN,
- LSM_CAP_ACCESS_GROUP_INITIATOR_ADD_WWPN,
- LSM_CAP_ACCESS_GROUP_INITIATOR_DELETE,
- LSM_CAP_VOLUMES_ACCESSIBLE_BY_ACCESS_GROUP,
- LSM_CAP_ACCESS_GROUPS_GRANTED_TO_VOLUME,
- LSM_CAP_VOLUME_CHILD_DEPENDENCY,
- LSM_CAP_VOLUME_CHILD_DEPENDENCY_RM,
- LSM_CAP_FS,
- LSM_CAP_FS_DELETE,
- LSM_CAP_FS_RESIZE,
- LSM_CAP_FS_CREATE,
- LSM_CAP_FS_CLONE,
- LSM_CAP_FILE_CLONE,
- LSM_CAP_FS_SNAPSHOTS,
- LSM_CAP_FS_SNAPSHOT_CREATE,
- LSM_CAP_FS_SNAPSHOT_DELETE,
- LSM_CAP_FS_SNAPSHOT_RESTORE,
- LSM_CAP_FS_SNAPSHOT_RESTORE_SPECIFIC_FILES,
- LSM_CAP_FS_CHILD_DEPENDENCY,
- LSM_CAP_FS_CHILD_DEPENDENCY_RM,
- LSM_CAP_FS_CHILD_DEPENDENCY_RM_SPECIFIC_FILES,
- LSM_CAP_EXPORT_AUTH,
- LSM_CAP_EXPORTS,
- LSM_CAP_EXPORT_FS,
- LSM_CAP_EXPORT_REMOVE,
- -1
- );
-
- G(rc, lsm_capability_set, cap, LSM_CAP_EXPORTS,
- LSM_CAP_SUPPORTED);
-
- for( i = 0;
- i < sizeof(expected_present)/sizeof(expected_present[0]);
- ++i) {
-
- fail_unless( lsm_capability_get(cap, expected_present[i]) ==
- LSM_CAP_SUPPORTED);
- }
-
- for( i = 0;
- i < sizeof(expected_absent)/sizeof(expected_absent[0]);
- ++i) {
-
- fail_unless( lsm_capability_get(cap, expected_absent[i]) ==
- LSM_CAP_UNSUPPORTED);
- }
-
-
- G(rc, lsm_capability_record_free, cap);
- }
-
-}
-END_TEST
-
-
-START_TEST(test_nfs_export_funcs)
-{
- const char id[] = "export_unique_id";
- const char fs_id[] = "fs_unique_id";
- const char export_path[] = "/mnt/foo";
- const char auth[] = "simple";
- uint64_t anonuid = 1021;
- uint64_t anongid = 1000;
- const char options[] = "vendor_specific_option";
- const char p_data[] = "plug-in private data";
- char rstring[33];
- int rc = 0;
-
-
- lsm_string_list *root = lsm_string_list_alloc(0);
- G(rc, lsm_string_list_append, root, "192.168.100.2");
- G(rc, lsm_string_list_append, root, "192.168.100.3");
-
- lsm_string_list *rw = lsm_string_list_alloc(0);
- G(rc, lsm_string_list_append, rw, "192.168.100.2");
- G(rc, lsm_string_list_append, rw, "192.168.100.3");
-
- lsm_string_list *rand = lsm_string_list_alloc(0);
-
- lsm_string_list *ro = lsm_string_list_alloc(0);
- G(rc, lsm_string_list_append, ro, "*");
-
-
- lsm_nfs_export *export = lsm_nfs_export_record_alloc(id, fs_id, export_path,
- auth, root, rw, ro, anonuid, anongid, options, p_data);
-
- lsm_nfs_export *copy = lsm_nfs_export_record_copy(export);
-
-
- fail_unless( strcmp(lsm_nfs_export_id_get(copy), id) == 0 );
- fail_unless( strcmp(lsm_nfs_export_fs_id_get(copy), fs_id) == 0);
- fail_unless( strcmp(lsm_nfs_export_export_path_get(copy), export_path) == 0);
- fail_unless( strcmp(lsm_nfs_export_auth_type_get(copy), auth) == 0);
- fail_unless( strcmp(lsm_nfs_export_options_get(copy), options) == 0);
- fail_unless( lsm_nfs_export_anon_uid_get(copy) == anonuid);
- fail_unless( lsm_nfs_export_anon_gid_get(copy) == anongid);
-
- fail_unless(compare_string_lists(lsm_nfs_export_root_get(export), lsm_nfs_export_root_get(copy)) == 0);
- fail_unless(compare_string_lists(lsm_nfs_export_read_write_get(export), lsm_nfs_export_read_write_get(copy)) == 0);
- fail_unless(compare_string_lists(lsm_nfs_export_read_only_get(export), lsm_nfs_export_read_only_get(copy)) == 0);
-
- G(rc, lsm_nfs_export_record_free, copy);
-
-
- generate_random(rstring, sizeof(rstring));
- G(rc, lsm_nfs_export_id_set, export, rstring);
- fail_unless( strcmp(lsm_nfs_export_id_get(export), rstring) == 0 );
-
- generate_random(rstring, sizeof(rstring));
- G(rc, lsm_nfs_export_fs_id_set, export, rstring);
- fail_unless( strcmp(lsm_nfs_export_fs_id_get(export), rstring) == 0 );
-
- generate_random(rstring, sizeof(rstring));
- G(rc, lsm_nfs_export_export_path_set, export, rstring);
- fail_unless( strcmp(lsm_nfs_export_export_path_get(export), rstring) == 0 );
-
- generate_random(rstring, sizeof(rstring));
- G(rc, lsm_nfs_export_auth_type_set, export, rstring);
- fail_unless( strcmp(lsm_nfs_export_auth_type_get(export), rstring) == 0 );
-
- generate_random(rstring, sizeof(rstring));
- G(rc, lsm_nfs_export_options_set, export, rstring);
- fail_unless( strcmp(lsm_nfs_export_options_get(export), rstring) == 0 );
-
- anonuid = anonuid + 700;
- G(rc, lsm_nfs_export_anon_uid_set, export, anonuid);
-
- anongid = anongid + 400;
- G(rc, lsm_nfs_export_anon_gid_set, export, anongid);
-
- fail_unless(lsm_nfs_export_anon_uid_get(export) == anonuid);
- fail_unless(lsm_nfs_export_anon_gid_get(export) == anongid);
-
-
- generate_random(rstring, sizeof(rstring));
- G(rc, lsm_string_list_append, rand, rstring);
- G(rc, lsm_nfs_export_root_set, export, rand);
- fail_unless(compare_string_lists(lsm_nfs_export_root_get(export), rand) == 0);
-
- generate_random(rstring, sizeof(rstring));
- G(rc, lsm_string_list_append, rand, rstring);
- G(rc, lsm_nfs_export_read_write_set, export, rand);
- fail_unless(compare_string_lists(lsm_nfs_export_read_write_get(export), rand) == 0);
-
- generate_random(rstring, sizeof(rstring));
- G(rc, lsm_string_list_append, rand, rstring);
- G(rc, lsm_nfs_export_read_only_set, export, rand);
- fail_unless(compare_string_lists(lsm_nfs_export_read_only_get(export), rand) == 0);
-
-
- G(rc, lsm_nfs_export_record_free, export);
- export = NULL;
- G(rc, lsm_string_list_free, root);
- root = NULL;
- G(rc, lsm_string_list_free, rw);
- rw = NULL;
- G(rc, lsm_string_list_free, ro);
- ro = NULL;
- G(rc, lsm_string_list_free, rand);
- rand = NULL;
-}
-END_TEST
-
-START_TEST(test_uri_parse)
-{
- const char uri_g[] = "sim://***@host:123/path/?namespace=root/uber";
- const char uri_no_path[] = "smis://***@host?namespace=root/emc";
- char *scheme = NULL;
- char *user = NULL;
- char *server = NULL;
- char *path = NULL;
- int port = 0;
- lsm_hash *qp = NULL;
- int rc = 0;
-
- G(rc, lsm_uri_parse, uri_g, &scheme, &user, &server, &port, &path, &qp);
-
- if( LSM_ERR_OK == rc ) {
- fail_unless(strcmp(scheme, "sim") == 0, "%s", scheme);
- fail_unless(strcmp(user, "user") == 0, "%s", user);
- fail_unless(strcmp(server, "host") == 0, "%s", server);
- fail_unless(strcmp(path, "/path/") == 0, "%s", path);
- fail_unless(port == 123, "%d", port);
-
- fail_unless(qp != NULL);
- if( qp ) {
- fail_unless(strcmp("root/uber",
- lsm_hash_string_get(qp, "namespace")) == 0,
- "%s", lsm_hash_string_get(qp, "namespace"));
- }
-
- free(scheme);
- scheme = NULL;
- free(user);
- user = NULL;
- free(server);
- server = NULL;
- free(path);
- path = NULL;
- G(rc, lsm_hash_free, qp);
- qp = NULL;
- }
-
- port = 0;
-
- G(rc, lsm_uri_parse, uri_no_path, &scheme, &user, &server, &port, &path,
- &qp);
-
- if( LSM_ERR_OK == rc ) {
- fail_unless(strcmp(scheme, "smis") == 0, "%s", scheme);
- fail_unless(strcmp(user, "user") == 0, "%s", user);
- fail_unless(strcmp(server, "host") == 0, "%s", server);
- fail_unless(path == NULL, "%s", path);
- fail_unless(port == 0, "%d", port);
-
- fail_unless(qp != NULL);
- if( qp ) {
- fail_unless(strcmp("root/emc",
- lsm_hash_string_get(qp, "namespace")) == 0,
- "%s", lsm_hash_string_get(qp, "namespace"));
- }
-
- free(scheme);
- scheme = NULL;
- free(user);
- user = NULL;
- free(server);
- server = NULL;
- G(rc, lsm_hash_free, qp);
- qp = NULL;
- }
-}
-END_TEST
-
-START_TEST(test_search_pools)
-{
- int rc;
- lsm_pool **pools = NULL;
- uint32_t poolCount = 0;
-
- G(rc, lsm_pool_list, c, NULL, NULL, &pools, &poolCount, LSM_CLIENT_FLAG_RSVD);
-
- if( LSM_ERR_OK == rc && poolCount ) {
- lsm_pool **search_pools = NULL;
- uint32_t search_count = 0;
-
- G(rc, lsm_pool_list, c, "id", lsm_pool_id_get(pools[0]), &search_pools,
- &search_count, LSM_CLIENT_FLAG_RSVD);
-
- fail_unless(search_count == 1, "Expecting 1 pool, got %d", search_count);
-
- G(rc, lsm_pool_record_array_free, search_pools, search_count);
-
- /* Search for non-existent pool*/
- search_pools = NULL;
- search_count = 0;
-
- G(rc, lsm_pool_list, c, "id", "non-existent-id", &search_pools,
- &search_count, LSM_CLIENT_FLAG_RSVD);
- fail_unless(search_count == 0, "Expecting no pools! %d", search_count);
-
- /* Search which results in all pools */
- G(rc, lsm_pool_list, c, "system_id", lsm_pool_system_id_get(pools[0]),
- &search_pools,
- &search_count, LSM_CLIENT_FLAG_RSVD);
-
- fail_unless(search_count == poolCount, "Expecting %d pools, got %d",
- poolCount, search_count);
-
- G(rc, lsm_pool_record_array_free, search_pools, search_count);
- search_pools = NULL;
- search_count = 0;
-
-
- G(rc, lsm_pool_record_array_free, pools, poolCount);
- pools = NULL;
- poolCount = 0;
- }
-
-}
-END_TEST
-
-START_TEST(test_search_volumes)
-{
- int rc;
- lsm_volume **volumes = NULL;
- uint32_t volume_count = 0;
-
- lsm_pool *pool = get_test_pool(c);
-
- // Make some volumes to we can actually filter
- create_volumes(c, pool, 10);
-
- G(rc, lsm_volume_list, c, NULL, NULL, &volumes, &volume_count,
- LSM_CLIENT_FLAG_RSVD);
-
- fail_unless(volume_count > 0, "We are expecting some volumes!");
-
- if( LSM_ERR_OK == rc && volume_count ) {
- lsm_volume **search_volume = NULL;
- uint32_t search_count = 0;
-
- G(rc, lsm_volume_list, c, "id", lsm_volume_id_get(volumes[0]),
- &search_volume,
- &search_count, LSM_CLIENT_FLAG_RSVD);
-
- fail_unless(search_count == 1, "Expecting 1 pool, got %d", search_count);
-
- G(rc, lsm_volume_record_array_free, search_volume, search_count);
- search_volume = NULL;
- search_count = 0;
-
- /* Search for non-existent */
- G(rc, lsm_volume_list, c, "id", "non-existent-id", &search_volume,
- &search_count, LSM_CLIENT_FLAG_RSVD);
- fail_unless(search_count == 0, "Expecting no volumes! %d", search_count);
-
- /* Search which results in all volumes */
- G(rc, lsm_volume_list, c, "system_id",
- lsm_volume_system_id_get(volumes[0]),
- &search_volume,
- &search_count, LSM_CLIENT_FLAG_RSVD);
-
- fail_unless(search_count == volume_count, "Expecting %d volumes, got %d",
- volume_count, search_count);
-
- G(rc, lsm_volume_record_array_free, search_volume, search_count);
- search_volume = NULL;
- search_count = 0;
-
- G(rc, lsm_volume_record_array_free, volumes, volume_count);
- volumes = NULL;
- volume_count = 0;
- }
-
- G(rc, lsm_pool_record_free, pool);
- pool = NULL;
-}
-END_TEST
-
-START_TEST(test_search_disks)
-{
- int rc;
- lsm_disk **disks = NULL;
- uint32_t disk_count = 0;
-
- lsm_pool *pool = get_test_pool(c);
-
-
- G(rc, lsm_disk_list, c, NULL, NULL, &disks, &disk_count, LSM_CLIENT_FLAG_RSVD);
- fail_unless(disk_count > 0, "We are expecting some disks!");
-
- if( LSM_ERR_OK == rc && disk_count ) {
-
- lsm_disk **search_disks = NULL;
- uint32_t search_count = 0;
-
- G(rc, lsm_disk_list, c, "id", lsm_disk_id_get(disks[0]),
- &search_disks,
- &search_count, LSM_CLIENT_FLAG_RSVD);
- fail_unless(search_count == 1, "Expecting 1 disk, got %d", search_count);
-
- G(rc, lsm_disk_record_array_free, search_disks, search_count);
- search_disks = NULL;
- search_count = 0;
-
- /* Search for non-existent */
- G(rc, lsm_disk_list, c, "id", "non-existent-id", &search_disks,
- &search_count, LSM_CLIENT_FLAG_RSVD);
-
- fail_unless(search_count == 0, "Expecting no disks! %d", search_count);
-
- /* Search which results in all disks */
- G(rc, lsm_disk_list, c, "system_id", lsm_disk_system_id_get(disks[0]),
- &search_disks,
- &search_count, LSM_CLIENT_FLAG_RSVD);
-
- fail_unless(search_count == disk_count, "Expecting %d disks, got %d",
- disk_count, search_count);
-
- G(rc, lsm_disk_record_array_free, search_disks, search_count);
- G(rc, lsm_disk_record_array_free, disks, disk_count);
- disks = NULL;
- disk_count = 0;
- }
-
- lsm_pool_record_free(pool);
-}
-END_TEST
-
-START_TEST(test_search_access_groups)
-{
- int rc;
- lsm_access_group **ag = NULL;
- uint32_t count = 0;
- int i = 0;
- lsm_access_group *group = NULL;
-
- lsm_pool *pool = get_test_pool(c);
- lsm_system *system = get_system(c);
-
-
- fail_unless(system != NULL, "Missing system!");
-
- for( i = 0; i < 2; ++i ) {
- char ag_name[64];
-
- snprintf(ag_name, sizeof(ag_name), "test_access_group_%d", i);
-
- G(rc, lsm_access_group_create, c, ag_name, ISCSI_HOST[i],
- LSM_ACCESS_GROUP_INIT_TYPE_ISCSI_IQN,
- system, &group, LSM_CLIENT_FLAG_RSVD);
-
- if( LSM_ERR_OK == rc ) {
- G(rc, lsm_access_group_record_free, group);
- group = NULL;
- }
- }
-
- G(rc, lsm_system_record_free, system);
- system = NULL;
-
- G(rc, lsm_access_group_list, c, NULL, NULL, &ag, &count, LSM_CLIENT_FLAG_RSVD);
- fail_unless(count > 0, "We are expecting some access_groups!");
-
- if( LSM_ERR_OK == rc && count ) {
-
- lsm_access_group **search_ag = NULL;
- uint32_t search_count = 0;
-
- G(rc, lsm_access_group_list, c, "id", lsm_access_group_id_get(ag[0]),
- &search_ag,
- &search_count, LSM_CLIENT_FLAG_RSVD);
- fail_unless(search_count == 1, "Expecting 1 access group, got %d",
- search_count);
-
- G(rc, lsm_access_group_record_array_free, search_ag, search_count);
-
- /* Search for non-existent */
- search_ag = NULL;
- search_count = 0;
-
- G(rc, lsm_access_group_list, c, "id", "non-existent-id", &search_ag,
- &search_count, LSM_CLIENT_FLAG_RSVD);
- fail_unless(search_count == 0, "Expecting no access groups! %d",
- search_count);
-
- /* Search which results in all disks */
- G(rc, lsm_access_group_list, c, "system_id",
- lsm_access_group_system_id_get(ag[0]),
- &search_ag,
- &search_count, LSM_CLIENT_FLAG_RSVD);
-
- fail_unless(search_count == count, "Expecting %d access groups, got %d",
- count, search_count);
-
- G(rc, lsm_access_group_record_array_free, search_ag, search_count);
- search_ag = NULL;
- search_count = 0;
-
- G(rc, lsm_access_group_record_array_free, ag, count);
- ag = NULL;
- count = 0;
- }
-
- G(rc, lsm_pool_record_free, pool);
- pool = NULL;
-}
-END_TEST
-
-START_TEST(test_search_fs)
-{
- int rc;
- lsm_fs **fsl = NULL;
- lsm_fs *fs = NULL;
- uint32_t count = 0;
- int i = 0;
- char *job = NULL;
-
- lsm_pool *pool = get_test_pool(c);
-
-
- for( i = 0; i < 2; ++i ) {
- char fs_name[64];
-
- snprintf(fs_name, sizeof(fs_name), "test_fs_%d", i);
-
- rc = lsm_fs_create(c, pool, fs_name, 50000000, &fs, &job, LSM_CLIENT_FLAG_RSVD);
-
- if( LSM_ERR_JOB_STARTED == rc ) {
- fail_unless(NULL == fs);
- fs = wait_for_job_fs(c, &job);
- } else {
- fail_unless(LSM_ERR_OK == rc);
- }
-
- G(rc, lsm_fs_record_free, fs);
- fs = NULL;
- }
-
- G(rc, lsm_fs_list, c, NULL, NULL, &fsl, &count, LSM_CLIENT_FLAG_RSVD);
- fail_unless(count > 0, "We are expecting some file systems!");
-
- if( LSM_ERR_OK == rc && count ) {
-
- lsm_fs **search_fs = NULL;
- uint32_t search_count = 0;
-
- G(rc, lsm_fs_list, c, "id", lsm_fs_id_get(fsl[0]),
- &search_fs,
- &search_count, LSM_CLIENT_FLAG_RSVD);
-
- fail_unless(search_count == 1, "Expecting 1 fs, got %d",
- search_count);
-
- G(rc, lsm_fs_record_array_free, search_fs, search_count);
- search_fs = NULL;
- search_count = 0;
-
- /* Search for non-existent */
- G(rc, lsm_fs_list, c, "id", "non-existent-id", &search_fs,
- &search_count, LSM_CLIENT_FLAG_RSVD);
-
- fail_unless(search_count == 0, "Expecting no fs! %d", search_count);
-
- /* Search which results in all disks */
- G(rc, lsm_fs_list, c, "system_id",
- lsm_fs_system_id_get(fsl[0]),
- &search_fs,
- &search_count, LSM_CLIENT_FLAG_RSVD);
-
- fail_unless(search_count == count, "Expecting %d fs, got %d",
- count, search_count);
-
- G(rc, lsm_fs_record_array_free, search_fs, search_count);
-
- G(rc, lsm_fs_record_array_free, fsl, count);
- fsl = NULL;
- count = 0;
- }
-
- lsm_pool_record_free(pool);
-}
-END_TEST
-
-static void verify_string(const char *method, const char *value)
-{
- fail_unless(method != NULL, "%s rc is NULL", method);
- if( value ) {
- fail_unless( strlen(value) > 0, "%s string len = 0", method);
- }
-}
-
-START_TEST(test_target_ports)
-{
- lsm_target_port **tp = NULL;
- uint32_t count = 0;
- uint32_t i = 0;
- int rc = 0;
-
-
- G(rc, lsm_target_port_list, c, NULL, NULL, &tp, &count, LSM_CLIENT_FLAG_RSVD);
-
- if( LSM_ERR_OK == rc ) {
- for( i = 0; i < count; ++i ) {
- verify_string("lsm_target_port_id_get",
- lsm_target_port_id_get(tp[i]));
-
- int pt = (int)lsm_target_port_type_get(tp[i]);
- fail_unless(pt >= 0 && pt <= 4, "%d", pt);
-
- verify_string("lsm_target_port_service_address_get",
- lsm_target_port_service_address_get(tp[i]));
-
- verify_string("lsm_target_port_network_address_get",
- lsm_target_port_network_address_get(tp[i]));
-
- verify_string("lsm_target_port_physical_address_get",
- lsm_target_port_physical_address_get(tp[i]));
-
- verify_string("lsm_target_port_physical_name_get",
- lsm_target_port_physical_name_get(tp[i]));
-
- verify_string("lsm_target_port_system_id_get",
- lsm_target_port_system_id_get(tp[i]));
-
- }
-
- {
- lsm_target_port **search = NULL;
- uint32_t search_count = 0;
-
- G(rc, lsm_target_port_list, c, "id", "does_not_exist",
- &search, &search_count,
- LSM_CLIENT_FLAG_RSVD);
- fail_unless(search_count == 0, "%d", search_count);
-
- G(rc, lsm_target_port_list, c, "system_id", "sim-01",
- &search, &search_count,
- LSM_CLIENT_FLAG_RSVD);
-
- fail_unless(search_count == 5, "%d", search_count);
- if( search_count ) {
- G(rc, lsm_target_port_record_array_free, search, search_count);
- }
- }
-
- G(rc, lsm_target_port_record_array_free, tp, count);
- }
-
-}
-END_TEST
-
-START_TEST(test_initiator_id_verification)
-{
- int rc = 0;
- lsm_access_group *group = NULL;
- lsm_access_group *updated_group = NULL;
- lsm_access_group **groups = NULL;
- uint32_t count = 0;
- lsm_system *system = get_system(c);
-
- G(rc, lsm_access_group_list, c, NULL, NULL, &groups, &count, LSM_CLIENT_FLAG_RSVD);
- fail_unless(count == 0, "Expect 0 access groups, got %"PRIu32, count);
- fail_unless(groups == NULL);
-
- /* Test valid iqns first, then invalid */
-
- G(rc, lsm_access_group_create, c, "test_ag_iscsi",
- "iqn.1994-05.com.domain.sub:whatever-the.users_wants",
- LSM_ACCESS_GROUP_INIT_TYPE_ISCSI_IQN, system,
- &group, LSM_CLIENT_FLAG_RSVD);
-
- G(rc, lsm_access_group_initiator_add, c, group,
- "iqn.2001-04.com.example:storage:diskarrays-sn-a8675309",
- LSM_ACCESS_GROUP_INIT_TYPE_ISCSI_IQN, &updated_group,
- LSM_CLIENT_FLAG_RSVD);
-
- G(rc, lsm_access_group_record_free, group);
- group = updated_group;
- updated_group = NULL;
-
- G(rc, lsm_access_group_initiator_add, c, group,
- "iqn.2001-04.com.example",
- LSM_ACCESS_GROUP_INIT_TYPE_ISCSI_IQN, &updated_group,
- LSM_CLIENT_FLAG_RSVD);
-
- G(rc, lsm_access_group_record_free, group);
- group = updated_group;
- updated_group = NULL;
-
- G(rc, lsm_access_group_initiator_add, c, group,
- "iqn.2001-04.com.example:storage.tape1.sys1.xyz",
- LSM_ACCESS_GROUP_INIT_TYPE_ISCSI_IQN, &updated_group,
- LSM_CLIENT_FLAG_RSVD);
-
- G(rc, lsm_access_group_record_free, group);
- group = updated_group;
- updated_group = NULL;
-
- G(rc, lsm_access_group_initiator_add, c, group,
- "iqn.2001-04.com.example:storage.disk2.sys1.xyz",
- LSM_ACCESS_GROUP_INIT_TYPE_ISCSI_IQN, &updated_group,
- LSM_CLIENT_FLAG_RSVD);
-
- G(rc, lsm_access_group_record_free, group);
- group = updated_group;
- updated_group = NULL;
-
- G(rc, lsm_access_group_initiator_add, c, group,
- "0x0011223344556677",
- LSM_ACCESS_GROUP_INIT_TYPE_WWPN, &updated_group,
- LSM_CLIENT_FLAG_RSVD);
-
- G(rc, lsm_access_group_record_free, group);
- group = updated_group;
- updated_group = NULL;
-
- G(rc, lsm_access_group_initiator_add, c, group,
- "00:11:22:33:44:55:66:78",
- LSM_ACCESS_GROUP_INIT_TYPE_WWPN, &updated_group,
- LSM_CLIENT_FLAG_RSVD);
-
- G(rc, lsm_access_group_record_free, group);
- group = updated_group;
- updated_group = NULL;
-
- G(rc, lsm_access_group_initiator_add, c, group,
- "00-11-22-33-44-55-66-79",
- LSM_ACCESS_GROUP_INIT_TYPE_WWPN, &updated_group,
- LSM_CLIENT_FLAG_RSVD);
-
- G(rc, lsm_access_group_record_free, group);
- group = updated_group;
- updated_group = NULL;
-
- G(rc, lsm_access_group_initiator_add, c, group,
- "0x00-11-22-33-44-55-66-80",
- LSM_ACCESS_GROUP_INIT_TYPE_WWPN, &updated_group,
- LSM_CLIENT_FLAG_RSVD);
-
- G(rc, lsm_access_group_record_free, group);
- group = updated_group;
- updated_group = NULL;
-
- /* Test invalid */
- rc = lsm_access_group_initiator_add(c, group, "0x:0011223344556677",
- LSM_ACCESS_GROUP_INIT_TYPE_WWPN, &updated_group,
- LSM_CLIENT_FLAG_RSVD);
-
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT,
- "Expected initiator id with invalid form to fail! %d", rc);
-
- /* Test invalid iqn */
- rc = lsm_access_group_initiator_add(c, group, "0011223344556677:",
- LSM_ACCESS_GROUP_INIT_TYPE_WWPN, &updated_group,
- LSM_CLIENT_FLAG_RSVD);
-
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT,
- "Expected initiator id with invalid form to fail! %d", rc);
-
- /* Test invalid iqn */
- rc = lsm_access_group_initiator_add(c, group, "001122334455667788",
- LSM_ACCESS_GROUP_INIT_TYPE_WWPN, &updated_group,
- LSM_CLIENT_FLAG_RSVD);
-
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT,
- "Expected initiator id with invalid form to fail! %d", rc);
-
- /* Test invalid iqn */
- rc = lsm_access_group_initiator_add(c, group, "0x001122334455",
- LSM_ACCESS_GROUP_INIT_TYPE_WWPN, &updated_group,
- LSM_CLIENT_FLAG_RSVD);
-
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT,
- "Expected initiator id with invalid form to fail! %d", rc);
-
- /* Test invalid iqn */
- rc = lsm_access_group_initiator_add(c, group, "0x00+11:22:33:44:55:66:77",
- LSM_ACCESS_GROUP_INIT_TYPE_WWPN, &updated_group,
- LSM_CLIENT_FLAG_RSVD);
-
- fail_unless(rc == LSM_ERR_INVALID_ARGUMENT,
- "Expected initiator id with invalid form to fail! %d", rc);
-
- /* Delete group */
- G(rc, lsm_access_group_delete, c, group, LSM_CLIENT_FLAG_RSVD);
- G(rc, lsm_access_group_record_free, group);
- group = NULL;
-
- G(rc, lsm_system_record_free, system);
- system = NULL;
-}
-END_TEST
-
-START_TEST(test_volume_vpd_check)
-{
- int rc;
-
- F(rc, lsm_volume_vpd83_verify, NULL );
- F(rc, lsm_volume_vpd83_verify, "012345678901234567890123456789AB");
- F(rc, lsm_volume_vpd83_verify, "012345678901234567890123456789ax");
- F(rc, lsm_volume_vpd83_verify, "012345678901234567890123456789ag");
- F(rc, lsm_volume_vpd83_verify, "1234567890123456789012345abcdef");
- F(rc, lsm_volume_vpd83_verify, "01234567890123456789012345abcdefa");
-
- G(rc, lsm_volume_vpd83_verify, "01234567890123456789012345abcdef");
-}
-END_TEST
-
-START_TEST(test_volume_raid_info)
-{
- lsm_volume *volume = NULL;
- char *job = NULL;
- lsm_pool *pool = get_test_pool(c);
-
- int rc = lsm_volume_create(
- c, pool, "volume_raid_info_test", 20000000,
- LSM_VOLUME_PROVISION_DEFAULT, &volume, &job, LSM_CLIENT_FLAG_RSVD);
-
- fail_unless( rc == LSM_ERR_OK || rc == LSM_ERR_JOB_STARTED,
- "lsmVolumeCreate %d (%s)", rc, error(lsm_error_last_get(c)));
-
- if( LSM_ERR_JOB_STARTED == rc ) {
- volume = wait_for_job_vol(c, &job);
- }
-
- lsm_volume_raid_type raid_type;
- uint32_t strip_size, disk_count, min_io_size, opt_io_size;
-
- G(
- rc, lsm_volume_raid_info, c, volume, &raid_type, &strip_size,
- &disk_count, &min_io_size, &opt_io_size, LSM_CLIENT_FLAG_RSVD);
-
- G(rc, lsm_volume_record_free, volume);
- volume = NULL;
-}
-END_TEST
-
-Suite * lsm_suite(void)
-{
- Suite *s = suite_create("libStorageMgmt");
-
- TCase *basic = tcase_create("Basic");
- tcase_add_checked_fixture (basic, setup, teardown);
-
- tcase_add_test(basic, test_volume_vpd_check);
- tcase_add_test(basic, test_initiator_id_verification);
- tcase_add_test(basic, test_target_ports);
- tcase_add_test(basic, test_search_fs);
- tcase_add_test(basic, test_search_access_groups);
- tcase_add_test(basic, test_search_disks);
- tcase_add_test(basic, test_search_volumes);
- tcase_add_test(basic, test_search_pools);
-
- tcase_add_test(basic, test_uri_parse);
-
- tcase_add_test(basic, test_error_reporting);
- tcase_add_test(basic, test_capability);
- tcase_add_test(basic, test_nfs_export_funcs);
- tcase_add_test(basic, test_disks);
- tcase_add_test(basic, test_plugin_info);
- tcase_add_test(basic, test_get_available_plugins);
- tcase_add_test(basic, test_volume_methods);
- tcase_add_test(basic, test_iscsi_auth_in);
- tcase_add_test(basic, test_capabilities);
- tcase_add_test(basic, test_smoke_test);
- tcase_add_test(basic, test_access_groups);
- tcase_add_test(basic, test_systems);
- tcase_add_test(basic, test_access_groups_grant_revoke);
- tcase_add_test(basic, test_fs);
- tcase_add_test(basic, test_ss);
- tcase_add_test(basic, test_nfs_exports);
- tcase_add_test(basic, test_invalid_input);
- tcase_add_test(basic, test_volume_raid_info);
-
- suite_add_tcase(s, basic);
- return s;
-}
-
-int main(int argc, char** argv)
-{
- int number_failed;
- Suite *s = lsm_suite();
- SRunner *sr = srunner_create(s);
-
- /*
- * Don't run python plug-in tests if we are looking for
- * memory leaks.
- */
- if( !getenv("LSM_VALGRIND") ) {
- srunner_run_all(sr, CK_NORMAL);
- }
-
- /* Switch plug-in backend to test C language compat. */
- which_plugin = 1;
-
- srunner_run_all(sr, CK_NORMAL);
-
- number_failed = srunner_ntests_failed(sr);
- srunner_free(sr);
- return(number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
-}
diff --git a/test/webtest/test.css b/test/webtest/test.css
deleted file mode 100644
index a410222..0000000
--- a/test/webtest/test.css
+++ /dev/null
@@ -1,126 +0,0 @@
-
-* {
- font-family: sans-serif;
-}
-
-pre,
-code,
-kbd,
-samp,
-tt{
- font-family:monospace,monospace;
- font-size:1em;
-}
-
-.angled_table {
- position: relative;
- background-color: #FFFFFF;
- font-size: 10px;
- padding: 20px 90px 20px 20px;
- -moz-border-radius: 4px;
- -webkit-border-radius: 4px;
- border-radius: 4px;
-}
-.angled_table a {
- color: #333333;
- text-decoration: none;
- font-size: 24px;
-}
-.angled_table notsupported {
- color: black;
- text-decoration: none;
- font-size: 20px;
- background-color:orange;
-}
-.angled_table fail {
- color: black;
- text-decoration: none;
- font-size: 20px;
- background-color:red;
- /* border:2px solid black; */
-}
-
-.angled_table fail_test {
- color: black;
- text-decoration: none;
- font-size: 20px;
- background-color:red;
- /* border:2px solid black; */
-}
-
-.angled_table pass {
- color: black;
- text-decoration: none;
- font-size: 20px;
- background-color:green;
- /* border:2px solid black; */
-}
-
-.angled_table pass_test {
- color: black;
- text-decoration: none;
- font-size: 20px;
- background-color:green;
- /* border:2px solid black; */
-}
-
-.angled_table table th.skew {
- height: 60px;
- width: 40px;
- position: relative;
- vertical-align: bottom;
-}
-.angled_table table th.skew > div {
- position: relative;
- top: 0px;
- left: 90px;
- height: 300%;
- transform:skew(-45deg, 0deg);
- -ms-transform:skew(-45deg, 0deg);
- -moz-transform:skew(-45deg, 0deg);
- -webkit-transform:skew(-45deg, 0deg);
- -o-transform:skew(-45deg, 0deg);
- overflow: hidden;
- border-top: 1px solid #CCCCCC;
- border-left: 1px solid #CCCCCC;
- border-right: 1px solid #CCCCCC;
-}
-.angled_table table th.skew span {
- transform:skew(45deg, 0deg) rotate(315deg);
- -ms-transform:skew(45deg, 0deg) rotate(315deg);
- -moz-transform:skew(45deg, 0deg) rotate(315deg);
- -webkit-transform:skew(45deg, 0deg) rotate(315deg);
- -o-transform:skew(45deg, 0deg) rotate(315deg);
- white-space: nowrap;
- position: absolute;
- bottom: 15px;
- left: 1px;
- display: inline-block;
- width: 100%;
- text-align: left;
-}
-.angled_table table td {
- width: 30px;
- height: 30px;
- text-align: center;
- vertical-align: middle;
- border: 1px solid #CCCCCC;
-}
-.angled_table table td a {
- display: block;
- width: 100%;
- text-align: center;
-}
-/* This is the API function names */
- .angled_table table td.operation {
- width: auto;
- text-align: right;
- font-weight: bold;
- border: none;
- padding-right: 8px;
-}
-
-/* Backgroud to make things easier to follow */
-.angled_table table .odd {
- background-color: #DDDDDD;
-}
diff --git a/test/webtest/test_automated.py b/test/webtest/test_automated.py
deleted file mode 100755
index 11cae40..0000000
--- a/test/webtest/test_automated.py
+++ /dev/null
@@ -1,123 +0,0 @@
-#!/usr/bin/env python2
-
-# 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
-# USA
-#
-# Author: tasleson
-
-# Takes a csv file of hardware array information and runs the plugin test
-# on each of them dumping the results to the specified directory
-
-import test_hardware
-import sys
-from subprocess import Popen, PIPE
-from multiprocessing import Process
-import yaml
-import time
-import os
-
-
-def call(command):
- """
- Call an executable and return a tuple of exitcode, stdout, stderr
- """
- process = Popen(command, stdout=PIPE, stderr=PIPE)
- out = process.communicate()
- return process.returncode, out[0], out[1]
-
-
-def run_test(cmdline, output_dir, sys_id, uri, password ):
-
- exec_array = [cmdline, '-q', '--uri', uri,
- '--password', password]
-
- (ec, out, error) = call(exec_array)
-
- # Save the output to a temp dir
- sys_id = sys_id.replace('/', '-')
- sys_id = sys_id.replace(' ', '_')
- fn = "%s/%s" % (output_dir, sys_id)
-
- with open(fn + ".out", 'w') as so:
- so.write(out)
- so.flush()
-
- with open(fn + ".error", 'w') as se:
- se.write(error)
- se.flush()
-
- # We should probably put more information in here
- with open(fn + ".ec", 'w') as error_file:
- error_file.write(yaml.dump(dict(ec=str(ec),
- error_file=fn + ".error",
- uri=uri)))
- error_file.flush()
-
-
-if __name__ == '__main__':
- time_limit_seconds = long(os.getenv('LSM_TEST_TMO_SECS', 90 * 60)) # 90 minutes
-
- if len(sys.argv) != 4:
- print('Syntax: %s <array_file> <plugin unit test> <output directory>'
- % (sys.argv[0]))
- sys.exit(1)
- else:
- run = True
- process_list = []
- results = []
- array_cimons = test_hardware.TestArrays().providers(sys.argv[1])
-
- for system in array_cimons:
- (uri, password) = test_hardware.TestArrays.uri_password_get(system)
- name = system['COMPANY']
- ip = system['IP']
- system_id = "%s-%s" % (name, ip)
-
- p = Process(target=run_test, args=(sys.argv[2], sys.argv[3],
- system_id, uri, password))
- p.name = system_id
- p.start()
- process_list.append(p)
-
- start = time.time()
- print 'Test run started at: %s, time limit is %s minutes' % \
- (time.strftime("%c"), str(time_limit_seconds / 60.0))
- sys.stdout.flush()
-
- while len(process_list) > 0:
- for p in process_list:
- p.join(1)
- if not p.is_alive():
- print '%s exited with %s at %s (runtime %s seconds)' % \
- (p.name, str(p.exitcode), time.strftime("%c"),
- str(time.time() - start))
- sys.stdout.flush()
- process_list.remove(p)
- break
-
- current = time.time()
- if (current - start) >= time_limit_seconds:
- print 'Test taking too long...'
- sys.stdout.flush()
- for p in process_list:
- print 'Terminating process %s, name %s' % \
- (str(p.pid), p.name)
- sys.stdout.flush()
- p.terminate()
- break
-
- print 'Test run exiting at: %s' % time.strftime("%c")
- sys.stdout.flush()
diff --git a/test/webtest/test_hardware.py b/test/webtest/test_hardware.py
deleted file mode 100755
index bb523af..0000000
--- a/test/webtest/test_hardware.py
+++ /dev/null
@@ -1,143 +0,0 @@
-#!/usr/bin/env python2
-
-# 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: tasleson
-import xlrd
-import sys
-import os
-import yaml
-
-
-class TestArrays(object):
- col_name = ['COMPANY', 'NAMESPACE', 'SMI_VERSION', 'PRODUCT', 'PRINCIPAL',
- 'PASSWORD', 'CIM_VERSION', 'IP', 'INTEROP_NS', 'PROTOCOL',
- 'PORT']
-
- skip_these = ['Brocade', 'Cisco']
-
- @staticmethod
- def should_skip(company):
- if company in TestArrays.skip_these:
- return True
- return False
-
- @staticmethod
- def uri_password_get(d):
-
- if 'URI' in d:
- return d['URI'], d['PASSWORD']
-
- uri = 'smispy'
- port = "5988"
-
- if "https" in d['PROTOCOL'].lower():
- uri += "+ssl"
- port = "5989"
-
- uri += "://%s@%s:%s/?no_ssl_verify=yes" % \
- (d["PRINCIPAL"], d["IP"], port)
- else:
- uri += "://%s@%s:%s" % (d["PRINCIPAL"], d["IP"],
- port)
-
- return uri, d['PASSWORD']
-
- def parse_csv_file(self, filename):
- rc = []
-
- with open(filename) as f:
- lines = f.read().splitlines()
-
- lines = lines[1:]
-
- for l in lines:
- elem = {}
- values = l.split(',')
- for i in range(0, len(values)):
- elem[self.col_name[i]] = str(values[i])
-
- if self.should_skip(elem['COMPANY']):
- continue
-
- rc.append(elem)
- return rc
-
- def get_data(self, work_sheet, row):
- rc = {}
-
- for i in range(0, len(self.col_name)):
- rc[self.col_name[i]] = str(work_sheet.cell_value(row, i))
- return rc
-
- def parse_xls_file(self, filename):
- rc = []
-
- wb = xlrd.open_workbook(filename, 'rb')
- ws_name = wb.sheet_names()[0]
- ws = wb.sheet_by_name(ws_name)
-
- # First line is column headers
- for x in range(1, ws.nrows):
- d = self.get_data(ws, x)
-
- if self.should_skip(d['COMPANY']):
- continue
-
- rc.append(d)
- return rc
-
- def parse_yaml_file(self, filename):
- with open(filename, 'r') as array_data:
- r = yaml.safe_load(array_data.read())
- return r
-
- def providers(self, filename):
- rc = []
- need_convert = True
-
- file_name, extension = os.path.splitext(filename)
-
- if extension.lower() == '.csv':
- rc = self.parse_csv_file(filename)
- elif extension.lower() == '.xls' or extension.lower() == '.xlsx':
- rc = self.parse_xls_file(filename)
- else:
- rc = self.parse_yaml_file(filename)
- need_convert = False
-
- if need_convert:
- converted = []
- for r in rc:
- (uri, password) = self.uri_password_get(r)
- t = dict(COMPANY=r["COMPANY"], IP=r["IP"],
- PASSWORD=password, URI=uri)
- converted.append(t.copy())
- t = None
-
- rc = converted
-
- return rc
-
-
-if __name__ == "__main__":
-
- if len(sys.argv) != 2:
- print 'Syntax: %s <file>' % (sys.argv[0])
- print 'File is an array file in xls/xlsx/csv/yaml format'
- sys.exit(1)
-
- sys.stdout.write(yaml.dump(TestArrays().providers(sys.argv[1])))
diff --git a/test/webtest/test_results.py b/test/webtest/test_results.py
deleted file mode 100755
index b0ed9a8..0000000
--- a/test/webtest/test_results.py
+++ /dev/null
@@ -1,235 +0,0 @@
-#!/usr/bin/env python2
-
-# 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
-# USA
-#
-# Author: tasleson
-
-# Takes a directory of output from the script test_automated.py and creates
-# a summary html table.
-
-from bs4 import BeautifulSoup as bs
-from htmltag import HTML, div, table, thead, tbody, tr, td, span, th, foo, \
- head, body, html, title, style, link, fail_test, notsupported, pass_test, \
- pre, h1
-
-import time
-
-import yaml
-import sys
-import os
-
-
-def _header_entry(odd, data):
- cl = ""
- if odd:
- cl = "odd"
- return div(span(data), _class=cl)
-
-
-def _table_header(rd):
- count = 1
-
- rc = th()
- for i in rd:
- rc += th(_header_entry(count % 2, i), _class="skew")
- count += 1
-
- return thead(tr(HTML(str(rc))))
-
-
-def _body_entry(cl, data):
- if data == 'P':
- data = pass_test(data)
- elif data == 'F':
- data = fail_test(data)
- elif data == 'U':
- data = notsupported(data)
- return td(data, _class=cl)
-
-
-def _table_body(rd):
- row = ""
- rows = ""
-
- for r in rd:
- count = 1
- row = _body_entry("operation", r[0])
-
- for i in r[1:]:
- cl = ""
- if count % 2:
- cl = "odd"
- row += _body_entry(cl, HTML(i))
- count += 1
-
- rows += tr(HTML(row))
-
- return tbody(HTML(rows))
-
-
-def _angled_html_table(column_headers, row_headers, row_data):
- rc = div(table(), _class="angled_table")
- return rc
-
-
-def has_errors(run_list):
- for i in run_list:
- if not i['rc']:
- return True
- return False
-
-
-def get_result(r, method):
-
- if 'RESULTS' in r and 'methods_called' in r['RESULTS']:
- if method in r['RESULTS']['methods_called']:
- if has_errors(r['RESULTS']['methods_called'][method]):
- return 'F'
- else:
- return 'P'
- else:
- return 'U'
- else:
- return '*'
-
-
-def to_html(results):
- PREAMBLE_FILE = os.getenv('LSM_PREAMBLE_FILE', "")
- preamble = ""
- methods = ['capabilities',
- 'systems', 'plugin_info', 'pools', 'job_status', 'job_free',
- 'iscsi_chap_auth',
- 'volumes', 'volume_create', 'volume_delete', 'volume_resize',
- 'volume_replicate', 'volume_replicate_range_block_size',
- 'volume_replicate_range', 'volume_enable', 'volume_disable',
- 'disks', 'target_ports',
- 'volume_mask',
- 'volume_unmask',
- 'volume_child_dependency',
- 'volume_child_dependency_rm',
- 'access_groups',
- 'access_groups_granted_to_volume',
- 'access_group_create',
- 'access_group_delete',
- 'volumes_accessible_by_access_group',
- 'access_groups_granted_to_volume',
- 'access_group_initiator_add',
- 'access_group_initiator_delete',
- 'fs',
- 'fs_create',
- 'fs_delete',
- 'fs_resize',
- 'fs_clone',
- 'fs_file_clone',
- 'fs_snapshots',
- 'fs_snapshot_create',
- 'fs_snapshot_delete',
- 'fs_snapshot_restore',
- 'fs_child_dependency',
- 'fs_child_dependency_rm',
- 'export_auth',
- 'exports',
- 'export_fs',
- 'export_remove'
- ]
-
- ch = []
- row_data = []
-
- if os.path.isfile(PREAMBLE_FILE):
- with open(PREAMBLE_FILE, 'r') as pm:
- preamble = pm.read()
-
- #Build column header
- for r in results:
- ch.append(r['SYSTEM']['ID'])
-
- # Add overall pass/fail for unit tests
- pass_fail = ['Overall Pass/Fail result']
- for r in results:
- if r['META']['ec'] == '0':
- pass_fail.append('P')
- else:
- pass_fail.append('F')
- row_data.append(pass_fail)
-
- # Append on link for error log
- error_log = ['Error log (click +)']
- for r in results:
- error_log.append('<a href="%s">+</a>' %
- ('./' + os.path.basename(r['META']['error_file'])))
- row_data.append(error_log)
-
- for m in methods:
- row = [m]
-
- for r in results:
- row.append(get_result(r, m))
-
- row_data.append(row)
-
- # Build HTML
- text = '<!DOCTYPE html>'
- text += str(html(
- head(link(rel="stylesheet", type="text/css",
- href="../../test.css"),
- title("libStorageMgmt test results"), ),
- body(
- HTML(h1("%s Results generated @ %s") % (preamble, time.strftime("%c"))),
- div(table(_table_header(ch), _table_body(row_data)),
- _class="angled_table"),
- div(pre(
- " Legend\n"
- " P = Pass (Method called and returned without error)\n"
- " F = Fail (Method call returned an error)\n"
- " U = Unsupported or unable to test due to other errors\n"
- " * = Unable to connect to array or provider totally unsupported\n"
- " + = hyper link to error log\n\n\n",
- HTML(' Source code for plug-in for this test run <a href=./smis.py.html>is here. </a>'))))
- ))
-
- return bs(text).prettify()
-
-
-def process_result_files(path, ext):
- results = []
- for f in os.listdir(path):
- cur_file = os.path.join(path, f)
- f_name, f_ext = os.path.splitext(f)
-
- # Look at the files to determine if we were unable to communicate
- # with the array
- if f_ext.lower() == ext.lower():
- with open(cur_file, 'r') as array_data:
- r = yaml.safe_load(array_data.read())
-
- with open(os.path.join(path, (f_name + ".ec"))) as meta:
- m = yaml.safe_load(meta.read())
-
- results.append(dict(SYSTEM=dict(ID=f_name), RESULTS=r, META=m))
-
- #Sort the list by ID and then generate the html
- sorted_results = sorted(results, key=lambda k: k['SYSTEM']['ID'])
- print to_html(sorted_results)
-
-
-if __name__ == '__main__':
- if len(sys.argv) != 2:
- print 'Syntax: %s <directory>' % (sys.argv[0])
- sys.exit(1)
-
- process_result_files(sys.argv[1], '.out')
diff --git a/tools/Makefile.am b/tools/Makefile.am
deleted file mode 100644
index 25c9abc..0000000
--- a/tools/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-SUBDIRS = lsmcli udev utility bash_completion
diff --git a/tools/bash_completion/Makefile.am b/tools/bash_completion/Makefile.am
deleted file mode 100644
index d1a9c3a..0000000
--- a/tools/bash_completion/Makefile.am
+++ /dev/null
@@ -1,4 +0,0 @@
-if WITH_BASH_COMPLETION
-EXTRA_DIST=lsmcli
-bashcompletion_DATA = lsmcli
-endif
diff --git a/tools/bash_completion/lsmcli b/tools/bash_completion/lsmcli
deleted file mode 100644
index a67083b..0000000
--- a/tools/bash_completion/lsmcli
+++ /dev/null
@@ -1,421 +0,0 @@
-# Copyright (C) 2015 Red Hat, Inc., Tony Asleson <***@redhat.com>
-# Distributed under the GNU General Public License, version 2.0.
-# See: https://www.gnu.org/licenses/gpl-2.0.html
-#
-# Bash completion for lsmcli. This may be far from ideal,
-# suggestions & improvements appreciated!
-
-potential_args=''
-
-# Skip value lookups by default
-NO_VALUE_LOOKUP=${LSMCLI_AUTO_COMPLETE_VALUE:=0}
-
-function join { local IFS="$1"; shift; echo "$*"; }
-
-# Linear search of an array of strings for the specified string
-function listcontains() {
- declare -a the_list=("${!1}")
-
- for word in "${the_list[@]}" ; do
- [[ ${word} == $2 ]] && return 0
- done
- return 1
-}
-
-# Given a list of what is possible and what is on the command line return
-# what is left.
-# $1 What is possible
-# Retults are returned in global string $potential_args
-function possible_args()
-{
- local l=()
-
- for i in $1
- do
- listcontains COMP_WORDS[@] "$i"
- if [[ $? -eq 1 ]] ; then
- l+=("$i")
- fi
- done
-
- potential_args=$( join ' ', "${l[@]}" )
-}
-
-# Returns the position of the value in the COMP_WORDS that contains $1, or
-# 255 if it doesn't exist
-function arg_index()
-{
- count=0
- for i in "${COMP_WORDS[@]}"
- do
- if [[ "$i" == "$1" ]] ; then
- return ${count}
- fi
- let count+=1
- done
- return 255
-}
-
-function _lsm()
-{
- local cur prev opts
- sep='#'
- COMPREPLY=()
- cur="${COMP_WORDS[COMP_CWORD]}"
- prev="${COMP_WORDS[COMP_CWORD-1]}"
- opts_short="-b -v -u -P -H -t -e -f -w -b"
- opts_long=" --help --version --uri --prompt --human --terse --enum \
- --force --wait --header --script "
- opts_cmds="list job-status capabilities plugin-info volume-create \
- volume-delete, volume-resize volume-replicate \
- volume-replicate-range volume-replicate-range-block-size \
- volume-dependants volume-dependants-rm volume-access-group \
- volume-mask volume-unmask access-group-create \
- access-group-delete access-group-add access-group-remove \
- volume-enable volume-disable iscsi-chap fs-create fs-delete \
- fs-resize fs-export fs-unexport fs-clone fs-snap-create \
- fs-snap-delete fs-snap-restore fs-dependants fs-dependants-rm \
- file-clone ls lp lv ld la lf lt c p vc vd vr vm vi ve vi ac \
- aa ar ad vri"
-
- list_args="--type"
- list_type_args="volumes pools fs snapshots exports nfs_client_auth \
- access_groups systems disks plugins target_ports"
-
- opts_filter="--sys --pool --vol --disk --ag --fs --nfs"
-
- cap_args="--sys"
- volume_create_args="--name --size --pool"
- volume_delete_args="--vol --force" # Should force be here, to easy to tab through?"
- volume_resize_args="--vol --size --force" # Should force be here, to easy to tab through?"
-
- volume_replicate_args="--vol --name --rep-type"
- # Hmmm, this looks like a bug with CLI, should support lower and upper case?
- volume_rep_types="CLONE COPY MIRROR_ASYNC MIRROR_SYNC"
-
- volume_replicate_range_args="--src-vol --dst-vol --rep-type --src-start \
- --dst-start --count --force" # Force ?
-
- volume_replication_range_bs="--sys"
- volume_dependants="--vol"
-
- volume_access_group_args="--vol"
- volume_masking_args="--vol --ag"
-
- access_group_create_args="--name --init --sys"
- access_group_delete_args="--ag"
-
- access_group_add_remove_args="--ag --init"
-
- volume_enable_disable_args="--vol"
-
- volume_raidinfo_args="--vol"
-
- iscsi_chap_args="--in-user --in-pass --out-user --out-pass"
-
- fs_create_args="--name --size --pool"
- fs_delete_args="--fs --force" # Force ?
- fs_resize_args="--fs --size --force" # Force ?
- fs_export_args="--fs --exportpath --anonuid --auth-type --root-host --ro-host --rw-host"
- fs_unexport_args="--export"
- fs_clone_args="--src-fs --dst-name"
- fs_snap_create_args="--name --fs"
- fs_snap_delete_args="--snap --fs"
- fs_snap_restore_args="--snap --fs --file --fileas --force"
- fs_dependants_args="--fs"
- file_clone_args="--fs --src --dst --backing-snapshot"
-
- # These operations can potentially be slow and cause hangs depending on plugin and configuration
- if [[ ${NO_VALUE_LOOKUP} -ne 0 ]] ; then
-
- # Check if we have somthing present that we can help the user with
- case "${prev}" in
- --sys)
- # Is there a better way todo this?
- local items=`lsmcli list --type systems -t${sep} | awk -F ${sep} '{print $1}'`
- COMPREPLY=( $(compgen -W "${items}" -- ${cur}) )
- return 0
- ;;
- --pool)
- # Is there a better way todo this?
- local items=`lsmcli list --type pools -t${sep} | awk -F ${sep} '{print $1}'`
- COMPREPLY=( $(compgen -W "${items}" -- ${cur}) )
- return 0
- ;;
- --vol|--src-vol|--dst-vol)
- # Is there a better way todo this?
- local items=`lsmcli list --type volumes -t${sep} | awk -F ${sep} '{print $1}'`
- COMPREPLY=( $(compgen -W "${items}" -- ${cur}) )
- return 0
- ;;
- --disk)
- # Is there a better way todo this?
- local items=`lsmcli list --type disks -t${sep} | awk -F ${sep} '{print $1}'`
- COMPREPLY=( $(compgen -W "${items}" -- ${cur}) )
- return 0
- ;;
- --ag)
- # Is there a better way todo this?
- local items=`lsmcli list --type access_groups -t${sep} | awk -F ${sep} '{print $1}'`
- COMPREPLY=( $(compgen -W "${items}" -- ${cur}) )
- return 0
- ;;
- --init)
- arg_index "--ag"
- i=$?
- # We have an access group present on the command line so filter the intiators to it
- if [[ ${i} -ne 255 ]]; then
- # It would be better if we filtered the result with the access group
- # if it's present on the command line already.
- local items=`lsmcli list --type access_groups -t${sep} --ag ${COMP_WORDS[${i}+1]} | awk -F ${sep} '{print $3}'`
- COMPREPLY=( $(compgen -W "${items}" -- ${cur}) )
- return 0
- else
- local items=`lsmcli list --type access_groups -t${sep} | awk -F ${sep} '{print $3}'`
- COMPREPLY=( $(compgen -W "${items}" -- ${cur}) )
- return 0
- fi
- ;;
- --nfs-export)
- # Is there a better way todo this?
- local items=`lsmcli list --type exports -t${sep} | awk -F ${sep} '{print $1}'`
- COMPREPLY=( $(compgen -W "${items}" -- ${cur}) )
- return 0
- ;;
- --tgt)
- # Is there a better way todo this?
- local items=`lsmcli list --type target_ports -t${sep} | awk -F ${sep} '{print $1}'`
- COMPREPLY=( $(compgen -W "${items}" -- ${cur}) )
- return 0
- ;;
- --fs|--src-fs)
- local items=`lsmcli list --type fs -t${sep} | awk -F ${sep} '{print $1}'`
- COMPREPLY=( $(compgen -W "${items}" -- ${cur}) )
- return 0
- ;;
- --export)
- local items=`lsmcli list --type exports -t${sep} | awk -F ${sep} '{print $1}'`
- COMPREPLY=( $(compgen -W "${items}" -- ${cur}) )
- return 0
- ;;
- --snap)
- arg_index "--fs"
- i=$?
- # We have an access group present on the command line so filter the snapshots to it
- if [[ ${i} -ne 255 ]]; then
- local items=`lsmcli list --type snapshots \
- --fs ${COMP_WORDS[${i}+1]} -t${sep} | awk -F ${sep} '{print $1}'`
- COMPREPLY=( $(compgen -W "${items}" -- ${cur}) )
- return 0
- else
- COMPREPLY=( $(compgen -W "" -- ${cur}) )
- return 0
- fi
- ;;
- --auth-type)
- local items=`lsmcli list --type nfs_client_auth -t ' '`
- COMPREPLY=( $(compgen -W "${items}" -- ${cur}) )
- return 0
- ;;
- *)
- ;;
- esac
- fi
-
- # Cases where we don't have to worry about look-up time
- case "${prev}" in
- --type)
- COMPREPLY=( $(compgen -W "${list_type_args}" -- ${cur}) )
- return 0
- ;;
- --size|--count|--src-start|--dst-start|--name|--in-user|--in-pass|\
- --out-user|--out-pass|--exportpath|--anonuid|--root-host|--ro-host|\
- --rw-host|--dest-name|--file|--fileas|--src|--dst)
- # These we cannot lookup, so don't offer any values
- COMPREPLY=( $(compgen -W "" -- ${cur}) )
- return 0
- ;;
- --rep-type)
- COMPREPLY=( $(compgen -W "${volume_rep_types}" -- ${cur}) )
- return 0
- ;;
- snapshots)
- # Specific listing case where you need a fs too
- if [[ ${COMP_WORDS[COMP_CWORD-2]} == '--type' && \
- ${COMP_WORDS[COMP_CWORD-3]} == 'list' ]] ; then
- COMPREPLY=( $(compgen -W "--fs" -- ${cur}) )
- return 0
- fi
- ;;
- *)
- esac
-
- case "${COMP_WORDS[1]}" in
- job-status)
- possible_args "--job"
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- list)
- possible_args ${list_args}
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- volume-create|vc)
- possible_args "${volume_create_args}"
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- volume-delete|vd)
- possible_args "${volume_delete_args}"
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- volume-raid-info|vri)
- possible_args "${volume_raidinfo_args}"
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- volume-resize|vr)
- possible_args "${volume_resize_args}"
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- volume-replicate)
- possible_args "${volume_replicate_args}"
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- volume-replicate-range)
- possible_args "${volume_replicate_range_args}"
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- volume-replicate-range-block-size)
- possible_args "${volume_replication_range_bs}"
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- volume-dependants|volume-dependants-rm)
- possible_args "${volume_dependants}"
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- volume-access-group)
- possible_args "${volume_access_group_args}"
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- volume-mask|volume-unmask|vm|vu)
- possible_args "${volume_masking_args}"
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- access-group-create|ac)
- possible_args "${access_group_create_args}"
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- access-group-delete|ad)
- possible_args "${access_group_delete_args}"
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- access-group-add|access-group-remove|aa|ar)
- possible_args "${access_group_add_remove_args}"
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- volume-enable|volume-disable|ve|vi)
- possible_args "${volume_enable_disable_args}"
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- iscsi-chap)
- possible_args "${iscsi_chap_args}"
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- fs-create)
- possible_args "${fs_create_args}"
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- fs-delete)
- possible_args "${fs_delete_args}"
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- fs-resize)
- possible_args "${fs_resize_args}"
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- fs-export)
- possible_args "${fs_export_args}"
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- fs-unexport)
- possible_args "${fs_unexport_args}"
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- fs-clone)
- possible_args "${fs_clone_args}"
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- fs-snap-create)
- possible_args "${fs_snap_create_args}"
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- fs-snap-delete)
- possible_args "${fs_snap_delete_args}"
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- fs-snap-restore)
- possible_args "${fs_snap_restore_args}"
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- fs-dependants|fs-dependants-rm)
- possible_args "${fs_dependants_args}"
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- file-clone)
- possible_args "${file_clone_args}"
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- capabilities|c)
- possible_args "${cap_args}"
- COMPREPLY=( $(compgen -W "${potential_args}" -- ${cur}) )
- return 0
- ;;
- *)
- ;;
- esac
-
- # Handle the case where we are starting out with nothing
- if [[ ${prev} == 'lsmcli' ]] ; then
- if [[ ${cur} == --* ]] ; then
- COMPREPLY=( $(compgen -W "${opts_long}" -- ${cur}) )
- return 0
- fi
-
- if [[ ${cur} == -* ]] ; then
- COMPREPLY=( $(compgen -W "${opts_short}${opts_long}" -- ${cur}) )
- return 0
- fi
-
- if [[ ${cur} == * ]] ; then
- COMPREPLY=( $(compgen -W "${opts_short}${opts_long}${opts_cmds}" -- ${cur}) )
- return 0
- fi
- fi
-}
-complete -F _lsm lsmcli
diff --git a/tools/lsmcli/Makefile.am b/tools/lsmcli/Makefile.am
deleted file mode 100644
index bcacfed..0000000
--- a/tools/lsmcli/Makefile.am
+++ /dev/null
@@ -1,8 +0,0 @@
-dist_bin_SCRIPTS = lsmcli
-
-lsmclidir = $(pythondir)/lsm/lsmcli
-
-lsmcli_PYTHON = \
- data_display.py \
- cmdline.py \
- __init__.py
diff --git a/tools/lsmcli/__init__.py b/tools/lsmcli/__init__.py
deleted file mode 100644
index 20db96c..0000000
--- a/tools/lsmcli/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from cmdline import cmd_line_wrapper
diff --git a/tools/lsmcli/cmdline.py b/tools/lsmcli/cmdline.py
deleted file mode 100644
index 980b3a0..0000000
--- a/tools/lsmcli/cmdline.py
+++ /dev/null
@@ -1,1451 +0,0 @@
-# Copyright (C) 2012-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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: tasleson
-# Gris Ge <***@redhat.com>
-
-import os
-import sys
-import getpass
-import time
-import tty
-import termios
-
-try:
- from collections import OrderedDict
-except ImportError:
- # python 2.6 or earlier, use backport
- from ordereddict import OrderedDict
-
-from argparse import ArgumentParser
-from argparse import RawTextHelpFormatter
-
-from lsm import (Client, Pool, VERSION, LsmError, Disk,
- Volume, JobStatus, ErrorNumber, BlockRange,
- uri_parse, Proxy, size_human_2_size_bytes,
- AccessGroup, FileSystem, NfsExport, TargetPort)
-
-from lsm.lsmcli.data_display import (
- DisplayData, PlugData, out,
- vol_provision_str_to_type, vol_rep_type_str_to_type, VolumeRAIDInfo)
-
-
-## Wraps the invocation to the command line
-# @param c Object to invoke calls on (optional)
-def cmd_line_wrapper(c=None):
- """
- Common command line code, called.
- """
- err_exit = 0
- cli = None
-
- try:
- cli = CmdLine()
- cli.process(c)
- except ArgError as ae:
- sys.stderr.write(str(ae))
- sys.stderr.flush()
- err_exit = 2
- except LsmError as le:
- sys.stderr.write(str(le) + "\n")
- sys.stderr.flush()
- err_exit = 4
- except KeyboardInterrupt:
- err_exit = 1
- finally:
- # We got here because of an exception, but we still may have a valid
- # connection to do an orderly shutdown with, lets try it before we
- # just exit closing the connection.
- if cli:
- try:
- # This will exit if are successful
- cli.shutdown(err_exit)
- except Exception:
- pass
- sys.exit(err_exit)
-
-
-## Get a character from stdin without needing a return key pressed.
-# Returns the character pressed
-def getch():
- fd = sys.stdin.fileno()
- prev = termios.tcgetattr(fd)
- try:
- tty.setraw(sys.stdin.fileno())
- ch = sys.stdin.read(1)
- finally:
- termios.tcsetattr(fd, termios.TCSADRAIN, prev)
- return ch
-
-
-def parse_convert_init(init_id):
- """
- If init_id is a WWPN, convert it into LSM standard version:
- (?:[0-9a-f]{2}:){7}[0-9a-f]{2}
-
- Return (converted_init_id, lsm_init_type)
- """
- valid, init_type, init_id = AccessGroup.initiator_id_verify(init_id)
-
- if valid:
- return (init_id, init_type)
-
- raise ArgError("--init-id %s is not a valid WWPN or iSCSI IQN" % init_id)
-
-
-## This class represents a command line argument error
-class ArgError(Exception):
- def __init__(self, message, *args, **kwargs):
- """
- Class represents an error.
- """
- Exception.__init__(self, *args, **kwargs)
- self.msg = message
-
- def __str__(self):
- return "%s: error: %s\n" % (os.path.basename(sys.argv[0]), self.msg)
-
-
-## Finds an item based on the id. Each list item requires a member "id"
-# @param l list to search
-# @param the_id the id to match
-# @param friendly_name - name to put in the exception saying what we
-# couldn't find
-def _get_item(l, the_id, friendly_name='item', raise_error=True):
- for item in l:
- if item.id == the_id:
- return item
- if raise_error:
- raise ArgError('%s with ID %s not found!' % (friendly_name, the_id))
- else:
- return None
-
-list_choices = ['VOLUMES', 'POOLS', 'FS', 'SNAPSHOTS',
- 'EXPORTS', "NFS_CLIENT_AUTH", 'ACCESS_GROUPS',
- 'SYSTEMS', 'DISKS', 'PLUGINS', 'TARGET_PORTS']
-
-provision_types = ('DEFAULT', 'THIN', 'FULL')
-provision_help = "provisioning type: " + ", ".join(provision_types)
-
-replicate_types = ('CLONE', 'COPY', 'MIRROR_ASYNC', 'MIRROR_SYNC')
-replicate_help = "replication type: " + ", ".join(replicate_types)
-
-size_help = 'Can use B, KiB, MiB, GiB, TiB, PiB postfix (IEC sizing)'
-
-sys_id_opt = dict(name='--sys', metavar='<SYS_ID>', help='System ID')
-sys_id_filter_opt = sys_id_opt.copy()
-sys_id_filter_opt['help'] = 'Search by System ID'
-
-pool_id_opt = dict(name='--pool', metavar='<POOL_ID>', help='Pool ID')
-pool_id_filter_opt = pool_id_opt.copy()
-pool_id_filter_opt['help'] = 'Search by Pool ID'
-
-vol_id_opt = dict(name='--vol', metavar='<VOL_ID>', help='Volume ID')
-vol_id_filter_opt = vol_id_opt.copy()
-vol_id_filter_opt['help'] = 'Search by Volume ID'
-
-fs_id_opt = dict(name='--fs', metavar='<FS_ID>', help='File System ID')
-
-ag_id_opt = dict(name='--ag', metavar='<AG_ID>', help='Access Group ID')
-ag_id_filter_opt = ag_id_opt.copy()
-ag_id_filter_opt['help'] = 'Search by Access Group ID'
-
-init_id_opt = dict(name='--init', metavar='<INIT_ID>', help='Initiator ID')
-snap_id_opt = dict(name='--snap', metavar='<SNAP_ID>', help='Snapshot ID')
-export_id_opt = dict(name='--export', metavar='<EXPORT_ID>', help='Export ID')
-
-nfs_export_id_filter_opt = dict(
- name='--nfs-export', metavar='<NFS_EXPORT_ID>',
- help='Search by NFS Export ID')
-
-disk_id_filter_opt = dict(name='--disk', metavar='<DISK_ID>',
- help='Search by Disk ID')
-
-size_opt = dict(name='--size', metavar='<SIZE>', help=size_help)
-
-tgt_id_opt = dict(name="--tgt", help="Search by target port ID",
- metavar='<TGT_ID>')
-
-cmds = (
- dict(
- name='list',
- help="List records of different types",
- args=[
- dict(name='--type',
- help="List records of type:\n " +
- "\n ".join(list_choices) +
- "\n\nWhen listing SNAPSHOTS, it requires --fs <FS_ID>.",
- metavar='<TYPE>',
- choices=list_choices,
- type=str.upper),
- ],
- optional=[
- dict(sys_id_filter_opt),
- dict(pool_id_filter_opt),
- dict(vol_id_filter_opt),
- dict(disk_id_filter_opt),
- dict(ag_id_filter_opt),
- dict(fs_id_opt),
- dict(nfs_export_id_filter_opt),
- dict(tgt_id_opt),
- ],
- ),
-
- dict(
- name='job-status',
- help='Retrieve information about a job',
- args=[
- dict(name="--job", metavar="<JOB_ID>", help='job status id'),
- ],
- ),
-
- dict(
- name='capabilities',
- help='Retrieves array capabilities',
- args=[
- dict(sys_id_opt),
- ],
- ),
-
- dict(
- name='plugin-info',
- help='Retrieves plugin description and version',
- ),
-
- dict(
- name='volume-create',
- help='Creates a volume (logical unit)',
- args=[
- dict(name="--name", help='volume name', metavar='<NAME>'),
- dict(size_opt),
- dict(pool_id_opt),
- ],
- optional=[
- dict(name="--provisioning", help=provision_help,
- default='DEFAULT',
- choices=provision_types,
- type=str.upper),
- ],
- ),
-
- dict(
- name='volume-delete',
- help='Deletes a volume given its id',
- args=[
- dict(vol_id_opt),
- ],
- ),
-
- dict(
- name='volume-resize',
- help='Re-sizes a volume',
- args=[
- dict(vol_id_opt),
- dict(name='--size', metavar='<NEW_SIZE>',
- help="New size. %s" % size_help),
- ],
- ),
-
- dict(
- name='volume-replicate',
- help='Creates a new volume and replicates provided volume to it.',
- args=[
- dict(vol_id_opt),
- dict(name="--name", metavar='<NEW_VOL_NAME>',
- help='The name for New replicated volume'),
- dict(name="--rep-type", metavar='<REPL_TYPE>',
- help=replicate_help, choices=replicate_types),
- ],
- optional=[
- dict(name="--pool",
- help='Pool ID to contain the new volume.\nBy default, '
- 'new volume will be created in the same pool.'),
- ],
- ),
-
- dict(
- name='volume-replicate-range',
- help='Replicates a portion of a volume',
- args=[
- dict(name="--src-vol", metavar='<SRC_VOL_ID>',
- help='Source volume id'),
- dict(name="--dst-vol", metavar='<DST_VOL_ID>',
- help='Destination volume id'),
- dict(name="--rep-type", metavar='<REP_TYPE>', help=replicate_help,
- choices=replicate_types),
- dict(name="--src-start", metavar='<SRC_START_BLK>',
- help='Source volume start block number.\n'
- 'This is repeatable argument.',
- action='append'),
- dict(name="--dst-start", metavar='<DST_START_BLK>',
- help='Destination volume start block number.\n'
- 'This is repeatable argument.',
- action='append'),
- dict(name="--count", metavar='<BLK_COUNT>',
- help='Number of blocks to replicate.\n'
- 'This is repeatable argument.',
- action='append'),
- ],
- ),
-
- dict(
- name='volume-replicate-range-block-size',
- help='Size of each replicated block on a system in bytes',
- args=[
- dict(sys_id_opt),
- ],
- ),
-
- dict(
- name='volume-dependants',
- help='Returns True if volume has a dependant child, like replication',
- args=[
- dict(vol_id_opt),
- ],
- ),
-
- dict(
- name='volume-dependants-rm',
- help='Removes dependencies',
- args=[
- dict(vol_id_opt),
- ],
- ),
-
- dict(
- name='volume-access-group',
- help='Lists the access group(s) that have access to volume',
- args=[
- dict(vol_id_opt),
- ],
- ),
-
- dict(
- name='volume-mask',
- help='Grants access to an access group to a volume, '
- 'like LUN Masking',
- args=[
- dict(vol_id_opt),
- dict(ag_id_opt),
- ],
- ),
-
- dict(
- name='volume-unmask',
- help='Revoke the access of specified access group to a volume',
- args=[
- dict(ag_id_opt),
- dict(vol_id_opt),
- ],
- ),
-
- dict(
- name='volume-enable',
- help='Enable block access of a volume',
- args=[
- dict(vol_id_opt),
- ],
- ),
-
- dict(
- name='volume-disable',
- help='Disable block access of a volume',
- args=[
- dict(vol_id_opt),
- ],
- ),
-
- dict(
- name='volume-raid-info',
- help='Query volume RAID infomation',
- args=[
- dict(vol_id_opt),
- ],
- ),
-
- dict(
- name='access-group-create',
- help='Create an access group',
- args=[
- dict(name='--name', metavar='<AG_NAME>',
- help="Human readable name for access group"),
- # TODO: _client.py access_group_create should support multiple
- # initiators when creating.
- dict(init_id_opt),
- dict(sys_id_opt),
- ],
- ),
-
- dict(
- name='access-group-add',
- help='Add an initiator into existing access group',
- args=[
- dict(ag_id_opt),
- dict(init_id_opt),
- ],
- ),
- dict(
- name='access-group-remove',
- help='Remove an initiator from existing access group',
- args=[
- dict(ag_id_opt),
- dict(init_id_opt),
- ],
- ),
-
- dict(
- name='access-group-delete',
- help='Deletes an access group',
- args=[
- dict(ag_id_opt),
- ],
- ),
-
- dict(
- name='access-group-volumes',
- help='Lists the volumes that the access group has'
- ' been granted access to',
- args=[
- dict(ag_id_opt),
- ],
- ),
-
- dict(
- name='iscsi-chap',
- help='Configures iSCSI inbound/outbound CHAP authentication',
- args=[
- dict(init_id_opt),
- ],
- optional=[
- dict(name="--in-user", metavar='<IN_USER>',
- help='Inbound chap user name'),
- dict(name="--in-pass", metavar='<IN_PASS>',
- help='Inbound chap password'),
- dict(name="--out-user", metavar='<OUT_USER>',
- help='Outbound chap user name'),
- dict(name="--out-pass", metavar='<OUT_PASS>',
- help='Outbound chap password'),
- ],
- ),
-
- dict(
- name='fs-create',
- help='Creates a file system',
- args=[
- dict(name="--name", metavar='<FS_NAME>',
- help='name of the file system'),
- dict(size_opt),
- dict(pool_id_opt),
- ],
- ),
-
- dict(
- name='fs-delete',
- help='Delete a filesystem',
- args=[
- dict(fs_id_opt)
- ],
- ),
-
- dict(
- name='fs-resize',
- help='Re-sizes a filesystem',
- args=[
- dict(fs_id_opt),
- dict(name="--size", metavar="<NEW_SIZE>",
- help="New size. %s" % size_help),
- ],
- ),
-
- dict(
- name='fs-export',
- help='Export a filesystem via NFS.',
- args=[
- dict(fs_id_opt),
- ],
- optional=[
- dict(name="--exportpath", metavar='<EXPORT_PATH>',
- help="NFS server export path. e.g. '/foo/bar'."),
- dict(name="--anonuid", metavar='<ANON_UID>',
- help='UID(User ID) to map to anonymous user',
- default=NfsExport.ANON_UID_GID_NA,
- type=long),
- dict(name="--anongid", metavar='<ANON_GID>',
- help='GID(Group ID) to map to anonymous user',
- default=NfsExport.ANON_UID_GID_NA,
- type=long),
- dict(name="--auth-type", metavar='<AUTH_TYPE>',
- help='NFS client authentication type'),
- dict(name="--root-host", metavar='<ROOT_HOST>',
- help="The host/IP has root access.\n"
- "This is repeatable argument.",
- action='append',
- default=[]),
- dict(name="--ro-host", metavar='<RO_HOST>',
- help="The host/IP has readonly access.\n"
- "This is repeatable argument.",
- action='append', default=[]),
- dict(name="--rw-host", metavar='<RW_HOST>',
- help="The host/IP has readwrite access.\n"
- "This is repeatable argument.",
- action='append', default=[]),
- ],
- ),
-
- dict(
- name='fs-unexport',
- help='Remove an NFS export',
- args=[
- dict(export_id_opt),
- ],
- ),
-
- dict(
- name='fs-clone',
- help='Creates a file system clone',
- args=[
- dict(name="--src-fs", metavar='<SRC_FS_ID>',
- help='The ID of existing source file system.'),
- dict(name="--dst-name", metavar='<DST_FS_NAME>',
- help='The name for newly created destination file system.'),
- ],
- optional=[
- dict(name="--backing-snapshot", metavar='<BE_SS_ID>',
- help='backing snapshot id'),
- ],
- ),
-
- dict(
- name='fs-snap-create',
- help='Creates a snapshot',
- args=[
- dict(name="--name", metavar="<SNAP_NAME>",
- help='The human friendly name of new snapshot'),
- dict(fs_id_opt),
- ],
- ),
-
- dict(
- name='fs-snap-delete',
- help='Deletes a snapshot',
- args=[
- dict(snap_id_opt),
- dict(fs_id_opt), # TODO: why we need filesystem ID?
- ],
- ),
-
- dict(
- name='fs-snap-restore',
- help='Restores a FS or specified files to '
- 'previous snapshot state',
- args=[
- dict(snap_id_opt),
- dict(fs_id_opt),
- ],
- optional=[
- dict(name="--file", metavar="<FILE_PATH>",
- help="Only restore provided file\n"
- "Without this argument, all files will be restored\n"
- "This is a repeatable argument.",
- action='append', default=[]),
- dict(name="--fileas", metavar="<NEW_FILE_PATH>",
- help="store restore file name to another name.\n"
- "This is a repeatable argument.",
- action='append',
- default=[]),
- ],
- ),
-
- dict(
- name='fs-dependants',
- help='Returns True if filesystem has a child '
- 'dependency(clone/snapshot) exists',
- args=[
- dict(fs_id_opt),
- ],
- optional=[
- dict(name="--file", metavar="<FILE_PATH>",
- action="append", default=[],
- help="For file check\nThis is a repeatable argument."),
- ],
- ),
-
- dict(
- name='fs-dependants-rm',
- help='Removes file system dependencies',
- args=[
- dict(fs_id_opt),
- ],
- optional=[
- dict(name="--file", action='append', default=[],
- help='File or files to remove dependencies for.\n'
- "This is a repeatable argument.",),
- ],
- ),
-
-
- dict(
- name='file-clone',
- help='Creates a clone of a file (thin provisioned)',
- args=[
- dict(fs_id_opt),
- dict(name="--src", metavar="<SRC_FILE_PATH>",
- help='source file to clone (relative path)\n'
- "This is a repeatable argument.",),
- dict(name="--dst", metavar="<DST_FILE_PATH>",
- help='Destination file (relative path)'
- ", this is a repeatable argument."),
- ],
- optional=[
- dict(name="--backing-snapshot", help='backing snapshot id'),
- ],
- ),
-
-)
-
-aliases = (
- ['ls', 'list --type systems'],
- ['lp', 'list --type pools'],
- ['lv', 'list --type volumes'],
- ['ld', 'list --type disks'],
- ['la', 'list --type access_groups'],
- ['lf', 'list --type fs'],
- ['lt', 'list --type target_ports'],
- ['c', 'capabilities'],
- ['p', 'plugin-info'],
- ['vc', 'volume-create'],
- ['vd', 'volume-delete'],
- ['vr', 'volume-resize'],
- ['vm', 'volume-mask'],
- ['vu', 'volume-unmask'],
- ['ve', 'volume-enable'],
- ['vi', 'volume-disable'],
- ['ac', 'access-group-create'],
- ['aa', 'access-group-add'],
- ['ar', 'access-group-remove'],
- ['ad', 'access-group-delete'],
- ['vri', 'volume-raid-info'],
-)
-
-
-## Class that encapsulates the command line arguments for lsmcli
-# Note: This class is used by lsmcli and any python plug-ins.
-class CmdLine:
- """
- Command line interface class.
- """
-
- ##
- # Warn of imminent data loss
- # @param deleting Indicate data will be lost vs. may be lost
- # (re-size)
- # @return True if operation confirmed, else False
- def confirm_prompt(self, deleting):
- """
- Give the user a chance to bail.
- """
- if not self.args.force:
- msg = "will" if deleting else "may"
- out("Warning: You are about to do an operation that %s cause data "
- "to be lost!\nPress [Y|y] to continue, any other key to abort"
- % msg)
-
- pressed = getch()
- if pressed.upper() == 'Y':
- return True
- else:
- out('Operation aborted!')
- return False
- else:
- return True
-
- ##
- # Tries to make the output better when it varies considerably from
- # plug-in to plug-in.
- # @param objects Data, first row is header all other data.
- def display_data(self, objects):
- display_all = False
-
- if len(objects) == 0:
- return
-
- display_way = DisplayData.DISPLAY_WAY_DEFAULT
-
- flag_with_header = True
- if self.args.sep:
- flag_with_header = False
- if self.args.header:
- flag_with_header = True
-
- if self.args.script:
- display_way = DisplayData.DISPLAY_WAY_SCRIPT
-
- DisplayData.display_data(
- objects, display_way=display_way, flag_human=self.args.human,
- flag_enum=self.args.enum,
- splitter=self.args.sep, flag_with_header=flag_with_header,
- flag_dsp_all_data=display_all)
-
- def display_available_plugins(self):
- d = []
- sep = '<}{>'
- plugins = Client.available_plugins(sep)
-
- for p in plugins:
- desc, version = p.split(sep)
- d.append(PlugData(desc, version))
-
- self.display_data(d)
-
- def handle_alias(self, args):
- cmd_arguments = args.cmd
- cmd_arguments.extend(self.unknown_args)
- new_args = self.parser.parse_args(cmd_arguments)
- new_args.func(new_args)
-
- ## All the command line arguments and options are created in this method
- def cli(self):
- """
- Command line interface parameters
- """
- parent_parser = ArgumentParser(add_help=False)
-
- parent_parser.add_argument(
- '-v', '--version', action='version',
- version="%s %s" % (sys.argv[0], VERSION))
-
- parent_parser.add_argument(
- '-u', '--uri', action="store", type=str, metavar='<URI>',
- dest="uri", help='Uniform resource identifier (env LSMCLI_URI)')
-
- parent_parser.add_argument(
- '-P', '--prompt', action="store_true", dest="prompt",
- help='Prompt for password (env LSMCLI_PASSWORD)')
-
- parent_parser.add_argument(
- '-H', '--human', action="store_true", dest="human",
- help='Print sizes in human readable format\n'
- '(e.g., MiB, GiB, TiB)')
-
- parent_parser.add_argument(
- '-t', '--terse', action="store", dest="sep", metavar='<SEP>',
- help='Print output in terse form with "SEP" '
- 'as a record separator')
-
- parent_parser.add_argument(
- '-e', '--enum', action="store_true", dest="enum", default=False,
- help='Display enumerated types as numbers instead of text')
-
- parent_parser.add_argument(
- '-f', '--force', action="store_true", dest="force", default=False,
- help='Bypass confirmation prompt for data loss operations')
-
- parent_parser.add_argument(
- '-w', '--wait', action="store", type=int, dest="wait",
- default=30000, help="Command timeout value in ms (default = 30s)")
-
- parent_parser.add_argument(
- '--header', action="store_true", dest="header",
- help='Include the header with terse')
-
- parent_parser.add_argument(
- '-b', action="store_true", dest="async", default=False,
- help='Run the command async. Instead of waiting for completion.\n '
- 'Command will exit(7) and job id written to stdout.')
-
- parent_parser.add_argument(
- '-s', '--script', action="store_true", dest="script",
- default=False, help='Displaying data in script friendly way.')
-
- parser = ArgumentParser(
- description='The libStorageMgmt command line interface.'
- ' Run %(prog)s <command> -h for more on each command.',
- epilog='Copyright 2012-2014 Red Hat, Inc.\n'
- 'Please report bugs to '
- '<libstoragemgmt-***@lists.sourceforge.net>\n',
- formatter_class=RawTextHelpFormatter,
- parents=[parent_parser])
-
- subparsers = parser.add_subparsers(metavar="command")
-
- # Walk the command list and add all of them to the parser
- for cmd in cmds:
- sub_parser = subparsers.add_parser(
- cmd['name'], help=cmd['help'], parents=[parent_parser],
- formatter_class=RawTextHelpFormatter)
-
- group = sub_parser.add_argument_group("cmd required arguments")
- for arg in cmd.get('args', []):
- name = arg['name']
- del arg['name']
- group.add_argument(name, required=True, **arg)
-
- group = sub_parser.add_argument_group("cmd optional arguments")
- for arg in cmd.get('optional', []):
- flags = arg['name']
- del arg['name']
- if not isinstance(flags, tuple):
- flags = (flags,)
- group.add_argument(*flags, **arg)
-
- sub_parser.set_defaults(
- func=getattr(self, cmd['name'].replace("-", "_")))
-
- for alias in aliases:
- sub_parser = subparsers.add_parser(
- alias[0], help="Alias of '%s'" % alias[1],
- parents=[parent_parser],
- formatter_class=RawTextHelpFormatter, add_help=False)
- sub_parser.set_defaults(
- cmd=alias[1].split(" "), func=self.handle_alias)
-
- self.parser = parser
- known_agrs, self.unknown_args = parser.parse_known_args()
- return known_agrs
-
- ## Display the types of nfs client authentication that are supported.
- # @return None
- def display_nfs_client_authentication(self):
- """
- Dump the supported nfs client authentication types
- """
- if self.args.sep:
- out(self.args.sep.join(self.c.export_auth()))
- else:
- out(", ".join(self.c.export_auth()))
-
- ## Method that calls the appropriate method based on what the list type is
- # @param args Argparse argument object
- def list(self, args):
- search_key = None
- search_value = None
- if args.sys:
- search_key = 'system_id'
- search_value = args.sys
- if args.pool:
- search_key = 'pool_id'
- search_value = args.pool
- if args.vol:
- search_key = 'volume_id'
- search_value = args.vol
- if args.disk:
- search_key = 'disk_id'
- search_value = args.disk
- if args.ag:
- search_key = 'access_group_id'
- search_value = args.ag
- if args.fs:
- search_key = 'fs_id'
- search_value = args.ag
- if args.nfs_export:
- search_key = 'nfs_export_id'
- search_value = args.nfs_export
- if args.tgt:
- search_key = 'tgt_port_id'
- search_value = args.tgt
-
- if args.type == 'VOLUMES':
- if search_key == 'volume_id':
- search_key = 'id'
- if search_key == 'access_group_id':
- lsm_ag = _get_item(self.c.access_groups(), args.ag,
- "Access Group", raise_error=False)
- if lsm_ag:
- return self.display_data(
- self.c.volumes_accessible_by_access_group(lsm_ag))
- else:
- return self.display_data([])
- elif search_key and search_key not in Volume.SUPPORTED_SEARCH_KEYS:
- raise ArgError("Search key '%s' is not supported by "
- "volume listing." % search_key)
- self.display_data(self.c.volumes(search_key, search_value))
- elif args.type == 'POOLS':
- if search_key == 'pool_id':
- search_key = 'id'
- if search_key and search_key not in Pool.SUPPORTED_SEARCH_KEYS:
- raise ArgError("Search key '%s' is not supported by "
- "pool listing." % search_key)
- self.display_data(
- self.c.pools(search_key, search_value))
- elif args.type == 'FS':
- if search_key == 'fs_id':
- search_key = 'id'
- if search_key and \
- search_key not in FileSystem.SUPPORTED_SEARCH_KEYS:
- raise ArgError("Search key '%s' is not supported by "
- "volume listing." % search_key)
- self.display_data(self.c.fs(search_key, search_value))
- elif args.type == 'SNAPSHOTS':
- if args.fs is None:
- raise ArgError("--fs <file system id> required")
- fs = _get_item(self.c.fs(), args.fs, 'File System')
- self.display_data(self.c.fs_snapshots(fs))
- elif args.type == 'EXPORTS':
- if search_key == 'nfs_export_id':
- search_key = 'id'
- if search_key and \
- search_key not in NfsExport.SUPPORTED_SEARCH_KEYS:
- raise ArgError("Search key '%s' is not supported by "
- "NFS Export listing" % search_key)
- self.display_data(self.c.exports(search_key, search_value))
- elif args.type == 'NFS_CLIENT_AUTH':
- self.display_nfs_client_authentication()
- elif args.type == 'ACCESS_GROUPS':
- if search_key == 'access_group_id':
- search_key = 'id'
- if search_key == 'volume_id':
- lsm_vol = _get_item(self.c.volumes(), args.vol,
- "Volume", raise_error=False)
- if lsm_vol:
- return self.display_data(
- self.c.access_groups_granted_to_volume(lsm_vol))
- else:
- return self.display_data([])
- elif (search_key and
- search_key not in AccessGroup.SUPPORTED_SEARCH_KEYS):
- raise ArgError("Search key '%s' is not supported by "
- "Access Group listing" % search_key)
- self.display_data(
- self.c.access_groups(search_key, search_value))
- elif args.type == 'SYSTEMS':
- if search_key:
- raise ArgError("System listing with search is not supported")
- self.display_data(self.c.systems())
- elif args.type == 'DISKS':
- if search_key == 'disk_id':
- search_key = 'id'
- if search_key and search_key not in Disk.SUPPORTED_SEARCH_KEYS:
- raise ArgError("Search key '%s' is not supported by "
- "disk listing" % search_key)
- self.display_data(
- self.c.disks(search_key, search_value))
- elif args.type == 'TARGET_PORTS':
- if search_key == 'tgt_port_id':
- search_key = 'id'
- if search_key and \
- search_key not in TargetPort.SUPPORTED_SEARCH_KEYS:
- raise ArgError("Search key '%s' is not supported by "
- "target port listing" % search_key)
- self.display_data(
- self.c.target_ports(search_key, search_value))
- elif args.type == 'PLUGINS':
- self.display_available_plugins()
- else:
- raise ArgError("unsupported listing type=%s" % args.type)
-
- ## Creates an access group.
- def access_group_create(self, args):
- system = _get_item(self.c.systems(), args.sys, "System")
- (init_id, init_type) = parse_convert_init(args.init)
- access_group = self.c.access_group_create(args.name, init_id,
- init_type, system)
- self.display_data([access_group])
-
- def _add_rm_access_grp_init(self, args, op):
- lsm_ag = _get_item(self.c.access_groups(), args.ag, "Access Group")
- (init_id, init_type) = parse_convert_init(args.init)
-
- if op:
- return self.c.access_group_initiator_add(lsm_ag, init_id,
- init_type)
- else:
- return self.c.access_group_initiator_delete(lsm_ag, init_id,
- init_type)
-
- ## Adds an initiator from an access group
- def access_group_add(self, args):
- self.display_data([self._add_rm_access_grp_init(args, True)])
-
- ## Removes an initiator from an access group
- def access_group_remove(self, args):
- self.display_data([self._add_rm_access_grp_init(args, False)])
-
- def access_group_volumes(self, args):
- agl = self.c.access_groups()
- group = _get_item(agl, args.ag, "Access Group")
- vols = self.c.volumes_accessible_by_access_group(group)
- self.display_data(vols)
-
- def iscsi_chap(self, args):
- (init_id, init_type) = parse_convert_init(args.init)
- if init_type != AccessGroup.INIT_TYPE_ISCSI_IQN:
- raise ArgError("--init-id %s is not a valid iSCSI IQN" % args.init)
-
- self.c.iscsi_chap_auth(init_id, args.in_user,
- self.args.in_pass,
- self.args.out_user,
- self.args.out_pass)
-
- def volume_access_group(self, args):
- vol = _get_item(self.c.volumes(), args.vol, "Volume")
- groups = self.c.access_groups_granted_to_volume(vol)
- self.display_data(groups)
-
- ## Used to delete access group
- def access_group_delete(self, args):
- agl = self.c.access_groups()
- group = _get_item(agl, args.ag, "Access Group")
- return self.c.access_group_delete(group)
-
- ## Used to delete a file system
- def fs_delete(self, args):
- fs = _get_item(self.c.fs(), args.fs, "File System")
- if self.confirm_prompt(True):
- self._wait_for_it("fs-delete", self.c.fs_delete(fs), None)
-
- ## Used to create a file system
- def fs_create(self, args):
- p = _get_item(self.c.pools(), args.pool, "Pool")
- fs = self._wait_for_it("fs-create",
- *self.c.fs_create(p, args.name,
- self._size(args.size)))
- self.display_data([fs])
-
- ## Used to resize a file system
- def fs_resize(self, args):
- fs = _get_item(self.c.fs(), args.fs, "File System")
- size = self._size(args.size)
-
- if self.confirm_prompt(False):
- fs = self._wait_for_it("fs-resize",
- *self.c.fs_resize(fs, size))
- self.display_data([fs])
-
- ## Used to clone a file system
- def fs_clone(self, args):
- src_fs = _get_item(
- self.c.fs(), args.src_fs, "Source File System")
-
- ss = None
- if args.backing_snapshot:
- #go get the snapshot
- ss = _get_item(self.c.fs_snapshots(src_fs),
- args.backing_snapshot, "Snapshot")
-
- fs = self._wait_for_it(
- "fs_clone", *self.c.fs_clone(src_fs, args.dst_name, ss))
- self.display_data([fs])
-
- ## Used to clone a file(s)
- def file_clone(self, args):
- fs = _get_item(self.c.fs(), args.fs, "File System")
- if self.args.backing_snapshot:
- #go get the snapshot
- ss = _get_item(self.c.fs_snapshots(fs),
- args.backing_snapshot, "Snapshot")
- else:
- ss = None
-
- self._wait_for_it(
- "fs_file_clone", self.c.fs_file_clone(fs, args.src, args.dst, ss),
- None)
-
- ##Converts a size parameter into the appropriate number of bytes
- # @param s Size to convert to bytes handles B, K, M, G, T, P postfix
- # @return Size in bytes
- @staticmethod
- def _size(s):
- size_bytes = size_human_2_size_bytes(s)
- if size_bytes <= 0:
- raise ArgError("Incorrect size argument format: '%s'" % s)
- return size_bytes
-
- def _cp(self, cap, val):
- if self.args.sep is not None:
- s = self.args.sep
- else:
- s = ':'
-
- if val:
- v = "SUPPORTED"
- else:
- v = "UNSUPPORTED"
-
- out("%s%s%s" % (cap, s, v))
-
- def capabilities(self, args):
- s = _get_item(self.c.systems(), args.sys, "System")
-
- cap = self.c.capabilities(s)
- sup_caps = sorted(cap.get_supported().values())
- all_caps = sorted(cap.get_supported(True).values())
-
- sep = DisplayData.DEFAULT_SPLITTER
- if self.args.sep is not None:
- sep = self.args.sep
-
- cap_data = OrderedDict()
- # Show support capabilities first
- for v in sup_caps:
- cap_data[v] = 'SUPPORTED'
-
- for v in all_caps:
- if v not in sup_caps:
- cap_data[v] = 'UNSUPPORTED'
-
- DisplayData.display_data_script_way([cap_data], sep)
-
- def plugin_info(self, args):
- desc, version = self.c.plugin_info()
-
- if args.sep:
- out("%s%s%s" % (desc, args.sep, version))
- else:
- out("Description: %s Version: %s" % (desc, version))
-
- ## Creates a volume
- def volume_create(self, args):
- #Get pool
- p = _get_item(self.c.pools(), args.pool, "Pool")
- vol = self._wait_for_it(
- "volume-create",
- *self.c.volume_create(
- p,
- args.name,
- self._size(args.size),
- vol_provision_str_to_type(args.provisioning)))
- self.display_data([vol])
-
- ## Creates a snapshot
- def fs_snap_create(self, args):
- #Get fs
- fs = _get_item(self.c.fs(), args.fs, "File System")
- ss = self._wait_for_it("snapshot-create",
- *self.c.fs_snapshot_create(
- fs,
- args.name))
-
- self.display_data([ss])
-
- ## Restores a snap shot
- def fs_snap_restore(self, args):
- #Get snapshot
- fs = _get_item(self.c.fs(), args.fs, "File System")
- ss = _get_item(self.c.fs_snapshots(fs), args.snap, "Snapshot")
-
- flag_all_files = True
-
- if self.args.file:
- flag_all_files = False
- if self.args.fileas:
- if len(self.args.file) != len(self.args.fileas):
- raise ArgError(
- "number of --file not equal to --fileas")
-
- if self.confirm_prompt(True):
- self._wait_for_it(
- 'fs-snap-restore',
- self.c.fs_snapshot_restore(
- fs, ss, self.args.file, self.args.fileas, flag_all_files),
- None)
-
- ## Deletes a volume
- def volume_delete(self, args):
- v = _get_item(self.c.volumes(), args.vol, "Volume")
- if self.confirm_prompt(True):
- self._wait_for_it("volume-delete", self.c.volume_delete(v),
- None)
-
- ## Deletes a snap shot
- def fs_snap_delete(self, args):
- fs = _get_item(self.c.fs(), args.fs, "File System")
- ss = _get_item(self.c.fs_snapshots(fs), args.snap, "Snapshot")
-
- if self.confirm_prompt(True):
- self._wait_for_it("fs_snap_delete",
- self.c.fs_snapshot_delete(fs, ss), None)
-
- ## Waits for an operation to complete by polling for the status of the
- # operations.
- # @param msg Message to display if this job fails
- # @param job The job id to wait on
- # @param item The item that could be available now if there is no job
- def _wait_for_it(self, msg, job, item):
- if not job:
- return item
- else:
- #If a user doesn't want to wait, return the job id to stdout
- #and exit with job in progress
- if self.args.async:
- out(job)
- self.shutdown(ErrorNumber.JOB_STARTED)
-
- while True:
- (s, percent, item) = self.c.job_status(job)
-
- if s == JobStatus.INPROGRESS:
- #Add an option to spit out progress?
- #print "%s - Percent %s complete" % (job, percent)
- time.sleep(0.25)
- elif s == JobStatus.COMPLETE:
- self.c.job_free(job)
- return item
- else:
- #Something better to do here?
- raise ArgError(msg + " job error code= " + str(s))
-
- ## Retrieves the status of the specified job
- def job_status(self, args):
- (s, percent, item) = self.c.job_status(args.job)
-
- if s == JobStatus.COMPLETE:
- if item:
- self.display_data([item])
-
- self.c.job_free(args.job)
- else:
- out(str(percent))
- self.shutdown(ErrorNumber.JOB_STARTED)
-
- ## Replicates a volume
- def volume_replicate(self, args):
- p = None
- if args.pool:
- p = _get_item(self.c.pools(), args.pool, "Pool")
-
- v = _get_item(self.c.volumes(), args.vol, "Volume")
-
- rep_type = vol_rep_type_str_to_type(args.rep_type)
- if rep_type == Volume.REPLICATE_UNKNOWN:
- raise ArgError("invalid replication type= %s" % rep_type)
-
- vol = self._wait_for_it(
- "replicate volume",
- *self.c.volume_replicate(p, rep_type, v, args.name))
- self.display_data([vol])
-
- ## Replicates a range of a volume
- def volume_replicate_range(self, args):
- src = _get_item(self.c.volumes(), args.src_vol, "Source Volume")
- dst = _get_item(self.c.volumes(), args.dst_vol,
- "Destination Volume")
-
- rep_type = vol_rep_type_str_to_type(args.rep_type)
- if rep_type == Volume.REPLICATE_UNKNOWN:
- raise ArgError("invalid replication type= %s" % rep_type)
-
- src_starts = args.src_start
- dst_starts = args.dst_start
- counts = args.count
-
- if not len(src_starts) \
- or not (len(src_starts) == len(dst_starts) == len(counts)):
- raise ArgError("Differing numbers of src_start, dest_start, "
- "and count parameters")
-
- ranges = []
- for b in range(len(src_starts)):
- ranges.append(BlockRange(src_starts[b], dst_starts[b], counts[b]))
-
- if self.confirm_prompt(False):
- self.c.volume_replicate_range(rep_type, src, dst, ranges)
-
- ##
- # Returns the block size in bytes for each block represented in
- # volume_replicate_range
- def volume_replicate_range_block_size(self, args):
- s = _get_item(self.c.systems(), args.sys, "System")
- out(self.c.volume_replicate_range_block_size(s))
-
- def volume_mask(self, args):
- vol = _get_item(self.c.volumes(), args.vol, 'Volume')
- ag = _get_item(self.c.access_groups(), args.ag, 'Access Group')
- self.c.volume_mask(ag, vol)
-
- def volume_unmask(self, args):
- ag = _get_item(self.c.access_groups(), args.ag, "Access Group")
- vol = _get_item(self.c.volumes(), args.vol, "Volume")
- return self.c.volume_unmask(ag, vol)
-
- ## Re-sizes a volume
- def volume_resize(self, args):
- v = _get_item(self.c.volumes(), args.vol, "Volume")
- size = self._size(args.size)
-
- if self.confirm_prompt(False):
- vol = self._wait_for_it("resize",
- *self.c.volume_resize(v, size))
- self.display_data([vol])
-
- ## Enable a volume
- def volume_enable(self, args):
- v = _get_item(self.c.volumes(), args.vol, "Volume")
- self.c.volume_enable(v)
-
- ## Disable a volume
- def volume_disable(self, args):
- v = _get_item(self.c.volumes(), args.vol, "Volume")
- self.c.volume_disable(v)
-
- ## Removes a nfs export
- def fs_unexport(self, args):
- export = _get_item(self.c.exports(), args.export, "NFS Export")
- self.c.export_remove(export)
-
- ## Exports a file system as a NFS export
- def fs_export(self, args):
- fs = _get_item(self.c.fs(), args.fs, "File System")
-
- # Check to see if we have some type of access specified
- if len(args.rw_host) == 0 \
- and len(args.ro_host) == 0:
- raise ArgError(" please specify --ro-host or --rw-host")
-
- export = self.c.export_fs(
- fs.id,
- args.exportpath,
- args.root_host,
- args.rw_host,
- args.ro_host,
- args.anonuid,
- args.anongid,
- args.auth_type,
- None)
- self.display_data([export])
-
- ## Displays volume dependants.
- def volume_dependants(self, args):
- v = _get_item(self.c.volumes(), args.vol, "Volume")
- rc = self.c.volume_child_dependency(v)
- out(rc)
-
- ## Removes volume dependants.
- def volume_dependants_rm(self, args):
- v = _get_item(self.c.volumes(), args.vol, "Volume")
- self._wait_for_it("volume-dependant-rm",
- self.c.volume_child_dependency_rm(v), None)
-
- def volume_raid_info(self, args):
- lsm_vol = _get_item(self.c.volumes(), args.vol, "Volume")
- self.display_data(
- [
- VolumeRAIDInfo(
- lsm_vol.id, *self.c.volume_raid_info(lsm_vol))])
-
- ## Displays file system dependants
- def fs_dependants(self, args):
- fs = _get_item(self.c.fs(), args.fs, "File System")
- rc = self.c.fs_child_dependency(fs, args.file)
- out(rc)
-
- ## Removes file system dependants
- def fs_dependants_rm(self, args):
- fs = _get_item(self.c.fs(), args.fs, "File System")
- self._wait_for_it("fs-dependants-rm",
- self.c.fs_child_dependency_rm(fs,
- args.file),
- None)
-
- def _read_configfile(self):
- """
- Set uri from config file. Will be overridden by cmdline option or
- env var if present.
- """
-
- allowed_config_options = ("uri",)
-
- config_path = os.path.expanduser("~") + "/.lsmcli"
- if not os.path.exists(config_path):
- return
-
- with open(config_path) as f:
- for line in f:
-
- if line.lstrip().startswith("#"):
- continue
-
- try:
- name, val = [x.strip() for x in line.split("=", 1)]
- if name in allowed_config_options:
- setattr(self, name, val)
- except ValueError:
- pass
-
- ## Class constructor.
- def __init__(self):
- self.uri = None
- self.c = None
- self.parser = None
- self.unknown_args = None
- self.args = self.cli()
-
- self.cleanup = None
-
- self.tmo = int(self.args.wait)
- if not self.tmo or self.tmo < 0:
- raise ArgError("[-w|--wait] requires a non-zero positive integer")
-
- self._read_configfile()
- if os.getenv('LSMCLI_URI') is not None:
- self.uri = os.getenv('LSMCLI_URI')
- self.password = os.getenv('LSMCLI_PASSWORD')
- if self.args.uri is not None:
- self.uri = self.args.uri
-
- if self.uri is None:
- # We need a valid plug-in to instantiate even if all we are trying
- # to do is list the plug-ins at the moment to keep that code
- # the same in all cases, even though it isn't technically
- # required for the client library (static method)
- # TODO: Make this not necessary.
- if ('type' in self.args and self.args.type == "PLUGINS"):
- self.uri = "sim://"
- self.password = None
- else:
- raise ArgError("--uri missing or export LSMCLI_URI")
-
- # Lastly get the password if requested.
- if self.args.prompt:
- self.password = getpass.getpass()
-
- if self.password is not None:
- #Check for username
- u = uri_parse(self.uri)
- if u['username'] is None:
- raise ArgError("password specified with no user name in uri")
-
- ## Does appropriate clean-up
- # @param ec The exit code
- def shutdown(self, ec=None):
- if self.cleanup:
- self.cleanup()
-
- if ec:
- sys.exit(ec)
-
- ## Process the specified command
- # @param cli The object instance to invoke methods on.
- def process(self, cli=None):
- """
- Process the parsed command.
- """
- if cli:
- #Directly invoking code though a wrapper to catch unsupported
- #operations.
- self.c = Proxy(cli())
- self.c.plugin_register(self.uri, self.password, self.tmo)
- self.cleanup = self.c.plugin_unregister
- else:
- #Going across the ipc pipe
- self.c = Proxy(Client(self.uri, self.password, self.tmo))
-
- if os.getenv('LSM_DEBUG_PLUGIN'):
- raw_input(
- "Attach debugger to plug-in, press <return> when ready...")
-
- self.cleanup = self.c.close
-
- self.args.func(self.args)
- self.shutdown()
diff --git a/tools/lsmcli/data_display.py b/tools/lsmcli/data_display.py
deleted file mode 100644
index 19f7114..0000000
--- a/tools/lsmcli/data_display.py
+++ /dev/null
@@ -1,768 +0,0 @@
-# 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
-# USA
-#
-# Author: Gris Ge <***@redhat.com>
-import sys
-
-try:
- from collections import OrderedDict
-except ImportError:
- # python 2.6 or earlier, use backport
- from ordereddict import OrderedDict
-
-from datetime import datetime
-
-from lsm import (size_bytes_2_size_human, LsmError, ErrorNumber,
- System, Pool, Disk, Volume, AccessGroup,
- FileSystem, FsSnapshot, NfsExport, TargetPort)
-
-BIT_MAP_STRING_SPLITTER = ','
-
-
-## Users are reporting errors with broken pipe when piping output
-# to another program. This appears to be related to this issue:
-# http://bugs.python.org/issue11380
-# Unable to reproduce, but hopefully this will address it.
-# @param msg The message to be written to stdout
-def out(msg):
- try:
- sys.stdout.write(str(msg))
- sys.stdout.write("\n")
- sys.stdout.flush()
- except IOError:
- sys.exit(1)
-
-
-def _bit_map_to_str(bit_map, conv_dict):
- rc = []
- bit_map = int(bit_map)
- for cur_enum in conv_dict.keys():
- if cur_enum & bit_map:
- rc.append(conv_dict[cur_enum])
- # If there are no bits set we really don't need a string
- if bit_map != 0 and len(rc) == 0:
- return 'Unknown(%s)' % hex(bit_map)
- return BIT_MAP_STRING_SPLITTER.join(rc)
-
-
-def _enum_type_to_str(int_type, conv_dict):
- rc = ''
- int_type = int(int_type)
-
- if int_type in conv_dict.keys():
- return conv_dict[int_type]
- return 'Unknown(%d)' % int_type
-
-
-def _str_to_enum(type_str, conv_dict):
- keys = [k for k, v in conv_dict.items() if v.lower() == type_str.lower()]
- if len(keys) > 0:
- return keys[0]
- raise LsmError(ErrorNumber.INVALID_ARGUMENT,
- "Failed to convert %s to lsm type" % type_str)
-
-
-_SYSTEM_STATUS_CONV = {
- System.STATUS_UNKNOWN: 'Unknown',
- System.STATUS_OK: 'OK',
- System.STATUS_ERROR: 'Error',
- System.STATUS_DEGRADED: 'Degraded',
- System.STATUS_PREDICTIVE_FAILURE: 'Predictive failure',
- System.STATUS_OTHER: 'Other',
-}
-
-
-def system_status_to_str(system_status):
- return _bit_map_to_str(system_status, _SYSTEM_STATUS_CONV)
-
-
-_POOL_STATUS_CONV = {
- Pool.STATUS_UNKNOWN: 'Unknown',
- Pool.STATUS_OK: 'OK',
- Pool.STATUS_OTHER: 'Other',
- Pool.STATUS_DEGRADED: 'Degraded',
- Pool.STATUS_ERROR: 'Error',
- Pool.STATUS_STOPPED: 'Stopped',
- Pool.STATUS_RECONSTRUCTING: 'Reconstructing',
- Pool.STATUS_VERIFYING: 'Verifying',
- Pool.STATUS_INITIALIZING: 'Initializing',
- Pool.STATUS_GROWING: 'Growing',
-}
-
-
-def pool_status_to_str(pool_status):
- return _bit_map_to_str(pool_status, _POOL_STATUS_CONV)
-
-
-_POOL_ELEMENT_TYPE_CONV = {
- Pool.ELEMENT_TYPE_POOL: 'POOL',
- Pool.ELEMENT_TYPE_VOLUME: 'VOLUME',
- Pool.ELEMENT_TYPE_VOLUME_THIN: 'VOLUME_THIN',
- Pool.ELEMENT_TYPE_VOLUME_FULL: 'VOLUME_FULL',
- Pool.ELEMENT_TYPE_FS: 'FS',
- Pool.ELEMENT_TYPE_SYS_RESERVED: 'SYSTEM_RESERVED',
- Pool.ELEMENT_TYPE_DELTA: "DELTA",
-}
-
-_POOL_UNSUPPORTED_ACTION_CONV = {
- Pool.UNSUPPORTED_VOLUME_GROW: "Volume Grow",
- Pool.UNSUPPORTED_VOLUME_SHRINK: "Volume Shrink"
-}
-
-
-def pool_element_type_to_str(element_type):
- return _bit_map_to_str(element_type, _POOL_ELEMENT_TYPE_CONV)
-
-
-def pool_unsupported_actions_to_str(unsupported_actions):
- return _bit_map_to_str(unsupported_actions, _POOL_UNSUPPORTED_ACTION_CONV)
-
-
-_VOL_PROVISION_CONV = {
- Volume.PROVISION_DEFAULT: 'DEFAULT',
- Volume.PROVISION_FULL: 'FULL',
- Volume.PROVISION_THIN: 'THIN',
- Volume.PROVISION_UNKNOWN: 'UNKNOWN',
-}
-
-
-def vol_provision_str_to_type(vol_provision_str):
- return _str_to_enum(vol_provision_str, _VOL_PROVISION_CONV)
-
-
-_VOL_ADMIN_STATE_CONV = {
- Volume.ADMIN_STATE_DISABLED: 'Yes',
- Volume.ADMIN_STATE_ENABLED: 'No',
-}
-
-
-def vol_admin_state_to_str(vol_admin_state):
- return _enum_type_to_str(vol_admin_state, _VOL_ADMIN_STATE_CONV)
-
-
-_VOL_REP_TYPE_CONV = {
- Volume.REPLICATE_CLONE: 'CLONE',
- Volume.REPLICATE_COPY: 'COPY',
- Volume.REPLICATE_MIRROR_SYNC: 'MIRROR_SYNC',
- Volume.REPLICATE_MIRROR_ASYNC: 'MIRROR_ASYNC',
- Volume.REPLICATE_UNKNOWN: 'UNKNOWN',
-}
-
-
-def vol_rep_type_str_to_type(vol_rep_type_str):
- return _str_to_enum(vol_rep_type_str, _VOL_REP_TYPE_CONV)
-
-
-_DISK_TYPE_CONV = {
- Disk.TYPE_UNKNOWN: 'UNKNOWN',
- Disk.TYPE_OTHER: 'Other',
- Disk.TYPE_ATA: 'ATA',
- Disk.TYPE_SATA: 'SATA',
- Disk.TYPE_SAS: 'SAS',
- Disk.TYPE_FC: 'FC',
- Disk.TYPE_SOP: 'SCSI Over PCI-E(SSD)',
- Disk.TYPE_SCSI: 'SCSI',
- Disk.TYPE_NL_SAS: 'NL_SAS',
- Disk.TYPE_HDD: 'HDD',
- Disk.TYPE_SSD: 'SSD',
- Disk.TYPE_HYBRID: 'Hybrid',
- Disk.TYPE_LUN: 'Remote LUN',
-}
-
-
-def disk_type_to_str(disk_type):
- return _enum_type_to_str(disk_type, _DISK_TYPE_CONV)
-
-
-_DISK_STATUS_CONV = {
- Disk.STATUS_UNKNOWN: 'Unknown',
- Disk.STATUS_OK: 'OK',
- Disk.STATUS_OTHER: 'Other',
- Disk.STATUS_PREDICTIVE_FAILURE: 'Predictive failure',
- Disk.STATUS_ERROR: 'Error',
- Disk.STATUS_REMOVED: 'Removed',
- Disk.STATUS_STARTING: 'Starting',
- Disk.STATUS_STOPPING: 'Stopping',
- Disk.STATUS_STOPPED: 'Stopped',
- Disk.STATUS_INITIALIZING: 'Initializing',
- Disk.STATUS_MAINTENANCE_MODE: 'Maintenance',
- Disk.STATUS_SPARE_DISK: 'Spare',
- Disk.STATUS_RECONSTRUCT: 'Reconstruct',
- Disk.STATUS_FREE: 'Free',
-}
-
-
-def disk_status_to_str(disk_status):
- return _bit_map_to_str(disk_status, _DISK_STATUS_CONV)
-
-
-_AG_INIT_TYPE_CONV = {
- AccessGroup.INIT_TYPE_UNKNOWN: 'Unknown',
- AccessGroup.INIT_TYPE_OTHER: 'Other',
- AccessGroup.INIT_TYPE_WWPN: 'WWPN',
- AccessGroup.INIT_TYPE_ISCSI_IQN: 'iSCSI',
- AccessGroup.INIT_TYPE_ISCSI_WWPN_MIXED: 'iSCSI/WWPN Mixed',
-}
-
-
-def ag_init_type_to_str(init_type):
- return _enum_type_to_str(init_type, _AG_INIT_TYPE_CONV)
-
-
-def ag_init_type_str_to_lsm(init_type_str):
- return _str_to_enum(init_type_str, _AG_INIT_TYPE_CONV)
-
-
-_TGT_PORT_TYPE_CONV = {
- TargetPort.TYPE_OTHER: 'Other',
- TargetPort.TYPE_FC: 'FC',
- TargetPort.TYPE_FCOE: 'FCoE',
- TargetPort.TYPE_ISCSI: 'iSCSI',
-}
-
-
-def tgt_port_type_to_str(port_type):
- return _enum_type_to_str(port_type, _TGT_PORT_TYPE_CONV)
-
-
-class PlugData(object):
- def __init__(self, description, plugin_version):
- self.desc = description
- self.version = plugin_version
-
-
-class VolumeRAIDInfo(object):
- _RAID_TYPE_MAP = {
- Volume.RAID_TYPE_RAID0: 'RAID0',
- Volume.RAID_TYPE_RAID1: 'RAID1',
- Volume.RAID_TYPE_RAID3: 'RAID3',
- Volume.RAID_TYPE_RAID4: 'RAID4',
- Volume.RAID_TYPE_RAID5: 'RAID5',
- Volume.RAID_TYPE_RAID6: 'RAID6',
- Volume.RAID_TYPE_RAID10: 'RAID10',
- Volume.RAID_TYPE_RAID15: 'RAID15',
- Volume.RAID_TYPE_RAID16: 'RAID16',
- Volume.RAID_TYPE_RAID50: 'RAID50',
- Volume.RAID_TYPE_RAID60: 'RAID60',
- Volume.RAID_TYPE_RAID51: 'RAID51',
- Volume.RAID_TYPE_RAID61: 'RAID61',
- Volume.RAID_TYPE_JBOD: 'JBOD',
- Volume.RAID_TYPE_MIXED: 'MIXED',
- Volume.RAID_TYPE_OTHER: 'OTHER',
- Volume.RAID_TYPE_UNKNOWN: 'UNKNOWN',
- }
-
- def __init__(self, vol_id, raid_type, strip_size, disk_count,
- min_io_size, opt_io_size):
- self.vol_id = vol_id
- self.raid_type = raid_type
- self.strip_size = strip_size
- self.disk_count = disk_count
- self.min_io_size = min_io_size
- self.opt_io_size = opt_io_size
-
- @staticmethod
- def raid_type_to_str(raid_type):
- return _enum_type_to_str(raid_type, VolumeRAIDInfo._RAID_TYPE_MAP)
-
-
-class DisplayData(object):
-
- def __init__(self):
- pass
-
- DISPLAY_WAY_COLUMN = 0
- DISPLAY_WAY_SCRIPT = 1
-
- DISPLAY_WAY_DEFAULT = DISPLAY_WAY_COLUMN
-
- DEFAULT_SPLITTER = ' | '
-
- VALUE_CONVERT = {}
-
- # lsm.System
- SYSTEM_HEADER = OrderedDict()
- SYSTEM_HEADER['id'] = 'ID'
- SYSTEM_HEADER['name'] = 'Name'
- SYSTEM_HEADER['status'] = 'Status'
- SYSTEM_HEADER['status_info'] = 'Info'
-
- SYSTEM_COLUMN_SKIP_KEYS = []
- # XXX_COLUMN_SKIP_KEYS contain a list of property should be skipped when
- # displaying in column way.
-
- SYSTEM_VALUE_CONV_ENUM = {
- 'status': system_status_to_str,
- }
-
- SYSTEM_VALUE_CONV_HUMAN = []
-
- VALUE_CONVERT[System] = {
- 'headers': SYSTEM_HEADER,
- 'column_skip_keys': SYSTEM_COLUMN_SKIP_KEYS,
- 'value_conv_enum': SYSTEM_VALUE_CONV_ENUM,
- 'value_conv_human': SYSTEM_VALUE_CONV_HUMAN,
- }
-
- PLUG_DATA_HEADER = OrderedDict()
- PLUG_DATA_HEADER['desc'] = 'Description'
- PLUG_DATA_HEADER['version'] = 'Version'
-
- PLUG_DATA_COLUMN_SKIP_KEYS = []
-
- PLUG_DATA_VALUE_CONV_ENUM = {}
- PLUG_DATA_VALUE_CONV_HUMAN = []
-
- VALUE_CONVERT[PlugData] = {
- 'headers': PLUG_DATA_HEADER,
- 'column_skip_keys': PLUG_DATA_COLUMN_SKIP_KEYS,
- 'value_conv_enum': PLUG_DATA_VALUE_CONV_ENUM,
- 'value_conv_human': PLUG_DATA_VALUE_CONV_HUMAN,
- }
-
- # lsm.Pool
- POOL_HEADER = OrderedDict()
- POOL_HEADER['id'] = 'ID'
- POOL_HEADER['name'] = 'Name'
- POOL_HEADER['element_type'] = 'Element Type'
- POOL_HEADER['unsupported_actions'] = 'Does not support'
- POOL_HEADER['total_space'] = 'Total Space'
- POOL_HEADER['free_space'] = 'Free Space'
- POOL_HEADER['status'] = 'Status'
- POOL_HEADER['status_info'] = 'Info'
- POOL_HEADER['system_id'] = 'System ID'
-
- POOL_COLUMN_SKIP_KEYS = ['unsupported_actions']
-
- POOL_VALUE_CONV_ENUM = {
- 'status': pool_status_to_str,
- 'element_type': pool_element_type_to_str,
- 'unsupported_actions': pool_unsupported_actions_to_str
- }
-
- POOL_VALUE_CONV_HUMAN = ['total_space', 'free_space']
-
- VALUE_CONVERT[Pool] = {
- 'headers': POOL_HEADER,
- 'column_skip_keys': POOL_COLUMN_SKIP_KEYS,
- 'value_conv_enum': POOL_VALUE_CONV_ENUM,
- 'value_conv_human': POOL_VALUE_CONV_HUMAN,
- }
-
- # lsm.Volume
- VOL_HEADER = OrderedDict()
- VOL_HEADER['id'] = 'ID'
- VOL_HEADER['name'] = 'Name'
- VOL_HEADER['vpd83'] = 'SCSI VPD 0x83'
- VOL_HEADER['block_size'] = 'Block Size'
- VOL_HEADER['num_of_blocks'] = 'Block Count'
- VOL_HEADER['size_bytes'] = 'Size'
- VOL_HEADER['admin_state'] = 'Disabled'
- VOL_HEADER['pool_id'] = 'Pool ID'
- VOL_HEADER['system_id'] = 'System ID'
-
- VOL_COLUMN_SKIP_KEYS = ['block_size', 'num_of_blocks']
-
- VOL_VALUE_CONV_ENUM = {
- 'admin_state': vol_admin_state_to_str
- }
-
- VOL_VALUE_CONV_HUMAN = ['size_bytes', 'block_size']
-
- VALUE_CONVERT[Volume] = {
- 'headers': VOL_HEADER,
- 'column_skip_keys': VOL_COLUMN_SKIP_KEYS,
- 'value_conv_enum': VOL_VALUE_CONV_ENUM,
- 'value_conv_human': VOL_VALUE_CONV_HUMAN,
- }
-
- # lsm.Disk
- DISK_HEADER = OrderedDict()
- DISK_HEADER['id'] = 'ID'
- DISK_HEADER['name'] = 'Name'
- DISK_HEADER['disk_type'] = 'Type'
- DISK_HEADER['block_size'] = 'Block Size'
- DISK_HEADER['num_of_blocks'] = 'Block Count'
- DISK_HEADER['size_bytes'] = 'Size'
- DISK_HEADER['status'] = 'Status'
- DISK_HEADER['system_id'] = 'System ID'
-
- DISK_COLUMN_SKIP_KEYS = ['block_size', 'num_of_blocks']
-
- DISK_VALUE_CONV_ENUM = {
- 'status': disk_status_to_str,
- 'disk_type': disk_type_to_str,
- }
-
- DISK_VALUE_CONV_HUMAN = ['size_bytes', 'block_size']
-
- VALUE_CONVERT[Disk] = {
- 'headers': DISK_HEADER,
- 'column_skip_keys': DISK_COLUMN_SKIP_KEYS,
- 'value_conv_enum': DISK_VALUE_CONV_ENUM,
- 'value_conv_human': DISK_VALUE_CONV_HUMAN,
- }
-
- # lsm.AccessGroup
- AG_HEADER = OrderedDict()
- AG_HEADER['id'] = 'ID'
- AG_HEADER['name'] = 'Name'
- AG_HEADER['init_ids'] = 'Initiator IDs'
- AG_HEADER['init_type'] = 'Type'
- AG_HEADER['system_id'] = 'System ID'
-
- AG_COLUMN_SKIP_KEYS = ['init_type']
-
- AG_VALUE_CONV_ENUM = {
- 'init_type': ag_init_type_to_str,
- }
-
- AG_VALUE_CONV_HUMAN = []
-
- VALUE_CONVERT[AccessGroup] = {
- 'headers': AG_HEADER,
- 'column_skip_keys': AG_COLUMN_SKIP_KEYS,
- 'value_conv_enum': AG_VALUE_CONV_ENUM,
- 'value_conv_human': AG_VALUE_CONV_HUMAN,
- }
-
- # lsm.FileSystem
- FS_HEADER = OrderedDict()
- FS_HEADER['id'] = 'ID'
- FS_HEADER['name'] = 'Name'
- FS_HEADER['total_space'] = 'Total Space'
- FS_HEADER['free_space'] = 'Free Space'
- FS_HEADER['pool_id'] = 'Pool ID'
- FS_HEADER['system_id'] = 'System ID'
-
- FS_COLUMN_SKIP_KEYS = []
-
- FS_VALUE_CONV_ENUM = {
- }
-
- FS_VALUE_CONV_HUMAN = ['total_space', 'free_space']
-
- VALUE_CONVERT[FileSystem] = {
- 'headers': FS_HEADER,
- 'column_skip_keys': FS_COLUMN_SKIP_KEYS,
- 'value_conv_enum': FS_VALUE_CONV_ENUM,
- 'value_conv_human': FS_VALUE_CONV_HUMAN,
- }
-
- # lsm.FsSnapshot
- FS_SNAP_HEADER = OrderedDict()
- FS_SNAP_HEADER['id'] = 'ID'
- FS_SNAP_HEADER['name'] = 'Name'
- FS_SNAP_HEADER['ts'] = 'Time Stamp'
-
- FS_SNAP_COLUMN_SKIP_KEYS = []
-
- FS_SNAP_VALUE_CONV_ENUM = {
- 'ts': datetime.fromtimestamp
- }
-
- FS_SNAP_VALUE_CONV_HUMAN = []
-
- VALUE_CONVERT[FsSnapshot] = {
- 'headers': FS_SNAP_HEADER,
- 'column_skip_keys': FS_SNAP_COLUMN_SKIP_KEYS,
- 'value_conv_enum': FS_SNAP_VALUE_CONV_ENUM,
- 'value_conv_human': FS_SNAP_VALUE_CONV_HUMAN,
- }
-
- # lsm.NfsExport
- NFS_EXPORT_HEADER = OrderedDict()
- NFS_EXPORT_HEADER['id'] = 'ID'
- NFS_EXPORT_HEADER['fs_id'] = 'FileSystem ID'
- NFS_EXPORT_HEADER['export_path'] = 'Export Path'
- NFS_EXPORT_HEADER['auth'] = 'Auth Type'
- NFS_EXPORT_HEADER['root'] = 'Root Hosts'
- NFS_EXPORT_HEADER['rw'] = 'RW Hosts'
- NFS_EXPORT_HEADER['ro'] = 'RO Hosts'
- NFS_EXPORT_HEADER['anonuid'] = 'Anonymous UID'
- NFS_EXPORT_HEADER['anongid'] = 'Anonymous GID'
- NFS_EXPORT_HEADER['options'] = 'Options'
-
- NFS_EXPORT_COLUMN_SKIP_KEYS = ['anonuid', 'anongid', 'auth']
-
- NFS_EXPORT_VALUE_CONV_ENUM = {}
-
- NFS_EXPORT_VALUE_CONV_HUMAN = []
-
- VALUE_CONVERT[NfsExport] = {
- 'headers': NFS_EXPORT_HEADER,
- 'column_skip_keys': NFS_EXPORT_COLUMN_SKIP_KEYS,
- 'value_conv_enum': NFS_EXPORT_VALUE_CONV_ENUM,
- 'value_conv_human': NFS_EXPORT_VALUE_CONV_HUMAN,
- }
-
- # lsm.TargetPort
- TGT_PORT_HEADER = OrderedDict()
- TGT_PORT_HEADER['id'] = 'ID'
- TGT_PORT_HEADER['port_type'] = 'Type'
- TGT_PORT_HEADER['physical_name'] = 'Physical Name'
- TGT_PORT_HEADER['service_address'] = 'Address'
- TGT_PORT_HEADER['network_address'] = 'Network Address'
- TGT_PORT_HEADER['physical_address'] = 'Physical Address'
- TGT_PORT_HEADER['system_id'] = 'System ID'
-
- TGT_PORT_COLUMN_SKIP_KEYS = ['physical_address', 'physical_name']
-
- TGT_PORT_VALUE_CONV_ENUM = {
- 'port_type': tgt_port_type_to_str,
- }
-
- TGT_PORT_VALUE_CONV_HUMAN = []
-
- VALUE_CONVERT[TargetPort] = {
- 'headers': TGT_PORT_HEADER,
- 'column_skip_keys': TGT_PORT_COLUMN_SKIP_KEYS,
- 'value_conv_enum': TGT_PORT_VALUE_CONV_ENUM,
- 'value_conv_human': TGT_PORT_VALUE_CONV_HUMAN,
- }
-
- VOL_RAID_INFO_HEADER = OrderedDict()
- VOL_RAID_INFO_HEADER['vol_id'] = 'Volume ID'
- VOL_RAID_INFO_HEADER['raid_type'] = 'RAID Type'
- VOL_RAID_INFO_HEADER['strip_size'] = 'Strip Size'
- VOL_RAID_INFO_HEADER['disk_count'] = 'Disk Count'
- VOL_RAID_INFO_HEADER['min_io_size'] = 'Minimum I/O Size'
- VOL_RAID_INFO_HEADER['opt_io_size'] = 'Optimal I/O Size'
-
- VOL_RAID_INFO_COLUMN_SKIP_KEYS = []
-
- VOL_RAID_INFO_VALUE_CONV_ENUM = {
- 'raid_type': VolumeRAIDInfo.raid_type_to_str,
- }
- VOL_RAID_INFO_VALUE_CONV_HUMAN = [
- 'strip_size', 'min_io_size', 'opt_io_size']
-
- VALUE_CONVERT[VolumeRAIDInfo] = {
- 'headers': VOL_RAID_INFO_HEADER,
- 'column_skip_keys': VOL_RAID_INFO_COLUMN_SKIP_KEYS,
- 'value_conv_enum': VOL_RAID_INFO_VALUE_CONV_ENUM,
- 'value_conv_human': VOL_RAID_INFO_VALUE_CONV_HUMAN,
- }
-
- @staticmethod
- def _get_man_pro_value(obj, key, value_conv_enum, value_conv_human,
- flag_human, flag_enum):
- value = getattr(obj, key)
- if not flag_enum:
- if key in value_conv_enum.keys():
- value = value_conv_enum[key](value)
- if flag_human:
- if key in value_conv_human:
- value = size_bytes_2_size_human(value)
- return value
-
- @staticmethod
- def _find_max_width(two_d_list, column_index):
- max_width = 1
- for row_index in range(0, len(two_d_list)):
- row_data = two_d_list[row_index]
- if len(row_data[column_index]) > max_width:
- max_width = len(row_data[column_index])
- return max_width
-
- @staticmethod
- def _data_dict_gen(obj, flag_human, flag_enum, display_way,
- extra_properties=None, flag_dsp_all_data=False):
- data_dict = OrderedDict()
- value_convert = DisplayData.VALUE_CONVERT[type(obj)]
- headers = value_convert['headers']
- value_conv_enum = value_convert['value_conv_enum']
- value_conv_human = value_convert['value_conv_human']
-
- if flag_dsp_all_data:
- display_way = DisplayData.DISPLAY_WAY_SCRIPT
-
- display_keys = []
-
- if display_way == DisplayData.DISPLAY_WAY_COLUMN:
- for key_name in headers.keys():
- if key_name not in value_convert['column_skip_keys']:
- display_keys.append(key_name)
- elif display_way == DisplayData.DISPLAY_WAY_SCRIPT:
- display_keys = headers.keys()
-
- if extra_properties:
- for extra_key_name in extra_properties:
- if extra_key_name not in display_keys:
- display_keys.append(extra_key_name)
-
- for key in display_keys:
- key_str = headers[key]
- value = DisplayData._get_man_pro_value(
- obj, key, value_conv_enum, value_conv_human, flag_human,
- flag_enum)
- data_dict[key_str] = value
-
- return data_dict
-
- @staticmethod
- def display_data(objs, display_way=None,
- flag_human=True, flag_enum=False,
- extra_properties=None,
- splitter=None,
- flag_with_header=True,
- flag_dsp_all_data=False):
- if len(objs) == 0:
- return None
-
- if display_way is None:
- display_way = DisplayData.DISPLAY_WAY_DEFAULT
-
- if splitter is None:
- splitter = DisplayData.DEFAULT_SPLITTER
-
- data_dict_list = []
- if type(objs[0]) in DisplayData.VALUE_CONVERT.keys():
- for obj in objs:
- data_dict = DisplayData._data_dict_gen(
- obj, flag_human, flag_enum, display_way,
- extra_properties, flag_dsp_all_data)
- data_dict_list.extend([data_dict])
- else:
- return None
- if display_way == DisplayData.DISPLAY_WAY_SCRIPT:
- DisplayData.display_data_script_way(data_dict_list, splitter)
- elif display_way == DisplayData.DISPLAY_WAY_COLUMN:
- DisplayData._display_data_column_way(
- data_dict_list, splitter, flag_with_header)
- return True
-
- @staticmethod
- def display_data_script_way(data_dict_list, splitter):
- key_column_width = 1
- value_column_width = 1
-
- for data_dict in data_dict_list:
- for key_name in data_dict.keys():
- # find the max column width of key
- cur_key_width = len(key_name)
- if cur_key_width > key_column_width:
- key_column_width = cur_key_width
- # find the max column width of value
- cur_value = data_dict[key_name]
- cur_value_width = 0
- if isinstance(cur_value, list):
- if len(cur_value) == 0:
- continue
- cur_value_width = len(str(cur_value[0]))
- else:
- cur_value_width = len(str(cur_value))
- if cur_value_width > value_column_width:
- value_column_width = cur_value_width
-
- row_format = '%%-%ds%s%%-%ds' % (key_column_width,
- splitter,
- value_column_width)
- sub_row_format = '%s%s%%-%ds' % (' ' * key_column_width,
- splitter,
- value_column_width)
- obj_splitter = '%s%s%s' % ('-' * key_column_width,
- '-' * len(splitter),
- '-' * value_column_width)
-
- for data_dict in data_dict_list:
- out(obj_splitter)
- for key_name in data_dict:
- value = data_dict[key_name]
- if isinstance(value, list):
- flag_first_data = True
- for sub_value in value:
- if flag_first_data:
- out(row_format % (key_name, str(sub_value)))
- flag_first_data = False
- else:
- out(sub_row_format % str(sub_value))
- else:
- out(row_format % (key_name, str(value)))
- out(obj_splitter)
-
- @staticmethod
- def _display_data_column_way(data_dict_list, splitter, flag_with_header):
- if len(data_dict_list) == 0:
- return
- two_d_list = []
-
- item_count = len(data_dict_list[0].keys())
-
- # determine how many lines we will print
- row_width = 0
- for data_dict in data_dict_list:
- cur_max_wd = 0
- for key_name in data_dict.keys():
- if isinstance(data_dict[key_name], list):
- cur_row_width = len(data_dict[key_name])
- if cur_row_width > cur_max_wd:
- cur_max_wd = cur_row_width
- else:
- pass
- if cur_max_wd == 0:
- cur_max_wd = 1
- row_width += cur_max_wd
-
- if flag_with_header:
- # first line for header
- row_width += 1
-
- # init 2D list
- for raw in range(0, row_width):
- new = []
- for column in range(0, item_count):
- new.append('')
- two_d_list.append(new)
-
- # header
- current_row_num = -1
- if flag_with_header:
- two_d_list[0] = data_dict_list[0].keys()
- current_row_num = 0
-
- # Fill the 2D list with data_dict_list
- for data_dict in data_dict_list:
- current_row_num += 1
- save_row_num = current_row_num
- values = data_dict.values()
- for index in range(0, len(values)):
- value = values[index]
- if isinstance(value, list):
- for sub_index in range(0, len(value)):
- tmp_row_num = save_row_num + sub_index
- two_d_list[tmp_row_num][index] = str(value[sub_index])
-
- if save_row_num + len(value) > current_row_num:
- current_row_num = save_row_num + len(value) - 1
- else:
- two_d_list[save_row_num][index] = str(value)
-
- # display two_list
- row_formats = []
- header_splitter = ''
- for column_index in range(0, len(two_d_list[0])):
- max_width = DisplayData._find_max_width(two_d_list, column_index)
- row_formats.extend(['%%-%ds' % max_width])
- header_splitter += '-' * max_width
- if column_index != (len(two_d_list[0]) - 1):
- header_splitter += '-' * len(splitter)
-
- row_format = splitter.join(row_formats)
- for row_index in range(0, len(two_d_list)):
- out(row_format % tuple(two_d_list[row_index]))
- if row_index == 0 and flag_with_header:
- out(header_splitter)
diff --git a/tools/lsmcli/lsmcli b/tools/lsmcli/lsmcli
deleted file mode 100755
index 6baa2df..0000000
--- a/tools/lsmcli/lsmcli
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/env python2
-
-# Copyright (C) 2012 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: tasleson
-from lsm.lsmcli import cmd_line_wrapper
-
-## Command line interface for libStorageMgmt.
-# This is contained in a separate class which can be shared across all the py
-# plug-ins.
-if __name__ == '__main__':
- cmd_line_wrapper()
diff --git a/tools/lsmenv b/tools/lsmenv
deleted file mode 100755
index 54bf0da..0000000
--- a/tools/lsmenv
+++ /dev/null
@@ -1,287 +0,0 @@
-#!/usr/bin/perl -w
-## 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: Gris Ge <***@redhat.com>
-
-use strict;
-use Config::IniFiles;
-use File::Basename;
-use Cwd 'abs_path';
-use Fcntl ':mode';
-
-$|++;
-
-my $LSM_UDS_PATH = '/var/run/lsm/ipc/';
-my $BASE_DIR = dirname( dirname( abs_path($0) ) );
-my $LSM_URI_FILE = "$ENV{HOME}/.lsm_uri";
-my $URI_CFG = Config::IniFiles->new( -file => $LSM_URI_FILE );
-my $LSM_USER = 'libstoragemgmt';
-my $LSM_GROUP = 'libstoragemgmt';
-
-my $REF_PRE_BUILD_URI = {
- "sim" => "sim://",
- "simc" => "simc://",
-};
-
-sub help() {
- my $help_str = <<END;
-
-Usage:
- lsmenv is used for setting up envirionment variables for running lsmcli
- or lsmd in the develop code folder.
- It also read a config file: $LSM_URI_FILE to set up URI and password.
-
- The sample config file format is:
-
- [emc] # dev_alias
- uri=smispy+ssl://admin\@emc-smi?no_ssl_verify=yes
- passwd=#1Password
-
- The sample command would be:
- lsmenv emc lsmcli list --type POOLS
-
- The URI for simulator plugins already prebuilded. Please use these command:
- lsmenv sim lsmcli
- lsmenv simc lsmcli
-
-Commands:
- lsmenv lsmd
- # Run the lsmd
- lsmenv -l
- # List all device alias
- lsmenv <dev_alias> lsmcli ...
- # Run lsmcli command on certain device
- lsmenv all lsmcli ...
- # Run lsmcli command on all devices
- lsmenv <dev_alias> <any_command>
- # Run <any_command> with LSM envirionment variables.
-END
- print $help_str;
- exit 1;
-}
-
-sub is_in_array($$) {
- my $ref_array = shift;
- my $item = shift;
- return 1 if grep { $_ eq $item } @{$ref_array};
- return undef;
-}
-
-sub chk_lsm_user(){
- my $code_gid = (stat $BASE_DIR)[5];
- my $code_group_name = getgrgid($code_gid);
- my $lsm_gid = (getpwnam("libstoragemgmt"))[3];
- if ($lsm_gid and $lsm_gid != $code_gid){
- print "FAIL: Existing $LSM_USER account is not sharing gid of " .
- "curren code tree which might cause plugin permission problem" .
- "\n";
- print " Please delete that user $LSM_USER " .
- "and rerun lsmenv as root user\n";
- exit 1;
- }
- unless($lsm_gid){
- # LSM_USER not exist.
- if ($> != 0){
- print "FAIL: Please run lsmenv as root user to create a proper " .
- "$LSM_USER account\n";
- exit 1;
- }
- print "WARN: Creating libstoragemgmt account and add it into " .
- "the group '$code_group_name($code_gid)' of code tree owner. \n";
-
- system("useradd -r -g $code_gid -d $LSM_UDS_PATH " .
- "-s /sbin/nologin " .
- "-c 'daemon account for libstoragemgmt' libstoragemgmt");
- # Check whether code tree $BASE_DIR is read and executable by LSM_USER
- # User are on their own if they changed file permission inside git
- # tree.
- my $cur_path = "$BASE_DIR/a";
- while(1){
- $cur_path = dirname($cur_path);
- print $cur_path, "\n";
- my $mod = (stat $cur_path)[2];
- unless(( $mod & S_IRGRP) and ( $mod & S_IXGRP )){
- print "WARN: Adding $cur_path with group read and " .
- "excute permision\n";
- system("chmod g+rx $cur_path");
- }
- last if ($cur_path eq '/');
- }
- }
- return 1;
-}
-
-sub lsm_env_setup() {
- my $py_binding_dir = "$BASE_DIR/python_binding";
- my $c_binding_dir = "$BASE_DIR/c_binding";
- unless ( ( -e $py_binding_dir ) && ( -e $c_binding_dir ) ) {
- print "FAIL: lsmenv is not from libstoragemgmt code tree.\n";
- exit 1;
- }
- my $py_lsm_dir = "$py_binding_dir/lsm";
- unless ( -l "$py_lsm_dir/plugin" ) {
- print "INFO: Creating softlink for plugin folder\n";
- system("ln -sv ../../plugin $py_lsm_dir");
- }
- unless ( -l "$py_lsm_dir/lsmcli" ) {
- print "INFO: Creating softlink for lsmcli folder\n";
- system("ln -sv ../../tools/lsmcli $py_lsm_dir");
- }
-
- unless ( -d "$LSM_UDS_PATH" ) {
- print "INFO: Creating socket folder $LSM_UDS_PATH\n";
- system("mkdir -pv $LSM_UDS_PATH");
- system("chown $LSM_USER $LSM_UDS_PATH");
- }
-
- $ENV{LSM_UDS_PATH} = $LSM_UDS_PATH;
- $ENV{PYTHONPATH} .= ":$py_binding_dir";
- $ENV{LD_LIBRARY_PATH} .= ":$c_binding_dir";
-}
-
-sub set_uri($) {
- my $uri = shift;
- $ENV{LSMCLI_URI} = $uri;
- $ENV{LSM_TEST_URI} = $uri;
-}
-
-sub set_pass($) {
- my $pass = shift;
- if ( defined $pass ) {
- $ENV{LSMCLI_PASSWORD} = $pass;
- $ENV{LSM_TEST_PASSWORD} = $pass;
- }
- else {
- delete $ENV{LSMCLI_PASSWORD};
- delete $ENV{LSM_TEST_PASSWORD};
- }
-}
-
-sub call_out($) {
-
- # take section name as $1 and global $cfg
- # then run commands after(not include) ARGV[0]
- my $dev_alias = shift;
-
- if ( $#ARGV < 1 ) {
- print "Missing command to excute\n\n";
- help();
- }
-
- my $uri;
- my $pass = undef;
- if ( is_in_array( [ keys( %{$REF_PRE_BUILD_URI} ) ], $dev_alias ) ) {
- $uri = $REF_PRE_BUILD_URI->{$dev_alias};
- }
- else {
- $uri = $URI_CFG->val( $dev_alias, 'uri' );
- if ( $uri =~ /\n/m ) {
- print "Duplicate settings for \"$dev_alias\"\n";
- exit 1;
- }
- $pass = $URI_CFG->val( $dev_alias, 'passwd' )
- if $URI_CFG->val( $dev_alias, 'passwd' );
- }
-
- print "Device alias: $dev_alias\n";
- print "URI: $uri\n";
- set_uri($uri);
- set_pass($pass);
-
- my @cmd = @ARGV;
- shift @cmd;
- print "@cmd", "\n";
- if ( $cmd[0] eq "lsmcli" ) {
- $cmd[0] = "$BASE_DIR/tools/lsmcli/lsmcli";
- }
- elsif ( $cmd[0] eq 'plugin_test' ) {
- $cmd[0] = "$BASE_DIR/test/plugin_test.py";
- }
- system( "time", "-f", '\nTime: %E\n', @cmd );
- my $rc = $? >> 8;
- if ( $rc != 0 ) {
- print "Return code: $rc\n";
- }
-}
-
-sub start_lsmd($) {
- my $flag_valgrind = shift;
- if ($> != 0){
- print "FAIL: Please run lsmenv as root to start lsmd\n";
- exit 1;
- }
- my $lsmd_exec_file = "$BASE_DIR/daemon/lsmd";
- unless ( -f $lsmd_exec_file ) {
- print "FAIL: $lsmd_exec_file not exist, "
- . "please run 'make' in '$BASE_DIR' folder again\n";
- exit 1;
- }
- unless ( -x $lsmd_exec_file ) {
- print "FAIL: $lsmd_exec_file is not excutable, "
- . "please run 'make' in '$BASE_DIR' folder again\n";
- exit 1;
- }
- my $cmd = '';
- if ($flag_valgrind){
- $cmd .= "valgrind --trace-children=no ";
- $cmd .= "--leak-check=full --show-reachable=no ";
- $cmd .= '--log-file=/tmp/lsmd_leaking_%p ';
- }
- $cmd .= $lsmd_exec_file;
- my $plugin_dir = "$BASE_DIR/plugin";
- my $conf_dir = "$BASE_DIR/config";
- system( "$cmd --plugindir $plugin_dir "
- . "--socketdir $LSM_UDS_PATH -v -d --confdir $conf_dir" );
-}
-
-sub main() {
- if ( $#ARGV < 0 ) {
- help();
- }
-
- chk_lsm_user();
- lsm_env_setup();
- if ( $ARGV[0] eq 'lsmd' ) {
- start_lsmd(0);
- exit 0;
- }
- elsif ( $ARGV[0] eq 'lsmdv' ) {
- start_lsmd(1);
- exit 0;
- }
- elsif ( $ARGV[0] eq '-l' ) {
- map { print "$_\n"; } @{ $URI_CFG->{sects} };
- exit 0;
- }
- elsif ( $ARGV[0] eq 'all' ) {
- map { call_out($_) } keys( %{$REF_PRE_BUILD_URI} );
- map { call_out($_) } @{ $URI_CFG->{sects} };
- exit 0;
- }
- elsif ( $ARGV[0] =~ /^-h$|^--help$/ ) {
- help();
- }
- elsif (( is_in_array( [ keys( %{$REF_PRE_BUILD_URI} ) ], $ARGV[0] ) )
- || ( is_in_array( $URI_CFG->{sects}, $ARGV[0] ) ) )
- {
- call_out( $ARGV[0] );
- exit 0;
- }
- print "ERROR: Configuration for '$ARGV[0]' not found\n";
- help();
-}
-
-main();
diff --git a/tools/netapp/netapp.py b/tools/netapp/netapp.py
deleted file mode 100755
index a219a28..0000000
--- a/tools/netapp/netapp.py
+++ /dev/null
@@ -1,76 +0,0 @@
-# Copyright (C) 2012-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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Author: tasleson
-
-import pprint
-import sys
-from lsm.plugin.ontap.na import netapp_filer
-import lsm.plugin.ontap.na
-import os
-from optparse import OptionParser
-
-
-def process_params(p):
- rc = {}
-
- if p is None:
- return p
- else:
- for e in p:
- if '==' in e:
- (name, value) = e.split('==')
- rc[name] = value
- else:
- print 'Param:', e, 'not in the form name==value'
- sys.exit(1)
- return rc
-
-if __name__ == '__main__':
- pp = pprint.PrettyPrinter(indent=2)
-
- user = os.getenv('NA_USER')
- password = os.getenv('NA_PASSWORD')
-
- parser = OptionParser()
- parser.add_option("-t", "--host", action="store", type="string",
- dest="host", help="controller name or IP")
- parser.add_option("-c", "--command", action="store", type="string",
- dest="command", help="command to execute")
- parser.add_option("-p", "--param", action="append", type="string",
- dest="params",
- help="command parameters in the form name==value")
- parser.add_option("-s", "--ssl", action="store_true", dest="ssl",
- help="enable ssl")
- parser.add_option('-d', "--dumpxml", action="store", dest="xmlfile",
- help="file to dump response to for debug")
-
- if user is not None and password is not None:
- (options, args) = parser.parse_args()
- if options.command and options.host:
- if options.xmlfile:
- lsm.plugin.ontap.na.xml_debug = options.xmlfile
-
- result = netapp_filer(options.host, user, password, 30,
- options.command,
- process_params(options.params),
- options.ssl)
- pp.pprint(result)
- else:
- parser.error("host and command are required")
- else:
- print 'Please create environmental variables for ' \
- 'NA_USER and NA_PASSWORD'
- sys.exit(1)
diff --git a/tools/smiscli/BlockMgmt.cpp b/tools/smiscli/BlockMgmt.cpp
deleted file mode 100644
index e889585..0000000
--- a/tools/smiscli/BlockMgmt.cpp
+++ /dev/null
@@ -1,547 +0,0 @@
-/* ex: set tabstop=4 expandtab: */
-/*
- * Copyright (C) 2011-2013 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#include "BlockMgmt.h"
-#include <unistd.h>
-
-template <class Type> void getPropValue(CIMInstance i, String key, Type &value)
-{
- i.getProperty(i.findProperty(CIMName(key))).getValue().get(value);
-}
-
-
-BlockMgmt::BlockMgmt(String host, Uint16 port, String smisNameSpace,
- String userName, String password ):ns(smisNameSpace)
-{
- c.connect(host, port, userName, password);
-}
-
-BlockMgmt::~BlockMgmt()
-{
- c.disconnect();
-}
-
-Array<String> BlockMgmt::getStoragePools()
-{
- return instancePropertyNames("CIM_StoragePool", "ElementName");
-}
-
-Array<String> BlockMgmt::getInitiators()
-{
- //Note: If you want the storage array IQN go after CIM_SCSIProtocolEndpoint.Name
- return instancePropertyNames("CIM_StorageHardwareID", "StorageID");
-}
-
-CIMInstance BlockMgmt::getSPC( String initiator, String lun, bool &found )
-{
- CIMInstance rc;
-
- CIMInstance init = getClassInstance("CIM_StorageHardwareID", "StorageID", initiator);
-
- Array<CIMObject> auth_priviledge = c.associators(ns, init.getPath(), "CIM_AuthorizedSubject");
-
- for( Uint32 i = 0; i < auth_priviledge.size(); ++i ) {
- Array<CIMObject> spc = c.associators(ns, auth_priviledge[i].getPath(), "CIM_AuthorizedTarget");
-
- //Make sure that we have associations for authorized targets and controllers.
- if( spc.size() > 0 ) {
- Array<CIMObject> logicalDevice = c.associators(ns, spc[0].getPath(), "CIM_ProtocolControllerForUnit");
-
- if( logicalDevice.size() > 0 ) {
- CIMInstance volume = c.getInstance(ns, logicalDevice[0].getPath().toString());
-
- String name;
- getPropValue(volume, "ElementName", name);
-
- if( name == lun ) {
- found = true;
- return (CIMInstance)spc[0];
- }
- }
- }
- }
- found = false;
- return rc;
-}
-
-void BlockMgmt::mapLun(String initiatorID, String lunName)
-{
- Array<CIMParamValue> in;
- Array<CIMParamValue> out;
- Array<String>lunNames;
- Array<String>initPortIDs;
- Array<String>deviceNumbers;
- Array<Uint16>deviceAccess;
-
- CIMInstance lun = getClassInstance("CIM_StorageVolume", "ElementName",
- lunName);
-
- lunNames.append(getClassValue(lun, "Name"));
- initPortIDs.append(initiatorID);
- deviceAccess.append(READ_WRITE); //Hard coded to Read Write
-
- CIMInstance ccs = getClassInstance("CIM_ControllerConfigurationService");
-
- in.append(CIMParamValue("LUNames", lunNames));
- in.append(CIMParamValue("InitiatorPortIDs", initPortIDs));
- in.append(CIMParamValue("DeviceAccesses", deviceAccess));
-
- evalInvoke(out, c.invokeMethod(ns, ccs.getPath(),
- CIMName("ExposePaths"),
- in, out));
-}
-
-void BlockMgmt::unmapLun(String initiatorID, String lunName)
-{
- bool found = false;
-
- //Need to find the SPC for the passed in initiator and volume (lun).
- CIMInstance spc = getSPC(initiatorID, lunName, found);
-
- if( found ) {
- Array<CIMParamValue> in;
- Array<CIMParamValue> out;
-
- //Let delete the SPC
- CIMInstance ccs = getClassInstance("CIM_ControllerConfigurationService");
- in.append(CIMParamValue("ProtocolController", spc.getPath()));
- in.append(CIMParamValue("DeleteChildrenProtocolControllers", true));
- in.append(CIMParamValue("DeleteUnits", true));
-
- evalInvoke(out, c.invokeMethod(ns, ccs.getPath(),
- CIMName("DeleteProtocolController"),
- in, out));
- } else {
- throw Exception("No mapping found");
- }
-}
-
-void BlockMgmt::printDebug( const CIMValue &v )
-{
- String id;
- String name;
- Uint64 blockSize;
- Uint64 numberOfBlocks;
-
- CIMInstance i = c.getInstance(ns, v.toString());
-
- getPropValue(i, "DeviceID", id);
- getPropValue(i, "ElementName", name);
- getPropValue(i, "BlockSize", blockSize);
- getPropValue(i, "NumberOfBlocks", numberOfBlocks);
-
- std::cout << "ID = " << id << " name = " << name << " blocksize = " <<
- blockSize << " # of blocks = " << numberOfBlocks << std::endl;
-}
-
-void BlockMgmt::createLun( String storagePoolName, String name, Uint64 size)
-{
- Array<CIMParamValue> in;
- Array<CIMParamValue> out;
-
- CIMInstance scs = getClassInstance("CIM_StorageConfigurationService");
- CIMInstance storagePool = getClassInstance("CIM_StoragePool", "ElementName",
- storagePoolName);
-
- std::cout << "pool = " << storagePool.getPath().toString() << std::endl;
-
- in.append(CIMParamValue("ElementName", CIMValue(name)));
- in.append(CIMParamValue("ElementType", (Uint16)STORAGE_VOLUME));
- in.append(CIMParamValue("InPool", storagePool.getPath()));
- in.append(CIMParamValue("Size", CIMValue(size)));
-
- Uint32 result = evalInvoke(out, c.invokeMethod(ns, scs.getPath(),
- CIMName("CreateOrModifyElementFromStoragePool"),
- in, out));
-
- if( result == 0 ) {
- for (Uint8 i = 0; i < out.size(); i++) {
- if( out[i].getParameterName() == "TheElement" ) {
- printDebug(out[i].getValue());
- }
- }
- }
-}
-
-void BlockMgmt::createInit( String name, String id, String type)
-{
- Array<CIMParamValue> in;
- Array<CIMParamValue> out;
-
- CIMInstance hardware = getClassInstance("CIM_StorageHardwareIDManagementService");
- in.append(CIMParamValue("ElementName", String(name)));
- in.append(CIMParamValue("StorageID", (CIMValue(id))));
-
- if( type == "WWN" ) {
- in.append(CIMParamValue("IDType", (Uint16)2));
- } else {
- in.append(CIMParamValue("IDType", (Uint16)5));
- }
-
- evalInvoke(out, c.invokeMethod(ns, hardware.getPath(),
- CIMName("CreateStorageHardwareID"), in, out));
-}
-
-void BlockMgmt::deleteInit( String id )
-{
- Array<CIMParamValue> in;
- Array<CIMParamValue> out;
-
- CIMInstance init = getClassInstance("CIM_StorageHardwareID", "StorageID", id);
-
- CIMInstance hardware = getClassInstance("CIM_StorageHardwareIDManagementService");
- in.append(CIMParamValue("HardwareID", init.getPath() ));
-
- evalInvoke(out, c.invokeMethod(ns, hardware.getPath(),
- CIMName("DeleteStorageHardwareID"), in, out));
-}
-
-void BlockMgmt::createSnapShot( String sourceLun, String destStoragePool,
- String destName)
-{
- Array<CIMParamValue> in;
- Array<CIMParamValue> out;
-
- CIMInstance rs = getClassInstance("CIM_ReplicationService");
- CIMInstance pool = getClassInstance("CIM_StoragePool", "ElementName",
- destStoragePool);
- CIMInstance lun = getClassInstance("CIM_StorageVolume", "ElementName",
- sourceLun);
-
- in.append(CIMParamValue("ElementName", CIMValue(destName)));
- in.append(CIMParamValue("SyncType", Uint16(SNAPSHOT)));
- in.append(CIMParamValue("Mode", Uint16(ASYNC)));
- in.append(CIMParamValue("SourceElement", lun.getPath()));
- in.append(CIMParamValue("TargetPool", pool.getPath()));
-
- evalInvoke(out, c.invokeMethod(ns, rs.getPath(),
- CIMName("CreateElementReplica"), in, out));
-}
-
-void BlockMgmt::resizeLun( String name, Uint64 size)
-{
- Array<CIMParamValue> in;
- Array<CIMParamValue> out;
-
- CIMInstance scs = getClassInstance("CIM_StorageConfigurationService");
- CIMInstance lun = getClassInstance("CIM_StorageVolume", "ElementName",
- name);
-
- in.append(CIMParamValue("TheElement", CIMValue(lun.getPath())));
- in.append(CIMParamValue("Size", CIMValue(size)));
-
- evalInvoke(out, c.invokeMethod(ns, scs.getPath(),
- CIMName("CreateOrModifyElementFromStoragePool"), in, out));
-}
-
-void BlockMgmt::deleteLun( String name )
-{
- Array<CIMParamValue> in;
- Array<CIMParamValue> out;
-
- CIMInstance scs = getClassInstance("CIM_StorageConfigurationService");
- CIMInstance lun = getClassInstance("CIM_StorageVolume", "ElementName", name);
-
- in.append(CIMParamValue("TheElement", lun.getPath()));
- evalInvoke(out, c.invokeMethod(ns,scs.getPath(),
- CIMName("ReturnToStoragePool"), in, out));
-}
-
-Uint32 BlockMgmt::evalInvoke(Array<CIMParamValue> &out, CIMValue value,
- String jobKey)
-{
- Uint32 result = 0;
- value.get(result);
- CIMValue job;
-
- if( result ) {
- String params;
-
- for (Uint8 i = 0; i < out.size(); i++) {
- params = params + " (key:value)(" + out[i].getParameterName() + ":" +
- out[i].getValue().toString() + ")";
-
- if( result == INVOKE_ASYNC ) {
- if(out[i].getParameterName() == jobKey) {
- job = out[i].getValue();
- }
- }
- }
-
- if( result == INVOKE_ASYNC ) {
- std::cout << "Params = " << params;
- processJob(job);
- } else {
- throw Exception(value.toString().append(params));
- }
- }
-
- return result;
-}
-
-void BlockMgmt::printVol(const CIMValue &job)
-{
- CIMInstance j = c.getInstance(ns, job.toString());
-
- /*Array<CIMObject> as = c.associators(ns, j.getPath(), NULL, NULL, "", false, false, NULL);
-
- for( Uint32 i = 0; i < as.size(); ++i ) {
-
- } */
-
-}
-
-void BlockMgmt::jobStatus(String id)
-{
- Array<Uint16> values;
- CIMObject status = c.getInstance(ns, id);
-
- status.getProperty(status.findProperty("OperationalStatus")).getValue().get(values);
-
- if( values.size() ) {
- std::cout << "Operational status: ";
-
- for( Uint32 i = 0; i < values.size() ; ++i ) {
- std::cout << values[i] << " ";
- }
- std::cout << std::endl;
- } else {
- std::cout << "Operational status is empty!" << std::endl;
- }
-
- std::cout << "Percent complete= "
- << status.getProperty(status.findProperty("PercentComplete")).getValue().toString()
- << std::endl;
-
- std::cout << "Job state= "
- << status.getProperty(status.findProperty("JobState")).getValue().toString()
- << std::endl;
-}
-
-bool BlockMgmt::jobCompletedOk(String jobId)
-{
- Array<Uint16> values;
- bool rc = false;
-
- CIMObject status = c.getInstance(ns, jobId);
-
- status.getProperty(status.findProperty("OperationalStatus")).
- getValue().get(values);
-
- if( values.size() > 0 ) {
- if( values.size() == 1 ) {
- //Based on the documentations on page 257 this should only
- //occur when the job was stopped.
- std::cout << "Error: Operational status = " << values[0] << std::endl;
- } else if( values.size() > 1 ) {
- if( (values[0] == OK || values[1] == OK) &&
- (values[0] == COMPLETE || values[1] == COMPLETE)) {
- rc = true;
- std::cout << "Success: Operational status = " << values[0] << ", "
- << values[1] << std::endl;
- } else {
- std::cout << "Error: Operational status = " << values[0] << ", "
- << values[1] << std::endl;
- }
- }
- } else {
- std::cout << "No operational status available!" << std::endl;
- }
- return rc;
-}
-
-void BlockMgmt::processJob(CIMValue &job)
-{
- std::cout << std::endl << "job started= " << job.toString() << std::endl;
-
- while( true ) {
- Uint16 jobState;
- Boolean autodelete = false;
-
- CIMObject status = c.getInstance(ns, job.toString());
- status.getProperty(status.findProperty("JobState")).
- getValue().get(jobState);
-
- switch( jobState ) {
- case(JS_NEW):
- case(JS_STARTING):
- break;
- case(JS_RUNNING):
- //Dump percentage
- std::cout << "Percent complete= "
- << status.getProperty(
- status.findProperty("PercentComplete")).
- getValue().toString()
- << std::endl;
- break;
- case(JS_COMPLETED):
- //Check operational status.
- std::cout << "Job is complete!" << std::endl;
-
- jobCompletedOk(job.toString());
-
- status.getProperty(status.findProperty("DeleteOnCompletion")).
- getValue().get(autodelete);
-
- if( !autodelete ) {
- //We are done, delete job instance.
- try {
- c.deleteInstance(ns, job.toString());
- std::cout << "Deleted job!" << std::endl;
- } catch (Exception &e) {
- std::cout << "Warning: error when deleting job! "
- << e.getMessage() << std::endl;
- }
- }
- return;
- default:
- std::cout << "Unexpected job state " << jobState << std::endl;
- return;
- break;
- }
-
- sleep(1);
- }
-
- /*
- status.getProperty(status.findProperty("OperationalStatus")).getValue().get(values);
- if( values.size() > 0 ) {
- if( values.size() == 1 ) {
- //Based on the documentations on page 257 this should only
- //occur when the job was stopped.
-
-
- } else if( values.size() > 1 ) {
- if( (values[0] == OK || values[1] == OK) &&
- (values[0] == COMPLETE || values[0] == COMPLETE)) {
-
- }
- }
- }
-
- if( values[0] == OK || values[1] == OK ) {
- //Array of values may have 1 or 2 values according to mof
- if( values.size() == 2 ) {
- Boolean autodelete = false;
- status.getProperty(status.findProperty("DeleteOnCompletion")).getValue().get(autodelete);
-
- if( !autodelete ) {
- //We are done, delete job instance.
- try {
- c.deleteInstance(ns, job.toString());
- } catch (Exception &e) {
- std::cout << "Warning: error when deleting job! "
- << e.getMessage() << std::endl;
- }
- }
-
- if( values[1] == COMPLETE) {
- std::cout << "Job complete!" << std::endl;
-
-
-
-
- } else if ( values[1] == STOPPED) {
- std::cout << "Job stopped!" << std::endl;
- } else if( values[1] == ERROR ) {
- std::cout << "Job errored!" << std::endl;
- }
- return;
- }
-
- std::cout << "Percent complete= "
- << status.getProperty(status.findProperty("PercentComplete")).getValue().toString()
- << std::endl;
-
- sleep(1);
- } else {
- throw Exception("Job " + job.toString() + " encountered an error!");
- }
- }
-
- */
-}
-
-Array<String> BlockMgmt::getLuns()
-{
- return instancePropertyNames("CIM_StorageVolume", "ElementName");
-}
-
-Array<CIMInstance> BlockMgmt::storagePools()
-{
- return c.enumerateInstances(ns, CIMName("CIM_StoragePool"));
-}
-
-Array<String> BlockMgmt::instancePropertyNames( String className, String prop )
-{
- Array<String> names;
-
- Array<CIMInstance> instances = c.enumerateInstances(ns, CIMName(className));
-
- for(Uint32 i = 0; i < instances.size(); ++i) {
- Uint32 propIndex = instances[i].findProperty(CIMName(prop));
- names.append(instances[i].getProperty(propIndex).getValue().toString());
- }
- return names;
-}
-
-String BlockMgmt::getClassValue(CIMInstance &instance, String propName)
-{
- return instance.getProperty(instance.findProperty(propName)).getValue().toString();
-}
-
-CIMInstance BlockMgmt::getClassInstance(String className)
-{
- Array<CIMInstance> cs = c.enumerateInstances(ns, CIMName(className));
-
- //Could there be more than one?
- //If there is, what would be a better thing to do, pick one?
- if( cs.size() != 1 ) {
- String instances;
-
- if( cs.size() == 0 ) {
- instances = "none!";
- } else {
- instances.append("\n");
- for(Uint32 i = 0; i < cs.size(); ++i ) {
- instances.append( cs[i].getPath().toString() + String("\n"));
- }
- }
-
- throw Exception("Expecting one object instance of " + className +
- "got " + instances);
- }
- return cs[0];
-}
-
-CIMInstance BlockMgmt::getClassInstance(String className, String propertyName,
- String propertyValue )
-{
- Array<CIMInstance> cs = c.enumerateInstances(ns, CIMName(className));
-
- for( Uint32 i = 0; i < cs.size(); ++i ) {
- Uint32 index = cs[i].findProperty(propertyName);
- if ( cs[i].getProperty(index).getValue().toString() == propertyValue ) {
- return cs[i];
- }
- }
- throw Exception("Instance of class name: " + className + " property=" +
- propertyName + " value= " + propertyValue + " not found.");
-}
diff --git a/tools/smiscli/BlockMgmt.h b/tools/smiscli/BlockMgmt.h
deleted file mode 100644
index 482aad1..0000000
--- a/tools/smiscli/BlockMgmt.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/* ex: set tabstop=4 expandtab: */
-/*
- * Copyright (C) 2011-2013 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-#ifndef __BLOCKMGMT_H__
-#define __BLOCKMGMT_H__
-
-#include <Pegasus/Common/Config.h>
-#include <Pegasus/Client/CIMClient.h>
-
-PEGASUS_USING_PEGASUS;
-PEGASUS_USING_STD;
-
-/**
- * A simple class used to learn about SMI-S utilizing the openpegasus library.
- * Released in hopes that other may benefit.
- */
-class BlockMgmt
-{
-public:
-
- /**
- * Class constructor.
- * Once this completes we have a connection to the SMI-S agent/proxy.
- * @param host a string representing the IP or host of SMI-S agent
- * @param port The server port to connect too.
- * @param smisNameSpace The SMI-S namespace to use.
- * @param userName User name when using authentication.
- * @param password Plain text password.
- */
- BlockMgmt( String host, Uint16 port, String smisNameSpace, String userName,
- String password );
-
- /**
- * Class destructor which closes the connection to the SMI-S agent/proxy
- */
- ~BlockMgmt();
-
- /**
- * Creates a logical unit.
- * @param storagePoolName Name of storage pool to allocate lun from.
- * @param name Name to be given to new lun.
- * @param size Size of the new Lun
- * @throws Exception
- */
- void createLun( String storagePoolName, String name, Uint64 size);
-
- /**
- * Creates an initiator to reference and use.
- * @param name User defined name
- * @param id Initiator id
- * @param type Type of id [WWN|IQN]
- * @throws Exception
- */
- void createInit( String name, String id, String type);
-
- /**
- * Deletes an initiator.
- * @param id Initiator ID
- * @throws Exception
- */
- void deleteInit( String id );
-
- /**
- * Creates a snapshot of a lun (point in time copy)
- * @param sourceLun Name of lun to snapshot.
- * @param destStoragePool Storage pool to create snapshot from.
- * @param destName Name of new snapshot.
- * @throws Exception
- */
- void createSnapShot( String sourceLun, String destStoragePool,
- String destName);
-
- /**
- * Deletes a logical unit.
- * @param name Name of lun to delete.
- * @throws Exception
- */
- void deleteLun( String name );
-
- /**
- * Resizes an existing Lun.
- * @param name Name of lun to resize
- * @param size New size
- * @throws Exception
- */
- void resizeLun( String name, Uint64 size);
-
- /**
- * Returns an array of Strings which are the names of the storage pools.
- * @return An Array<String>
- * @throws Exception
- */
- Array<String> getStoragePools();
-
- /**
- * Returns an array of Strings which are the names of the logical units
- * @return An Array<String>
- * @throws Exception
- */
- Array<String> getLuns();
-
-
- /**
- * Returns an array of Strings which are the ID(s) of the initiators
- * @return An Array<String> of initiator IDs
- * @throws Exception
- */
- Array<String> getInitiators();
-
- /**
- * Grants read/write access for a lun to the specified initiator.
- * @param initiatorID The initiator ID
- * @param lunName The lun name
- * @throws Exception
- */
- void mapLun(String initiatorID, String lunName);
-
- /**
- * Removes acces for a lun to the specified initiator
- * @param initiatorID The initiator ID
- * @param lunName The lun name
- * @throws Exception
- */
- void unmapLun(String initiatorID, String lunName);
-
-
- void jobStatus(String id);
-
-private:
- enum ElementType { UNKNOWN = 0, RESERVED = 1, STORAGE_VOLUME = 2,
- STORAGE_EXTENT = 3, STORAGE_POOL = 4, LOGICAL_DISK = 5
- };
-
- enum DeviceAccess { READ_WRITE = 2, READ_ONLY = 3,
- NO_ACCESS = 4
- };
-
- enum SyncType { MIRROR = 6, SNAPSHOT = 7, CLONE = 8 };
-
- enum Mode { SYNC = 2, ASYNC = 3 };
-
- enum MethodInvoke { INVOKE_OK = 0, INVOKE_ASYNC = 4096 };
-
- enum OperationalStatus { OK = 2, ERROR = 6, STOPPED = 10, COMPLETE = 17 };
-
- enum JobState { JS_NEW = 2, JS_STARTING = 3, JS_RUNNING = 4,
- JS_SUSPENDED = 5, JS_SHUTTING_DOWN = 6, JS_COMPLETED = 7,
- JS_TERMINATED = 8, JS_KILLED = 9, JS_EXCEPTION = 10 };
-
- CIMClient c;
- CIMNamespaceName ns;
-
- Array<CIMInstance> storagePools();
- Array<String> instancePropertyNames( String className, String prop );
-
- String getClassValue(CIMInstance &instance, String propName);
- CIMInstance getClassInstance(String className);
- CIMInstance getClassInstance(String className, String propertyName,
- String propertyValue );
-
- Uint32 evalInvoke(Array<CIMParamValue> &out, CIMValue value,
- String jobKey = "Job");
-
- void processJob(CIMValue &job);
-
- void printDebug(const CIMValue &v);
-
- void printVol(const CIMValue &job);
-
- CIMInstance getSPC( String initiator, String lun, bool &found );
-
- bool jobCompletedOk(String jobId);
-};
-
-#endif
diff --git a/tools/smiscli/Makefile.am b/tools/smiscli/Makefile.am
deleted file mode 100644
index 43139ab..0000000
--- a/tools/smiscli/Makefile.am
+++ /dev/null
@@ -1,4 +0,0 @@
-INCLUDES = $(PEGASUS_CFLAGS) $(DEFS)
-noinst_PROGRAMS = smiscli
-smiscli_LDADD = $(PEGASUS_LIBS)
-smiscli_SOURCES = BlockMgmt.cpp BlockMgmt.h smiscli.cpp
diff --git a/tools/smiscli/README b/tools/smiscli/README
deleted file mode 100644
index e541160..0000000
--- a/tools/smiscli/README
+++ /dev/null
@@ -1 +0,0 @@
-Experimental tool to get familiar with SMI-S and openpegasus.
diff --git a/tools/smiscli/smiscli.cpp b/tools/smiscli/smiscli.cpp
deleted file mode 100644
index 73784b0..0000000
--- a/tools/smiscli/smiscli.cpp
+++ /dev/null
@@ -1,209 +0,0 @@
-/* ex: set tabstop=4 expandtab: */
-/*
- * Copyright (C) 2011-2013 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: tasleson
- */
-
-/*
- g++ -DPEGASUS_PLATFORM_LINUX_X86_64_GNU -g -Wall -lpegcommon -lpegclient BlockMgmt.cpp smiscli.cpp -o smiscli
- */
-
-#include "BlockMgmt.h"
-#include <stdint.h>
-#include <getopt.h>
-#include <string.h>
-#include <stdlib.h>
-
-void dump_strings( Array<String> strings)
-{
- for(Uint32 i = 0; i < strings.size(); ++i ) {
- std::cout << strings[i] << std::endl;
- }
-}
-
-void usage(String name)
-{
- std::cout << name << " is a simple utility to learn smi-s block service "
- "functionality with openpegasus\n\n" << std::endl;
- std::cout << "Syntax: " << name << " host port namespace [ createvol <storage pool> <name> <size>\n"
- "| createinit <name> <id> [WWN|ISCSI]]\n"
- "| deleteinit <id>\n"
- "| deletevol <Volume name> \n"
- "| resize <name> <size> | list [volumes|pools|initiators]] \n"
- "| mapcreate <initiator> <volumes>\n"
- "| mapdelete <initiator> <volumes>\n"
- "| jobstatus <job>\n"
- "| snapshot <source volumes> <dest pool> <dest name> ]" << std::endl;
- std::cout << "Note: Expects no authentication, if required export DEMO_SMIS_USER and DEMO_SMIS_PASS" << std::endl;
- std::cout << "Built on " << __DATE__ << " @ " << __TIME__ << std::endl;
- std::cout << "\n\nExample:\n" << std::endl;
- std::cout << name << " 192.168.2.25 5988 root/ontap create aggr3 testvolume 50000000\n" << std::endl;
- exit(EXIT_FAILURE);
-}
-
-/**
- * Arguments for the program
- */
-struct args {
- String host; /**< Host to connect to */
- Uint16 port; /**< port */
- String ns; /**< namespace */
- String username; /**< Username */
- String password; /**< Password */
- String operation; /**< Operation */
- Array<String> opArgs; /**< Optional arguments */
-};
-
-void process_args( int argc, char *argv[] , struct args *cmdline_args)
-{
- if( argc < 5 ) {
- usage(argv[0]);
- }
-
- cmdline_args->host = argv[1];
- cmdline_args->port = (Uint16)atol(argv[2]);
- cmdline_args->ns = argv[3];
- cmdline_args->operation = argv[4];
- cmdline_args->operation.toLower();
-
- for(int i = 5; i < argc; ++i) {
- cmdline_args->opArgs.append(argv[i]);
- }
-
- if( getenv("DEMO_SMIS_USER") ) {
- cmdline_args->username = getenv("DEMO_SMIS_USER");
-
- if( getenv("DEMO_SMIS_PASS") ) {
- cmdline_args->password = getenv("DEMO_SMIS_PASS");
- } else {
- std::cout << "Missing DEMO_SMIS_PASS ?" << std::endl;
- usage(argv[0]);
- }
- }
-}
-
-int main(int argc, char *argv[])
-{
- struct args arguments;
-
- try {
- process_args(argc, argv, &arguments);
- BlockMgmt bm(arguments.host, arguments.port, arguments.ns, arguments.username, arguments.password);
-
- if( arguments.operation == "createvol" ) {
- if( arguments.opArgs.size() != 3 ) {
- std::cout << "create expects <storage pool> <name> <size>" << std::endl;
- return EXIT_FAILURE;
- }
-
- bm.createLun(arguments.opArgs[0], arguments.opArgs[1], atoll(arguments.opArgs[2].getCString()));
-
- }
- else if ( arguments.operation == "createinit" ) {
- if( arguments.opArgs.size() != 3 ) {
- std::cout << "createinit expects <Name> <ID> [WWN|IQN]" << std::endl;
- return EXIT_FAILURE;
- }
-
- if( arguments.opArgs[2] == "WWN" || arguments.opArgs[2] == "IQN" ) {
- bm.createInit(arguments.opArgs[0], arguments.opArgs[1], arguments.opArgs[2]);
- } else {
- std::cout << "[WWN|IQN] expected not " << arguments.opArgs[2] << std::endl;
- return EXIT_FAILURE;
- }
- }
- else if ( arguments.operation == "deleteinit" ) {
- if( arguments.opArgs.size() != 1 ) {
- std::cout << "deleteinit expects <ID>" << std::endl;
- return EXIT_FAILURE;
- }
-
- bm.deleteInit(arguments.opArgs[0]);
- }
- else if ( arguments.operation == "snapshot" ) {
- if( arguments.opArgs.size() != 3 ) {
- std::cout << "snapshot expects <source volume> <dest. storage pool> <dest. name>" << std::endl;
- return EXIT_FAILURE;
- }
-
- bm.createSnapShot(arguments.opArgs[0], arguments.opArgs[1], arguments.opArgs[2]);
- } else if( arguments.operation == "deletevol" ) {
- if( arguments.opArgs.size() != 1 ) {
- std::cout << "deletevol expects <name>" << std::endl;
- return EXIT_FAILURE;
- }
-
- bm.deleteLun(arguments.opArgs[0]);
- } else if( arguments.operation == "resize" ) {
- if( arguments.opArgs.size() != 2 ) {
- std::cout << "resize expects <name> <size>" << std::endl;
- return EXIT_FAILURE;
- }
-
- bm.resizeLun(arguments.opArgs[0], atoll(arguments.opArgs[1].getCString()));
-
- } else if( arguments.operation == "list" ) {
- if( arguments.opArgs.size() != 1 ) {
- std::cout << "list expects one of the following [volumes|pools|initiators|initgroups]" << std::endl;
- return EXIT_FAILURE;
- }
-
- arguments.opArgs[0].toLower();
-
- if( arguments.opArgs[0] == "volumes" ) {
- dump_strings( bm.getLuns());
- } else if( arguments.opArgs[0] == "pools" ) {
- dump_strings( bm.getStoragePools());
- } else if( arguments.opArgs[0] == "initiators") {
- dump_strings( bm.getInitiators());
- } else {
- std::cout << "Unsupported list type= " << arguments.opArgs[0] << std::endl;
- }
-
- } else if ( arguments.operation == "mapcreate" ) {
- if( arguments.opArgs.size() != 2 ) {
- std::cout << "mapcreate expects <initiator> <volume>" << std::endl;
- return EXIT_FAILURE;
- }
-
- bm.mapLun(arguments.opArgs[0], arguments.opArgs[1]);
-
- } else if ( arguments.operation == "mapdelete" ) {
- if( arguments.opArgs.size() != 2 ) {
- std::cout << "mapdelete expects <initiator> <volume>" << std::endl;
- return EXIT_FAILURE;
- }
-
- bm.unmapLun(arguments.opArgs[0], arguments.opArgs[1]);
- } else if ( arguments.operation == "jobstatus" ) {
- if( arguments.opArgs.size() != 1 ) {
- std::cout << "jobstatus expects job id" << std::endl;
- return EXIT_FAILURE;
- }
-
- bm.jobStatus(arguments.opArgs[0]);
- }else {
- std::cout << "Unsupported operation: " << arguments.operation << std::endl;
- }
-
- } catch (Exception &e) {
- std::cerr << "Error: " << e.getMessage() << std::endl;
- exit(1);
- }
- return 0;
-}
-
diff --git a/tools/udev/90-scsi-ua.rules b/tools/udev/90-scsi-ua.rules
deleted file mode 100644
index 193e22c..0000000
--- a/tools/udev/90-scsi-ua.rules
+++ /dev/null
@@ -1,5 +0,0 @@
-#ACTION=="change", SUBSYSTEM=="scsi", ENV{SDEV_UA}=="INQUIRY_DATA_HAS_CHANGED", TEST=="rescan", ATTR{rescan}="x"
-#ACTION=="change", SUBSYSTEM=="scsi", ENV{SDEV_UA}=="CAPACITY_DATA_HAS_CHANGED", TEST=="rescan", ATTR{rescan}="x"
-#ACTION=="change", SUBSYSTEM=="scsi", ENV{SDEV_UA}=="THIN_PROVISIONING_SOFT_THRESHOLD_REACHED", TEST=="rescan", ATTR{rescan}="x"
-#ACTION=="change", SUBSYSTEM=="scsi", ENV{SDEV_UA}=="MODE_PARAMETERS_CHANGED", TEST=="rescan", ATTR{rescan}="x"
-ACTION=="change", SUBSYSTEM=="scsi", ENV{SDEV_UA}=="REPORTED_LUNS_DATA_HAS_CHANGED", RUN+="scan-scsi-target $env{DEVPATH}"
diff --git a/tools/udev/Makefile.am b/tools/udev/Makefile.am
deleted file mode 100644
index 567b55f..0000000
--- a/tools/udev/Makefile.am
+++ /dev/null
@@ -1,5 +0,0 @@
-EXTRA_DIST = 90-scsi-ua.rules
-
-noinst_PROGRAMS = scan-scsi-target
-
-scan_scsi_target_SOURCES = scan-scsi-target.c
diff --git a/tools/udev/scan-scsi-target.c b/tools/udev/scan-scsi-target.c
deleted file mode 100644
index 3b4b2a8..0000000
--- a/tools/udev/scan-scsi-target.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Scan a SCSI target given a uevent path to one of its devices
- * Author: Ewan D. Milne <***@redhat.com>
- *
- * Copyright (C) 2013, Red Hat Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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
- * General Public License for more details.
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/fcntl.h>
-#include <errno.h>
-#include <getopt.h>
-
-/*
- * Example SCSI uevent device path:
- *
- * /devices/pseudo_0/adapter0/host3/target3:0:0/3:0:0:0
- *
- * Desired sysfs action:
- *
- * write "<channel> <id> -" to "/sys/devices/pseudo_0/adapter0/host3/scsi_host/host3/scan"
- *
- * Note: Per kernel Documentation/sysfs-rules.txt, sysfs is always mounted at /sys
- */
-
-static void __attribute__ ((__noreturn__)) usage(char **argv, int err)
-{
- fprintf(stderr, "\nUsage:\n");
- fprintf(stderr, "%s <uevent DEVPATH of SCSI device>\n", argv[0]);
- fprintf(stderr, "\nOptions:\n");
- fprintf(stderr, " -h, --help display this help and exit\n");
- exit(err);
-}
-
-static void __attribute__ ((__noreturn__)) invalid(char **argv, char *devpath)
-{
- fprintf(stderr, "Invalid DEVPATH '%s'.\n", devpath);
- usage(argv, 1);
-}
-
-int main(int argc, char **argv)
-{
- char c;
- char *devpath;
-
- char *sysfs_path;
- char *sysfs_data;
- struct stat sysfs_stat;
- int fd;
-
- char *host_str;
- int host_pos;
- int host_len;
- char *host_next_str;
- int host_next_pos;
- int host_next_len;
- char *target_str;
- int target_pos;
- int target_len;
-
- char *channel_str;
- int channel_pos;
- int channel_len;
- char *id_str;
- int id_pos;
- int id_len;
-
- char *dir_str;
-
- static const struct option longopts[] = {
- {"help", no_argument, 0, 'h'},
- {NULL, no_argument, 0, '0'},
- };
-
-
- while ((c = getopt_long(argc, argv, "rh", longopts, NULL)) != -1) {
- switch (c) {
- case 'h':
- usage(argv, 0);
- default:
- usage(argv, 1);
- }
- }
-
- if (optind >= argc) {
- usage(argv, 1);
- }
- devpath = argv[optind++];
-
- /*
- * Make sure SCSI device uevent DEVPATH was supplied, and that it exists.
- * Also verify that it is a directory, to provide some argument validation.
- * Note: the devpath does not include the "/sys" prefix, so we must add it.
- */
- if (devpath == NULL) {
- usage(argv, 1);
- }
-
- sysfs_path = malloc(strlen("/sys") + strlen(devpath) + 1);
- strcpy(sysfs_path, "/sys");
- strcat(sysfs_path, devpath);
-
- if (stat(sysfs_path, &sysfs_stat) < 0) {
- fprintf(stderr, "Cannot stat '%s': %s\n", sysfs_path, strerror(errno));
- usage(argv, 1);
- }
- if (!S_ISDIR(sysfs_stat.st_mode))
- invalid(argv, devpath);
-
- free(sysfs_path);
-
- /*
- * Construct the path to the "scan" entry in the Scsi_Host sysfs object.
- */
- if ((host_str = strstr(devpath, "/host")) == NULL)
- invalid(argv, devpath);
- host_pos = strlen(devpath) - strlen(host_str);
-
- if ((host_next_str = strstr(&devpath[host_pos + 1], "/")) == NULL)
- invalid(argv, devpath);
- host_next_pos = strlen(devpath) - strlen(host_next_str);
-
- if ((target_str = strstr(devpath, "/target")) == NULL)
- invalid(argv, devpath);
- target_pos = strlen(devpath) - strlen(target_str);
-
- host_len = host_next_pos - host_pos;
- if (host_len <= strlen("/host"))
- invalid(argv, devpath);
-
- host_next_len = strlen(&devpath[host_next_pos]);
- if (host_next_len <= strlen("/"))
- invalid(argv, devpath);
-
- target_len = strlen(&devpath[target_pos]);
- if (target_len <= strlen("/target"))
- invalid(argv, devpath);
-
- sysfs_path = malloc(strlen("/sys") + strlen(devpath) - host_next_len + strlen("/scsi_host") + host_len + strlen("/scan") + 1);
-
- strcpy(sysfs_path, "/sys");
- strncat(sysfs_path, devpath, host_next_pos);
- strcat(sysfs_path, "/scsi_host");
- strncat(sysfs_path, host_str, host_len);
- strcat(sysfs_path, "/scan");
-
- /*
- * Obtain the SCSI channel and ID, and construct the string to write to the "scan" entry.
- */
- if ((channel_str = strstr(&devpath[target_pos], ":")) == NULL)
- invalid(argv, devpath);
- channel_pos = strlen(&devpath[target_pos]) - strlen(channel_str) + 1;
-
- if ((id_str = strstr(&devpath[target_pos + channel_pos], ":")) == NULL)
- invalid(argv, devpath);
- id_pos = strlen(&devpath[target_pos + channel_pos]) - strlen(id_str) + 1;
-
- if ((dir_str = strstr(&devpath[target_pos + channel_pos + id_pos], "/")) == NULL)
- invalid(argv, devpath);
-
- channel_len = strlen(&devpath[target_pos + channel_pos]) - strlen(id_str);
- if (channel_len < 1)
- invalid(argv, devpath);
-
- id_len = strlen(&devpath[target_pos + channel_pos + id_pos]) - strlen(dir_str);
- if (id_len < 1)
- invalid(argv, devpath);
-
- sysfs_data = malloc(channel_len + strlen(" ") + id_len + strlen(" -") + 1);
-
- sysfs_data[0] = '\0';
- strncat(sysfs_data, &devpath[target_pos + channel_pos], channel_len);
- strcat(sysfs_data, " ");
- strncat(sysfs_data, &devpath[target_pos + channel_pos + id_pos], id_len);
- strcat(sysfs_data, " -");
-
- /*
- * Tell the kernel to rescan the SCSI target for new LUNs.
- */
- if ((fd = open(sysfs_path, O_WRONLY)) < 0) {
- fprintf(stderr, "Cannot open '%s': %s\n", sysfs_path, strerror(errno));
- usage(argv, 1);
- }
- if (write(fd, sysfs_data, strlen(sysfs_data)) < 0) {
- fprintf(stderr, "Cannot write '%s': %s\n", sysfs_path, strerror(errno));
- usage(argv, 1);
- }
- close(fd);
- free(sysfs_path);
- free(sysfs_data);
- return 0;
-}
diff --git a/tools/utility/Makefile.am b/tools/utility/Makefile.am
deleted file mode 100644
index ccd31b9..0000000
--- a/tools/utility/Makefile.am
+++ /dev/null
@@ -1 +0,0 @@
-EXTRA_DIST = check_const.pl
diff --git a/tools/utility/check_const.pl b/tools/utility/check_const.pl
deleted file mode 100644
index e41c1e9..0000000
--- a/tools/utility/check_const.pl
+++ /dev/null
@@ -1,489 +0,0 @@
-#!/usr/bin/perl
-# 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
-# USA
-#
-# Author: Gris Ge <***@redhat.com>
-#
-
-# This script compare public constants of lsm Python library files with C
-# library include files.
-
-# Naming scheme:
-# py_name # Constant name used in Python, example:
-# # 'lsm.System.STATUS_OK'
-#
-# py_value # The value of python constant.
-#
-# c_name # Constant name used in C, example:
-# # 'LSM_SYSTEM_STATUS_OK'
-#
-# c_value # The value of C constant. We stored the raw string.
-
-use strict;
-use warnings;
-
-use File::Basename;
-use Cwd 'abs_path';
-use Data::Dumper;
-
-my $LSM_CODE_BASE_DIR = dirname( dirname( dirname( abs_path($0) ) ) );
-my $PYTHON_LIB_DIR = "$LSM_CODE_BASE_DIR/python_binding/lsm";
-my $C_LIB_HEADER = "$LSM_CODE_BASE_DIR"
- . "/c_binding/include/libstoragemgmt/libstoragemgmt.h";
-
-my $REGEX_VALUE_FORMAT = qr/
- (?<NUM>(?&NUM_PAT))
-
- (?(DEFINE)
- # integer number
- (?<NUM_INT>
- [0-9]+
- )
- # Bit shift:
- # 1 << 9
- (?<NUM_BIT_SHIFT>
- 1
- [\ \t]+
- <<
- [\ \t]+
- [0-9]+
- )
- # Hex number
- (?<NUM_HEX>
- 0x[0-9]+
- )
- (?<NUM_PAT>
- (?&NUM_BIT_SHIFT) | (?&NUM_HEX) | (?&NUM_INT)
- )
- )
-/x;
-
-my $REGEX_C_CONST_FORMAT = qr/
- ^
- (?: (?&HEADER_PAT))
- (?<CNAME>(?&CNAME_PAT))
- (?: (?&SPLITER_PAT))
- (?<NUM>(?&NUM_PAT))
-
- (?(DEFINE)
- # integer number
- (?<NUM_INT>
- [0-9]+
- )
- # Bit shift:
- # 1 << 9
- (?<NUM_BIT_SHIFT>
- 1
- [\ \t]+
- <<
- [\ \t]+
- [0-9]+
- )
- # Hex number
- # 0x0000000000000001
- (?<NUM_HEX>
- 0x[0-9]+
- )
- (?<NUM_PAT>
- (?&NUM_BIT_SHIFT) | (?&NUM_HEX) | (?&NUM_INT)
- )
- (?<CNAME_PAT>
- [A-Z][A-Z_0-9]+
- )
- (?<HEADER1>
- [\ \t]*
- )
- (?<HEADER2>
- \#define[\ \t]+
- )
- (?<HEADER_PAT>
- (?&HEADER1) | (?&HEADER2)
- )
- (?<SPLITER_PAT>
- [\ \t]*
- [=]*
- [\ \t]*
- )
- )
-/x;
-
-my %PY_CLASS_NAME_CONV = (
- 'Capabilities' => 'CAP',
- 'ErrorNumber' => 'ERR',
- 'JobStatus' => 'JOB',
- 'ErrorLevel' => 'ERR_LEVEL',
-);
-
-my $REF_RESULT = {
- 'pass' => {},
- 'fail' => {},
- 'c_missing' => {},
- 'py_missing' => {},
- 'c_const_hash' => {},
- 'py_const_hash' => {},
- 'known_c_to_py_name' => {},
- 'known_py_to_c_name' => {},
-};
-
-# $REF_RESULT = {
-# 'pass' => {
-# $py_name => 1, # Just for deduplication.
-# },
-# 'fail' => {
-# $py_name => 1, # Just for deduplication.
-# },
-# 'c_missing' => {
-# $py_name => 1,
-# },
-# 'py_missing' => {
-# $c_name => 1,
-# },
-# 'py_const_hash' => {
-# $py_name => $py_value,
-# },
-# 'c_const_hash' => {
-# $c_name => $c_value,
-# },
-# 'known_c_to_py_name' => {
-# $c_name => $py_name,
-# }
-# }
-#
-
-$|++;
-
-sub is_in_array($$) {
- my $ref_array = shift;
- my $item = shift;
- return 1 if grep { $_ eq $item } @{$ref_array};
- return undef;
-}
-
-sub py_name_2_c_name($) {
-
- # We do these conversion:
- # 1. Convert CaMel to CA_MEL
- # 2. Convert System to SYSTEM
- # 3. Convert Capabilities to CAP and etc using %PY_CLASS_NAME_CONV;
- my $py_name = shift;
- if ( $py_name =~ /^lsm\.([a-zA-Z]+)\.([A-Z_][A-Z_0-9]+)$/ ) {
- my $py_class_name = $1;
- my $py_var_name = $2;
-
- # Convert camel class name
- if (defined $PY_CLASS_NAME_CONV{$py_class_name}){
- return sprintf "LSM_%s_%s",
- $PY_CLASS_NAME_CONV{$py_class_name}, $py_var_name;
- }
- if ( $py_class_name =~ /^[A-Z][a-z]+$/ ) {
- $py_class_name =~ tr/[a-z]/[A-Z]/;
- return sprintf "LSM_%s_%s", $py_class_name, $py_var_name;
- }
- if ( $py_class_name =~ /^([A-Z][a-z]+)([A-Z][a-z]+)$/ ) {
- $py_class_name = sprintf "%s_%s", $1, $2;
- $py_class_name =~ tr/[a-z]/[A-Z]/;
- return sprintf "LSM_%s_%s", $py_class_name, $py_var_name;
- }
- }
-
- die "FAIL: Ilegal python constant name '$py_name'.\n";
-}
-
-sub _parse_c_init_header($){
- # Take initial C header file and read its sub header files
- # Return a reference of array containing file path.
- my $init_header = shift;
- my $folder_path = dirname($init_header);
- open my $init_header_fd, "<", $init_header
- or die "FAIL: Failed to open $init_header $!\n";
- my @rc = ();
- map{
- push @rc, "$folder_path/$1" if /#include "([^"]+)"/;
- }<$init_header_fd>;
- return \@rc;
-}
-
-sub _get_c_constants($){
- my $c_header = shift;
- open my $c_header_fd, "<", $c_header
- or die "FAIL: Failed to open $c_header $!\n";
- my %rc = ();
- map{
- $rc{$+{'CNAME'}} = $+{'NUM'} if /$REGEX_C_CONST_FORMAT/;
- }<$c_header_fd>;
- return \%rc;
-}
-
-sub parse_out_c_const() {
-
- # Return a reference like this:
- # {
- # $c_name => $value,
- # }
- my $ref_sub_c_headers = _parse_c_init_header($C_LIB_HEADER);
- my $ref_c_name_2_value = {};
- foreach my $cur_c_header (@{$ref_sub_c_headers}){
- my $ref_tmp = _get_c_constants($cur_c_header);
- foreach my $key_name (keys %{$ref_tmp}){
- $ref_c_name_2_value->{$key_name} = $ref_tmp->{$key_name};
- }
- }
- return $ref_c_name_2_value;
-}
-
-sub _parse_py_init_file($) {
-
- # Return a reference of array containging file path of sub python module.
- my $init_file = shift;
- open my $init_fd, "<", $init_file
- or die "FAIL: Failed to open $init_file: $!\n";
- my $folder_path = dirname($init_file);
- my @rc1 = ();
- my @rc2 = ();
- my @lines = ();
-
- # Merge multiline codes
- foreach my $line (<$init_fd>) {
- chomp $line;
- if ( $line =~ /^[^ ]/ ) {
- push @lines, $line;
- }
- else {
- $lines[-1] .= $line;
- }
- }
- close $init_fd;
-
- foreach my $line (@lines) {
- if ( $line =~ /from ([^ ]+) import (.+)$/ ) {
- push @rc1, sprintf "%s/%s.py", $folder_path, $1;
- my $class_line = $2;
- while ( $class_line =~ /([A-Z][a-zA-Z]+)[, \\]*/g ) {
- push @rc2, $1;
- }
- }
- }
- return \@rc1, \@rc2;
-}
-
-sub _get_py_class_consts($$){
- # Take $file_path and $ref_classes
- # Return reference of hash:
- # {
- # $py_name => $value,
- # }
- my $py_file = shift;
- my $ref_classes = shift;
-
- open my $py_fd, "<", $py_file
- or die "FAIL: Failed to open $py_file: $!\n";
- my %rc_hash = ();
- my $cur_class_name = undef;
- my $current_idention = undef;
- foreach my $line (<$py_fd>){
- chomp $line;
- if ($line =~ /^([ ]*)class[ ]+([^\(]+)\(/){
- $current_idention = $1;
- $cur_class_name = $2;
- unless (is_in_array($ref_classes, $cur_class_name)){
- $cur_class_name = undef;
- next;
- }
- }
- unless(defined $cur_class_name){
- next;
- }
- if ($line =~ /^$current_idention
- [\ ]+
- ([A-Z][A-Z\_0-9]+)
- [\ ]*=[\ ]*
- ($REGEX_VALUE_FORMAT)/x){
- my $var_name = $1;
- my $py_value = $2;
- my $py_name = sprintf "lsm.%s.%s", $cur_class_name, $var_name;
- $rc_hash{$py_name} = $py_value;
- }
- }
- close $py_fd;
- return \%rc_hash;
-}
-
-sub parse_out_py_const() {
-
- # Return a reference like this:
- # {
- # $py_name => $value,
- # }
- my ( $ref_sub_files, $ref_classes ) =
- _parse_py_init_file("$PYTHON_LIB_DIR/__init__.py");
-
- my $ref_py_name_2_value = {};
- foreach my $cur_py_file (@{$ref_sub_files}){
- my $ref_tmp = _get_py_class_consts($cur_py_file, $ref_classes);
- foreach my $key_name (keys %{$ref_tmp}){
- $ref_py_name_2_value->{$key_name} = $ref_tmp->{$key_name};
- }
- }
- return $ref_py_name_2_value;
-}
-
-sub value_str_to_int($) {
- my $raw_value = shift;
- unless ( defined $raw_value ) {
- return undef;
- }
- if ( $raw_value =~ /^[0-9]+$/ ) {
- return $raw_value;
- }
- if ( $raw_value =~ /^0x[0-9]+$/ ) {
- return hex $raw_value;
- }
- if ( $raw_value =~ /^([0-9]+) +<< +([0-9]+)$/ ) {
- return $1 << $2;
- }
- die "FAIL: Failed to convert $raw_value to integer\n";
-}
-
-sub record_result($$$$) {
-
- # Take ($py_name, $py_value, $c_name, $c_value)
- # Update $REF_RESULT
- my $py_name = shift;
- my $py_value = shift;
- my $c_name = shift;
- my $c_value = shift;
- my $real_py_value = undef;
- my $real_c_value = undef;
-
- if ( ( defined $py_name ) && ( defined $py_value ) ) {
- $real_py_value = value_str_to_int($py_value);
- $REF_RESULT->{'py_const_hash'}->{$py_name} = sprintf "%s(%s)",
- $py_value, $real_py_value;
- }
- if ( ( defined $c_name ) && ( defined $c_value ) ) {
- $real_c_value = value_str_to_int($c_value);
- $REF_RESULT->{'c_const_hash'}->{$c_name} = sprintf "%s(%s)", $c_value,
- $real_c_value;
- }
-
- unless ($py_name) {
- my $known_py_name = $REF_RESULT->{'known_c_to_py_name'}->{$c_name};
- return 1 if $known_py_name; # Already checked.
- $REF_RESULT->{'py_missing'}->{$c_name} = 'unknown';
- return 1;
- }
-
- unless ($c_name) {
-
- # ilegal python variable name, result already updated by
- # py_name_2_c_name()
- return 1;
- }
-
- $REF_RESULT->{'known_c_to_py_name'}->{$c_name} = $py_name;
- $REF_RESULT->{'known_py_to_c_name'}->{$py_name} = $c_name;
-
- unless ( defined $py_value ) {
-
- # value for py_value will never be undef, just in case.
- $REF_RESULT->{'py_missing'}->{$c_name} = $py_value;
- return 1;
- }
-
- unless ( defined $c_value ) {
- $REF_RESULT->{'c_missing'}->{$py_name} = $c_name;
- return 1;
- }
- if ( $real_py_value == $real_c_value ) {
- $REF_RESULT->{'pass'}->{$py_name} = 1;
- }
- else {
- $REF_RESULT->{'fail'}->{$py_name} = 1;
- }
- 1;
-}
-
-sub show_result() {
- my $format = "%-10s%-60s %s\n";
- my @pass_py_names = sort keys %{ $REF_RESULT->{'pass'} };
- my @fail_py_names = sort keys %{ $REF_RESULT->{'fail'} };
- my @py_missing_c_names = sort keys %{ $REF_RESULT->{'py_missing'} };
- my @c_missing_py_names = sort keys %{ $REF_RESULT->{'c_missing'} };
- my $ref_py_name_2_c_name = $REF_RESULT->{'known_py_to_c_name'};
- my $ref_py_name_2_value = $REF_RESULT->{'py_const_hash'};
- my $ref_c_name_2_value = $REF_RESULT->{'c_const_hash'};
-
- # Header
- printf $format, '#'x8, 'Name', 'Value';
- print "\n";
- foreach my $py_name (@pass_py_names) {
- my $py_value = $ref_py_name_2_value->{$py_name};
- my $c_name = $ref_py_name_2_c_name->{$py_name};
- my $c_value = $ref_c_name_2_value->{$c_name};
- printf ($format, "PASS", $py_name, $py_value);
- printf ($format, " ", $c_name, $c_value);
- }
- foreach my $c_name (@py_missing_c_names) {
- my $py_name = '-' x 8;
- my $py_value = '-' x 8;
- my $c_value = $ref_c_name_2_value->{$c_name};
- printf ($format, "PY_MISS", $c_name, $c_value);
- }
- foreach my $py_name (@c_missing_py_names) {
- my $c_name = '-' x 8;
- my $c_value = '-' x 8;
- my $py_value = $ref_py_name_2_value->{$py_name};
- printf ($format, "C_MISS", $py_name, $py_value);
- }
- foreach my $py_name (@fail_py_names) {
- my $py_value = $ref_py_name_2_value->{$py_name};
- my $c_name = $ref_py_name_2_c_name->{$py_name};
- my $c_value = $ref_c_name_2_value->{$c_name};
- printf ($format, "FAIL", $py_name, $py_value);
- printf ($format, " ", $c_name, $c_value);
- }
- 1;
-}
-
-sub main() {
- my $ref_py_const_hash = parse_out_py_const();
- my $ref_c_const_hash = parse_out_c_const();
- map {
- my $py_name = $_;
- my $c_name = py_name_2_c_name($py_name);
- record_result(
- $py_name, $ref_py_const_hash->{$py_name},
- $c_name, $ref_c_const_hash->{$c_name}
- )
- } keys %{$ref_py_const_hash};
-
- map {
- my $c_name = $_;
-
- # We don't have a way to convert C constant name to python one.
- # We just treat all C constant as missing if not marked by previous
- # check.
- record_result( undef, undef, $c_name, $ref_c_const_hash->{$c_name} )
- } keys %{$ref_c_const_hash};
- show_result();
- exit 1
- if ( %{ $REF_RESULT->{'fail'} }
- || %{ $REF_RESULT->{'c_missing'} }
- || %{ $REF_RESULT->{'py_missing'} } );
- exit 0;
-}
-
-main();
diff --git a/tools/utility/public_symbols.py b/tools/utility/public_symbols.py
deleted file mode 100755
index e030f0a..0000000
--- a/tools/utility/public_symbols.py
+++ /dev/null
@@ -1,120 +0,0 @@
-#!/usr/bin/env python2
-
-# 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-
-# This is a file that simply dumps the publicly available symbols for the
-# python library. Anything that starts with a '_' is considered private.
-
-import inspect
-import lsm
-
-nesting = 0
-visited_module = {}
-visited_class = {'ABCMeta': True}
-visited_function = {}
-
-
-def o_p(msg):
- print("%s%s" % (' ' * nesting, msg))
-
-
-def handle_data(c, a):
- d = getattr(c, a[0])
- o_p("DATA: %s %s %s" % (a[0], type(d), a[3]))
-
-
-def handle_property(c, a):
- o_p("PROPERTY: %s" % (a[0]))
-
-
-def handle_method(c, a):
- o_p("%s: %s %s" % (a[1].upper(), a[0],
- inspect.getargspec(getattr(c, a[0]))))
-
-
-def handle_other(c, a):
- o_p("OTHER: %s: %s" % (a[0], a[1]))
-
-
-f_map = {'data': handle_data,
- 'property': handle_property,
- 'method': handle_method,
- 'static method': handle_method}
-
-
-def h_class(c):
-
- global nesting
-
- nesting += 4
-
- info = [x for x in inspect.classify_class_attrs(c)
- if not x[0].startswith('_')]
-
- s = sorted(info, key=lambda x: (x[1], x[0]))
-
- for i in s:
- if i[1] in f_map:
- f_map[i[1]](c, i)
- else:
- handle_other(c, i)
-
- nesting -= 4
-
-
-def h_module(mod):
- global nesting
- global visited_module
- global visited_class
- global visited_function
-
- if str(mod.__name__) in visited_module:
- return
- else:
- visited_module[str(mod.__name__)] = True
-
- class_list = [x for x in inspect.getmembers(mod, inspect.isclass)
- if not x[0].startswith('_')]
-
- function_list = [x for x in inspect.getmembers(mod, inspect.isfunction)
- if not x[0].startswith('_')]
-
- module_list = [x for x in inspect.getmembers(mod, inspect.ismodule)
- if not x[0].startswith('_')]
-
- print '%sModule: %s' % (' ' * nesting, str(mod.__name__))
- nesting += 4
- for m in function_list:
- if not m[0] in visited_function:
- visited_function[m[0]] = True
- print '%sf: %s' % (' ' * nesting, m[0])
-
- nesting -= 4
-
- for c in class_list:
- if not c[0] in visited_class:
- visited_class[c[0]] = True
- nesting += 4
- print '%sClass: %s' % (' ' * nesting, c[0])
- h_class(c[1])
- nesting -= 4
-
- for m in module_list:
- h_module(m[1])
-
-if __name__ == '__main__':
- h_module(lsm)
diff --git a/tools/utility/web_cap.py b/tools/utility/web_cap.py
deleted file mode 100755
index e4740e3..0000000
--- a/tools/utility/web_cap.py
+++ /dev/null
@@ -1,121 +0,0 @@
-#!/usr/bin/env python2
-
-# Copyright (C) 2011-2013 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 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-
-# This is a file that simply outputs html to std out which can then
-# be redirected to a file to be used on the project web site for supported
-# array features.
-
-import sys
-import os.path
-
-
-def process_file(cap_file):
- h = open(cap_file, 'r')
- data = h.readlines()
- d = {}
-
- for l in data:
- (k, v) = l[0:-1].split(":")
- if v == "SUPPORTED":
- d[k] = True
- else:
- d[k] = False
- return os.path.basename(cap_file), d
-
-
-def create_html(data):
- print \
-'''
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
-<title>Array support</title>
-<script type='text/javascript' src='https://www.google.com/jsapi'></script>
-<script type='text/javascript'>
-
-google.load('visualization', '1', {packages:['table']});
-google.setOnLoadCallback(drawTable);
-function drawTable() {
- var data = new google.visualization.DataTable(); '''
-
- array_vendors = [x for x, v in data]
-
- cap_keys = data[0][1].keys()
- cap_keys.sort()
-
- print '''data.addColumn('string', 'Capability/Feature');'''
-
- #Create vendor columns
- for a in array_vendors:
- print "data.addColumn('boolean', '" + a + "');"
-
- #Create plugin column
- print "data.addRows(["
-
- #Output the rows
- for c in cap_keys:
- line = "['%s'" % c
-
- for v, d in data:
- line += ",%s" % str(d[c]).lower()
-
- line += "],"
- print line
- print "]);"
-
- print \
-'''
- var table = new google.visualization.Table(document.getElementById('table_div'));
- table.draw(data, {showRowNumber: false});
- }
- </script>
- </head>
-
- <body>
- <h2>Supported API calls for each plug-in </h2>
-
- <h3>Notes</h3>
- <ul>
- <li> This data is generated from querying the capabilities of the plug-in.
- <li> Plug-in must pass rudimentary tests for each advertised feature to be included here.
- <li> At this time all plug-ins listed are included in the install packages as they are all open source.
- <li> Columns are sort-able, click header to sort.
- </ul>
-
- <div id='table_div'></div>
- </body>
-</html>
-'''
-
-if __name__ == '__main__':
- arrays = []
-
- if len(sys.argv) < 2:
- print 'syntax: web_cap.py <array_cap_1.txt> <array_cap_N.txt>\n\n'
- print 'HOWTO: \n' \
- '1. Take the output of lsmcli --capabilities <system>\n' \
- '2. Dump to a file for 1 or more arrays. \n' \
- '3. Then supply each file name on the command line for this \n' \
- ' utility and the html output will be dumped to STDOUT\n\n'
- print 'Note: The file name is used as the column header for output.'
- for f in sys.argv[1:]:
- arrays.append(process_file(f))
-
- if len(arrays):
- create_html(arrays)
--
1.8.3.1
Tony Asleson
2015-04-02 19:58:37 UTC
Permalink
Post by Gris Ge
https://github.com/libstorage/libstoragemgmt
Committed, main repo is on github.

Thanks,
Tony

Loading...