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 Lesser General Public
18 * License along with this file; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include "pylibmount.h"
23 static PyMemberDef Context_members
[] = {
27 static PyObject
*Context_set_tables_errcb(ContextObjext
*self
, PyObject
*func
,
28 void *closure
__attribute__((unused
)))
31 PyErr_SetString(PyExc_TypeError
, NODEL_ATTR
);
35 if (!PyCallable_Check(func
))
38 PyObject
*tmp
= self
->table_errcb
;
40 self
->table_errcb
= func
;
43 return UL_IncRef(self
);
46 static void Context_dealloc(ContextObjext
*self
)
48 if (!self
->cxt
) /* if init fails */
51 Py_XDECREF(mnt_context_get_fs_userdata(self
->cxt
));
52 Py_XDECREF(mnt_context_get_fstab_userdata(self
->cxt
));
53 Py_XDECREF(mnt_context_get_mtab_userdata(self
->cxt
));
55 mnt_free_context(self
->cxt
);
59 static PyObject
*Context_new(PyTypeObject
*type
,
60 PyObject
*args
__attribute__((unused
)),
61 PyObject
*kwds
__attribute__((unused
)))
63 ContextObjext
*self
= (ContextObjext
*) type
->tp_alloc(type
, 0);
67 self
->table_errcb
= NULL
;
70 return (PyObject
*)self
;
74 * Note there is no pointer to encapsulating object needed here, since Cxt is
75 * on top of the Context(Table(Filesystem)) hierarchy
77 #define Context_HELP "Context(source=None, target=None, fstype=None, " \
78 "options=None, mflags=0, fstype_pattern=None, " \
79 "options_pattern=None, fs=None, fstab=None, optsmode=0)"
80 static int Context_init(ContextObjext
*self
, PyObject
*args
, PyObject
*kwds
)
82 char *source
= NULL
, *target
= NULL
, *fstype
= NULL
;
83 char *options
= NULL
, *fstype_pattern
= NULL
, *options_pattern
= NULL
;
84 unsigned long mflags
= 0;
85 int optsmode
= 0, syscall_status
= 1;
87 TableObject
*fstab
= NULL
;
90 "source", "target", "fstype",
91 "options", "mflags", "fstype_pattern",
92 "options_pattern", "fs", "fstab",
96 if (!PyArg_ParseTupleAndKeywords(
97 args
, kwds
, "|sssskssO!O!i", kwlist
,
98 &source
, &target
, &fstype
, &options
, &mflags
,
99 &fstype_pattern
, &options_pattern
, &FsType
, &fs
,
100 &TableType
, &fstab
, &optsmode
, &syscall_status
)) {
101 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
106 mnt_free_context(self
->cxt
);
108 self
->cxt
= mnt_new_context();
110 PyErr_SetString(PyExc_MemoryError
, MEMORY_ERR
);
114 if (source
&& (rc
= mnt_context_set_source(self
->cxt
, source
))) {
119 if (target
&& (rc
= mnt_context_set_target(self
->cxt
, target
))) {
124 if (fstype
&& (rc
= mnt_context_set_fstype(self
->cxt
, fstype
))) {
129 if (options
&& (rc
= mnt_context_set_options(self
->cxt
, options
))) {
134 if (fstype_pattern
&& (rc
= mnt_context_set_fstype_pattern(self
->cxt
, fstype_pattern
))) {
139 if (options_pattern
&& (rc
= mnt_context_set_options_pattern(self
->cxt
, options_pattern
))) {
144 if (fs
&& (rc
= mnt_context_set_fs(self
->cxt
, fs
->fs
))) {
149 if (fstab
&& (rc
= mnt_context_set_fstab(self
->cxt
, fstab
->tab
))) {
154 if (optsmode
&& (rc
= mnt_context_set_optsmode(self
->cxt
, optsmode
))) {
159 mnt_context_set_mflags(self
->cxt
, mflags
);
160 mnt_context_set_optsmode(self
->cxt
, optsmode
);
161 mnt_context_set_tables_errcb(self
->cxt
, pymnt_table_parser_errcb
);
166 #define Context_enable_fake_HELP "enable_fake(enable)\n\n" \
167 "Enable/disable fake mounting (see mount(8) man page, option -f).\n" \
169 "Returns self or raises an exception in case of an error."
170 static PyObject
*Context_enable_fake(ContextObjext
*self
, PyObject
*args
, PyObject
*kwds
)
174 char *kwlist
[] = { "enable", NULL
};
176 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "i", kwlist
, &enable
)) {
177 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
180 rc
= mnt_context_enable_fake(self
->cxt
, enable
);
181 return rc
? UL_RaiseExc(-rc
) : UL_IncRef(self
);
184 #define Context_enable_force_HELP "enable_force(enable)\n\n" \
185 "Enable/disable force umounting (see umount(8) man page, option -f).\n" \
187 "Returns self or raises an exception in case of an error."
188 static PyObject
*Context_enable_force(ContextObjext
*self
, PyObject
*args
, PyObject
*kwds
)
192 char *kwlist
[] = { "enable", NULL
};
194 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "i", kwlist
, &enable
)) {
195 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
198 rc
= mnt_context_enable_force(self
->cxt
, enable
);
199 return rc
? UL_RaiseExc(-rc
) : UL_IncRef(self
);
202 #define Context_enable_lazy_HELP "enable_lazy(enable)\n\n" \
203 "Enable/disable lazy umount (see umount(8) man page, option -l).\n" \
205 "Returns self or raises an exception in case of an error."
206 static PyObject
*Context_enable_lazy(ContextObjext
*self
, PyObject
*args
, PyObject
*kwds
)
210 char *kwlist
[] = { "enable", NULL
};
212 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "i", kwlist
, &enable
)) {
213 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
216 rc
= mnt_context_enable_lazy(self
->cxt
, enable
);
217 return rc
? UL_RaiseExc(-rc
) : UL_IncRef(self
);
220 #define Context_enable_loopdel_HELP "enable_loopdel(enable)\n\n" \
221 "Enable/disable loop delete (destroy) after umount (see umount(8), option -d)\n" \
223 "Returns self or raises an exception in case of an error."
224 static PyObject
*Context_enable_loopdel(ContextObjext
*self
, PyObject
*args
, PyObject
*kwds
)
228 char *kwlist
[] = { "enable", NULL
};
230 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "i", kwlist
, &enable
)) {
231 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
234 rc
= mnt_context_enable_loopdel(self
->cxt
, enable
);
235 return rc
? UL_RaiseExc(-rc
) : UL_IncRef(self
);
238 #define Context_enable_rdonly_umount_HELP "enable_rdonly_umount(enable)\n\n" \
239 "Enable/disable read-only remount on failed umount(2)\n "\
240 "(see umount(8) man page, option -r).\n" \
242 "Returns self or raises an exception in case of an error."
243 static PyObject
*Context_enable_rdonly_umount(ContextObjext
*self
, PyObject
*args
, PyObject
*kwds
)
247 char *kwlist
[] = { "enable", NULL
};
249 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "i", kwlist
, &enable
)) {
250 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
253 rc
= mnt_context_enable_rdonly_umount(self
->cxt
, enable
);
254 return rc
? UL_RaiseExc(-rc
) : UL_IncRef(self
);
257 #define Context_enable_sloppy_HELP "enable_sloppy(enable)\n\n" \
258 "Set/unset sloppy mounting (see mount(8) man page, option -s).\n" \
260 "Returns self or raises an exception in case of an error."
261 static PyObject
*Context_enable_sloppy(ContextObjext
*self
, PyObject
*args
, PyObject
*kwds
)
265 char *kwlist
[] = { "enable", NULL
};
267 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "i", kwlist
, &enable
)) {
268 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
271 rc
= mnt_context_enable_sloppy(self
->cxt
, enable
);
272 return rc
? UL_RaiseExc(-rc
) : UL_IncRef(self
);
275 #define Context_enable_verbose_HELP "enable_verbose(enable)\n\n" \
276 "Enable/disable verbose output (TODO: not implemented yet)\n" \
278 "Returns self or raises an exception in case of an error."
279 static PyObject
*Context_enable_verbose(ContextObjext
*self
, PyObject
*args
, PyObject
*kwds
)
283 char *kwlist
[] = { "enable", NULL
};
285 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "i", kwlist
, &enable
)) {
286 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
289 rc
= mnt_context_enable_verbose(self
->cxt
, enable
);
290 return rc
? UL_RaiseExc(-rc
) : UL_IncRef(self
);
293 #define Context_enable_fork_HELP "enable_fork(enable)\n\n" \
294 "Enable/disable fork(2) call in Cxt.next_mount()(not yet implemented) (see mount(8) man\n" \
295 "page, option -F).\n" \
297 "Returns self or raises an exception in case of an error."
298 static PyObject
*Context_enable_fork(ContextObjext
*self
, PyObject
*args
, PyObject
*kwds
)
302 char *kwlist
[] = {"enable", NULL
};
304 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "i", kwlist
, &enable
)) {
305 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
308 rc
= mnt_context_enable_fork(self
->cxt
, enable
);
309 return rc
? UL_RaiseExc(-rc
) : UL_IncRef(self
);
312 #define Context_disable_canonicalize_HELP "disable_canonicalize(disable)\n\n" \
313 "Enable/disable paths canonicalization and tags evaluation. The libmount context\n" \
314 "canonicalies paths when search in fstab and when prepare source and target paths\n" \
315 "for mount(2) syscall.\n" \
317 "This fuction has effect to the private (within context) fstab instance only\n" \
318 "(see Cxt.fstab).\n" \
319 "Returns self or raises an exception in case of an error."
320 static PyObject
*Context_disable_canonicalize(ContextObjext
*self
, PyObject
*args
, PyObject
*kwds
)
324 char *kwlist
[] = {"disable", NULL
};
326 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "i", kwlist
, &disable
)) {
327 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
330 rc
= mnt_context_disable_canonicalize(self
->cxt
, disable
);
331 return rc
? UL_RaiseExc(-rc
) : UL_IncRef(self
);
334 #define Context_disable_helpers_HELP "disable_helpers(disable)\n\n" \
335 "Enable/disable /sbin/[u]mount.* helpers (see mount(8) man page, option -i).\n" \
337 "Returns self or raises an exception in case of an error."
338 static PyObject
*Context_disable_helpers(ContextObjext
*self
, PyObject
*args
, PyObject
*kwds
)
342 char *kwlist
[] = {"disable", NULL
};
344 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "i", kwlist
, &disable
)) {
345 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
348 rc
= mnt_context_disable_helpers(self
->cxt
, disable
);
349 return rc
? UL_RaiseExc(-rc
) : UL_IncRef(self
);
352 #define Context_disable_mtab_HELP "disable_mtab(disable)\n\n" \
353 "Disable/enable mtab update (see mount(8) man page, option -n).\n" \
355 "Returns self or raises an exception in case of an error."
356 static PyObject
*Context_disable_mtab(ContextObjext
*self
, PyObject
*args
, PyObject
*kwds
)
360 char *kwlist
[] = {"disable", NULL
};
362 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "i", kwlist
, &disable
)) {
363 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
366 rc
= mnt_context_disable_mtab(self
->cxt
, disable
);
367 return rc
? UL_RaiseExc(-rc
) : UL_IncRef(self
);
370 #define Context_disable_swapmatch_HELP "disable_swapmatch(disable)\n\n" \
371 "Disable/enable swap between source and target for mount(8) if only one path\n" \
374 "Returns self or raises an exception in case of an error."
375 static PyObject
*Context_disable_swapmatch(ContextObjext
*self
, PyObject
*args
, PyObject
*kwds
)
379 char *kwlist
[] = { "disable", NULL
};
381 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "i", kwlist
, &disable
)) {
382 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
385 rc
= mnt_context_disable_swapmatch(self
->cxt
, disable
);
386 return rc
? UL_RaiseExc(-rc
) : UL_IncRef(self
);
389 static int Context_set_source(ContextObjext
*self
, PyObject
*value
, void *closure
__attribute__((unused
)))
395 PyErr_SetString(PyExc_TypeError
, NODEL_ATTR
);
398 if (!(source
= pystos(value
)))
401 rc
= mnt_context_set_source(self
->cxt
, source
);
409 static int Context_set_mountdata(ContextObjext
*self
, PyObject
*value
, void *closure
__attribute__((unused
)))
415 PyErr_SetString(PyExc_TypeError
, NODEL_ATTR
);
418 if (!(mountdata
= pystos(value
)))
421 rc
= mnt_context_set_mountdata(self
->cxt
, mountdata
);
429 static int Context_set_target(ContextObjext
*self
, PyObject
*value
, void *closure
__attribute__((unused
)))
435 PyErr_SetString(PyExc_TypeError
, NODEL_ATTR
);
438 if (!(target
= pystos(value
)))
441 rc
= mnt_context_set_target(self
->cxt
, target
);
449 static int Context_set_fstype(ContextObjext
*self
, PyObject
*value
, void *closure
__attribute__((unused
)))
455 PyErr_SetString(PyExc_TypeError
, NODEL_ATTR
);
458 if (!(fstype
= pystos(value
)))
461 rc
= mnt_context_set_fstype(self
->cxt
, fstype
);
469 static int Context_set_options(ContextObjext
*self
, PyObject
*value
, void *closure
__attribute__((unused
)))
475 PyErr_SetString(PyExc_TypeError
, NODEL_ATTR
);
478 if (!(options
= pystos(value
)))
481 rc
= mnt_context_set_options(self
->cxt
, options
);
489 static int Context_set_fstype_pattern(ContextObjext
*self
, PyObject
*value
, void *closure
__attribute__((unused
)))
491 char * fstype_pattern
;
495 PyErr_SetString(PyExc_TypeError
, NODEL_ATTR
);
498 if (!(fstype_pattern
= pystos(value
)))
501 rc
= mnt_context_set_fstype_pattern(self
->cxt
, fstype_pattern
);
509 static int Context_set_options_pattern(ContextObjext
*self
, PyObject
*value
, void *closure
__attribute__((unused
)))
511 char * options_pattern
;
515 PyErr_SetString(PyExc_TypeError
, NODEL_ATTR
);
518 if (!(options_pattern
= pystos(value
)))
521 rc
= mnt_context_set_options_pattern(self
->cxt
, options_pattern
);
529 static int Context_set_fs(ContextObjext
*self
, PyObject
*value
, void *closure
__attribute__((unused
)))
534 PyErr_SetString(PyExc_TypeError
, NODEL_ATTR
);
537 if (!PyArg_Parse(value
, "O!", &FsType
, &fs
)) {
538 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
542 Py_XDECREF(mnt_context_get_fs_userdata(self
->cxt
));
544 return mnt_context_set_fs(self
->cxt
, fs
->fs
);
547 static int Context_set_fstab(ContextObjext
*self
, PyObject
*value
, void *closure
__attribute__((unused
)))
552 PyErr_SetString(PyExc_TypeError
, NODEL_ATTR
);
555 if (!PyArg_Parse(value
, "O!", &TableType
, &fstab
)) {
556 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
560 Py_XDECREF(mnt_context_get_fstab_userdata(self
->cxt
));
562 return mnt_context_set_fstab(self
->cxt
, fstab
->tab
);
565 static int Context_set_optsmode(ContextObjext
*self
, PyObject
*value
, void *closure
__attribute__((unused
)))
570 PyErr_SetString(PyExc_TypeError
, NODEL_ATTR
);
573 else if (!PyLong_Check(value
)) {
574 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
577 optsmode
= PyLong_AsLong(value
);
578 return mnt_context_set_optsmode(self
->cxt
, optsmode
);
581 static int Context_set_syscall_status(ContextObjext
*self
, PyObject
*value
, void *closure
__attribute__((unused
)))
586 PyErr_SetString(PyExc_TypeError
, NODEL_ATTR
);
589 else if (!PyLong_Check(value
)) {
590 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
593 syscall_status
= PyLong_AsLong(value
);
594 return mnt_context_set_syscall_status(self
->cxt
, syscall_status
);
597 static int Context_set_user_mflags(ContextObjext
*self
, PyObject
*value
, void *closure
__attribute__((unused
)))
602 PyErr_SetString(PyExc_TypeError
, NODEL_ATTR
);
605 else if (!PyLong_Check(value
)) {
606 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
609 flags
= PyLong_AsUnsignedLong(value
);
610 return mnt_context_set_mflags(self
->cxt
, flags
);
614 static int Context_set_mflags(ContextObjext
*self
, PyObject
*value
, void *closure
__attribute__((unused
)))
619 PyErr_SetString(PyExc_TypeError
, NODEL_ATTR
);
622 else if (!PyLong_Check(value
)) {
623 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
626 flags
= PyLong_AsUnsignedLong(value
);
627 return mnt_context_set_mflags(self
->cxt
, flags
);
630 /* returns a flags integer (behavior differs from C API) */
631 static PyObject
*Context_get_mflags(ContextObjext
*self
)
636 mnt_context_get_mflags(self
->cxt
, &flags
);
637 result
= Py_BuildValue("k", flags
);
640 PyErr_SetString(PyExc_RuntimeError
, CONSTRUCT_ERR
);
644 /* returns a flags integer (behavior differs from C API) */
645 static PyObject
*Context_get_user_mflags(ContextObjext
*self
)
650 mnt_context_get_user_mflags(self
->cxt
, &flags
);
651 result
= Py_BuildValue("k", flags
);
654 PyErr_SetString(PyExc_RuntimeError
, CONSTRUCT_ERR
);
658 #define Context_reset_status_HELP "reset_status()\n\n" \
659 "Resets mount(2) and mount.type statuses, so Cxt.do_mount() or\n" \
660 "Cxt.do_umount() could be again called with the same settings.\n" \
662 "BE CAREFUL -- after this soft reset the libmount will NOT parse mount\n" \
663 "options, evaluate permissions or apply stuff from fstab.\n" \
665 "Returns self or raises an exception in case of an error."
666 static PyObject
*Context_reset_status(ContextObjext
*self
)
668 int rc
= mnt_context_reset_status(self
->cxt
);
670 return rc
? UL_RaiseExc(-rc
) : UL_IncRef(self
);
673 #define Context_is_fake_HELP "is_fake()\n\n" \
674 "Returns True if fake flag is enabled or False"
675 static PyObject
*Context_is_fake(ContextObjext
*self
)
677 return PyBool_FromLong(mnt_context_is_fake(self
->cxt
));
680 #define Context_is_force_HELP "is_force()\n\n" \
681 "Returns True if force umounting flag is enabled or False"
682 static PyObject
*Context_is_force(ContextObjext
*self
)
684 return PyBool_FromLong(mnt_context_is_force(self
->cxt
));
687 #define Context_is_lazy_HELP "is_lazy()\n\n" \
688 "Returns True if lazy umount is enabled or False"
689 static PyObject
*Context_is_lazy(ContextObjext
*self
)
691 return PyBool_FromLong(mnt_context_is_lazy(self
->cxt
));
694 #define Context_is_nomtab_HELP "is_nomtab()\n\n" \
695 "Returns True if no-mtab is enabled or False"
696 static PyObject
*Context_is_nomtab(ContextObjext
*self
)
698 return PyBool_FromLong(mnt_context_is_nomtab(self
->cxt
));
701 #define Context_is_rdonly_umount_HELP "is_rdonly_umount()\n\n" \
702 "Enable/disable read-only remount on failed umount(2)\n" \
703 "(see umount(8) man page, option -r).\n" \
705 "Returns self on success, raises an exception in case of error."
706 static PyObject
*Context_is_rdonly_umount(ContextObjext
*self
)
708 int rc
= mnt_context_is_rdonly_umount(self
->cxt
);
709 return rc
? UL_RaiseExc(-rc
) : UL_IncRef(self
);
712 #define Context_is_restricted_HELP "is_restricted()\n\n" \
713 "Returns False for unrestricted mount (user is root), or True for non-root mounts"
714 static PyObject
*Context_is_restricted(ContextObjext
*self
)
716 return PyBool_FromLong(mnt_context_is_restricted(self
->cxt
));
719 #define Context_is_sloppy_HELP "is_sloppy()\n\n" \
720 "Returns True if sloppy flag is enabled or False"
721 static PyObject
*Context_is_sloppy(ContextObjext
*self
)
723 return PyBool_FromLong(mnt_context_is_sloppy(self
->cxt
));
726 #define Context_is_verbose_HELP "is_verbose()\n\n" \
727 "Returns True if verbose flag is enabled or False"
728 static PyObject
*Context_is_verbose(ContextObjext
*self
)
730 return PyBool_FromLong(mnt_context_is_verbose(self
->cxt
));
732 #define Context_is_fs_mounted_HELP "is_fs_mounted(fs, mounted)\n\n" \
733 "Returns self or raises an exception in case of an error."
734 static PyObject
*Context_is_fs_mounted(ContextObjext
*self
, PyObject
*args
, PyObject
*kwds
)
736 char *kwlist
[] = {"fs", "mounted", NULL
};
740 if (PyArg_ParseTupleAndKeywords(args
, kwds
, "O!i", kwlist
,
741 &FsType
, &fs
, &mounted
)) {
742 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
745 return PyBool_FromLong(mnt_context_is_fs_mounted(self
->cxt
, fs
->fs
, &mounted
));
748 #define Context_is_child_HELP "is_child()\n\n" \
749 "Returns True if mount -F enabled and the current context is child, or False"
750 static PyObject
*Context_is_child(ContextObjext
*self
)
752 return PyBool_FromLong(mnt_context_is_child(self
->cxt
));
755 #define Context_is_fork_HELP "is_fork()\n\n" \
756 "Returns True if fork (mount -F) is enabled or False"
757 static PyObject
*Context_is_fork(ContextObjext
*self
)
759 return PyBool_FromLong(mnt_context_is_fork(self
->cxt
));
762 #define Context_is_parent_HELP "is_parent()\n\n" \
763 "Returns True if mount -F enabled and the current context is parent, or False"
764 static PyObject
*Context_is_parent(ContextObjext
*self
)
766 return PyBool_FromLong(mnt_context_is_parent(self
->cxt
));
769 #define Context_is_loopdel_HELP "is_loopdel()\n\n" \
770 "Returns True if loop device should be deleted after umount (umount -d) or False."
771 static PyObject
*Context_is_loopdel(ContextObjext
*self
)
773 return PyBool_FromLong(mnt_context_is_loopdel(self
->cxt
));
776 #define Context_is_nocanonicalize_HELP "is_nocanonicalize()\n\n" \
777 "Returns True if no-canonicalize mode enabled or False."
778 static PyObject
*Context_is_nocanonicalize(ContextObjext
*self
)
780 return PyBool_FromLong(mnt_context_is_nocanonicalize(self
->cxt
));
783 #define Context_is_nohelpers_HELP "is_nohelpers()\n\n" \
784 "Returns True if helpers are disabled (mount -i) or False."
785 static PyObject
*Context_is_nohelpers(ContextObjext
*self
)
787 return PyBool_FromLong(mnt_context_is_nohelpers(self
->cxt
));
790 #define Context_syscall_called_HELP "syscall_called()\n\n" \
791 "Returns True if mount(2) syscall has been called, or False."
792 static PyObject
*Context_syscall_called(ContextObjext
*self
)
794 return PyBool_FromLong(mnt_context_syscall_called(self
->cxt
));
797 #define Context_is_swapmatch_HELP "is_swapmatch()\n\n" \
798 "Returns True if swap between source and target is allowed (default is True) or False."
799 static PyObject
*Context_is_swapmatch(ContextObjext
*self
)
801 return PyBool_FromLong(mnt_context_is_swapmatch(self
->cxt
));
804 #define Context_tab_applied_HELP "tab_applied()\n\n" \
805 "Returns True if fstab (or mtab) has been applied to the context, False otherwise."
806 static PyObject
*Context_tab_applied(ContextObjext
*self
)
808 return PyBool_FromLong(mnt_context_tab_applied(self
->cxt
));
811 #define Context_apply_fstab_HELP "apply_fstab()\n\n" \
812 "This function is optional.\n" \
814 "Returns self or raises an exception in case of an error."
815 static PyObject
*Context_apply_fstab(ContextObjext
*self
)
817 int rc
= mnt_context_apply_fstab(self
->cxt
);
818 return rc
? UL_RaiseExc(-rc
) : UL_IncRef(self
);
821 #define Context_helper_executed_HELP "helper_executed()\n\n" \
822 "Returns True if mount.type helper has been executed, or False."
823 static PyObject
*Context_helper_executed(ContextObjext
*self
)
825 return PyBool_FromLong(mnt_context_helper_executed(self
->cxt
));
828 static PyObject
*Context_get_source(ContextObjext
*self
)
830 return PyObjectResultStr(mnt_context_get_source(self
->cxt
));
833 static PyObject
*Context_get_target(ContextObjext
*self
)
835 return PyObjectResultStr(mnt_context_get_target(self
->cxt
));
838 static PyObject
*Context_get_options(ContextObjext
*self
)
840 return PyObjectResultStr(mnt_context_get_options(self
->cxt
));
843 static PyObject
*Context_get_fstype(ContextObjext
*self
)
845 return PyObjectResultStr(mnt_context_get_fstype(self
->cxt
));
848 static PyObject
*Context_get_fs(ContextObjext
*self
)
850 return PyObjectResultFs(mnt_context_get_fs(self
->cxt
));
853 static PyObject
*Context_get_fstab(ContextObjext
*self
)
855 struct libmnt_table
*tab
= NULL
;
857 if (mnt_context_get_fstab(self
->cxt
, &tab
) != 0 || !tab
)
859 return PyObjectResultTab(tab
);
862 static PyObject
*Context_get_mtab(ContextObjext
*self
)
864 struct libmnt_table
*tab
= NULL
;
866 if (mnt_context_get_mtab(self
->cxt
, &tab
) != 0 || !tab
)
868 return PyObjectResultTab(tab
);
871 static PyObject
*Context_get_optsmode(ContextObjext
*self
)
873 return PyObjectResultInt(mnt_context_get_optsmode(self
->cxt
));
876 static PyObject
*Context_get_status(ContextObjext
*self
)
878 return PyObjectResultInt(mnt_context_get_status(self
->cxt
));
881 static PyObject
*Context_get_syscall_errno(ContextObjext
*self
)
883 return PyObjectResultInt(mnt_context_get_syscall_errno(self
->cxt
));
886 #define Context_do_mount_HELP "do_mount()\n\n" \
887 "Call mount(2) or mount.type helper. Unnecessary for Cxt.mount().\n" \
889 "Note that this function could be called only once. If you want to mount\n" \
890 "another source or target than you have to call Cxt.reset_context().\n" \
892 "If you want to call mount(2) for the same source and target with a different\n" \
893 "mount flags or fstype then call Cxt.reset_status() and then try\n" \
894 "again Cxt.do_mount().\n" \
896 "WARNING: non-zero return code does not mean that mount(2) syscall or\n" \
897 "mount.type helper wasn't successfully called.\n" \
899 "Check Cxt.status after error!\n" \
901 "Returns self on success or an exception in case of other errors."
902 static PyObject
*Context_do_mount(ContextObjext
*self
)
904 int rc
= mnt_context_do_mount(self
->cxt
);
905 return rc
? UL_RaiseExc(rc
< 0 ? -rc
: rc
) : UL_IncRef(self
);
908 #define Context_do_umount_HELP "do_umount()\n\n" \
909 "Umount filesystem by umount(2) or fork()+exec(/sbin/umount.type).\n" \
910 "Unnecessary for Cxt.umount().\n" \
912 "See also Cxt.disable_helpers().\n" \
914 "WARNING: non-zero return code does not mean that umount(2) syscall or\n" \
915 "umount.type helper wasn't successfully called.\n" \
917 "Check Cxt.status after error!\n" \
919 "Returns self on success or an exception in case of other errors."
920 static PyObject
*Context_do_umount(ContextObjext
*self
)
922 int rc
= mnt_context_do_umount(self
->cxt
);
923 return rc
? UL_RaiseExc(rc
< 0 ? -rc
: rc
) : UL_IncRef(self
);
926 #define Context_mount_HELP "mount()\n\n" \
927 "High-level, mounts filesystem by mount(2) or fork()+exec(/sbin/mount.type).\n" \
929 "This is similar to:\n" \
931 "Cxt.prepare_mount();\n" \
932 "Cxt.do_mount();\n" \
933 "Cxt.finalize_mount();\n" \
935 "See also Cxt.disable_helper().\n" \
937 "Note that this function could be called only once. If you want to mount with\n" \
938 "different setting than you have to call Cxt.reset_context(). It's NOT enough\n" \
939 "to call Cxt.reset_status() if you want call this function more than\n" \
940 "once, whole context has to be reset.\n" \
942 "WARNING: non-zero return code does not mean that mount(2) syscall or\n" \
943 "mount.type helper wasn't successfully called.\n" \
945 "Check Cxt.status after error!\n" \
947 "Returns self on success or an exception in case of other errors."
948 static PyObject
*Context_mount(ContextObjext
*self
)
950 int rc
= mnt_context_mount(self
->cxt
);
951 return rc
? UL_RaiseExc(rc
< 0 ? -rc
: rc
) : UL_IncRef(self
);
954 #define Context_umount_HELP "umount()\n\n" \
955 "High-level, umounts filesystem by umount(2) or fork()+exec(/sbin/umount.type).\n" \
957 "This is similar to:\n" \
959 "Cxt.prepare_umount();\n" \
960 "Cxt.do_umount();\n" \
961 "Cxt.finalize_umount();\n" \
963 "See also Cxt.disable_helpers().\n" \
965 "WARNING: non-zero return code does not mean that umount(2) syscall or\n" \
966 "umount.type helper wasn't successfully called.\n" \
968 "Check Cxt.status after error!\n" \
970 "Returns self on success or an exception in case of other errors."
971 static PyObject
*Context_umount(ContextObjext
*self
)
973 int rc
= mnt_context_umount(self
->cxt
);
974 return rc
? UL_RaiseExc(rc
< 0 ? -rc
: rc
) : UL_IncRef(self
);
977 #define Context_finalize_mount_HELP "finalize_mount()\n\n" \
978 "Mtab update, etc. Unnecessary for Cxt.mount(), but should be called\n" \
979 "after Cxt.do_mount(). See also Cxt.syscall_status.\n" \
981 "Returns self or raises an exception in case of an error."
982 static PyObject
*Context_finalize_mount(ContextObjext
*self
)
984 int rc
= mnt_context_finalize_mount(self
->cxt
);
985 return rc
? UL_RaiseExc(-rc
) : UL_IncRef(self
);
988 #define Context_prepare_umount_HELP "prepare_umount()\n\n" \
989 "Prepare context for umounting, unnecessary for Cxt.umount().\n" \
991 "Returns self or raises an exception in case of an error."
992 static PyObject
*Context_prepare_umount(ContextObjext
*self
)
994 int rc
= mnt_context_prepare_umount(self
->cxt
);
995 return rc
? UL_RaiseExc(-rc
) : UL_IncRef(self
);
998 #define Context_prepare_mount_HELP "prepare_mount()\n\n" \
999 "Prepare context for mounting, unnecessary for Cxt.mount().\n" \
1001 "Returns self or raises an exception in case of an error."
1002 static PyObject
*Context_prepare_mount(ContextObjext
*self
)
1004 int rc
= mnt_context_prepare_mount(self
->cxt
);
1005 return rc
? UL_RaiseExc(-rc
) : UL_IncRef(self
);
1008 #define Context_finalize_umount_HELP "finalize_umount()\n\n" \
1009 "Mtab update, etc. Unnecessary for Cxt.umount(), but should be called\n" \
1010 "after Cxt.do_umount(). See also Cxt.syscall_status.\n" \
1012 "Returns self on success, raises LibmountError if target filesystem not found, or other exception on error."
1013 static PyObject
*Context_finalize_umount(ContextObjext
*self
)
1015 int rc
= mnt_context_finalize_umount(self
->cxt
);
1016 return rc
? UL_RaiseExc(-rc
) : UL_IncRef(self
);
1019 #define Context_find_umount_fs_HELP "find_umount_fs(tgt, pfs)\n\n" \
1020 "Returns self or raises an exception in case of an error."
1021 static PyObject
*Context_find_umount_fs(ContextObjext
*self
, PyObject
*args
, PyObject
*kwds
)
1024 char *kwlist
[] = { "tgt", "pfs", NULL
};
1028 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "sO!", kwlist
, &tgt
, &FsType
, &fs
)) {
1029 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
1033 rc
= mnt_context_find_umount_fs(self
->cxt
, tgt
, &fs
->fs
);
1034 return rc
? UL_RaiseExc(-rc
) : UL_IncRef(self
);
1037 #define Context_append_options_HELP "append_options(optstr)\n\n" \
1038 "Returns self or raises an exception in case of an error."
1039 static PyObject
*Context_append_options(ContextObjext
*self
, PyObject
*args
, PyObject
*kwds
)
1042 char *kwlist
[] = {"optstr", NULL
};
1043 char *optstr
= NULL
;
1045 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "s", kwlist
, &optstr
)) {
1046 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
1050 rc
= mnt_context_append_options(self
->cxt
, optstr
);
1051 return rc
? UL_RaiseExc(-rc
) : UL_IncRef(self
);
1054 #define Context_helper_setopt_HELP "helper_setopt(c, arg)\n\n" \
1055 "This function applies [u]mount.type command line option (for example parsed\n" \
1056 "by getopt or getopt_long) to cxt. All unknown options are ignored and\n" \
1057 "then ValueError is raised.\n" \
1059 "Returns self on success, raises ValueError if c is unknown or other exception in case of an error."
1060 static PyObject
*Context_helper_setopt(ContextObjext
*self
, PyObject
*args
, PyObject
*kwds
)
1065 char *kwlist
[] = { "c", "arg", NULL
};
1067 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "is", kwlist
, &c
, &arg
)) {
1068 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
1072 rc
= mnt_context_helper_setopt(self
->cxt
, c
, arg
);
1073 return rc
? UL_RaiseExc(-rc
) : UL_IncRef(self
);
1076 #define Context_init_helper_HELP "init_helper(action, flags)\n\n" \
1077 "This function infors libmount that used from [u]mount.type helper.\n" \
1079 "The function also calls Cxt.disable_helpers() to avoid recursive\n" \
1080 "mount.type helpers calling. It you really want to call another\n" \
1081 "mount.type helper from your helper than you have to explicitly enable this\n" \
1084 "Cxt.disable_helpers(False);\n" \
1086 "Returns self or raises an exception in case of an error."
1087 static PyObject
*Context_init_helper(ContextObjext
*self
, PyObject
*args
, PyObject
*kwds
)
1091 char *kwlist
[] = {"action", "flags", NULL
};
1093 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "ii", kwlist
, &action
, &flags
)) {
1094 PyErr_SetString(PyExc_TypeError
, ARG_ERR
);
1098 rc
= mnt_context_init_helper(self
->cxt
, action
, flags
);
1099 return rc
? UL_RaiseExc(-rc
) : UL_IncRef(self
);
1102 static PyGetSetDef Context_getseters
[] = {
1103 {"tables_errcb", NULL
, (setter
)Context_set_tables_errcb
, "error callback function", NULL
},
1104 {"status", (getter
)Context_get_status
, NULL
, "status", NULL
},
1105 {"source", (getter
)Context_get_source
, (setter
)Context_set_source
, "source", NULL
},
1106 {"target", (getter
)Context_get_target
, (setter
)Context_set_target
, "target", NULL
},
1107 {"fstype", (getter
)Context_get_fstype
, (setter
)Context_set_fstype
, "fstype", NULL
},
1108 {"options", (getter
)Context_get_options
, (setter
)Context_set_options
, "options", NULL
},
1109 {"mflags", (getter
)Context_get_mflags
, (setter
)Context_set_mflags
, "mflags", NULL
},
1110 {"mountdata", NULL
, (setter
)Context_set_mountdata
, "mountdata", NULL
},
1111 {"fstype_pattern", NULL
, (setter
)Context_set_fstype_pattern
, "fstype_pattern", NULL
},
1112 {"options_pattern", NULL
, (setter
)Context_set_options_pattern
, "options_pattern", NULL
},
1113 {"fs", (getter
)Context_get_fs
, (setter
)Context_set_fs
, "filesystem description (type, mountpoint, device, ...)", NULL
},
1114 {"mtab", (getter
)Context_get_mtab
, NULL
, "mtab entries", NULL
},
1115 {"fstab", (getter
)Context_get_fstab
, (setter
)Context_set_fstab
, "fstab (or mtab for some remounts)", NULL
},
1116 {"optsmode", (getter
)Context_get_optsmode
, (setter
)Context_set_optsmode
, "fstab optstr mode MNT_OPTSMODE_{AUTO,FORCE,IGNORE}", NULL
},
1117 {"syscall_errno", (getter
)Context_get_syscall_errno
, (setter
)Context_set_syscall_status
, "1: not_called yet, 0: success, <0: -errno", NULL
},
1118 {"user_mflags", (getter
)Context_get_user_mflags
, (setter
)Context_set_user_mflags
, "user mflags", NULL
},
1121 static PyMethodDef Context_methods
[] = {
1122 {"find_umount_fs", (PyCFunction
)Context_find_umount_fs
, METH_VARARGS
|METH_KEYWORDS
, Context_find_umount_fs_HELP
},
1123 {"reset_status", (PyCFunction
)Context_reset_status
, METH_NOARGS
, Context_reset_status_HELP
},
1124 {"helper_executed", (PyCFunction
)Context_helper_executed
, METH_NOARGS
, Context_helper_executed_HELP
},
1125 {"init_helper", (PyCFunction
)Context_init_helper
, METH_VARARGS
|METH_KEYWORDS
, Context_init_helper_HELP
},
1126 {"helper_setopt", (PyCFunction
)Context_helper_setopt
, METH_VARARGS
|METH_KEYWORDS
, Context_helper_setopt_HELP
},
1127 {"append_options", (PyCFunction
)Context_append_options
, METH_VARARGS
|METH_KEYWORDS
, Context_append_options_HELP
},
1128 {"apply_fstab", (PyCFunction
)Context_apply_fstab
, METH_NOARGS
, Context_apply_fstab_HELP
},
1129 {"disable_canonicalize", (PyCFunction
)Context_disable_canonicalize
, METH_VARARGS
|METH_KEYWORDS
, Context_disable_canonicalize_HELP
},
1130 {"disable_helpers", (PyCFunction
)Context_disable_helpers
, METH_VARARGS
|METH_KEYWORDS
, Context_disable_helpers_HELP
},
1131 {"disable_mtab", (PyCFunction
)Context_disable_mtab
, METH_VARARGS
|METH_KEYWORDS
, Context_disable_mtab_HELP
},
1132 {"do_mount", (PyCFunction
)Context_do_mount
, METH_NOARGS
, Context_do_mount_HELP
},
1133 {"do_umount", (PyCFunction
)Context_do_umount
, METH_NOARGS
, Context_do_umount_HELP
},
1134 {"enable_fake", (PyCFunction
)Context_enable_fake
, METH_VARARGS
|METH_KEYWORDS
, Context_enable_fake_HELP
},
1135 {"enable_force", (PyCFunction
)Context_enable_force
, METH_VARARGS
|METH_KEYWORDS
, Context_enable_force_HELP
},
1136 {"enable_lazy", (PyCFunction
)Context_enable_lazy
, METH_VARARGS
|METH_KEYWORDS
, Context_enable_lazy_HELP
},
1137 {"enable_loopdel", (PyCFunction
)Context_enable_loopdel
, METH_VARARGS
|METH_KEYWORDS
, Context_enable_loopdel_HELP
},
1138 {"enable_rdonly_umount", (PyCFunction
)Context_enable_rdonly_umount
, METH_VARARGS
|METH_KEYWORDS
, Context_enable_rdonly_umount_HELP
},
1139 {"enable_sloppy", (PyCFunction
)Context_enable_sloppy
, METH_VARARGS
|METH_KEYWORDS
, Context_enable_sloppy_HELP
},
1140 {"enable_verbose", (PyCFunction
)Context_enable_verbose
, METH_VARARGS
|METH_KEYWORDS
, Context_enable_verbose_HELP
},
1141 {"enable_fork", (PyCFunction
)Context_enable_fork
, METH_VARARGS
|METH_KEYWORDS
, Context_enable_fork_HELP
},
1142 {"finalize_mount", (PyCFunction
)Context_finalize_mount
, METH_NOARGS
, Context_finalize_mount_HELP
},
1143 {"finalize_umount", (PyCFunction
)Context_finalize_umount
, METH_NOARGS
, Context_finalize_umount_HELP
},
1144 {"is_fake", (PyCFunction
)Context_is_fake
, METH_NOARGS
, Context_is_fake_HELP
},
1145 {"is_force", (PyCFunction
)Context_is_force
, METH_NOARGS
, Context_is_force_HELP
},
1146 {"is_fork", (PyCFunction
)Context_is_fork
, METH_NOARGS
, Context_is_fork_HELP
},
1147 {"is_fs_mounted", (PyCFunction
)Context_is_fs_mounted
, METH_VARARGS
|METH_KEYWORDS
, Context_is_fs_mounted_HELP
},
1148 {"is_lazy", (PyCFunction
)Context_is_lazy
, METH_NOARGS
, Context_is_lazy_HELP
},
1149 {"is_nomtab", (PyCFunction
)Context_is_nomtab
, METH_NOARGS
, Context_is_nomtab_HELP
},
1150 {"is_rdonly_umount", (PyCFunction
)Context_is_rdonly_umount
, METH_NOARGS
, Context_is_rdonly_umount_HELP
},
1151 {"is_restricted", (PyCFunction
)Context_is_restricted
, METH_NOARGS
, Context_is_restricted_HELP
},
1152 {"is_sloppy", (PyCFunction
)Context_is_sloppy
, METH_NOARGS
, Context_is_sloppy_HELP
},
1153 {"is_verbose", (PyCFunction
)Context_is_verbose
, METH_NOARGS
, Context_is_verbose_HELP
},
1154 {"is_child", (PyCFunction
)Context_is_child
, METH_NOARGS
, Context_is_child_HELP
},
1155 {"is_parent", (PyCFunction
)Context_is_parent
, METH_NOARGS
, Context_is_parent_HELP
},
1156 {"is_loopdel", (PyCFunction
)Context_is_loopdel
, METH_NOARGS
, Context_is_loopdel_HELP
},
1157 {"is_nocanonicalize", (PyCFunction
)Context_is_nocanonicalize
, METH_NOARGS
, Context_is_nocanonicalize_HELP
},
1158 {"is_nohelpers", (PyCFunction
)Context_is_nohelpers
, METH_NOARGS
, Context_is_nohelpers_HELP
},
1159 {"is_swapmatch", (PyCFunction
)Context_is_swapmatch
, METH_NOARGS
, Context_is_swapmatch_HELP
},
1160 {"mount", (PyCFunction
)Context_mount
, METH_NOARGS
, Context_mount_HELP
},
1161 {"prepare_mount", (PyCFunction
)Context_prepare_mount
, METH_NOARGS
, Context_prepare_mount_HELP
},
1162 {"prepare_umount", (PyCFunction
)Context_prepare_umount
, METH_NOARGS
, Context_prepare_umount_HELP
},
1163 {"umount", (PyCFunction
)Context_umount
, METH_NOARGS
, Context_umount_HELP
},
1164 {"syscall_called", (PyCFunction
)Context_syscall_called
, METH_NOARGS
, Context_syscall_called_HELP
},
1165 {"disable_swapmatch", (PyCFunction
)Context_disable_swapmatch
, METH_VARARGS
|METH_KEYWORDS
, Context_disable_swapmatch_HELP
},
1166 {"tab_applied", (PyCFunction
)Context_tab_applied
, METH_NOARGS
, Context_tab_applied_HELP
},
1170 static PyObject
*Context_repr(ContextObjext
*self
)
1172 return PyUnicode_FromFormat("<libmount.Context object at %p, restricted=%s>",
1173 self
, mnt_context_is_restricted(self
->cxt
) ? "True" : "False");
1176 PyTypeObject ContextType
= {
1177 PyVarObject_HEAD_INIT(NULL
, 0)
1178 "libmount.Context", /*tp_name*/
1179 sizeof(ContextObjext
), /*tp_basicsize*/
1181 (destructor
)Context_dealloc
, /*tp_dealloc*/
1186 (reprfunc
) Context_repr
,
1188 0, /*tp_as_sequence*/
1189 0, /*tp_as_mapping*/
1196 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
, /*tp_flags*/
1197 Context_HELP
, /* tp_doc */
1198 0, /* tp_traverse */
1200 0, /* tp_richcompare */
1201 0, /* tp_weaklistoffset */
1203 0, /* tp_iternext */
1204 Context_methods
, /* tp_methods */
1205 Context_members
, /* tp_members */
1206 Context_getseters
, /* tp_getset */
1209 0, /* tp_descr_get */
1210 0, /* tp_descr_set */
1211 0, /* tp_dictoffset */
1212 (initproc
)Context_init
, /* tp_init */
1214 Context_new
, /* tp_new */
1217 void Context_AddModuleObject(PyObject
*mod
)
1219 if (PyType_Ready(&ContextType
) < 0)
1222 DBG(CXT
, pymnt_debug("add to module"));
1224 Py_INCREF(&ContextType
);
1225 PyModule_AddObject(mod
, "Context", (PyObject
*)&ContextType
);