(root)/
util-linux-2.39/
libmount/
python/
context.c
       1  /*
       2   * Python bindings for the libmount library.
       3   *
       4   * Copyright (C) 2013, Red Hat, Inc. All rights reserved.
       5   * Written by Ondrej Oprala and Karel Zak
       6   *
       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.
      11   *
      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.
      16   *
      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.
      20   */
      21  #include "pylibmount.h"
      22  
      23  static PyMemberDef Context_members[] = {
      24  	{ NULL }
      25  };
      26  
      27  static PyObject *Context_set_tables_errcb(ContextObjext *self, PyObject *func,
      28  				      void *closure __attribute__((unused)))
      29  {
      30  	if (!func) {
      31  		PyErr_SetString(PyExc_TypeError, NODEL_ATTR);
      32  		return NULL;
      33  	}
      34  
      35  	if (!PyCallable_Check(func))
      36  		return NULL;
      37  
      38  	PyObject *tmp = self->table_errcb;
      39  	Py_INCREF(func);
      40  	self->table_errcb = func;
      41  	Py_XDECREF(tmp);
      42  
      43  	return UL_IncRef(self);
      44  }
      45  
      46  static void Context_dealloc(ContextObjext *self)
      47  {
      48  	if (!self->cxt) /* if init fails */
      49  		return;
      50  
      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));
      54  
      55  	mnt_free_context(self->cxt);
      56  	PyFree(self);
      57  }
      58  
      59  static PyObject *Context_new(PyTypeObject *type,
      60  			 PyObject *args __attribute__((unused)),
      61  			 PyObject *kwds __attribute__((unused)))
      62  {
      63  	ContextObjext *self = (ContextObjext*) type->tp_alloc(type, 0);
      64  
      65  	if (self) {
      66  		self->cxt = NULL;
      67  		self->table_errcb = NULL;
      68  	}
      69  
      70  	return (PyObject *)self;
      71  }
      72  
      73  /*
      74   * Note there is no pointer to encapsulating object needed here, since Cxt is
      75   * on top of the Context(Table(Filesystem)) hierarchy
      76   */
      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)
      81  {
      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;
      86  	FsObject *fs = NULL;
      87  	TableObject *fstab = NULL;
      88  	int rc = 0;
      89  	char *kwlist[] = {
      90  		"source", "target", "fstype",
      91  		"options", "mflags", "fstype_pattern",
      92  		"options_pattern", "fs", "fstab",
      93  		"optsmode", NULL
      94  	};
      95  
      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);
     102  			return -1;
     103  	}
     104  
     105  	if (self->cxt)
     106  		mnt_free_context(self->cxt);
     107  
     108  	self->cxt = mnt_new_context();
     109  	if (!self->cxt) {
     110  		PyErr_SetString(PyExc_MemoryError, MEMORY_ERR);
     111  		return -1;
     112  	}
     113  
     114  	if (source && (rc = mnt_context_set_source(self->cxt, source))) {
     115  		UL_RaiseExc(-rc);
     116  		return -1;
     117  	}
     118  
     119  	if (target && (rc = mnt_context_set_target(self->cxt, target))) {
     120  		UL_RaiseExc(-rc);
     121  		return -1;
     122  	}
     123  
     124  	if (fstype && (rc = mnt_context_set_fstype(self->cxt, fstype))) {
     125  		UL_RaiseExc(-rc);
     126  		return -1;
     127  	}
     128  
     129  	if (options && (rc = mnt_context_set_options(self->cxt, options))) {
     130  		UL_RaiseExc(-rc);
     131  		return -1;
     132  	}
     133  
     134  	if (fstype_pattern && (rc = mnt_context_set_fstype_pattern(self->cxt, fstype_pattern))) {
     135  		UL_RaiseExc(-rc);
     136  		return -1;
     137  	}
     138  
     139  	if (options_pattern && (rc = mnt_context_set_options_pattern(self->cxt, options_pattern))) {
     140  		UL_RaiseExc(-rc);
     141  		return -1;
     142  	}
     143  
     144  	if (fs && (rc = mnt_context_set_fs(self->cxt, fs->fs))) {
     145  		UL_RaiseExc(-rc);
     146  		return -1;
     147  	}
     148  
     149  	if (fstab && (rc = mnt_context_set_fstab(self->cxt, fstab->tab))) {
     150  		UL_RaiseExc(-rc);
     151  		return -1;
     152  	}
     153  
     154  	if (optsmode && (rc = mnt_context_set_optsmode(self->cxt, optsmode))) {
     155  		UL_RaiseExc(-rc);
     156  		return -1;
     157  	}
     158  
     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);
     162  
     163  	return 0;
     164  }
     165  
     166  #define Context_enable_fake_HELP "enable_fake(enable)\n\n" \
     167  	"Enable/disable fake mounting (see mount(8) man page, option -f).\n" \
     168  	"\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)
     171  {
     172  	int rc;
     173  	int enable;
     174  	char *kwlist[] = { "enable", NULL };
     175  
     176  	if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &enable)) {
     177  		PyErr_SetString(PyExc_TypeError, ARG_ERR);
     178  		return NULL;
     179  	}
     180  	rc = mnt_context_enable_fake(self->cxt, enable);
     181  	return rc ? UL_RaiseExc(-rc) : UL_IncRef(self);
     182  }
     183  
     184  #define Context_enable_force_HELP "enable_force(enable)\n\n" \
     185  	"Enable/disable force umounting (see umount(8) man page, option -f).\n" \
     186  	"\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)
     189  {
     190  	int rc;
     191  	int enable;
     192  	char *kwlist[] = { "enable", NULL };
     193  
     194  	if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &enable)) {
     195  		PyErr_SetString(PyExc_TypeError, ARG_ERR);
     196  		return NULL;
     197  	}
     198  	rc = mnt_context_enable_force(self->cxt, enable);
     199  	return rc ? UL_RaiseExc(-rc) : UL_IncRef(self);
     200  }
     201  
     202  #define Context_enable_lazy_HELP "enable_lazy(enable)\n\n" \
     203  	"Enable/disable lazy umount (see umount(8) man page, option -l).\n" \
     204  	"\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)
     207  {
     208  	int rc;
     209  	int enable;
     210  	char *kwlist[] = { "enable", NULL };
     211  
     212  	if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &enable)) {
     213  		PyErr_SetString(PyExc_TypeError, ARG_ERR);
     214  		return NULL;
     215  	}
     216  	rc = mnt_context_enable_lazy(self->cxt, enable);
     217  	return rc ? UL_RaiseExc(-rc) : UL_IncRef(self);
     218  }
     219  
     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" \
     222  	"\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)
     225  {
     226  	int rc;
     227  	int enable;
     228  	char *kwlist[] = { "enable", NULL };
     229  
     230  	if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &enable)) {
     231  		PyErr_SetString(PyExc_TypeError, ARG_ERR);
     232  		return NULL;
     233  	}
     234  	rc = mnt_context_enable_loopdel(self->cxt, enable);
     235  	return rc ? UL_RaiseExc(-rc) : UL_IncRef(self);
     236  }
     237  
     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" \
     241  	"\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)
     244  {
     245  	int rc;
     246  	int enable;
     247  	char *kwlist[] = { "enable", NULL };
     248  
     249  	if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &enable)) {
     250  		PyErr_SetString(PyExc_TypeError, ARG_ERR);
     251  		return NULL;
     252  	}
     253  	rc = mnt_context_enable_rdonly_umount(self->cxt, enable);
     254  	return rc ? UL_RaiseExc(-rc) : UL_IncRef(self);
     255  }
     256  
     257  #define Context_enable_sloppy_HELP "enable_sloppy(enable)\n\n" \
     258  	"Set/unset sloppy mounting (see mount(8) man page, option -s).\n" \
     259  	"\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)
     262  {
     263  	int rc;
     264  	int enable;
     265  	char *kwlist[] = { "enable", NULL };
     266  
     267  	if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &enable)) {
     268  		PyErr_SetString(PyExc_TypeError, ARG_ERR);
     269  		return NULL;
     270  	}
     271  	rc = mnt_context_enable_sloppy(self->cxt, enable);
     272  	return rc ? UL_RaiseExc(-rc) : UL_IncRef(self);
     273  }
     274  
     275  #define Context_enable_verbose_HELP "enable_verbose(enable)\n\n" \
     276  	"Enable/disable verbose output (TODO: not implemented yet)\n" \
     277  	"\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)
     280  {
     281  	int rc;
     282  	int enable;
     283  	char *kwlist[] = { "enable", NULL };
     284  
     285  	if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &enable)) {
     286  		PyErr_SetString(PyExc_TypeError, ARG_ERR);
     287  		return NULL;
     288  	}
     289  	rc = mnt_context_enable_verbose(self->cxt, enable);
     290  	return rc ? UL_RaiseExc(-rc) : UL_IncRef(self);
     291  }
     292  
     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" \
     296  	"\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)
     299  {
     300  	int rc;
     301  	int enable;
     302  	char *kwlist[] = {"enable", NULL};
     303  
     304  	if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &enable)) {
     305  		PyErr_SetString(PyExc_TypeError, ARG_ERR);
     306  		return NULL;
     307  	}
     308  	rc = mnt_context_enable_fork(self->cxt, enable);
     309  	return rc ? UL_RaiseExc(-rc) : UL_IncRef(self);
     310  }
     311  
     312  #define Context_disable_canonicalize_HELP "disable_canonicalize(disable)\n\n" \
     313  	"Enable/disable paths canonicalization and tags evaluation. The libmount context\n" \
     314  	"canonicalizes paths when searching fstab and when preparing source and target paths\n" \
     315  	"for mount(2) syscall.\n" \
     316  	"\n" \
     317  	"This function 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)
     321  {
     322  	int rc;
     323  	int disable;
     324  	char *kwlist[] = {"disable", NULL};
     325  
     326  	if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &disable)) {
     327  		PyErr_SetString(PyExc_TypeError, ARG_ERR);
     328  		return NULL;
     329  	}
     330  	rc = mnt_context_disable_canonicalize(self->cxt, disable);
     331  	return rc ? UL_RaiseExc(-rc) : UL_IncRef(self);
     332  }
     333  
     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" \
     336  	"\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)
     339  {
     340  	int rc;
     341  	int disable;
     342  	char *kwlist[] = {"disable", NULL};
     343  
     344  	if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &disable)) {
     345  		PyErr_SetString(PyExc_TypeError, ARG_ERR);
     346  		return NULL;
     347  	}
     348  	rc = mnt_context_disable_helpers(self->cxt, disable);
     349  	return rc ? UL_RaiseExc(-rc) : UL_IncRef(self);
     350  }
     351  
     352  #define Context_disable_mtab_HELP "disable_mtab(disable)\n\n" \
     353  	"Disable/enable mtab update (see mount(8) man page, option -n).\n" \
     354  	"\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)
     357  {
     358  	int rc;
     359  	int disable;
     360  	char *kwlist[] = {"disable", NULL };
     361  
     362  	if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &disable)) {
     363  		PyErr_SetString(PyExc_TypeError, ARG_ERR);
     364  		return NULL;
     365  	}
     366  	rc = mnt_context_disable_mtab(self->cxt, disable);
     367  	return rc ? UL_RaiseExc(-rc) : UL_IncRef(self);
     368  }
     369  
     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" \
     372  	"is specified.\n" \
     373  	"\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)
     376  {
     377  	int rc;
     378  	int disable;
     379  	char *kwlist[] = { "disable", NULL };
     380  
     381  	if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &disable)) {
     382  		PyErr_SetString(PyExc_TypeError, ARG_ERR);
     383  		return NULL;
     384  	}
     385  	rc = mnt_context_disable_swapmatch(self->cxt, disable);
     386  	return rc ? UL_RaiseExc(-rc) : UL_IncRef(self);
     387  }
     388  
     389  static int Context_set_source(ContextObjext *self, PyObject *value, void *closure __attribute__((unused)))
     390  {
     391  	char *source;
     392  	int rc = 0;
     393  
     394  	if (!value) {
     395  		PyErr_SetString(PyExc_TypeError, NODEL_ATTR);
     396  		return -1;
     397  	}
     398  	if (!(source = pystos(value)))
     399  		return -1;
     400  
     401  	rc = mnt_context_set_source(self->cxt, source);
     402  	if (rc) {
     403  		UL_RaiseExc(-rc);
     404  		return -1;
     405  	}
     406  	return 0;
     407  }
     408  
     409  static int Context_set_mountdata(ContextObjext *self, PyObject *value, void *closure __attribute__((unused)))
     410  {
     411  	char *mountdata;
     412  	int rc = 0;
     413  
     414  	if (!value) {
     415  		PyErr_SetString(PyExc_TypeError, NODEL_ATTR);
     416  		return -1;
     417  	}
     418  	if (!(mountdata = pystos(value)))
     419  		return -1;
     420  
     421  	rc = mnt_context_set_mountdata(self->cxt, mountdata);
     422  	if (rc) {
     423  		UL_RaiseExc(-rc);
     424  		return -1;
     425  	}
     426  	return 0;
     427  }
     428  
     429  static int Context_set_target(ContextObjext *self, PyObject *value, void *closure __attribute__((unused)))
     430  {
     431  	char * target;
     432  	int rc = 0;
     433  
     434  	if (!value) {
     435  		PyErr_SetString(PyExc_TypeError, NODEL_ATTR);
     436  		return -1;
     437  	}
     438  	if (!(target = pystos(value)))
     439  		return -1;
     440  
     441  	rc = mnt_context_set_target(self->cxt, target);
     442  	if (rc) {
     443  		UL_RaiseExc(-rc);
     444  		return -1;
     445  	}
     446  	return 0;
     447  }
     448  
     449  static int Context_set_fstype(ContextObjext *self, PyObject *value, void *closure __attribute__((unused)))
     450  {
     451  	char * fstype;
     452  	int rc = 0;
     453  
     454  	if (!value) {
     455  		PyErr_SetString(PyExc_TypeError, NODEL_ATTR);
     456  		return -1;
     457  	}
     458  	if (!(fstype = pystos(value)))
     459  		return -1;
     460  
     461  	rc = mnt_context_set_fstype(self->cxt, fstype);
     462  	if (rc) {
     463  		UL_RaiseExc(-rc);
     464  		return -1;
     465  	}
     466  	return 0;
     467  }
     468  
     469  static int Context_set_options(ContextObjext *self, PyObject *value, void *closure __attribute__((unused)))
     470  {
     471  	char * options;
     472  	int rc = 0;
     473  
     474  	if (!value) {
     475  		PyErr_SetString(PyExc_TypeError, NODEL_ATTR);
     476  		return -1;
     477  	}
     478  	if (!(options = pystos(value)))
     479  		return -1;
     480  
     481  	rc = mnt_context_set_options(self->cxt, options);
     482  	if (rc) {
     483  		UL_RaiseExc(-rc);
     484  		return -1;
     485  	}
     486  	return 0;
     487  }
     488  
     489  static int Context_set_fstype_pattern(ContextObjext *self, PyObject *value, void *closure __attribute__((unused)))
     490  {
     491  	char * fstype_pattern;
     492  	int rc = 0;
     493  
     494  	if (!value) {
     495  		PyErr_SetString(PyExc_TypeError, NODEL_ATTR);
     496  		return -1;
     497  	}
     498  	if (!(fstype_pattern = pystos(value)))
     499  		return -1;
     500  
     501  	rc = mnt_context_set_fstype_pattern(self->cxt, fstype_pattern);
     502  	if (rc) {
     503  		UL_RaiseExc(-rc);
     504  		return -1;
     505  	}
     506  	return 0;
     507  }
     508  
     509  static int Context_set_options_pattern(ContextObjext *self, PyObject *value, void *closure __attribute__((unused)))
     510  {
     511  	char * options_pattern;
     512  	int rc = 0;
     513  
     514  	if (!value) {
     515  		PyErr_SetString(PyExc_TypeError, NODEL_ATTR);
     516  		return -1;
     517  	}
     518  	if (!(options_pattern = pystos(value)))
     519  		return -1;
     520  
     521  	rc = mnt_context_set_options_pattern(self->cxt, options_pattern);
     522  	if (rc) {
     523  		UL_RaiseExc(-rc);
     524  		return -1;
     525  	}
     526  	return 0;
     527  }
     528  
     529  static int Context_set_fs(ContextObjext *self, PyObject *value, void *closure __attribute__((unused)))
     530  {
     531  	FsObject *fs;
     532  
     533  	if (!value) {
     534  		PyErr_SetString(PyExc_TypeError, NODEL_ATTR);
     535  		return -1;
     536  	}
     537  	if (!PyArg_Parse(value, "O!", &FsType, &fs)) {
     538  		PyErr_SetString(PyExc_TypeError, ARG_ERR);
     539  		return -1;
     540  	}
     541  	Py_INCREF(fs);
     542  	Py_XDECREF(mnt_context_get_fs_userdata(self->cxt));
     543  
     544  	return mnt_context_set_fs(self->cxt, fs->fs);
     545  }
     546  
     547  static int Context_set_fstab(ContextObjext *self, PyObject *value, void *closure __attribute__((unused)))
     548  {
     549  	TableObject *fstab;
     550  
     551  	if (!value) {
     552  		PyErr_SetString(PyExc_TypeError, NODEL_ATTR);
     553  		return -1;
     554  	}
     555  	if (!PyArg_Parse(value, "O!", &TableType, &fstab)) {
     556  		PyErr_SetString(PyExc_TypeError, ARG_ERR);
     557  		return -1;
     558  	}
     559  	Py_INCREF(fstab);
     560  	Py_XDECREF(mnt_context_get_fstab_userdata(self->cxt));
     561  
     562  	return mnt_context_set_fstab(self->cxt, fstab->tab);
     563  }
     564  
     565  static int Context_set_optsmode(ContextObjext *self, PyObject *value, void *closure __attribute__((unused)))
     566  {
     567  	int optsmode;
     568  
     569  	if (!value) {
     570  		PyErr_SetString(PyExc_TypeError, NODEL_ATTR);
     571  		return -1;
     572  	}
     573  	if (!PyLong_Check(value)) {
     574  		PyErr_SetString(PyExc_TypeError, ARG_ERR);
     575  		return -1;
     576  	}
     577  	optsmode = PyLong_AsLong(value);
     578  	return mnt_context_set_optsmode(self->cxt, optsmode);
     579  }
     580  
     581  static int Context_set_syscall_status(ContextObjext *self, PyObject *value, void *closure __attribute__((unused)))
     582  {
     583  	int syscall_status;
     584  
     585  	if (!value) {
     586  		PyErr_SetString(PyExc_TypeError, NODEL_ATTR);
     587  		return -1;
     588  	}
     589  	if (!PyLong_Check(value)) {
     590  		PyErr_SetString(PyExc_TypeError, ARG_ERR);
     591  		return -1;
     592  	}
     593  	syscall_status = PyLong_AsLong(value);
     594  	return mnt_context_set_syscall_status(self->cxt, syscall_status);
     595  }
     596  
     597  static int Context_set_user_mflags(ContextObjext *self, PyObject *value, void *closure __attribute__((unused)))
     598  {
     599  	unsigned long flags;
     600  
     601  	if (!value) {
     602  		PyErr_SetString(PyExc_TypeError, NODEL_ATTR);
     603  		return -1;
     604  	}
     605  	if (!PyLong_Check(value)) {
     606  		PyErr_SetString(PyExc_TypeError, ARG_ERR);
     607  		return -1;
     608  	}
     609  	flags = PyLong_AsUnsignedLong(value);
     610  	return mnt_context_set_mflags(self->cxt, flags);
     611  
     612  }
     613  
     614  static int Context_set_mflags(ContextObjext *self, PyObject *value, void *closure __attribute__((unused)))
     615  {
     616  	unsigned long flags;
     617  
     618  	if (!value) {
     619  		PyErr_SetString(PyExc_TypeError, NODEL_ATTR);
     620  		return -1;
     621  	}
     622  	if (!PyLong_Check(value)) {
     623  		PyErr_SetString(PyExc_TypeError, ARG_ERR);
     624  		return -1;
     625  	}
     626  	flags = PyLong_AsUnsignedLong(value);
     627  	return mnt_context_set_mflags(self->cxt, flags);
     628  }
     629  
     630  /* returns a flags integer (behavior differs from C API) */
     631  static PyObject *Context_get_mflags(ContextObjext *self)
     632  {
     633  	unsigned long flags;
     634  
     635  	PyObject *result;
     636  	mnt_context_get_mflags(self->cxt, &flags);
     637  	result = Py_BuildValue("k", flags);
     638  
     639  	if (!result)
     640  		PyErr_SetString(PyExc_RuntimeError, CONSTRUCT_ERR);
     641  	return result;
     642  
     643  }
     644  /* returns a flags integer (behavior differs from C API) */
     645  static PyObject *Context_get_user_mflags(ContextObjext *self)
     646  {
     647  	unsigned long flags;
     648  
     649  	PyObject *result;
     650  	mnt_context_get_user_mflags(self->cxt, &flags);
     651  	result = Py_BuildValue("k", flags);
     652  
     653  	if (!result)
     654  		PyErr_SetString(PyExc_RuntimeError, CONSTRUCT_ERR);
     655  	return result;
     656  
     657  }
     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" \
     661  	"\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" \
     664  	"\n" \
     665  	"Returns self or raises an exception in case of an error."
     666  static PyObject *Context_reset_status(ContextObjext *self)
     667  {
     668  	int rc = mnt_context_reset_status(self->cxt);
     669  
     670  	return rc ? UL_RaiseExc(-rc) : UL_IncRef(self);
     671  }
     672  
     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)
     676  {
     677  	return PyBool_FromLong(mnt_context_is_fake(self->cxt));
     678  }
     679  
     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)
     683  {
     684  	return PyBool_FromLong(mnt_context_is_force(self->cxt));
     685  }
     686  
     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)
     690  {
     691  	return PyBool_FromLong(mnt_context_is_lazy(self->cxt));
     692  }
     693  
     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)
     697  {
     698  	return PyBool_FromLong(mnt_context_is_nomtab(self->cxt));
     699  }
     700  
     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" \
     704  	"\n" \
     705  	"Returns self on success, raises an exception in case of error."
     706  static PyObject *Context_is_rdonly_umount(ContextObjext *self)
     707  {
     708  	int rc = mnt_context_is_rdonly_umount(self->cxt);
     709  	return rc ? UL_RaiseExc(-rc) : UL_IncRef(self);
     710  }
     711  
     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)
     715  {
     716  	return PyBool_FromLong(mnt_context_is_restricted(self->cxt));
     717  }
     718  
     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)
     722  {
     723  	return PyBool_FromLong(mnt_context_is_sloppy(self->cxt));
     724  }
     725  
     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)
     729  {
     730  	return PyBool_FromLong(mnt_context_is_verbose(self->cxt));
     731  }
     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)
     735  {
     736  	char *kwlist[] = {"fs", "mounted", NULL};
     737  	FsObject *fs;
     738  	int mounted;
     739  
     740  	if (PyArg_ParseTupleAndKeywords(args, kwds, "O!i", kwlist,
     741  					&FsType, &fs, &mounted)) {
     742  		PyErr_SetString(PyExc_TypeError, ARG_ERR);
     743  		return NULL;
     744  	}
     745  	return PyBool_FromLong(mnt_context_is_fs_mounted(self->cxt, fs->fs, &mounted));
     746  }
     747  
     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)
     751  {
     752  	return PyBool_FromLong(mnt_context_is_child(self->cxt));
     753  }
     754  
     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)
     758  {
     759  	return PyBool_FromLong(mnt_context_is_fork(self->cxt));
     760  }
     761  
     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)
     765  {
     766  	return PyBool_FromLong(mnt_context_is_parent(self->cxt));
     767  }
     768  
     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)
     772  {
     773  	return PyBool_FromLong(mnt_context_is_loopdel(self->cxt));
     774  }
     775  
     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)
     779  {
     780  	return PyBool_FromLong(mnt_context_is_nocanonicalize(self->cxt));
     781  }
     782  
     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)
     786  {
     787  	return PyBool_FromLong(mnt_context_is_nohelpers(self->cxt));
     788  }
     789  
     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)
     793  {
     794  	return PyBool_FromLong(mnt_context_syscall_called(self->cxt));
     795  }
     796  
     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)
     800  {
     801  	return PyBool_FromLong(mnt_context_is_swapmatch(self->cxt));
     802  }
     803  
     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)
     807  {
     808  	return PyBool_FromLong(mnt_context_tab_applied(self->cxt));
     809  }
     810  
     811  #define Context_apply_fstab_HELP "apply_fstab()\n\n" \
     812  	"This function is optional.\n" \
     813  	"\n" \
     814  	"Returns self or raises an exception in case of an error."
     815  static PyObject *Context_apply_fstab(ContextObjext *self)
     816  {
     817  	int rc = mnt_context_apply_fstab(self->cxt);
     818  	return rc ? UL_RaiseExc(-rc) : UL_IncRef(self);
     819  }
     820  
     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)
     824  {
     825  	return PyBool_FromLong(mnt_context_helper_executed(self->cxt));
     826  }
     827  
     828  static PyObject *Context_get_source(ContextObjext *self)
     829  {
     830  	return PyObjectResultStr(mnt_context_get_source(self->cxt));
     831  }
     832  
     833  static PyObject *Context_get_target(ContextObjext *self)
     834  {
     835  	return PyObjectResultStr(mnt_context_get_target(self->cxt));
     836  }
     837  
     838  static PyObject *Context_get_options(ContextObjext *self)
     839  {
     840  	return PyObjectResultStr(mnt_context_get_options(self->cxt));
     841  }
     842  
     843  static PyObject *Context_get_fstype(ContextObjext *self)
     844  {
     845  	return PyObjectResultStr(mnt_context_get_fstype(self->cxt));
     846  }
     847  
     848  static PyObject *Context_get_fs(ContextObjext *self)
     849  {
     850  	return PyObjectResultFs(mnt_context_get_fs(self->cxt));
     851  }
     852  
     853  static PyObject *Context_get_fstab(ContextObjext *self)
     854  {
     855  	struct libmnt_table *tab = NULL;
     856  
     857  	if (mnt_context_get_fstab(self->cxt, &tab) != 0 || !tab)
     858  		return NULL;
     859  	return PyObjectResultTab(tab);
     860  }
     861  
     862  static PyObject *Context_get_mtab(ContextObjext *self)
     863  {
     864  	struct libmnt_table *tab = NULL;
     865  
     866  	if (mnt_context_get_mtab(self->cxt, &tab) != 0 || !tab)
     867  		return NULL;
     868  	return PyObjectResultTab(tab);
     869  }
     870  
     871  static PyObject *Context_get_optsmode(ContextObjext *self)
     872  {
     873  	return PyObjectResultInt(mnt_context_get_optsmode(self->cxt));
     874  }
     875  
     876  static PyObject *Context_get_status(ContextObjext *self)
     877  {
     878  	return PyObjectResultInt(mnt_context_get_status(self->cxt));
     879  }
     880  
     881  static PyObject *Context_get_syscall_errno(ContextObjext *self)
     882  {
     883  	return PyObjectResultInt(mnt_context_get_syscall_errno(self->cxt));
     884  }
     885  
     886  #define Context_do_mount_HELP "do_mount()\n\n" \
     887  	"Call mount(2) or mount.type helper. Unnecessary for Cxt.mount().\n" \
     888  	"\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" \
     891  	"\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" \
     895  	"\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" \
     898  	"\n" \
     899  	"Check Cxt.status after error!\n" \
     900  	"\n" \
     901  	"Returns self on success or an exception in case of other errors."
     902  static PyObject *Context_do_mount(ContextObjext *self)
     903  {
     904  	int rc = mnt_context_do_mount(self->cxt);
     905  	return rc ? UL_RaiseExc(rc < 0 ? -rc : rc) : UL_IncRef(self);
     906  }
     907  
     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" \
     911  	"\n" \
     912  	"See also Cxt.disable_helpers().\n" \
     913  	"\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" \
     916  	"\n" \
     917  	"Check Cxt.status after error!\n" \
     918  	"\n" \
     919  	"Returns self on success or an exception in case of other errors."
     920  static PyObject *Context_do_umount(ContextObjext *self)
     921  {
     922  	int rc = mnt_context_do_umount(self->cxt);
     923  	return rc ? UL_RaiseExc(rc < 0 ? -rc : rc) : UL_IncRef(self);
     924  }
     925  
     926  #define Context_mount_HELP "mount()\n\n" \
     927  	"High-level, mounts filesystem by mount(2) or fork()+exec(/sbin/mount.type).\n" \
     928  	"\n" \
     929  	"This is similar to:\n" \
     930  	"\n" \
     931  	"Cxt.prepare_mount();\n" \
     932  	"Cxt.do_mount();\n" \
     933  	"Cxt.finalize_mount();\n" \
     934  	"\n" \
     935  	"See also Cxt.disable_helper().\n" \
     936  	"\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" \
     941  	"\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" \
     944  	"\n" \
     945  	"Check Cxt.status after error!\n" \
     946  	"\n" \
     947  	"Returns self on success or an exception in case of other errors."
     948  static PyObject *Context_mount(ContextObjext *self)
     949  {
     950  	int rc = mnt_context_mount(self->cxt);
     951  	return rc ? UL_RaiseExc(rc < 0 ? -rc : rc) : UL_IncRef(self);
     952  }
     953  
     954  #define Context_umount_HELP "umount()\n\n" \
     955  	"High-level, umounts filesystem by umount(2) or fork()+exec(/sbin/umount.type).\n" \
     956  	"\n" \
     957  	"This is similar to:\n" \
     958  	"\n" \
     959  	"Cxt.prepare_umount();\n" \
     960  	"Cxt.do_umount();\n" \
     961  	"Cxt.finalize_umount();\n" \
     962  	"\n" \
     963  	"See also Cxt.disable_helpers().\n" \
     964  	"\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" \
     967  	"\n" \
     968  	"Check Cxt.status after error!\n" \
     969  	"\n" \
     970  	"Returns self on success or an exception in case of other errors."
     971  static PyObject *Context_umount(ContextObjext *self)
     972  {
     973  	int rc = mnt_context_umount(self->cxt);
     974  	return rc ? UL_RaiseExc(rc < 0 ? -rc : rc) : UL_IncRef(self);
     975  }
     976  
     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" \
     980  	"\n" \
     981  	"Returns self or raises an exception in case of an error."
     982  static PyObject *Context_finalize_mount(ContextObjext *self)
     983  {
     984  	int rc = mnt_context_finalize_mount(self->cxt);
     985  	return rc ? UL_RaiseExc(-rc) : UL_IncRef(self);
     986  }
     987  
     988  #define Context_prepare_umount_HELP "prepare_umount()\n\n" \
     989  	"Prepare context for umounting, unnecessary for Cxt.umount().\n" \
     990  	"\n" \
     991  	"Returns self or raises an exception in case of an error."
     992  static PyObject *Context_prepare_umount(ContextObjext *self)
     993  {
     994  	int rc = mnt_context_prepare_umount(self->cxt);
     995  	return rc ? UL_RaiseExc(-rc) : UL_IncRef(self);
     996  }
     997  
     998  #define Context_prepare_mount_HELP "prepare_mount()\n\n" \
     999  	"Prepare context for mounting, unnecessary for Cxt.mount().\n" \
    1000  	"\n" \
    1001  	"Returns self or raises an exception in case of an error."
    1002  static PyObject *Context_prepare_mount(ContextObjext *self)
    1003  {
    1004  	int rc = mnt_context_prepare_mount(self->cxt);
    1005  	return rc ? UL_RaiseExc(-rc) : UL_IncRef(self);
    1006  }
    1007  
    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" \
    1011  	"\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)
    1014  {
    1015  	int rc = mnt_context_finalize_umount(self->cxt);
    1016  	return rc ? UL_RaiseExc(-rc) : UL_IncRef(self);
    1017  }
    1018  
    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)
    1022  {
    1023  	int rc;
    1024  	char *kwlist[] = { "tgt", "pfs", NULL };
    1025  	char *tgt = NULL;
    1026  	FsObject *fs;
    1027  
    1028  	if (!PyArg_ParseTupleAndKeywords(args, kwds, "sO!", kwlist, &tgt, &FsType, &fs)) {
    1029  		PyErr_SetString(PyExc_TypeError, ARG_ERR);
    1030  		return NULL;
    1031  	}
    1032  
    1033  	rc = mnt_context_find_umount_fs(self->cxt, tgt, &fs->fs);
    1034  	return rc ? UL_RaiseExc(-rc) : UL_IncRef(self);
    1035  }
    1036  
    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)
    1040  {
    1041  	int rc;
    1042  	char *kwlist[] = {"optstr", NULL};
    1043  	char *optstr = NULL;
    1044  
    1045  	if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &optstr)) {
    1046  		PyErr_SetString(PyExc_TypeError, ARG_ERR);
    1047  		return NULL;
    1048  	}
    1049  
    1050  	rc = mnt_context_append_options(self->cxt, optstr);
    1051  	return rc ? UL_RaiseExc(-rc) : UL_IncRef(self);
    1052  }
    1053  
    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" \
    1058  	"\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)
    1061  {
    1062  	int rc;
    1063  	int c;
    1064  	char *arg;
    1065  	char *kwlist[] = { "c", "arg", NULL };
    1066  
    1067  	if (!PyArg_ParseTupleAndKeywords(args, kwds, "is", kwlist, &c, &arg)) {
    1068  		PyErr_SetString(PyExc_TypeError, ARG_ERR);
    1069  		return NULL;
    1070  	}
    1071  
    1072  	rc = mnt_context_helper_setopt(self->cxt, c, arg);
    1073  	return rc ? UL_RaiseExc(-rc) : UL_IncRef(self);
    1074  }
    1075  
    1076  #define Context_init_helper_HELP "init_helper(action, flags)\n\n" \
    1077  	"This function informs libmount that it is used from [u]mount.type helper.\n" \
    1078  	"\n" \
    1079  	"The function also calls Cxt.disable_helpers() to avoid calling\n" \
    1080  	"mount.type helpers recursively. If you really want to call another\n" \
    1081  	"mount.type helper from your helper then you have to explicitly enable this\n" \
    1082  	"feature by:\n" \
    1083  	"\n" \
    1084  	"Cxt.disable_helpers(False);\n" \
    1085  	"\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)
    1088  {
    1089  	int rc;
    1090  	int action, flags;
    1091  	char *kwlist[] = {"action", "flags", NULL};
    1092  
    1093  	if (!PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwlist, &action, &flags)) {
    1094  		PyErr_SetString(PyExc_TypeError, ARG_ERR);
    1095  		return NULL;
    1096  	}
    1097  
    1098  	rc = mnt_context_init_helper(self->cxt, action, flags);
    1099  	return rc ? UL_RaiseExc(-rc) : UL_IncRef(self);
    1100  }
    1101  
    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},
    1119  	{NULL}
    1120  };
    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},
    1167  	{NULL}
    1168  };
    1169  
    1170  static PyObject *Context_repr(ContextObjext *self)
    1171  {
    1172  	return PyUnicode_FromFormat("<libmount.Context object at %p, restricted=%s>",
    1173  			self, mnt_context_is_restricted(self->cxt) ? "True" : "False");
    1174  }
    1175  
    1176  PyTypeObject ContextType = {
    1177  	PyVarObject_HEAD_INIT(NULL, 0)
    1178  	"libmount.Context", /*tp_name*/
    1179  	sizeof(ContextObjext), /*tp_basicsize*/
    1180  	0, /*tp_itemsize*/
    1181  	(destructor)Context_dealloc, /*tp_dealloc*/
    1182  	0, /*tp_print*/
    1183  	NULL, /*tp_getattr*/
    1184  	NULL, /*tp_setattr*/
    1185  	NULL, /*tp_compare*/
    1186  	(reprfunc) Context_repr,
    1187  	NULL, /*tp_as_number*/
    1188  	NULL, /*tp_as_sequence*/
    1189  	NULL, /*tp_as_mapping*/
    1190  	NULL, /*tp_hash */
    1191  	NULL, /*tp_call*/
    1192  	NULL, /*tp_str*/
    1193  	NULL, /*tp_getattro*/
    1194  	NULL, /*tp_setattro*/
    1195  	NULL, /*tp_as_buffer*/
    1196  	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
    1197  	Context_HELP, /* tp_doc */
    1198  	NULL, /* tp_traverse */
    1199  	NULL, /* tp_clear */
    1200  	NULL, /* tp_richcompare */
    1201  	0, /* tp_weaklistoffset */
    1202  	NULL, /* tp_iter */
    1203  	NULL, /* tp_iternext */
    1204  	Context_methods, /* tp_methods */
    1205  	Context_members, /* tp_members */
    1206  	Context_getseters, /* tp_getset */
    1207  	NULL, /* tp_base */
    1208  	NULL, /* tp_dict */
    1209  	NULL, /* tp_descr_get */
    1210  	NULL, /* tp_descr_set */
    1211  	0, /* tp_dictoffset */
    1212  	(initproc)Context_init, /* tp_init */
    1213  	NULL, /* tp_alloc */
    1214  	Context_new, /* tp_new */
    1215  };
    1216  
    1217  void Context_AddModuleObject(PyObject *mod)
    1218  {
    1219  	if (PyType_Ready(&ContextType) < 0)
    1220  		return;
    1221  
    1222  	DBG(CXT, pymnt_debug("add to module"));
    1223  
    1224  	Py_INCREF(&ContextType);
    1225  	PyModule_AddObject(mod, "Context", (PyObject *)&ContextType);
    1226  }
    1227  
    1228