2 * Python bindings for the libmount library.
4 * Copyright (C) 2013, Red Hat, Inc. All rights reserved.
5 * Written by Ondrej Oprala and Karel Zak
7 * This file is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 3 of the License, or (at your option) any later version.
12 * This file is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://gnu.org/licenses/>.
23 * mnt_fs_match_{source,target}
24 * mnt_fs_get_{attribute,option}
27 #include "pylibmount.h"
30 #define Fs_HELP "Fs(source=None, root=None, target=None, fstype=None, options=None, attributes=None, freq=0, passno=0)"
32 static PyMemberDef Fs_members
[] = {
36 static PyObject
*Fs_get_tag(FsObject
*self
)
38 const char *tag
= NULL
, *val
= NULL
;
41 if (mnt_fs_get_tag(self
->fs
, &tag
, &val
) != 0)
44 result
= Py_BuildValue("(ss)", tag
, val
);
46 PyErr_SetString(PyExc_RuntimeError
, CONSTRUCT_ERR
);
50 static PyObject
*Fs_get_id(FsObject
*self
)
52 return PyObjectResultInt(mnt_fs_get_id(self
->fs
));
55 static PyObject
*Fs_get_parent_id(FsObject
*self
)
57 return PyObjectResultInt(mnt_fs_get_parent_id(self
->fs
));
60 static PyObject
*Fs_get_devno(FsObject
*self
)
62 return PyObjectResultInt(mnt_fs_get_devno(self
->fs
));
65 static void _dump_debug_string(const char *lead
, const char *s
, char quote
)
67 /* PySys_WriteStdout() will automatically truncate any '%s' token
68 * longer than a certain length (documented as 1000 bytes, but we
69 * give ourselves some margin here just in case). The only way I
70 * know to get around this is to print such strings in bite-sized
73 static const unsigned int _PY_MAX_LEN
= 900;
74 static const char *_PY_MAX_LEN_FMT
= "%.900s";
78 PySys_WriteStdout("%s", lead
);
81 PySys_WriteStdout("%c", quote
);
83 for (len
= strlen(s
); len
> _PY_MAX_LEN
; len
-= _PY_MAX_LEN
, s
+= _PY_MAX_LEN
)
84 PySys_WriteStdout(_PY_MAX_LEN_FMT
, s
);
87 PySys_WriteStdout(_PY_MAX_LEN_FMT
, s
);
90 PySys_WriteStdout("%c\n", quote
);
92 PySys_WriteStdout("\n");
95 #define Fs_print_debug_HELP "print_debug()\n\n"
96 static PyObject
*Fs_print_debug(FsObject
*self
)
98 PySys_WriteStdout("------ fs: %p\n", self
->fs
);
99 _dump_debug_string("source: ", mnt_fs_get_source(self
->fs
), 0);
100 _dump_debug_string("target: ", mnt_fs_get_target(self
->fs
), 0);
101 _dump_debug_string("fstype: ", mnt_fs_get_fstype(self
->fs
), 0);
103 if (mnt_fs_get_options(self
->fs
))
104 _dump_debug_string("optstr: ", mnt_fs_get_options(self
->fs
), 0);
105 if (mnt_fs_get_vfs_options(self
->fs
))
106 _dump_debug_string("VFS-optstr: ", mnt_fs_get_vfs_options(self
->fs
), 0);
107 if (mnt_fs_get_fs_options(self
->fs
))
108 _dump_debug_string("FS-opstr: ", mnt_fs_get_fs_options(self
->fs
), 0);
109 if (mnt_fs_get_user_options(self
->fs
))
110 _dump_debug_string("user-optstr: ", mnt_fs_get_user_options(self
->fs
), 0);
111 if (mnt_fs_get_optional_fields(self
->fs
))
112 _dump_debug_string("optional-fields: ", mnt_fs_get_optional_fields(self
->fs
), '\'');
113 if (mnt_fs_get_attributes(self
->fs
))
114 _dump_debug_string("attributes: ", mnt_fs_get_attributes(self
->fs
), 0);
116 if (mnt_fs_get_root(self
->fs
))
117 _dump_debug_string("root: ", mnt_fs_get_root(self
->fs
), 0);
119 if (mnt_fs_get_swaptype(self
->fs
))
120 _dump_debug_string("swaptype: ", mnt_fs_get_swaptype(self
->fs
), 0);
121 if (mnt_fs_get_size(self
->fs
))
122 PySys_WriteStdout("size: %jd\n", mnt_fs_get_size(self
->fs
));
123 if (mnt_fs_get_usedsize(self
->fs
))
124 PySys_WriteStdout("usedsize: %jd\n", mnt_fs_get_usedsize(self
->fs
));
125 if (mnt_fs_get_priority(self
->fs
))
126 PySys_WriteStdout("priority: %d\n", mnt_fs_get_priority(self
->fs
));
128 if (mnt_fs_get_bindsrc(self
->fs
))
129 _dump_debug_string("bindsrc: ", mnt_fs_get_bindsrc(self
->fs
), 0);
130 if (mnt_fs_get_freq(self
->fs
))
131 PySys_WriteStdout("freq: %d\n", mnt_fs_get_freq(self
->fs
));
132 if (mnt_fs_get_passno(self
->fs
))
133 PySys_WriteStdout("pass: %d\n", mnt_fs_get_passno(self
->fs
));
134 if (mnt_fs_get_id(self
->fs
))
135 PySys_WriteStdout("id: %d\n", mnt_fs_get_id(self
->fs
));
136 if (mnt_fs_get_parent_id(self
->fs
))
137 PySys_WriteStdout("parent: %d\n", mnt_fs_get_parent_id(self
->fs
));
138 if (mnt_fs_get_devno(self
->fs
))
139 PySys_WriteStdout("devno: %d:%d\n", major(mnt_fs_get_devno(self
->fs
)),
140 minor(mnt_fs_get_devno(self
->fs
)));
141 if (mnt_fs_get_tid(self
->fs
))
142 PySys_WriteStdout("tid: %d\n", mnt_fs_get_tid(self
->fs
));
143 if (mnt_fs_get_comment(self
->fs
))
144 _dump_debug_string("comment: ", mnt_fs_get_comment(self
->fs
), '\'');
145 return UL_IncRef(self
);
148 ** Fs getters/setters
151 static PyObject
*Fs_get_comment(FsObject
*self
, void *closure
__attribute__((unused
)))
153 return PyObjectResultStr(mnt_fs_get_comment(self
->fs
));
156 static int Fs_set_comment(FsObject
*self
, PyObject
*value
, void *closure
__attribute__((unused
)))
158 char *comment
= NULL
;
162 PyErr_SetString(PyExc_TypeError
, NODEL_ATTR
);
165 if (!(comment
= pystos(value
)))
168 rc
= mnt_fs_set_comment(self
->fs
, comment
);
176 static PyObject
*Fs_get_source(FsObject
*self
)
178 return PyObjectResultStr(mnt_fs_get_source(self
->fs
));
181 static int Fs_set_source(FsObject
*self
, PyObject
*value
, void *closure
__attribute__((unused
)))
187 PyErr_SetString(PyExc_TypeError
, NODEL_ATTR
);
190 if (!(source
= pystos(value
)))
193 rc
= mnt_fs_set_source(self
->fs
, source
);
201 static PyObject
*Fs_get_srcpath(FsObject
*self
)
203 return PyObjectResultStr(mnt_fs_get_srcpath(self
->fs
));
206 static PyObject
*Fs_get_root(FsObject
*self
)
208 return PyObjectResultStr(mnt_fs_get_root(self
->fs
));
211 static int Fs_set_root(FsObject
*self
, PyObject
*value
, void *closure
__attribute__((unused
)))
217 PyErr_SetString(PyExc_TypeError
, NODEL_ATTR
);
220 if (!(root
= pystos(value
)))
223 rc
= mnt_fs_set_root(self
->fs
, root
);
231 static PyObject
*Fs_get_target(FsObject
*self
)
233 return PyObjectResultStr(mnt_fs_get_target(self
->fs
));
236 static int Fs_set_target(FsObject
*self
, PyObject
*value
, void *closure
__attribute__((unused
)))
242 PyErr_SetString(PyExc_TypeError
, NODEL_ATTR
);
245 if (!(target
= pystos(value
)))
248 rc
= mnt_fs_set_target(self
->fs
, target
);
256 static PyObject
*Fs_get_fstype(FsObject
*self
)
258 return PyObjectResultStr(mnt_fs_get_fstype(self
->fs
));
261 static int Fs_set_fstype(FsObject
*self
, PyObject
*value
,
262 void *closure
__attribute__((unused
)))
268 PyErr_SetString(PyExc_TypeError
, NODEL_ATTR
);
271 if (!(fstype
= pystos(value
)))
274 rc
= mnt_fs_set_fstype(self
->fs
, fstype
);
282 static PyObject
*Fs_get_options(FsObject
*self
)
284 return PyObjectResultStr(mnt_fs_get_options(self
->fs
));
287 static int Fs_set_options(FsObject
*self
, PyObject
*value
,
288 void *closure
__attribute__((unused
)))
290 char *options
= NULL
;
294 PyErr_SetString(PyExc_TypeError
, NODEL_ATTR
);
297 if (!(options
= pystos(value
)))
300 rc
= mnt_fs_set_options(self
->fs
, options
);
308 static PyObject
*Fs_get_vfs_options(FsObject
*self
)
310 return PyObjectResultStr(mnt_fs_get_vfs_options(self
->fs
));
314 static PyObject
*Fs_get_optional_fields(FsObject
*self
)
316 return PyObjectResultStr(mnt_fs_get_optional_fields(self
->fs
));
320 static PyObject
*Fs_get_fs_options(FsObject
*self
)
322 return PyObjectResultStr(mnt_fs_get_fs_options(self
->fs
));
326 static PyObject
*Fs_get_user_options(FsObject
*self
)
328 return PyObjectResultStr(mnt_fs_get_user_options(self
->fs
));
332 static PyObject
*Fs_get_attributes(FsObject
*self
)
334 return PyObjectResultStr(mnt_fs_get_attributes(self
->fs
));
337 static int Fs_set_attributes(FsObject
*self
, PyObject
*value
,
338 void *closure
__attribute__((unused
)))
340 char *attributes
= NULL
;
344 PyErr_SetString(PyExc_TypeError
, NODEL_ATTR
);
347 if (!(attributes
= pystos(value
)))
350 rc
= mnt_fs_set_attributes(self
->fs
, attributes
);
358 static PyObject
*Fs_get_freq(FsObject
*self
, void *closure
__attribute__((unused
)))
360 return PyObjectResultInt(mnt_fs_get_freq(self
->fs
));
363 static int Fs_set_freq(FsObject
*self
, PyObject
*value
,
364 void *closure
__attribute__((unused
)))
369 PyErr_SetString(PyExc_TypeError
, NODEL_ATTR
);
374 if (!PyLong_Check(value
)) {
375 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
379 freq
= PyLong_AsLong(value
);
380 if (freq
== -1 && PyErr_Occurred()) {
381 PyErr_SetString(PyExc_RuntimeError
, "type conversion failed");
384 return mnt_fs_set_freq(self
->fs
, freq
);
387 static PyObject
*Fs_get_passno(FsObject
*self
)
389 return PyObjectResultInt(mnt_fs_get_passno(self
->fs
));
392 static int Fs_set_passno(FsObject
*self
, PyObject
*value
, void *closure
__attribute__((unused
)))
397 PyErr_SetString(PyExc_TypeError
, NODEL_ATTR
);
401 if (!PyLong_Check(value
)) {
402 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
406 passno
= PyLong_AsLong(value
);
407 if (passno
== -1 && PyErr_Occurred()) {
408 PyErr_SetString(PyExc_RuntimeError
, "type conversion failed");
411 return mnt_fs_set_passno(self
->fs
, passno
);
414 static PyObject
*Fs_get_swaptype(FsObject
*self
)
416 return PyObjectResultStr(mnt_fs_get_swaptype(self
->fs
));
419 static PyObject
*Fs_get_size(FsObject
*self
)
421 return PyObjectResultInt(mnt_fs_get_size(self
->fs
));
424 static PyObject
*Fs_get_usedsize(FsObject
*self
)
426 return PyObjectResultInt(mnt_fs_get_usedsize(self
->fs
));
429 static PyObject
*Fs_get_priority(FsObject
*self
)
431 return PyObjectResultInt(mnt_fs_get_priority(self
->fs
));
434 #define Fs_get_propagation_HELP "get_propagation(flags)\n\n\
435 Note that this function set flags to zero if not found any propagation flag\n\
436 in mountinfo file. The kernel default is MS_PRIVATE, this flag is not stored\n\
437 in the mountinfo file.\n\
439 Returns self or raises an exception in case of an error."
440 static PyObject
*Fs_get_propagation(FsObject
*self
)
445 rc
= mnt_fs_get_propagation(self
->fs
, &flags
);
446 return rc
? UL_RaiseExc(-rc
) : PyObjectResultInt(flags
);
449 static PyObject
*Fs_get_tid(FsObject
*self
)
451 return PyObjectResultInt(mnt_fs_get_tid(self
->fs
));
454 #define Fs_is_kernel_HELP "is_kernel()\n\nReturns 1 if the filesystem " \
455 "description is read from kernel e.g. /proc/mounts."
456 static PyObject
*Fs_is_kernel(FsObject
*self
)
458 return PyBool_FromLong(mnt_fs_is_kernel(self
->fs
));
461 #define Fs_is_netfs_HELP "is_netfs()\n\nReturns 1 if the filesystem is " \
462 "a network filesystem"
463 static PyObject
*Fs_is_netfs(FsObject
*self
)
465 return PyBool_FromLong(mnt_fs_is_netfs(self
->fs
));
468 #define Fs_is_pseudofs_HELP "is_pseudofs()\n\nReturns 1 if the filesystem is "\
469 "a pseudo fs type (proc, cgroups)"
470 static PyObject
*Fs_is_pseudofs(FsObject
*self
)
472 return PyBool_FromLong(mnt_fs_is_pseudofs(self
->fs
));
475 #define Fs_is_swaparea_HELP "is_swaparea()\n\nReturns 1 if the filesystem " \
476 "uses \"swap\" as a type"
477 static PyObject
*Fs_is_swaparea(FsObject
*self
)
479 return PyBool_FromLong(mnt_fs_is_swaparea(self
->fs
));
482 #define Fs_append_attributes_HELP "append_attributes(optstr)\n\n" \
483 "Appends mount attributes."
484 static PyObject
*Fs_append_attributes(FsObject
*self
, PyObject
*args
, PyObject
*kwds
)
486 char *kwlist
[] = {"optstr", NULL
};
490 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "s", kwlist
, &optstr
)) {
491 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
494 rc
= mnt_fs_append_attributes(self
->fs
, optstr
);
495 return rc
? UL_RaiseExc(-rc
) : UL_IncRef(self
);
498 #define Fs_append_options_HELP "append_options(optstr)\n\n" \
499 "Parses (splits) optstr and appends results to VFS, " \
500 "FS and userspace lists of options."
501 static PyObject
*Fs_append_options(FsObject
*self
, PyObject
*args
, PyObject
*kwds
)
503 char *kwlist
[] = {"optstr", NULL
};
507 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "s", kwlist
, &optstr
)) {
508 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
511 rc
= mnt_fs_append_options(self
->fs
, optstr
);
512 return rc
? UL_RaiseExc(-rc
) : UL_IncRef(self
);
515 #define Fs_prepend_attributes_HELP "prepend_attributes(optstr)\n\n" \
516 "Prepends mount attributes."
517 static PyObject
*Fs_prepend_attributes(FsObject
*self
, PyObject
*args
, PyObject
*kwds
)
519 char *kwlist
[] = {"optstr", NULL
};
523 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "s", kwlist
, &optstr
)) {
524 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
527 rc
= mnt_fs_prepend_attributes(self
->fs
, optstr
);
528 return rc
? UL_RaiseExc(-rc
) : UL_IncRef(self
);
531 #define Fs_prepend_options_HELP "prepend_options(optstr)\n\n" \
532 "Parses (splits) optstr and prepends results to VFS, " \
533 "FS and userspace lists of options."
534 static PyObject
*Fs_prepend_options(FsObject
*self
, PyObject
*args
, PyObject
*kwds
)
536 char *kwlist
[] = {"optstr", NULL
};
540 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "s", kwlist
, &optstr
)) {
541 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
544 rc
= mnt_fs_prepend_options(self
->fs
, optstr
);
545 return rc
? UL_RaiseExc(-rc
) : UL_IncRef(self
);
548 #define Fs_match_fstype_HELP "match_fstype(pattern)\n\n" \
549 "pattern: filesystem name or comma delimited list(string) of names\n\n" \
550 "The pattern list of filesystem can be prefixed with a global\n" \
551 "\"no\" prefix to invert matching of the whole list. The \"no\" could\n" \
552 "also be used for individual items in the pattern list. So,\n" \
553 "\"nofoo,bar\" has the same meaning as \"nofoo,nobar\".\n" \
554 "\"bar\" : \"nofoo,bar\" -> False (global \"no\" prefix)\n" \
555 "\"bar\" : \"foo,bar\" -> True\n" \
556 "\"bar\" : \"foo,nobar\" -> False\n\n" \
557 "Returns True if type is matching, else False."
558 static PyObject
*Fs_match_fstype(FsObject
*self
, PyObject
*args
, PyObject
*kwds
)
560 char *kwlist
[] = {"pattern", NULL
};
561 char *pattern
= NULL
;
563 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "s", kwlist
, &pattern
)) {
564 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
567 return PyBool_FromLong(mnt_fs_match_fstype(self
->fs
, pattern
));
570 #define Fs_match_options_HELP "match_options(options)\n\n" \
571 "options: comma delimited list of options (and nooptions)\n" \
572 "Returns True if fs type is matching to options else False."
573 static PyObject
*Fs_match_options(FsObject
*self
, PyObject
*args
, PyObject
*kwds
)
575 char *kwlist
[] = {"options", NULL
};
576 char *options
= NULL
;
578 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "s", kwlist
, &options
)) {
579 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
582 return PyBool_FromLong(mnt_fs_match_options(self
->fs
, options
));
585 #define Fs_streq_srcpath_HELP "streq_srcpath(srcpath)\n\n" \
586 "Compares fs source path with path. The trailing slash is ignored.\n" \
587 "Returns True if fs source path equal to path, otherwise False."
588 static PyObject
*Fs_streq_srcpath(FsObject
*self
, PyObject
*args
, PyObject
*kwds
)
590 char *kwlist
[] = {"srcpath", NULL
};
591 char *srcpath
= NULL
;
593 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "s", kwlist
, &srcpath
)) {
594 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
597 return PyBool_FromLong(mnt_fs_streq_srcpath(self
->fs
, srcpath
));
600 #define Fs_streq_target_HELP "streq_target(target)\n\n" \
601 "Compares fs target path with path. The trailing slash is ignored.\n" \
602 "See also Fs.match_target().\n" \
603 "Returns True if fs target path equal to path, otherwise False."
604 static PyObject
*Fs_streq_target(FsObject
*self
, PyObject
*args
, PyObject
*kwds
)
606 char *kwlist
[] = {"target", NULL
};
609 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "s", kwlist
, &target
)) {
610 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
613 return PyBool_FromLong(mnt_fs_streq_target(self
->fs
, target
));
616 #define Fs_copy_fs_HELP "copy_fs(dest=None)\n\n" \
617 "If dest is None, a new object is created, if any fs " \
618 "field is already set, then the field is NOT overwritten."
619 static PyObject
*Fs_copy_fs(FsObject
*self
, PyObject
*args
, PyObject
*kwds
);
621 static PyMethodDef Fs_methods
[] = {
622 {"get_propagation", (PyCFunction
)Fs_get_propagation
, METH_NOARGS
, Fs_get_propagation_HELP
},
623 {"mnt_fs_append_attributes", (PyCFunction
)Fs_append_attributes
, METH_VARARGS
|METH_KEYWORDS
, Fs_append_attributes_HELP
},
624 {"append_options", (PyCFunction
)Fs_append_options
, METH_VARARGS
|METH_KEYWORDS
, Fs_append_options_HELP
},
625 {"mnt_fs_prepend_attributes", (PyCFunction
)Fs_prepend_attributes
, METH_VARARGS
|METH_KEYWORDS
, Fs_prepend_attributes_HELP
},
626 {"prepend_options", (PyCFunction
)Fs_prepend_options
, METH_VARARGS
|METH_KEYWORDS
, Fs_prepend_options_HELP
},
627 {"copy_fs", (PyCFunction
)Fs_copy_fs
, METH_VARARGS
|METH_KEYWORDS
, Fs_copy_fs_HELP
},
628 {"is_kernel", (PyCFunction
)Fs_is_kernel
, METH_NOARGS
, Fs_is_kernel_HELP
},
629 {"is_netfs", (PyCFunction
)Fs_is_netfs
, METH_NOARGS
, Fs_is_netfs_HELP
},
630 {"is_pseudofs", (PyCFunction
)Fs_is_pseudofs
, METH_NOARGS
, Fs_is_pseudofs_HELP
},
631 {"is_swaparea", (PyCFunction
)Fs_is_swaparea
, METH_NOARGS
, Fs_is_swaparea_HELP
},
632 {"match_fstype", (PyCFunction
)Fs_match_fstype
, METH_VARARGS
|METH_KEYWORDS
, Fs_match_fstype_HELP
},
633 {"match_options", (PyCFunction
)Fs_match_options
, METH_VARARGS
|METH_KEYWORDS
, Fs_match_options_HELP
},
634 {"streq_srcpath", (PyCFunction
)Fs_streq_srcpath
, METH_VARARGS
|METH_KEYWORDS
, Fs_streq_srcpath_HELP
},
635 {"streq_target", (PyCFunction
)Fs_streq_target
, METH_VARARGS
|METH_KEYWORDS
, Fs_streq_target_HELP
},
636 {"print_debug", (PyCFunction
)Fs_print_debug
, METH_NOARGS
, Fs_print_debug_HELP
},
640 static void Fs_destructor(FsObject
*self
)
642 DBG(FS
, pymnt_debug_h(self
->fs
, "destructor py-obj: %p, py-refcnt=%d",
643 self
, (int) ((PyObject
*) self
)->ob_refcnt
));
644 mnt_unref_fs(self
->fs
);
648 static PyObject
*Fs_new(PyTypeObject
*type
, PyObject
*args
__attribute__((unused
)),
649 PyObject
*kwds
__attribute__((unused
)))
651 FsObject
*self
= (FsObject
*)type
->tp_alloc(type
, 0);
655 DBG(FS
, pymnt_debug_h(self
, "new"));
657 return (PyObject
*) self
;
660 static int Fs_init(FsObject
*self
, PyObject
*args
, PyObject
*kwds
)
662 char *source
= NULL
, *root
= NULL
, *target
= NULL
;
663 char *fstype
= NULL
, *options
= NULL
, *attributes
=NULL
;
664 int freq
= 0; int passno
= 0;
667 "source", "root", "target",
668 "fstype", "options", "attributes",
669 "freq", "passno", NULL
672 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "|ssssssii", kwlist
,
673 &source
, &root
, &target
, &fstype
, &options
,
674 &attributes
, &freq
, &passno
)) {
675 PyErr_SetString(PyExc_TypeError
, "Invalid type");
679 DBG(FS
, pymnt_debug_h(self
, "init"));
682 mnt_unref_fs(self
->fs
);
684 self
->fs
= mnt_new_fs(); /* new FS with refcount=1 */
686 if (source
&& (rc
= mnt_fs_set_source(self
->fs
, source
))) {
687 PyErr_SetString(PyExc_MemoryError
, MEMORY_ERR
);
690 if (root
&& (rc
= mnt_fs_set_root(self
->fs
, root
))) {
691 PyErr_SetString(PyExc_MemoryError
, MEMORY_ERR
);
694 if (target
&& (rc
= mnt_fs_set_target(self
->fs
, target
))) {
695 PyErr_SetString(PyExc_MemoryError
, MEMORY_ERR
);
698 if (fstype
&& (rc
= mnt_fs_set_fstype(self
->fs
, fstype
))) {
699 PyErr_SetString(PyExc_MemoryError
, MEMORY_ERR
);
702 if (options
&& (rc
= mnt_fs_set_options(self
->fs
, options
))) {
703 PyErr_SetString(PyExc_MemoryError
, MEMORY_ERR
);
706 if (attributes
&& (rc
= mnt_fs_set_attributes(self
->fs
, attributes
))) {
707 PyErr_SetString(PyExc_MemoryError
, MEMORY_ERR
);
711 mnt_fs_set_freq(self
->fs
, freq
);
712 mnt_fs_set_passno(self
->fs
, passno
);
713 mnt_fs_set_userdata(self
->fs
, self
); /* store a pointer to self, convenient when resetting the table */
722 static PyGetSetDef Fs_getseters
[] = {
723 {"id", (getter
)Fs_get_id
, NULL
, "mountinfo[1]: ID", NULL
},
724 {"parent", (getter
)Fs_get_parent_id
, NULL
, "mountinfo[2]: parent", NULL
},
725 {"devno", (getter
)Fs_get_devno
, NULL
, "mountinfo[3]: st_dev", NULL
},
726 {"comment", (getter
)Fs_get_comment
, (setter
)Fs_set_comment
, "fstab entry comment", NULL
},
727 {"source", (getter
)Fs_get_source
, (setter
)Fs_set_source
, "fstab[1], mountinfo[10], swaps[1]: source dev, file, dir or TAG", NULL
},
728 {"srcpath", (getter
)Fs_get_srcpath
, NULL
, "mount source path or NULL in case of error or when the path is not defined.", NULL
},
729 {"root", (getter
)Fs_get_root
, (setter
)Fs_set_root
, "mountinfo[4]: root of the mount within the FS", NULL
},
730 {"target", (getter
)Fs_get_target
, (setter
)Fs_set_target
, "mountinfo[5], fstab[2]: mountpoint", NULL
},
731 {"fstype", (getter
)Fs_get_fstype
, (setter
)Fs_set_fstype
, "mountinfo[9], fstab[3]: filesystem type", NULL
},
732 {"options", (getter
)Fs_get_options
, (setter
)Fs_set_options
, "fstab[4]: merged options", NULL
},
733 {"vfs_options", (getter
)Fs_get_vfs_options
, NULL
, "mountinfo[6]: fs-independent (VFS) options", NULL
},
734 {"opt_fields", (getter
)Fs_get_optional_fields
, NULL
, "mountinfo[7]: optional fields", NULL
},
735 {"fs_options", (getter
)Fs_get_fs_options
, NULL
, "mountinfo[11]: fs-dependent options", NULL
},
736 {"usr_options", (getter
)Fs_get_user_options
, NULL
, "userspace mount options", NULL
},
737 {"attributes", (getter
)Fs_get_attributes
, (setter
)Fs_set_attributes
, "mount attributes", NULL
},
738 {"freq", (getter
)Fs_get_freq
, (setter
)Fs_set_freq
, "fstab[5]: dump frequency in days", NULL
},
739 {"passno", (getter
)Fs_get_passno
, (setter
)Fs_set_passno
, "fstab[6]: pass number on parallel fsck", NULL
},
740 {"swaptype", (getter
)Fs_get_swaptype
, NULL
, "swaps[2]: device type", NULL
},
741 {"size", (getter
)Fs_get_size
, NULL
, "saps[3]: swaparea size", NULL
},
742 {"usedsize", (getter
)Fs_get_usedsize
, NULL
, "swaps[4]: used size", NULL
},
743 {"priority", (getter
)Fs_get_priority
, NULL
, "swaps[5]: swap priority", NULL
},
744 {"tag", (getter
)Fs_get_tag
, NULL
, "(Name, Value)", NULL
},
745 {"tid", (getter
)Fs_get_tid
, NULL
, "/proc/<tid>/mountinfo, otherwise zero", NULL
},
749 static PyObject
*Fs_repr(FsObject
*self
)
751 const char *src
= mnt_fs_get_source(self
->fs
),
752 *tgt
= mnt_fs_get_target(self
->fs
),
753 *type
= mnt_fs_get_fstype(self
->fs
);
755 return PyUnicode_FromFormat(
756 "<libmount.Fs object at %p, "
757 "source=%s, target=%s, fstype=%s>",
761 type
? type
: "None");
764 PyObject
*PyObjectResultFs(struct libmnt_fs
*fs
)
769 PyErr_SetString(LibmountError
, "internal exception");
773 result
= mnt_fs_get_userdata(fs
);
776 DBG(FS
, pymnt_debug_h(fs
, "result py-obj %p: already exists, py-refcnt=%d",
777 result
, (int) ((PyObject
*) result
)->ob_refcnt
));
778 return (PyObject
*) result
;
781 /* Creating an encapsulating object: increment the refcount, so that code
782 * such as tab.next_fs() doesn't call the destructor, which would free
783 * our fs struct as well
785 result
= PyObject_New(FsObject
, &FsType
);
794 DBG(FS
, pymnt_debug_h(fs
, "result py-obj %p new, py-refcnt=%d",
795 result
, (int) ((PyObject
*) result
)->ob_refcnt
));
797 mnt_fs_set_userdata(fs
, result
);
798 return (PyObject
*) result
;
801 static PyObject
*Fs_copy_fs(FsObject
*self
, PyObject
*args
, PyObject
*kwds
)
803 PyObject
*dest
= NULL
;
804 char *kwlist
[] = {"dest", NULL
};
806 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "|O", kwlist
, &dest
)) {
807 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
810 if (PyObject_TypeCheck(dest
, &FsType
)) { /* existing object passed as argument */
811 if (!mnt_copy_fs(((FsObject
*)dest
)->fs
, self
->fs
))
813 DBG(FS
, pymnt_debug_h(dest
, "copy data"));
814 return (PyObject
*)dest
;
818 if (dest
== Py_None
) { /* create new object */
819 FsObject
*result
= PyObject_New(FsObject
, &FsType
);
821 DBG(FS
, pymnt_debug_h(result
, "new copy"));
822 result
->fs
= mnt_copy_fs(NULL
, self
->fs
);
823 mnt_fs_set_userdata(result
->fs
, result
); /* keep a pointer to encapsulating object */
824 return (PyObject
*)result
;
827 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
832 PyTypeObject FsType
= {
833 PyVarObject_HEAD_INIT(NULL
, 0)
834 .tp_name
= "libmount.Fs",
835 .tp_basicsize
= sizeof(FsObject
),
836 .tp_dealloc
= (destructor
)Fs_destructor
,
837 .tp_repr
= (reprfunc
)Fs_repr
,
838 .tp_flags
= Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
,
840 .tp_methods
= Fs_methods
,
841 .tp_members
= Fs_members
,
842 .tp_getset
= Fs_getseters
,
843 .tp_init
= (initproc
)Fs_init
,
847 void FS_AddModuleObject(PyObject
*mod
)
849 if (PyType_Ready(&FsType
) < 0)
852 DBG(FS
, pymnt_debug("add to module"));
854 PyModule_AddObject(mod
, "Fs", (PyObject
*)&FsType
);