Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
---
python/sanlock.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 133 insertions(+), 2 deletions(-)
diff --git a/python/sanlock.c b/python/sanlock.c
index 64a95d7..e1fe1a9 100644
--- a/python/sanlock.c
+++ b/python/sanlock.c
@@ -694,7 +694,7 @@ py_rem_lockspace(PyObject *self __unused, PyObject *args, PyObject
*keywds)
/* get_lockspaces */
PyDoc_STRVAR(pydoc_get_lockspaces, "\
-get_lockspaces() -> dict\n\
+get_lockspaces() -> list\n\
Return the list of lockspaces currently managed by sanlock. The reported\n\
flag indicates whether the lockspace is acquired (0) or in transition.\n\
The possible transition values are LSFLAG_ADD if the lockspace is in the\n\
@@ -714,7 +714,7 @@ py_get_lockspaces(PyObject *self __unused, PyObject *args, PyObject
*keywds)
Py_END_ALLOW_THREADS
if (rv < 0) {
- __set_exception(rv, "Sanlock get lockspace failure");
+ __set_exception(rv, "Sanlock get lockspaces failure");
goto exit_fail;
}
@@ -784,6 +784,108 @@ exit_fail:
return NULL;
}
+/* get_hosts */
+PyDoc_STRVAR(pydoc_get_hosts, "\
+get_hosts(lockspace, host_id=0) -> list\n\
+Return the list of hosts currently alive in a lockspace. When the host_id\n\
+is specified then only the requested host status is returned. The reported\n\
+flag indicates whether the host is free (HOST_FREE), alive (HOST_LIVE),\n\
+failing (HOST_FAIL) or dead (HOST_DEAD).\n\
+The other returned information are: the generation, the last timestamp and\n\
+the io_timeout.\n");
+
+static PyObject *
+py_get_hosts(PyObject *self __unused, PyObject *args, PyObject *keywds)
+{
+ int rv, i, hss_count = 0;
+ uint64_t host_id = 0;
+ const char *lockspace = NULL;
+ struct sanlk_host *hss = NULL;
+ PyObject *ls_list = NULL, *ls_entry = NULL, *ls_value = NULL;
+
+ static char *kwlist[] = {"lockspace", "host_id", NULL};
+
+ /* parse python tuple */
+ if (!PyArg_ParseTupleAndKeywords(args, keywds, "s|k", kwlist,
+ &lockspace, &host_id)) {
+ return NULL;
+ }
+
+ /* get all the lockspaces (gil disabled) */
+ Py_BEGIN_ALLOW_THREADS
+ rv = sanlock_get_hosts(lockspace, host_id, &hss, &hss_count, 0);
+ Py_END_ALLOW_THREADS
+
+ if (rv < 0) {
+ __set_exception(rv, "Sanlock get hosts failure");
+ goto exit_fail;
+ }
+
+ /* prepare the dictionary holding the information */
+ if ((ls_list = PyList_New(0)) == NULL)
+ goto exit_fail;
+
+ for (i = 0; i < hss_count; i++) {
+ if ((ls_entry = PyDict_New()) == NULL)
+ goto exit_fail;
+
+ /* fill the dictionary information: host_id */
+ if ((ls_value = PyInt_FromLong(hss[i].host_id)) == NULL)
+ goto exit_fail;
+ rv = PyDict_SetItemString(ls_entry, "host_id", ls_value);
+ Py_DECREF(ls_value);
+ if (rv != 0)
+ goto exit_fail;
+
+ /* fill the dictionary information: generation */
+ if ((ls_value = PyInt_FromLong(hss[i].generation)) == NULL)
+ goto exit_fail;
+ rv = PyDict_SetItemString(ls_entry, "generation", ls_value);
+ Py_DECREF(ls_value);
+ if (rv != 0)
+ goto exit_fail;
+
+ /* fill the dictionary information: timestamp */
+ if ((ls_value = PyInt_FromLong(hss[i].timestamp)) == NULL)
+ goto exit_fail;
+ rv = PyDict_SetItemString(ls_entry, "timestamp", ls_value);
+ Py_DECREF(ls_value);
+ if (rv != 0)
+ goto exit_fail;
+
+ /* fill the dictionary information: io_timeout */
+ if ((ls_value = PyInt_FromLong(hss[i].io_timeout)) == NULL)
+ goto exit_fail;
+ rv = PyDict_SetItemString(ls_entry, "io_timeout", ls_value);
+ Py_DECREF(ls_value);
+ if (rv != 0)
+ goto exit_fail;
+
+ /* fill the dictionary information: flags */
+ if ((ls_value = PyInt_FromLong(hss[i].flags)) == NULL)
+ goto exit_fail;
+ rv = PyDict_SetItemString(ls_entry, "flags", ls_value);
+ Py_DECREF(ls_value);
+ if (rv != 0)
+ goto exit_fail;
+
+ if (PyList_Append(ls_list, ls_entry) != 0)
+ goto exit_fail;
+
+ Py_DECREF(ls_entry);
+ }
+
+ /* success */
+ free(hss);
+ return ls_list;
+
+ /* failure */
+exit_fail:
+ if (hss) free(hss);
+ Py_XDECREF(ls_entry);
+ Py_XDECREF(ls_list);
+ return NULL;
+}
/* acquire */
PyDoc_STRVAR(pydoc_acquire, "\
@@ -1089,6 +1191,8 @@ sanlock_methods[] = {
METH_VARARGS|METH_KEYWORDS, pydoc_rem_lockspace},
{"get_lockspaces", (PyCFunction) py_get_lockspaces,
METH_VARARGS|METH_KEYWORDS, pydoc_get_lockspaces},
+ {"get_hosts", (PyCFunction) py_get_hosts,
+ METH_VARARGS|METH_KEYWORDS, pydoc_get_hosts},
{"acquire", (PyCFunction) py_acquire,
METH_VARARGS|METH_KEYWORDS, pydoc_acquire},
{"release", (PyCFunction) py_release,
@@ -1155,6 +1259,7 @@ initsanlock(void)
Py_INCREF(py_exception);
}
+ /* lockspaces list flags */
if ((sk_constant = PyInt_FromLong(SANLK_LSF_ADD)) != NULL) {
if (PyModule_AddObject(py_module, "LSFLAG_ADD", sk_constant)) {
Py_DECREF(sk_constant);
@@ -1167,6 +1272,7 @@ initsanlock(void)
}
}
+ /* resource request flags */
if ((sk_constant = PyInt_FromLong(SANLK_REQ_FORCE)) != NULL) {
if (PyModule_AddObject(py_module, "REQ_FORCE", sk_constant)) {
Py_DECREF(sk_constant);
@@ -1178,4 +1284,29 @@ initsanlock(void)
Py_DECREF(sk_constant);
}
}
+
+ /* hosts list flags */
+ if ((sk_constant = PyInt_FromLong(SANLK_HOST_FREE)) != NULL) {
+ if (PyModule_AddObject(py_module, "HOST_FREE", sk_constant)) {
+ Py_DECREF(sk_constant);
+ }
+ }
+
+ if ((sk_constant = PyInt_FromLong(SANLK_HOST_LIVE)) != NULL) {
+ if (PyModule_AddObject(py_module, "HOST_LIVE", sk_constant)) {
+ Py_DECREF(sk_constant);
+ }
+ }
+
+ if ((sk_constant = PyInt_FromLong(SANLK_HOST_FAIL)) != NULL) {
+ if (PyModule_AddObject(py_module, "HOST_FAIL", sk_constant)) {
+ Py_DECREF(sk_constant);
+ }
+ }
+
+ if ((sk_constant = PyInt_FromLong(SANLK_HOST_DEAD)) != NULL) {
+ if (PyModule_AddObject(py_module, "HOST_DEAD", sk_constant)) {
+ Py_DECREF(sk_constant);
+ }
+ }
}
--
1.7.1