Update Red Hat Copyright Notices
[nbdkit.git] / plugins / python / modfunctions.c
blob479707e78f189a39f0174e0e38c38377df0e0c25
1 /* nbdkit
2 * Copyright Red Hat
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of Red Hat nor the names of its contributors may be
16 * used to endorse or promote products derived from this software without
17 * specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
33 /* Functions and constants in the virtual nbdkit.* module. */
35 #include <config.h>
37 #include <stdio.h>
38 #include <stdlib.h>
40 #include "plugin.h"
42 __thread int last_error;
44 /* nbdkit.debug */
45 static PyObject *
46 debug (PyObject *self, PyObject *args)
48 const char *msg;
50 if (!PyArg_ParseTuple (args, "s:debug", &msg))
51 return NULL;
52 nbdkit_debug ("%s", msg);
53 Py_RETURN_NONE;
56 /* nbdkit.export_name */
57 static PyObject *
58 export_name (PyObject *self, PyObject *args)
60 const char *s = nbdkit_export_name ();
62 if (!s) {
63 /* Unfortunately we lose the actual error. XXX */
64 PyErr_SetString (PyExc_RuntimeError, "nbdkit.export_name failed");
65 return NULL;
68 /* NBD spec says that the export name should be UTF-8, so this
69 * ought to work, and if it fails the client gave us a bad export
70 * name which should turn into an exception.
72 return PyUnicode_FromString (s);
75 /* nbdkit.set_error */
76 static PyObject *
77 set_error (PyObject *self, PyObject *args)
79 int err;
81 if (!PyArg_ParseTuple (args, "i:set_error", &err))
82 return NULL;
83 nbdkit_set_error (err);
84 last_error = err;
85 Py_RETURN_NONE;
88 /* nbdkit.shutdown */
89 static PyObject *
90 do_shutdown (PyObject *self, PyObject *args)
92 nbdkit_shutdown ();
93 Py_RETURN_NONE;
96 /* nbdkit.disconnect */
97 static PyObject *
98 do_disconnect (PyObject *self, PyObject *args)
100 int force;
102 if (!PyArg_ParseTuple (args, "p:disconnect", &force))
103 return NULL;
104 nbdkit_disconnect (force);
105 Py_RETURN_NONE;
108 /* nbdkit.parse_size */
109 static PyObject *
110 parse_size (PyObject *self, PyObject *args)
112 const char *s;
113 if (!PyArg_ParseTuple (args, "s:parse_size", &s))
114 return NULL;
116 int64_t size = nbdkit_parse_size (s);
117 if (size == -1) {
118 PyErr_SetString (PyExc_ValueError, "Unable to parse string as size");
119 return NULL;
122 return PyLong_FromSize_t ((size_t)size);
125 static PyMethodDef NbdkitMethods[] = {
126 { "debug", debug, METH_VARARGS,
127 "Print a debug message" },
128 { "export_name", export_name, METH_NOARGS,
129 "Return the optional export name negotiated with the client" },
130 { "parse_size", parse_size, METH_VARARGS,
131 "Parse human-readable size strings into bytes" },
132 { "set_error", set_error, METH_VARARGS,
133 "Store an errno value prior to throwing an exception" },
134 { "shutdown", do_shutdown, METH_NOARGS,
135 "Request asynchronous shutdown" },
136 { "disconnect", do_disconnect, METH_VARARGS,
137 "Request disconnection from current client" },
138 { NULL }
141 static struct PyModuleDef moduledef = {
142 PyModuleDef_HEAD_INIT,
143 "nbdkit",
144 "Module used to access nbdkit server API",
146 NbdkitMethods,
147 NULL,
148 NULL,
149 NULL,
150 NULL
153 PyMODINIT_FUNC
154 create_nbdkit_module (void)
156 PyObject *m;
158 m = PyModule_Create (&moduledef);
159 if (m == NULL) {
160 nbdkit_error ("could not create the nbdkit API module");
161 exit (EXIT_FAILURE);
164 /* Constants corresponding to various flags. */
165 #define ADD_INT_CONSTANT(name) \
166 if (PyModule_AddIntConstant (m, #name, NBDKIT_##name) == -1) { \
167 nbdkit_error ("could not add constant %s to nbdkit API module", \
168 #name); \
169 exit (EXIT_FAILURE); \
171 ADD_INT_CONSTANT (THREAD_MODEL_SERIALIZE_CONNECTIONS);
172 ADD_INT_CONSTANT (THREAD_MODEL_SERIALIZE_ALL_REQUESTS);
173 ADD_INT_CONSTANT (THREAD_MODEL_SERIALIZE_REQUESTS);
174 ADD_INT_CONSTANT (THREAD_MODEL_PARALLEL);
176 ADD_INT_CONSTANT (FLAG_MAY_TRIM);
177 ADD_INT_CONSTANT (FLAG_FUA);
178 ADD_INT_CONSTANT (FLAG_REQ_ONE);
179 ADD_INT_CONSTANT (FLAG_FAST_ZERO);
181 ADD_INT_CONSTANT (FUA_NONE);
182 ADD_INT_CONSTANT (FUA_EMULATE);
183 ADD_INT_CONSTANT (FUA_NATIVE);
185 ADD_INT_CONSTANT (CACHE_NONE);
186 ADD_INT_CONSTANT (CACHE_EMULATE);
187 ADD_INT_CONSTANT (CACHE_NATIVE);
189 ADD_INT_CONSTANT (EXTENT_HOLE);
190 ADD_INT_CONSTANT (EXTENT_ZERO);
191 #undef ADD_INT_CONSTANT
193 return m;