static int update_remove_entry(struct libmnt_update *upd, struct libmnt_lock *lc) { struct libmnt_table *tb; int rc = 0; assert(upd); assert(upd->target); DBG(UPDATE, mnt_debug_h(upd, "%s: remove entry", upd->filename)); if (lc) rc = mnt_lock_file(lc); if (rc) return rc; tb = __mnt_new_table_from_file(upd->filename, upd->userspace_only ? MNT_FMT_UTAB : MNT_FMT_MTAB); if (tb) { struct libmnt_fs *rem = mnt_table_find_target(tb, upd->target, MNT_ITER_BACKWARD); if (rem) { mnt_table_remove_fs(tb, rem); rc = update_table(upd, tb); mnt_free_fs(rem); } } if (lc) mnt_unlock_file(lc); mnt_free_table(tb); return rc; }
/** * mnt_unref_fs: * @fs: fs pointer * * De-increments reference counter, on zero the @fs is automatically * deallocated by mnt_free_fs(). */ void mnt_unref_fs(struct libmnt_fs *fs) { if (fs) { fs->refcount--; /*DBG(FS, ul_debugobj(fs, "unref=%d", fs->refcount));*/ if (fs->refcount <= 0) mnt_free_fs(fs); } }
/** * mnt_table_parse_stream: * @tb: tab pointer * @f: file stream * @filename: filename used for debug and error messages * * Returns: 0 on success, negative number in case of error. */ int mnt_table_parse_stream(struct libmnt_table *tb, FILE *f, const char *filename) { int nlines = 0; int rc = -1; int flags = 0; pid_t tid = -1; assert(tb); assert(f); assert(filename); DBG(TAB, mnt_debug_h(tb, "%s: start parsing (%d entries)", filename, mnt_table_get_nents(tb))); /* necessary for /proc/mounts only, the /proc/self/mountinfo * parser sets the flag properly */ if (filename && strcmp(filename, _PATH_PROC_MOUNTS) == 0) flags = MNT_FS_KERNEL; while (!feof(f)) { struct libmnt_fs *fs = mnt_new_fs(); if (!fs) goto err; rc = mnt_table_parse_next(tb, f, fs, filename, &nlines); if (!rc && tb->fltrcb && tb->fltrcb(fs, tb->fltrcb_data)) rc = 1; /* filtered out by callback... */ if (!rc) { rc = mnt_table_add_fs(tb, fs); fs->flags |= flags; if (tb->fmt == MNT_FMT_MOUNTINFO && filename) { if (tid == -1) tid = path_to_tid(filename); fs->tid = tid; } } if (rc) { mnt_free_fs(fs); if (rc == 1) continue; /* recoverable error */ if (feof(f)) break; goto err; /* fatal error */ } } DBG(TAB, mnt_debug_h(tb, "%s: stop parsing (%d entries)", filename, mnt_table_get_nents(tb))); return 0; err: DBG(TAB, mnt_debug_h(tb, "%s: parse error (rc=%d)", filename, rc)); return rc; }
static struct libmnt_fs *add_dummy_fs(const char *device) { struct libmnt_fs *fs = mnt_new_fs(); if (fs && mnt_fs_set_source(fs, device) == 0 && mnt_table_add_fs(fstab, fs) == 0) return fs; mnt_free_fs(fs); err(FSCK_EX_ERROR, _("failed to setup description for %s"), device); }
/** * mnt_free_update: * @upd: update * * Deallocates struct libmnt_update handler. */ void mnt_free_update(struct libmnt_update *upd) { if (!upd) return; DBG(UPDATE, mnt_debug_h(upd, "free")); mnt_free_fs(upd->fs); mnt_free_table(upd->mountinfo); free(upd->target); free(upd->filename); free(upd); }
static int test_remount(struct libmnt_test *ts, int argc, char *argv[]) { struct libmnt_fs *fs = mnt_new_fs(); int rc; if (argc < 3) return -1; mnt_fs_set_target(fs, argv[1]); mnt_fs_set_options(fs, argv[2]); rc = update(NULL, fs, MS_REMOUNT); mnt_free_fs(fs); return rc; }
static int test_move(struct libmnt_test *ts, int argc, char *argv[]) { struct libmnt_fs *fs = mnt_new_fs(); int rc; if (argc < 3) return -1; mnt_fs_set_source(fs, argv[1]); mnt_fs_set_target(fs, argv[2]); rc = update(NULL, fs, MS_MOVE); mnt_free_fs(fs); return rc; }
/** * mnt_reset_table: * @tb: tab pointer * * Dealocates all entries (filesystems) from the table * * Returns: 0 on success or negative number in case of error. */ int mnt_reset_table(struct libmnt_table *tb) { if (!tb) return -EINVAL; DBG(TAB, mnt_debug_h(tb, "reset")); while (!list_empty(&tb->ents)) { struct libmnt_fs *fs = list_entry(tb->ents.next, struct libmnt_fs, ents); mnt_free_fs(fs); } tb->nents = 0; return 0; }
static int test_add(struct libmnt_test *ts, int argc, char *argv[]) { struct libmnt_fs *fs = mnt_new_fs(); int rc; if (argc < 5 || !fs) return -1; mnt_fs_set_source(fs, argv[1]); mnt_fs_set_target(fs, argv[2]); mnt_fs_set_fstype(fs, argv[3]); mnt_fs_set_options(fs, argv[4]); rc = update(NULL, fs, 0); mnt_free_fs(fs); return rc; }
int main(const int argc, const char* argv[]) { if (argc == 2) { if (strcmp(argv[1], "--verbose") == 0) { verbose_mode = 1; } } prepare(); clearSupplementaryGroups(); selfCheck(); struct libmnt_table* mt = mnt_new_table_from_file("/opt/xware_desktop/mounts"); if (mt == NULL) { fprintf(stderr, "mnt_new_table_from_file failed.\n"); exit(EXIT_FAILURE); } struct libmnt_iter* itr = mnt_new_iter(MNT_ITER_FORWARD); struct libmnt_fs* fs = NULL; while(1) { int tmp = mnt_table_find_next_fs(mt, itr, &matchAll, NULL, &fs); if (tmp < 0) { // error fprintf(stderr, "mnt_table_find_next_fs failed.\n"); break; } else { if (tmp == 1) { // reach EOF break; } const char* target = mnt_fs_get_target(fs); if (target == NULL) { fprintf(stderr, "mnt_fs_get_target failed.\n"); } else { printf("%s%s%s\n", BOLD, target, NOSTYLE); printf("================================\n"); if (checkDirXPermissions(target)) { checkTargetDirPermissions(target); } printf("\n"); } } } printf("%s", NOSTYLE); mnt_free_fs(fs); mnt_free_iter(itr); mnt_free_table(mt); return 0; }
/* * See if device has been mounted by looking in mount table. If so, set * device name and mount point name, and return 1, otherwise return 0. */ static int device_get_mountpoint(char **devname, char **mnt) { struct libmnt_fs *fs; int rc; *mnt = NULL; if (!mtab) { mtab = mnt_new_table(); if (!mtab) err(EXIT_FAILURE, _("failed to initialize libmount table")); cache = mnt_new_cache(); mnt_table_set_cache(mtab, cache); if (p_option) rc = mnt_table_parse_file(mtab, _PATH_PROC_MOUNTINFO); else rc = mnt_table_parse_mtab(mtab, NULL); if (rc) err(EXIT_FAILURE, _("failed to parse mount table")); } fs = mnt_table_find_source(mtab, *devname, MNT_ITER_BACKWARD); if (!fs) { /* maybe 'devname' is mountpoint rather than a real device */ fs = mnt_table_find_target(mtab, *devname, MNT_ITER_BACKWARD); if (fs) { free(*devname); *devname = xstrdup(mnt_fs_get_source(fs)); } } if (fs) { *mnt = xstrdup(mnt_fs_get_target(fs)); /* We'll call umount(), so remove the filesystem from the table * to avoid duplicate results in the next device_get_mountpoint() * call */ mnt_free_fs(fs); } return *mnt ? 0 : -1; }
static inline void mnt_free_fsp(struct libmnt_fs **itr) { if (*itr) mnt_free_fs(*itr); *itr=NULL; }
/* * Allocates utab entry (upd->fs) for mount/remount. This function should be * called *before* mount(2) syscall. The @fs is used as a read-only template. * * Returns: 0 on success, negative number on error, 1 if utabs update is * unnecessary. */ static int utab_new_entry(struct libmnt_update *upd, struct libmnt_fs *fs, unsigned long mountflags) { int rc = 0; const char *o = NULL, *a = NULL; char *u = NULL; assert(fs); assert(upd); assert(upd->fs == NULL); assert(!(mountflags & MS_MOVE)); DBG(UPDATE, mnt_debug("prepare utab entry")); o = mnt_fs_get_user_options(fs); a = mnt_fs_get_attributes(fs); upd->fs = NULL; if (o) { /* remove non-mtab options */ rc = mnt_optstr_get_options(o, &u, mnt_get_builtin_optmap(MNT_USERSPACE_MAP), MNT_NOMTAB); if (rc) goto err; } if (!u && !a) { DBG(UPDATE, mnt_debug("utab entry unnecessary (no options)")); return 1; } /* allocate the entry */ upd->fs = mnt_copy_fs(NULL, fs); if (!upd->fs) { rc = -ENOMEM; goto err; } rc = mnt_fs_set_options(upd->fs, u); if (rc) goto err; rc = mnt_fs_set_attributes(upd->fs, a); if (rc) goto err; if (!(mountflags & MS_REMOUNT)) { rc = set_fs_root(upd, fs, mountflags); if (rc) goto err; } free(u); DBG(UPDATE, mnt_debug("utab entry OK")); return 0; err: free(u); mnt_free_fs(upd->fs); upd->fs = NULL; return rc; }
/** * mnt_update_set_fs: * @upd: update handler * @mountflags: MS_* flags * @target: umount target, must be NULL for mount * @fs: mount filesystem description, must be NULL for umount * * Returns: <0 in case on error, 0 on success, 1 if update is unnecessary. */ int mnt_update_set_fs(struct libmnt_update *upd, unsigned long mountflags, const char *target, struct libmnt_fs *fs) { int rc; assert(upd); assert(target || fs); if (!upd) return -EINVAL; if ((mountflags & MS_MOVE) && (!fs || !mnt_fs_get_srcpath(fs))) return -EINVAL; if (target && fs) return -EINVAL; DBG(UPDATE, mnt_debug_h(upd, "reseting FS [fs=0x%p, target=%s, flags=0x%08lx]", fs, target, mountflags)); if (fs) { DBG(UPDATE, mnt_debug_h(upd, "FS template:")); DBG(UPDATE, mnt_fs_print_debug(fs, stderr)); } mnt_free_fs(upd->fs); free(upd->target); upd->ready = FALSE; upd->fs = NULL; upd->target = NULL; upd->mountflags = 0; if (mountflags & MS_PROPAGATION) return 1; upd->mountflags = mountflags; rc = mnt_update_set_filename(upd, NULL, 0); if (rc) { DBG(UPDATE, mnt_debug_h(upd, "no writable file available [rc=%d]", rc)); return rc; /* error or no file available (rc = 1) */ } if (target) { upd->target = strdup(target); if (!upd->target) return -ENOMEM; } else if (fs) { if (upd->userspace_only && !(mountflags & MS_MOVE)) { int rc = utab_new_entry(upd, fs, mountflags); if (rc) return rc; } else { upd->fs = mnt_copy_mtab_fs(fs); if (!upd->fs) return -ENOMEM; } } DBG(UPDATE, mnt_debug_h(upd, "ready")); upd->ready = TRUE; return 0; }