1 /*
2  * Python object wrapper of libvslvm_volume_group_t
3  *
4  * Copyright (C) 2014-2021, Joachim Metz <joachim.metz@gmail.com>
5  *
6  * Refer to AUTHORS for acknowledgements.
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20  */
21 
22 #include <common.h>
23 #include <memory.h>
24 #include <types.h>
25 
26 #if defined( HAVE_STDLIB_H )
27 #include <stdlib.h>
28 #endif
29 
30 #include "pyvslvm_error.h"
31 #include "pyvslvm_libcerror.h"
32 #include "pyvslvm_libvslvm.h"
33 #include "pyvslvm_logical_volume.h"
34 #include "pyvslvm_logical_volumes.h"
35 #include "pyvslvm_physical_volume.h"
36 #include "pyvslvm_physical_volumes.h"
37 #include "pyvslvm_python.h"
38 #include "pyvslvm_unused.h"
39 #include "pyvslvm_volume_group.h"
40 
41 PyMethodDef pyvslvm_volume_group_object_methods[] = {
42 
43 	/* Functions to access the volume group values */
44 
45 	{ "get_name",
46 	  (PyCFunction) pyvslvm_volume_group_get_name,
47 	  METH_NOARGS,
48 	  "get_name() -> Unicode string or None\n"
49 	  "\n"
50 	  "Retrieves the name." },
51 
52 	{ "get_identifier",
53 	  (PyCFunction) pyvslvm_volume_group_get_identifier,
54 	  METH_NOARGS,
55 	  "get_identifier() -> Unicode string or None\n"
56 	  "\n"
57 	  "Retrieves the identifier." },
58 
59 	/* Functions to access the physical volumes */
60 
61 	{ "get_number_of_physical_volumes",
62 	  (PyCFunction) pyvslvm_volume_group_get_number_of_physical_volumes,
63 	  METH_NOARGS,
64 	  "get_number_of_physical_volumes() -> Integer\n"
65 	  "\n"
66 	  "Retrieves the number of physical volumes." },
67 
68 	{ "get_physical_volume",
69 	  (PyCFunction) pyvslvm_volume_group_get_physical_volume,
70 	  METH_VARARGS | METH_KEYWORDS,
71 	  "get_physical_volume(volume_index) -> Object or None\n"
72 	  "\n"
73 	  "Retrieves a specific physical volume." },
74 
75 	{ "get_physical_volumes",
76 	  (PyCFunction) pyvslvm_volume_group_get_physical_volumes,
77 	  METH_VARARGS | METH_KEYWORDS,
78 	  "get_physical_volumes() -> Object\n"
79 	  "\n"
80 	  "Retrieves a sequence object of the physical volumes." },
81 
82 	/* Functions to access the logical volumes */
83 
84 	{ "get_number_of_logical_volumes",
85 	  (PyCFunction) pyvslvm_volume_group_get_number_of_logical_volumes,
86 	  METH_NOARGS,
87 	  "get_number_of_logical_volumes() -> Integer\n"
88 	  "\n"
89 	  "Retrieves the number of logical volumes." },
90 
91 	{ "get_logical_volume",
92 	  (PyCFunction) pyvslvm_volume_group_get_logical_volume,
93 	  METH_VARARGS | METH_KEYWORDS,
94 	  "get_logical_volume(volume_index) -> Object or None\n"
95 	  "\n"
96 	  "Retrieves a specific logical volume." },
97 
98 	{ "get_logical_volumes",
99 	  (PyCFunction) pyvslvm_volume_group_get_logical_volumes,
100 	  METH_VARARGS | METH_KEYWORDS,
101 	  "get_logical_volumes() -> Object\n"
102 	  "\n"
103 	  "Retrieves a sequence object of the logical volumes." },
104 
105 	/* Sentinel */
106 	{ NULL, NULL, 0, NULL }
107 };
108 
109 PyGetSetDef pyvslvm_volume_group_object_get_set_definitions[] = {
110 
111 	{ "name",
112 	  (getter) pyvslvm_volume_group_get_name,
113 	  (setter) 0,
114 	  "The name.",
115 	  NULL },
116 
117 	{ "identifier",
118 	  (getter) pyvslvm_volume_group_get_identifier,
119 	  (setter) 0,
120 	  "The identifier.",
121 	  NULL },
122 
123 	{ "number_of_physical_volumes",
124 	  (getter) pyvslvm_volume_group_get_number_of_physical_volumes,
125 	  (setter) 0,
126 	  "The number of physical volumes.",
127 	  NULL },
128 
129 	{ "physical_volumes",
130 	  (getter) pyvslvm_volume_group_get_physical_volumes,
131 	  (setter) 0,
132 	  "The physical volumes.",
133 	  NULL },
134 
135 	{ "number_of_logical_volumes",
136 	  (getter) pyvslvm_volume_group_get_number_of_logical_volumes,
137 	  (setter) 0,
138 	  "The number of logical volumes.",
139 	  NULL },
140 
141 	{ "logical_volumes",
142 	  (getter) pyvslvm_volume_group_get_logical_volumes,
143 	  (setter) 0,
144 	  "The logical volumes.",
145 	  NULL },
146 
147 	/* Sentinel */
148 	{ NULL, NULL, NULL, NULL, NULL }
149 };
150 
151 PyTypeObject pyvslvm_volume_group_type_object = {
152 	PyVarObject_HEAD_INIT( NULL, 0 )
153 
154 	/* tp_name */
155 	"pyvslvm.volume_group",
156 	/* tp_basicsize */
157 	sizeof( pyvslvm_volume_group_t ),
158 	/* tp_itemsize */
159 	0,
160 	/* tp_dealloc */
161 	(destructor) pyvslvm_volume_group_free,
162 	/* tp_print */
163 	0,
164 	/* tp_getattr */
165 	0,
166 	/* tp_setattr */
167 	0,
168 	/* tp_compare */
169 	0,
170 	/* tp_repr */
171 	0,
172 	/* tp_as_number */
173 	0,
174 	/* tp_as_sequence */
175 	0,
176 	/* tp_as_mapping */
177 	0,
178 	/* tp_hash */
179 	0,
180 	/* tp_call */
181 	0,
182 	/* tp_str */
183 	0,
184 	/* tp_getattro */
185 	0,
186 	/* tp_setattro */
187 	0,
188 	/* tp_as_buffer */
189 	0,
190 	/* tp_flags */
191 	Py_TPFLAGS_DEFAULT,
192 	/* tp_doc */
193 	"pyvslvm volume group object (wraps libvslvm_volume_group_t)",
194 	/* tp_traverse */
195 	0,
196 	/* tp_clear */
197 	0,
198 	/* tp_richcompare */
199 	0,
200 	/* tp_weaklistoffset */
201 	0,
202 	/* tp_iter */
203 	0,
204 	/* tp_iternext */
205 	0,
206 	/* tp_methods */
207 	pyvslvm_volume_group_object_methods,
208 	/* tp_members */
209 	0,
210 	/* tp_getset */
211 	pyvslvm_volume_group_object_get_set_definitions,
212 	/* tp_base */
213 	0,
214 	/* tp_dict */
215 	0,
216 	/* tp_descr_get */
217 	0,
218 	/* tp_descr_set */
219 	0,
220 	/* tp_dictoffset */
221 	0,
222 	/* tp_init */
223 	(initproc) pyvslvm_volume_group_init,
224 	/* tp_alloc */
225 	0,
226 	/* tp_new */
227 	0,
228 	/* tp_free */
229 	0,
230 	/* tp_is_gc */
231 	0,
232 	/* tp_bases */
233 	NULL,
234 	/* tp_mro */
235 	NULL,
236 	/* tp_cache */
237 	NULL,
238 	/* tp_subclasses */
239 	NULL,
240 	/* tp_weaklist */
241 	NULL,
242 	/* tp_del */
243 	0
244 };
245 
246 /* Creates a new pyvslvm volume group object
247  * Returns a Python object if successful or NULL on error
248  */
pyvslvm_volume_group_new(libvslvm_volume_group_t * volume_group,pyvslvm_handle_t * handle_object)249 PyObject *pyvslvm_volume_group_new(
250            libvslvm_volume_group_t *volume_group,
251            pyvslvm_handle_t *handle_object )
252 {
253 	static char *function                        = "pyvslvm_volume_group_new";
254 	pyvslvm_volume_group_t *pyvslvm_volume_group = NULL;
255 
256 	pyvslvm_volume_group = PyObject_New(
257 	                        struct pyvslvm_volume_group,
258 	                        &pyvslvm_volume_group_type_object );
259 
260 	if( pyvslvm_volume_group == NULL )
261 	{
262 		PyErr_Format(
263 		 PyExc_MemoryError,
264 		 "%s: unable to initialize volume group.",
265 		 function );
266 
267 		goto on_error;
268 	}
269 	if( pyvslvm_volume_group_init(
270 	     pyvslvm_volume_group ) != 0 )
271 	{
272 		PyErr_Format(
273 		 PyExc_MemoryError,
274 		 "%s: unable to initialize volume group.",
275 		 function );
276 
277 		goto on_error;
278 	}
279 	pyvslvm_volume_group->volume_group  = volume_group;
280 	pyvslvm_volume_group->handle_object = handle_object;
281 
282 	Py_IncRef(
283 	 (PyObject *) pyvslvm_volume_group->handle_object );
284 
285 	return( (PyObject *) pyvslvm_volume_group );
286 
287 on_error:
288 	if( pyvslvm_volume_group != NULL )
289 	{
290 		Py_DecRef(
291 		 (PyObject *) pyvslvm_volume_group );
292 	}
293 	return( NULL );
294 }
295 
296 /* Initializes a volume group object
297  * Returns 0 if successful or -1 on error
298  */
pyvslvm_volume_group_init(pyvslvm_volume_group_t * pyvslvm_volume_group)299 int pyvslvm_volume_group_init(
300      pyvslvm_volume_group_t *pyvslvm_volume_group )
301 {
302 	static char *function = "pyvslvm_volume_group_init";
303 
304 	if( pyvslvm_volume_group == NULL )
305 	{
306 		PyErr_Format(
307 		 PyExc_TypeError,
308 		 "%s: invalid volume group.",
309 		 function );
310 
311 		return( -1 );
312 	}
313 	/* Make sure libvslvm volume group is set to NULL
314 	 */
315 	pyvslvm_volume_group->volume_group = NULL;
316 
317 	return( 0 );
318 }
319 
320 /* Frees a volume group object
321  */
pyvslvm_volume_group_free(pyvslvm_volume_group_t * pyvslvm_volume_group)322 void pyvslvm_volume_group_free(
323       pyvslvm_volume_group_t *pyvslvm_volume_group )
324 {
325 	libcerror_error_t *error    = NULL;
326 	struct _typeobject *ob_type = NULL;
327 	static char *function       = "pyvslvm_volume_group_free";
328 	int result                  = 0;
329 
330 	if( pyvslvm_volume_group == NULL )
331 	{
332 		PyErr_Format(
333 		 PyExc_TypeError,
334 		 "%s: invalid volume group.",
335 		 function );
336 
337 		return;
338 	}
339 	if( pyvslvm_volume_group->volume_group == NULL )
340 	{
341 		PyErr_Format(
342 		 PyExc_TypeError,
343 		 "%s: invalid volume group - missing libvslvm volume group.",
344 		 function );
345 
346 		return;
347 	}
348 	ob_type = Py_TYPE(
349 	           pyvslvm_volume_group );
350 
351 	if( ob_type == NULL )
352 	{
353 		PyErr_Format(
354 		 PyExc_ValueError,
355 		 "%s: missing ob_type.",
356 		 function );
357 
358 		return;
359 	}
360 	if( ob_type->tp_free == NULL )
361 	{
362 		PyErr_Format(
363 		 PyExc_ValueError,
364 		 "%s: invalid ob_type - missing tp_free.",
365 		 function );
366 
367 		return;
368 	}
369 	Py_BEGIN_ALLOW_THREADS
370 
371 	result = libvslvm_volume_group_free(
372 	          &( pyvslvm_volume_group->volume_group ),
373 	          &error );
374 
375 	Py_END_ALLOW_THREADS
376 
377 	if( result != 1 )
378 	{
379 		pyvslvm_error_raise(
380 		 error,
381 		 PyExc_MemoryError,
382 		 "%s: unable to free volume group.",
383 		 function );
384 
385 		libcerror_error_free(
386 		 &error );
387 	}
388 	if( pyvslvm_volume_group->handle_object != NULL )
389 	{
390 		Py_DecRef(
391 		 (PyObject *) pyvslvm_volume_group->handle_object );
392 	}
393 	ob_type->tp_free(
394 	 (PyObject*) pyvslvm_volume_group );
395 }
396 
397 /* Retrieves the name
398  * Returns a Python object if successful or NULL on error
399  */
pyvslvm_volume_group_get_name(pyvslvm_volume_group_t * pyvslvm_volume_group,PyObject * arguments PYVSLVM_ATTRIBUTE_UNUSED)400 PyObject *pyvslvm_volume_group_get_name(
401            pyvslvm_volume_group_t *pyvslvm_volume_group,
402            PyObject *arguments PYVSLVM_ATTRIBUTE_UNUSED )
403 {
404 	libcerror_error_t *error = NULL;
405 	PyObject *string_object  = NULL;
406 	char *name               = NULL;
407 	const char *errors       = NULL;
408 	static char *function    = "pyvslvm_volume_group_get_name";
409 	size_t name_size         = 0;
410 	int result               = 0;
411 
412 	PYVSLVM_UNREFERENCED_PARAMETER( arguments )
413 
414 	if( pyvslvm_volume_group == NULL )
415 	{
416 		PyErr_Format(
417 		 PyExc_TypeError,
418 		 "%s: invalid volume group.",
419 		 function );
420 
421 		return( NULL );
422 	}
423 	Py_BEGIN_ALLOW_THREADS
424 
425 	result = libvslvm_volume_group_get_name_size(
426 	          pyvslvm_volume_group->volume_group,
427 	          &name_size,
428 	          &error );
429 
430 	Py_END_ALLOW_THREADS
431 
432 	if( result == -1 )
433 	{
434 		pyvslvm_error_raise(
435 		 error,
436 		 PyExc_IOError,
437 		 "%s: unable to retrieve name size.",
438 		 function );
439 
440 		libcerror_error_free(
441 		 &error );
442 
443 		goto on_error;
444 	}
445 	else if( ( result == 0 )
446 	      || ( name_size == 0 ) )
447 	{
448 		Py_IncRef(
449 		 Py_None );
450 
451 		return( Py_None );
452 	}
453 	name = (char *) PyMem_Malloc(
454 	                 sizeof( char ) * name_size );
455 
456 	if( name == NULL )
457 	{
458 		PyErr_Format(
459 		 PyExc_IOError,
460 		 "%s: unable to create name.",
461 		 function );
462 
463 		goto on_error;
464 	}
465 	Py_BEGIN_ALLOW_THREADS
466 
467 	result = libvslvm_volume_group_get_name(
468 		  pyvslvm_volume_group->volume_group,
469 		  name,
470 		  name_size,
471 		  &error );
472 
473 	Py_END_ALLOW_THREADS
474 
475 	if( result != 1 )
476 	{
477 		pyvslvm_error_raise(
478 		 error,
479 		 PyExc_IOError,
480 		 "%s: unable to retrieve name.",
481 		 function );
482 
483 		libcerror_error_free(
484 		 &error );
485 
486 		goto on_error;
487 	}
488 	/* Pass the string length to PyUnicode_DecodeUTF8
489 	 * otherwise it makes the end of string character is part
490 	 * of the string
491 	 */
492 	string_object = PyUnicode_DecodeUTF8(
493 			 name,
494 			 (Py_ssize_t) name_size - 1,
495 			 errors );
496 
497 	PyMem_Free(
498 	 name );
499 
500 	return( string_object );
501 
502 on_error:
503 	if( name != NULL )
504 	{
505 		PyMem_Free(
506 		 name );
507 	}
508 	return( NULL );
509 }
510 
511 /* Retrieves the identifier
512  * Returns a Python object if successful or NULL on error
513  */
pyvslvm_volume_group_get_identifier(pyvslvm_volume_group_t * pyvslvm_volume_group,PyObject * arguments PYVSLVM_ATTRIBUTE_UNUSED)514 PyObject *pyvslvm_volume_group_get_identifier(
515            pyvslvm_volume_group_t *pyvslvm_volume_group,
516            PyObject *arguments PYVSLVM_ATTRIBUTE_UNUSED )
517 {
518 	libcerror_error_t *error = NULL;
519 	PyObject *string_object  = NULL;
520 	char *identifier         = NULL;
521 	const char *errors       = NULL;
522 	static char *function    = "pyvslvm_volume_group_get_identifier";
523 	size_t identifier_size   = 0;
524 	int result               = 0;
525 
526 	PYVSLVM_UNREFERENCED_PARAMETER( arguments )
527 
528 	if( pyvslvm_volume_group == NULL )
529 	{
530 		PyErr_Format(
531 		 PyExc_TypeError,
532 		 "%s: invalid volume group.",
533 		 function );
534 
535 		return( NULL );
536 	}
537 	Py_BEGIN_ALLOW_THREADS
538 
539 	result = libvslvm_volume_group_get_identifier_size(
540 	          pyvslvm_volume_group->volume_group,
541 	          &identifier_size,
542 	          &error );
543 
544 	Py_END_ALLOW_THREADS
545 
546 	if( result == -1 )
547 	{
548 		pyvslvm_error_raise(
549 		 error,
550 		 PyExc_IOError,
551 		 "%s: unable to retrieve identifier size.",
552 		 function );
553 
554 		libcerror_error_free(
555 		 &error );
556 
557 		goto on_error;
558 	}
559 	else if( ( result == 0 )
560 	      || ( identifier_size == 0 ) )
561 	{
562 		Py_IncRef(
563 		 Py_None );
564 
565 		return( Py_None );
566 	}
567 	identifier = (char *) PyMem_Malloc(
568 	                       sizeof( char ) * identifier_size );
569 
570 	if( identifier == NULL )
571 	{
572 		PyErr_Format(
573 		 PyExc_IOError,
574 		 "%s: unable to create identifier.",
575 		 function );
576 
577 		goto on_error;
578 	}
579 	Py_BEGIN_ALLOW_THREADS
580 
581 	result = libvslvm_volume_group_get_identifier(
582 		  pyvslvm_volume_group->volume_group,
583 		  identifier,
584 		  identifier_size,
585 		  &error );
586 
587 	Py_END_ALLOW_THREADS
588 
589 	if( result != 1 )
590 	{
591 		pyvslvm_error_raise(
592 		 error,
593 		 PyExc_IOError,
594 		 "%s: unable to retrieve identifier.",
595 		 function );
596 
597 		libcerror_error_free(
598 		 &error );
599 
600 		goto on_error;
601 	}
602 	/* Pass the string length to PyUnicode_DecodeUTF8
603 	 * otherwise it makes the end of string character is part
604 	 * of the string
605 	 */
606 	string_object = PyUnicode_DecodeUTF8(
607 			 identifier,
608 			 (Py_ssize_t) identifier_size - 1,
609 			 errors );
610 
611 	PyMem_Free(
612 	 identifier );
613 
614 	return( string_object );
615 
616 on_error:
617 	if( identifier != NULL )
618 	{
619 		PyMem_Free(
620 		 identifier );
621 	}
622 	return( NULL );
623 }
624 
625 /* Retrieves the number of physical volumes
626  * Returns a Python object if successful or NULL on error
627  */
pyvslvm_volume_group_get_number_of_physical_volumes(pyvslvm_volume_group_t * pyvslvm_volume_group,PyObject * arguments PYVSLVM_ATTRIBUTE_UNUSED)628 PyObject *pyvslvm_volume_group_get_number_of_physical_volumes(
629            pyvslvm_volume_group_t *pyvslvm_volume_group,
630            PyObject *arguments PYVSLVM_ATTRIBUTE_UNUSED )
631 {
632 	libcerror_error_t *error       = NULL;
633 	PyObject *integer_object       = NULL;
634 	static char *function          = "pyvslvm_volume_group_get_number_of_physical_volumes";
635 	int number_of_physical_volumes = 0;
636 	int result                     = 0;
637 
638 	PYVSLVM_UNREFERENCED_PARAMETER( arguments )
639 
640 	if( pyvslvm_volume_group == NULL )
641 	{
642 		PyErr_Format(
643 		 PyExc_TypeError,
644 		 "%s: invalid volume group.",
645 		 function );
646 
647 		return( NULL );
648 	}
649 	Py_BEGIN_ALLOW_THREADS
650 
651 	result = libvslvm_volume_group_get_number_of_physical_volumes(
652 	          pyvslvm_volume_group->volume_group,
653 	          &number_of_physical_volumes,
654 	          &error );
655 
656 	Py_END_ALLOW_THREADS
657 
658 	if( result != 1 )
659 	{
660 		pyvslvm_error_raise(
661 		 error,
662 		 PyExc_IOError,
663 		 "%s: unable to retrieve number of physical volumes.",
664 		 function );
665 
666 		libcerror_error_free(
667 		 &error );
668 
669 		return( NULL );
670 	}
671 #if PY_MAJOR_VERSION >= 3
672 	integer_object = PyLong_FromLong(
673 	                  (long) number_of_physical_volumes );
674 #else
675 	integer_object = PyInt_FromLong(
676 	                  (long) number_of_physical_volumes );
677 #endif
678 	return( integer_object );
679 }
680 
681 /* Retrieves a specific physical volume by index
682  * Returns a Python object if successful or NULL on error
683  */
pyvslvm_volume_group_get_physical_volume_by_index(PyObject * pyvslvm_volume_group,int volume_index)684 PyObject *pyvslvm_volume_group_get_physical_volume_by_index(
685            PyObject *pyvslvm_volume_group,
686            int volume_index )
687 {
688 	libcerror_error_t *error                    = NULL;
689 	libvslvm_physical_volume_t *physical_volume = NULL;
690 	PyObject *physical_volume_object            = NULL;
691 	static char *function                       = "pyvslvm_volume_group_get_physical_volume_by_index";
692 	int result                                  = 0;
693 
694 	if( pyvslvm_volume_group == NULL )
695 	{
696 		PyErr_Format(
697 		 PyExc_TypeError,
698 		 "%s: invalid volume group.",
699 		 function );
700 
701 		return( NULL );
702 	}
703 	Py_BEGIN_ALLOW_THREADS
704 
705 	result = libvslvm_volume_group_get_physical_volume(
706 	          ( (pyvslvm_volume_group_t *) pyvslvm_volume_group )->volume_group,
707 	          volume_index,
708 	          &physical_volume,
709 	          &error );
710 
711 	Py_END_ALLOW_THREADS
712 
713 	if( result != 1 )
714 	{
715 		pyvslvm_error_raise(
716 		 error,
717 		 PyExc_IOError,
718 		 "%s: unable to retrieve physical volume: %d.",
719 		 function,
720 		 volume_index );
721 
722 		libcerror_error_free(
723 		 &error );
724 
725 		goto on_error;
726 	}
727 	physical_volume_object = pyvslvm_physical_volume_new(
728 	                          physical_volume,
729 	                          (pyvslvm_volume_group_t *) pyvslvm_volume_group );
730 
731 	if( physical_volume_object == NULL )
732 	{
733 		PyErr_Format(
734 		 PyExc_MemoryError,
735 		 "%s: unable to create physical volume object.",
736 		 function );
737 
738 		goto on_error;
739 	}
740 	return( physical_volume_object );
741 
742 on_error:
743 	if( physical_volume != NULL )
744 	{
745 		libvslvm_physical_volume_free(
746 		 &physical_volume,
747 		 NULL );
748 	}
749 	return( NULL );
750 }
751 
752 /* Retrieves a specific physical volume
753  * Returns a Python object if successful or NULL on error
754  */
pyvslvm_volume_group_get_physical_volume(pyvslvm_volume_group_t * pyvslvm_volume_group,PyObject * arguments,PyObject * keywords)755 PyObject *pyvslvm_volume_group_get_physical_volume(
756            pyvslvm_volume_group_t *pyvslvm_volume_group,
757            PyObject *arguments,
758            PyObject *keywords )
759 {
760 	PyObject *physical_volume_object = NULL;
761 	static char *keyword_list[]      = { "volume_index", NULL };
762 	int volume_index                 = 0;
763 
764 	if( PyArg_ParseTupleAndKeywords(
765 	     arguments,
766 	     keywords,
767 	     "i",
768 	     keyword_list,
769 	     &volume_index ) == 0 )
770 	{
771 		return( NULL );
772 	}
773 	physical_volume_object = pyvslvm_volume_group_get_physical_volume_by_index(
774 	                          (PyObject *) pyvslvm_volume_group,
775 	                          volume_index );
776 
777 	return( physical_volume_object );
778 }
779 
780 /* Retrieves a physical volumes sequence and iterator object for the physical volumes
781  * Returns a Python object if successful or NULL on error
782  */
pyvslvm_volume_group_get_physical_volumes(pyvslvm_volume_group_t * pyvslvm_volume_group,PyObject * arguments PYVSLVM_ATTRIBUTE_UNUSED)783 PyObject *pyvslvm_volume_group_get_physical_volumes(
784            pyvslvm_volume_group_t *pyvslvm_volume_group,
785            PyObject *arguments PYVSLVM_ATTRIBUTE_UNUSED )
786 {
787 	libcerror_error_t *error          = NULL;
788 	PyObject *physical_volumes_object = NULL;
789 	static char *function             = "pyvslvm_volume_group_get_physical_volumes";
790 	int number_of_physical_volumes    = 0;
791 	int result                        = 0;
792 
793 	PYVSLVM_UNREFERENCED_PARAMETER( arguments )
794 
795 	if( pyvslvm_volume_group == NULL )
796 	{
797 		PyErr_Format(
798 		 PyExc_TypeError,
799 		 "%s: invalid volume group.",
800 		 function );
801 
802 		return( NULL );
803 	}
804 	Py_BEGIN_ALLOW_THREADS
805 
806 	result = libvslvm_volume_group_get_number_of_physical_volumes(
807 	          pyvslvm_volume_group->volume_group,
808 	          &number_of_physical_volumes,
809 	          &error );
810 
811 	Py_END_ALLOW_THREADS
812 
813 	if( result != 1 )
814 	{
815 		pyvslvm_error_raise(
816 		 error,
817 		 PyExc_IOError,
818 		 "%s: unable to retrieve number of physical volumes.",
819 		 function );
820 
821 		libcerror_error_free(
822 		 &error );
823 
824 		return( NULL );
825 	}
826 	physical_volumes_object = pyvslvm_physical_volumes_new(
827 	                           (PyObject *) pyvslvm_volume_group,
828 	                           &pyvslvm_volume_group_get_physical_volume_by_index,
829 	                           number_of_physical_volumes );
830 
831 	if( physical_volumes_object == NULL )
832 	{
833 		PyErr_Format(
834 		 PyExc_MemoryError,
835 		 "%s: unable to create physical volumes object.",
836 		 function );
837 
838 		return( NULL );
839 	}
840 	return( physical_volumes_object );
841 }
842 
843 /* Retrieves the number of logical volumes
844  * Returns a Python object if successful or NULL on error
845  */
pyvslvm_volume_group_get_number_of_logical_volumes(pyvslvm_volume_group_t * pyvslvm_volume_group,PyObject * arguments PYVSLVM_ATTRIBUTE_UNUSED)846 PyObject *pyvslvm_volume_group_get_number_of_logical_volumes(
847            pyvslvm_volume_group_t *pyvslvm_volume_group,
848            PyObject *arguments PYVSLVM_ATTRIBUTE_UNUSED )
849 {
850 	libcerror_error_t *error      = NULL;
851 	PyObject *integer_object      = NULL;
852 	static char *function         = "pyvslvm_volume_group_get_number_of_logical_volumes";
853 	int number_of_logical_volumes = 0;
854 	int result                    = 0;
855 
856 	PYVSLVM_UNREFERENCED_PARAMETER( arguments )
857 
858 	if( pyvslvm_volume_group == NULL )
859 	{
860 		PyErr_Format(
861 		 PyExc_TypeError,
862 		 "%s: invalid volume group.",
863 		 function );
864 
865 		return( NULL );
866 	}
867 	Py_BEGIN_ALLOW_THREADS
868 
869 	result = libvslvm_volume_group_get_number_of_logical_volumes(
870 	          pyvslvm_volume_group->volume_group,
871 	          &number_of_logical_volumes,
872 	          &error );
873 
874 	Py_END_ALLOW_THREADS
875 
876 	if( result != 1 )
877 	{
878 		pyvslvm_error_raise(
879 		 error,
880 		 PyExc_IOError,
881 		 "%s: unable to retrieve number of logical volumes.",
882 		 function );
883 
884 		libcerror_error_free(
885 		 &error );
886 
887 		return( NULL );
888 	}
889 #if PY_MAJOR_VERSION >= 3
890 	integer_object = PyLong_FromLong(
891 	                  (long) number_of_logical_volumes );
892 #else
893 	integer_object = PyInt_FromLong(
894 	                  (long) number_of_logical_volumes );
895 #endif
896 	return( integer_object );
897 }
898 
899 /* Retrieves a specific logical volume by index
900  * Returns a Python object if successful or NULL on error
901  */
pyvslvm_volume_group_get_logical_volume_by_index(PyObject * pyvslvm_volume_group,int volume_index)902 PyObject *pyvslvm_volume_group_get_logical_volume_by_index(
903            PyObject *pyvslvm_volume_group,
904            int volume_index )
905 {
906 	libcerror_error_t *error                  = NULL;
907 	libvslvm_logical_volume_t *logical_volume = NULL;
908 	PyObject *logical_volume_object           = NULL;
909 	static char *function                     = "pyvslvm_volume_group_get_logical_volume_by_index";
910 	int result                                = 0;
911 
912 	if( pyvslvm_volume_group == NULL )
913 	{
914 		PyErr_Format(
915 		 PyExc_TypeError,
916 		 "%s: invalid volume group.",
917 		 function );
918 
919 		return( NULL );
920 	}
921 	Py_BEGIN_ALLOW_THREADS
922 
923 	result = libvslvm_volume_group_get_logical_volume(
924 	          ( (pyvslvm_volume_group_t *) pyvslvm_volume_group )->volume_group,
925 	          volume_index,
926 	          &logical_volume,
927 	          &error );
928 
929 	Py_END_ALLOW_THREADS
930 
931 	if( result != 1 )
932 	{
933 		pyvslvm_error_raise(
934 		 error,
935 		 PyExc_IOError,
936 		 "%s: unable to retrieve logical volume: %d.",
937 		 function,
938 		 volume_index );
939 
940 		libcerror_error_free(
941 		 &error );
942 
943 		goto on_error;
944 	}
945 	logical_volume_object = pyvslvm_logical_volume_new(
946 	                         logical_volume,
947 	                         (pyvslvm_volume_group_t *) pyvslvm_volume_group );
948 
949 	if( logical_volume_object == NULL )
950 	{
951 		PyErr_Format(
952 		 PyExc_MemoryError,
953 		 "%s: unable to create logical volume object.",
954 		 function );
955 
956 		goto on_error;
957 	}
958 	return( logical_volume_object );
959 
960 on_error:
961 	if( logical_volume != NULL )
962 	{
963 		libvslvm_logical_volume_free(
964 		 &logical_volume,
965 		 NULL );
966 	}
967 	return( NULL );
968 }
969 
970 /* Retrieves a specific logical volume
971  * Returns a Python object if successful or NULL on error
972  */
pyvslvm_volume_group_get_logical_volume(pyvslvm_volume_group_t * pyvslvm_volume_group,PyObject * arguments,PyObject * keywords)973 PyObject *pyvslvm_volume_group_get_logical_volume(
974            pyvslvm_volume_group_t *pyvslvm_volume_group,
975            PyObject *arguments,
976            PyObject *keywords )
977 {
978 	PyObject *logical_volume_object = NULL;
979 	static char *keyword_list[]     = { "volume_index", NULL };
980 	int volume_index                = 0;
981 
982 	if( PyArg_ParseTupleAndKeywords(
983 	     arguments,
984 	     keywords,
985 	     "i",
986 	     keyword_list,
987 	     &volume_index ) == 0 )
988 	{
989 		return( NULL );
990 	}
991 	logical_volume_object = pyvslvm_volume_group_get_logical_volume_by_index(
992 	                         (PyObject *) pyvslvm_volume_group,
993 	                         volume_index );
994 
995 	return( logical_volume_object );
996 }
997 
998 /* Retrieves a logical volumes sequence and iterator object for the logical volumes
999  * Returns a Python object if successful or NULL on error
1000  */
pyvslvm_volume_group_get_logical_volumes(pyvslvm_volume_group_t * pyvslvm_volume_group,PyObject * arguments PYVSLVM_ATTRIBUTE_UNUSED)1001 PyObject *pyvslvm_volume_group_get_logical_volumes(
1002            pyvslvm_volume_group_t *pyvslvm_volume_group,
1003            PyObject *arguments PYVSLVM_ATTRIBUTE_UNUSED )
1004 {
1005 	libcerror_error_t *error         = NULL;
1006 	PyObject *logical_volumes_object = NULL;
1007 	static char *function            = "pyvslvm_volume_group_get_logical_volumes";
1008 	int number_of_logical_volumes    = 0;
1009 	int result                       = 0;
1010 
1011 	PYVSLVM_UNREFERENCED_PARAMETER( arguments )
1012 
1013 	if( pyvslvm_volume_group == NULL )
1014 	{
1015 		PyErr_Format(
1016 		 PyExc_TypeError,
1017 		 "%s: invalid volume group.",
1018 		 function );
1019 
1020 		return( NULL );
1021 	}
1022 	Py_BEGIN_ALLOW_THREADS
1023 
1024 	result = libvslvm_volume_group_get_number_of_logical_volumes(
1025 	          pyvslvm_volume_group->volume_group,
1026 	          &number_of_logical_volumes,
1027 	          &error );
1028 
1029 	Py_END_ALLOW_THREADS
1030 
1031 	if( result != 1 )
1032 	{
1033 		pyvslvm_error_raise(
1034 		 error,
1035 		 PyExc_IOError,
1036 		 "%s: unable to retrieve number of logical volumes.",
1037 		 function );
1038 
1039 		libcerror_error_free(
1040 		 &error );
1041 
1042 		return( NULL );
1043 	}
1044 	logical_volumes_object = pyvslvm_logical_volumes_new(
1045 	                          (PyObject *) pyvslvm_volume_group,
1046 	                          &pyvslvm_volume_group_get_logical_volume_by_index,
1047 	                          number_of_logical_volumes );
1048 
1049 	if( logical_volumes_object == NULL )
1050 	{
1051 		PyErr_Format(
1052 		 PyExc_MemoryError,
1053 		 "%s: unable to create logical volumes object.",
1054 		 function );
1055 
1056 		return( NULL );
1057 	}
1058 	return( logical_volumes_object );
1059 }
1060 
1061