Beispiel #1
0
static int parse_fstab(void) {
        FILE *f;
        int r = 0;
        struct mntent *me;

        errno = 0;
        f = setmntent("/etc/fstab", "r");
        if (!f) {
                if (errno == ENOENT)
                        return 0;

                log_error("Failed to open /etc/fstab: %m");
                return -errno;
        }

        while ((me = getmntent(f))) {
                char _cleanup_free_ *where = NULL, *what = NULL;
                int k;

                what = fstab_node_to_udev_node(me->mnt_fsname);
                where = strdup(me->mnt_dir);
                if (!what || !where) {
                        r = log_oom();
                        goto finish;
                }

                if (is_path(where))
                        path_kill_slashes(where);

                log_debug("Found entry what=%s where=%s type=%s", what, where, me->mnt_type);

                if (streq(me->mnt_type, "swap"))
                        k = add_swap(what, me);
                else {
                        bool noauto, nofail, automount, isbind, isnetwork;

                        noauto = !!hasmntopt(me, "noauto");
                        nofail = !!hasmntopt(me, "nofail");
                        automount =
                                  hasmntopt(me, "comment=systemd.automount") ||
                                  hasmntopt(me, "x-systemd.automount");
                        isbind = mount_is_bind(me);
                        isnetwork = mount_is_network(me);

                        k = add_mount(what, where, me->mnt_type, me->mnt_opts,
                                     me->mnt_passno, false, noauto, nofail,
                                     automount, isbind, isnetwork,
                                     "/etc/fstab");
                }

                if (k < 0)
                        r = k;
        }

finish:
        endmntent(f);
        return r;
}
static bool mount_is_bind(struct mntent *me) {
        assert(me);

        return
                hasmntopt(me, "bind") ||
                streq(me->mnt_type, "bind") ||
                hasmntopt(me, "rbind") ||
                streq(me->mnt_type, "rbind");
}
Beispiel #3
0
/*
 * Setup mount profiles as described by snapd.
 *
 * This function reads /var/lib/snapd/mount/$security_tag.fstab as a fstab(5) file
 * and executes the mount requests described there.
 *
 * Currently only bind mounts are allowed. All bind mounts are read only by
 * default though the `rw` flag can be used.
 *
 * This function is called with the rootfs being "consistent" so that it is
 * either the core snap on an all-snap system or the core snap + punched holes
 * on a classic system.
 **/
static void sc_setup_mount_profiles(const char *security_tag)
{
	debug("%s: %s", __FUNCTION__, security_tag);

	FILE *f __attribute__ ((cleanup(sc_cleanup_endmntent))) = NULL;
	const char *mount_profile_dir = "/var/lib/snapd/mount";

	char profile_path[PATH_MAX];
	must_snprintf(profile_path, sizeof(profile_path), "%s/%s.fstab",
		      mount_profile_dir, security_tag);

	debug("opening mount profile %s", profile_path);
	f = setmntent(profile_path, "r");
	// it is ok for the file to not exist
	if (f == NULL && errno == ENOENT) {
		debug("mount profile %s doesn't exist, ignoring", profile_path);
		return;
	}
	// however any other error is a real error
	if (f == NULL) {
		die("cannot open %s", profile_path);
	}

	struct mntent *m = NULL;
	while ((m = getmntent(f)) != NULL) {
		debug("read mount entry\n"
		      "\tmnt_fsname: %s\n"
		      "\tmnt_dir: %s\n"
		      "\tmnt_type: %s\n"
		      "\tmnt_opts: %s\n"
		      "\tmnt_freq: %d\n"
		      "\tmnt_passno: %d",
		      m->mnt_fsname, m->mnt_dir, m->mnt_type,
		      m->mnt_opts, m->mnt_freq, m->mnt_passno);
		int flags = MS_BIND | MS_RDONLY | MS_NODEV | MS_NOSUID;
		debug("initial flags are: bind,ro,nodev,nosuid");
		if (strcmp(m->mnt_type, "none") != 0) {
			die("cannot honor mount profile, only 'none' filesystem type is supported");
		}
		if (hasmntopt(m, "bind") == NULL) {
			die("cannot honor mount profile, the bind mount flag is mandatory");
		}
		if (hasmntopt(m, "rw") != NULL) {
			flags &= ~MS_RDONLY;
		}
		if (mount(m->mnt_fsname, m->mnt_dir, NULL, flags, NULL) != 0) {
			die("cannot mount %s at %s with options %s",
			    m->mnt_fsname, m->mnt_dir, m->mnt_opts);
		}
	}
}
Beispiel #4
0
static int get_cgroup_flags(struct mntent *mntent)
{
	int flags = 0;


	if (hasmntopt(mntent, "ns"))
		flags |= CGROUP_NS_CGROUP;

	if (hasmntopt(mntent, "clone_children"))
		flags |= CGROUP_CLONE_CHILDREN;

	DEBUG("cgroup %s has flags 0x%x", mntent->mnt_dir, flags);
	return flags;
}
Beispiel #5
0
static int get_cgroup_flags(const char *mtab, int *flags)
{
        struct mntent *mntent;
        FILE *file = NULL;
        int err = -1;

        file = setmntent(mtab, "r");
        if (!file) {
                SYSERROR("failed to open %s", mtab);
		return -1;
        }

	*flags = 0;

        while ((mntent = getmntent(file))) {

		/* there is a cgroup mounted named "lxc" */
		if (!strcmp(mntent->mnt_fsname, "lxc") &&
		    !strcmp(mntent->mnt_type, "cgroup")) {

			if (hasmntopt(mntent, "ns"))
				*flags |= CGROUP_NS_CGROUP;

			if (hasmntopt(mntent, "clone_children"))
				*flags |= CGROUP_CLONE_CHILDREN;

			err = 0;
			break;
		}

		/* fallback to the first non-lxc cgroup found */
                if (!strcmp(mntent->mnt_type, "cgroup") && err) {

			if (hasmntopt(mntent, "ns"))
				*flags |= CGROUP_NS_CGROUP;

			if (hasmntopt(mntent, "clone_children"))
				*flags |= CGROUP_CLONE_CHILDREN;

			err = 0;
		}
        };

	DEBUG("cgroup flags is 0x%x", *flags);

        fclose(file);

        return err;
}
Beispiel #6
0
static int get_cgroup_mount(const char *subsystem, char *mnt)
{
	struct mntent *mntent;
	FILE *file = NULL;

	file = setmntent(MTAB, "r");
	if (!file) {
		SYSERROR("failed to open %s", MTAB);
		return -1;
	}

	while ((mntent = getmntent(file))) {

		if (strcmp(mntent->mnt_type, "cgroup"))
			continue;
		if (!subsystem || hasmntopt(mntent, subsystem)) {
			strcpy(mnt, mntent->mnt_dir);
			fclose(file);
			DEBUG("using cgroup mounted at '%s'", mnt);
			return 0;
		}
	};

	DEBUG("Failed to find cgroup for %s\n", subsystem ? subsystem : "(NULL)");

	fclose(file);

	return -1;
}
static bool mount_is_network(struct mntent *me) {
        assert(me);

        return
                hasmntopt(me, "_netdev") ||
                fstype_is_network(me->mnt_type);
}
Beispiel #8
0
/**
 * Get cgroup path for group cgroup_name in specified subsystem
 *
 * @param path where to write result
 */
void cgroup_get_path(const char *subsystem, const char *cgroup_name, char *path)
{
    struct mntent *mntent;
    FILE *file = NULL;

    file = setmntent(MTAB, "r");
    if (!file) {
        SYSERROR("failed to open %s", MTAB);
        throw -1;
    }

    while ((mntent = getmntent(file))) {
        if (strcmp(mntent->mnt_type, "cgroup"))
            continue;
        if (!subsystem || hasmntopt(mntent, subsystem)) {
            snprintf(path, MAXPATHLEN, "%s/%s", mntent->mnt_dir, cgroup_name);
            fclose(file);
            DEBUG("using cgroup at '%s'", path);
            return;
        }
    };

    DEBUG("Failed to find cgroup for %s\n", subsystem ? subsystem : "(NULL)");
    fclose(file);
    throw -1;
}
static bool mount_in_initrd(struct mntent *me) {
        assert(me);

        return
                hasmntopt(me, "x-initrd.mount") ||
                streq(me->mnt_dir, "/usr");
}
Beispiel #10
0
int au_plink(char cwd[], int cmd, int begin_maint, int end_maint)
{
	int err, nbr;
	struct mntent ent;
	char **br;

	if (begin_maint)
		au_plink_maint(cwd);

	err = au_proc_getmntent(cwd, &ent);
	if (err)
		AuFin("no such mount point");

	if (hasmntopt(&ent, "noplink"))
		goto out; /* success */

#ifdef DEBUG
	//char a[] = "a,b,br:/tmp/br0=rw:/br1=ro";
	char a[] = "a,b,si=1,c";
	ent.mnt_opts = a;
#endif
	err = au_br(&br, &nbr, &ent);
	//printf("nbr %d\n", nbr);
	if (err)
		AuFin(NULL);

	err = do_plink(cwd, cmd, nbr, br);
	if (err)
		AuFin(NULL);

 out:
	if (end_maint)
		au_plink_maint(NULL);
	return err;
}
Beispiel #11
0
/* Check if a mount is a cgroup hierarchy for any subsystem.
 * Return the first subsystem found (or NULL if none).
 */
static char *mount_has_subsystem(const struct mntent *mntent)
{
	FILE *f;
	char *c, *ret = NULL;
	char line[MAXPATHLEN];

	/* read the list of subsystems from the kernel */
	f = fopen("/proc/cgroups", "r");
	if (!f)
		return 0;

	/* skip the first line, which contains column headings */
	if (!fgets(line, MAXPATHLEN, f))
		return 0;

	while (fgets(line, MAXPATHLEN, f)) {
		c = strchr(line, '\t');
		if (!c)
			continue;
		*c = '\0';

		ret = hasmntopt(mntent, line);
		if (ret)
			break;
	}

	fclose(f);
	return ret;
}
Beispiel #12
0
static int do_em_all(void)
{
	struct mntent *m;
	FILE *f;
	int err;

	f = setmntent("/etc/fstab", "r");
	if (f == NULL)
		bb_perror_msg_and_die("/etc/fstab");

	err = 0;
	while ((m = getmntent(f)) != NULL) {
		if (strcmp(m->mnt_type, MNTTYPE_SWAP) == 0) {
			/* swapon -a should ignore entries with noauto,
			 * but swapoff -a should process them */
			if (applet_name[5] != 'n'
			 || hasmntopt(m, MNTOPT_NOAUTO) == NULL
			) {
				err += swap_enable_disable(m->mnt_fsname);
			}
		}
	}

	if (ENABLE_FEATURE_CLEAN_UP)
		endmntent(f);

	return err;
}
Beispiel #13
0
int
VAttachPartitions(void)
{
    int errors = 0;
    FILE *mfd;
    struct mntent *mntent;

    if ((mfd = setmntent(MOUNTED, "r")) == NULL) {
	Log("Problems in getting mount entries(setmntent)\n");
	exit(-1);
    }
    while (mntent = getmntent(mfd)) {
	if (!hasmntopt(mntent, MNTOPT_RW))
	    continue;

	/* If we're going to always attach this partition, do it later. */
	if (VIsAlwaysAttach(mntent->mnt_dir))
	    continue;

	if (VCheckPartition(mntent->mnt_dir, mntent->mnt_fsname) < 0)
	    errors++;
    }

    endmntent(mfd);

    /* Process the always-attach partitions, if any. */
    VAttachPartitions2();

    return errors;
}
Beispiel #14
0
static int mount_find_discard(struct mntent *me, char **ret) {
        char *opt, *ans;
        size_t len;

        assert(me);
        assert(ret);

        opt = hasmntopt(me, "discard");
        if (!opt)
                return 0;

        opt += strlen("discard");

        if (*opt == ',' || *opt == '\0')
                ans = strdup("all");
        else {
                if (*opt != '=')
                        return -EINVAL;

                len = strcspn(opt + 1, ",");
                if (len == 0)
                        return -EINVAL;

                ans = strndup(opt + 1, len);
        }

        if (!ans)
                return -ENOMEM;

        *ret = ans;
        return 1;
}
Beispiel #15
0
static int mount_find_pri(struct mntent *me, int *ret) {
        char *end, *opt;
        unsigned long r;

        assert(me);
        assert(ret);

        opt = hasmntopt(me, "pri");
        if (!opt)
                return 0;

        opt += strlen("pri");

        if (*opt != '=')
                return -EINVAL;

        errno = 0;
        r = strtoul(opt + 1, &end, 10);
        if (errno > 0)
                return -errno;

        if (end == opt + 1 || (*end != ',' && *end != 0))
                return -EINVAL;

        *ret = (int) r;
        return 1;
}
Beispiel #16
0
/* Check if an ecryptfs private device or mount point is mounted.
 * Return 1 if a filesystem in mtab matches dev && mnt && sig.
 * Return 0 otherwise.
 */
int ecryptfs_private_is_mounted(char *dev, char *mnt, char *sig, int mounting) {
	FILE *fh = NULL;
	struct mntent *m = NULL;
	char *opt = NULL;
	int mounted;
#if 0   //sw.yoo_20120111 - do not use setmntent, hasmntopt, endmntent function
	if (asprintf(&opt, "ecryptfs_sig=%s", sig) < 0) {
		perror("asprintf");
		return 0;
	}
	fh = setmntent("/proc/mounts", "r");
	if (fh == NULL) {
		perror("setmntent");
		return 0;
	}
	mounted = 0;
	flockfile(fh);
	while ((m = getmntent(fh)) != NULL) {
		if (strcmp(m->mnt_type, "ecryptfs") != 0)
			/* Skip if this entry is not an ecryptfs mount */
			continue;
		if (mounting == 1) {
			/* If mounting, return "already mounted" if EITHER the
 			 * dev or the mnt dir shows up in mtab/mounts;
 			 * regardless of the signature of such mounts;
 			 */
			if (dev != NULL && strcmp(m->mnt_fsname, dev) == 0) {
				mounted = 1;
				break;
			}
			if (mnt != NULL && strcmp(m->mnt_dir, mnt) == 0) {
				mounted = 1;
				break;
			}
		} else {
			/* Otherwise, we're unmounting, and we need to be
			 * very conservative in finding a perfect match
			 * to unmount.  The device, mountpoint, and signature
			 * must *all* match perfectly.
			 */
			if (
			    strcmp(m->mnt_fsname, dev) == 0 &&
			    strcmp(m->mnt_dir, mnt) == 0 &&
			    hasmntopt(m, opt) != NULL
			) {
				mounted = 1;
				break;
			}
		}
	}
	endmntent(fh);
	if (opt != NULL)
		free(opt);
	return mounted;
#else
	return 0;
#endif
}
Beispiel #17
0
/*
 * This function constructs a new filesystem table (fs_tab[]) entry based on
 * an /etc/mnttab entry. When it returns, the new entry has been inserted
 * into fs_tab[].
 */
static int
construct_mt(struct mnttab *mt)
{
	struct	fstable	*nfte;

	/*
	 * Initialize fstable structure and make the standard entries.
	 */
	if ((nfte = fs_tab_init(mt->mnt_mountp, mt->mnt_fstype)) == NULL)
		return (1);

	/*
	 * See if this is served from another host.
	 * Testing the type is cheap; finding the hostname is not.
	 * At this point, we're using the REAL mnttab; since we're not
	 * allowed to mount ourself with "NFS", "NFS" must be remote.
	 * The automount will translate "nfs:self" to a lofs mount.
	 */
	if (strcmp(mt->mnt_fstype, MNTTYPE_AUTO) == 0 ||
	    strcmp(mt->mnt_fstype, MNTTYPE_NFS) == 0 ||
	    is_remote_src(mt->mnt_special) == REAL_REMOTE)
		nfte->remote = 1;
	else
		nfte->remote = 0;

	/* It's mounted now (by definition), so we don't have to remap it. */
	nfte->srvr_map = 0;
	nfte->mounted = 1;

	nfte->remote_name = strdup(mt->mnt_special);

	/*
	 * This checks the mount commands which establish the most
	 * basic level of access. Later further tests may be
	 * necessary to fully qualify this. We set this bit
	 * preliminarily because we have access to the mount data
	 * now.
	 */
	nfte->writeable = 0;	/* Assume read-only. */
	if (hasmntopt(mt, MNTOPT_RO) == NULL) {
		nfte->writeable = 1;
		if (!(nfte->remote))
			/*
			 * There's no network involved, so this
			 * assessment is confirmed.
			 */
			nfte->write_tested = 1;
	} else
		/* read-only is read-only */
		nfte->write_tested = 1;

	/* Is this coming to us from a server? */
	if (nfte->remote && !(nfte->writeable))
		nfte->served = 1;

	return (0);
}
Beispiel #18
0
/* Open a temporary file in an executable and writable mount point
   listed in the mounts file.  Subsequent calls with the same mounts
   keep searching for mount points in the same file.  Providing NULL
   as the mounts file closes the file.  */
static int
open_temp_exec_file_mnt (const char *mounts)
{
  static const char *last_mounts;
  static FILE *last_mntent;

  if (mounts != last_mounts)
    {
      if (last_mntent)
	endmntent (last_mntent);

      last_mounts = mounts;

      if (mounts)
	last_mntent = setmntent (mounts, "r");
      else
	last_mntent = NULL;
    }

  if (!last_mntent)
    return -1;

  for (;;)
    {
      int fd;
      struct mntent mnt;
      char buf[MAXPATHLEN * 3];

      if (getmntent_r (last_mntent, &mnt, buf, sizeof (buf)))
	return -1;

      if (hasmntopt (&mnt, "ro")
	  || hasmntopt (&mnt, "noexec")
	  || access (mnt.mnt_dir, W_OK))
	continue;

      fd = open_temp_exec_file_dir (mnt.mnt_dir);

      if (fd != -1)
	return fd;
    }
}
Beispiel #19
0
static int storage_enum(struct mntent *mount_entry, void* user_data)
{
	char *pStart = strstr(mount_entry->mnt_dir ,PLEXTALK_MOUNT_ROOT_STR);
	if(NULL != pStart){
		if(!strncmp(pStart, user_data, strlen(pStart))){
			readonly = hasmntopt (mount_entry, MNTOPT_RO) != NULL;
			return 1;
		}
	}
	return 0;
}
Beispiel #20
0
/* compute generic mount flags */
int
compute_mount_flags(mntent_t *mntp)
{
  struct opt_tab *opt;
  int flags;

  /* start: this must come first */
#ifdef MNT2_GEN_OPT_NEWTYPE
  flags = MNT2_GEN_OPT_NEWTYPE;
#else /* not MNT2_GEN_OPT_NEWTYPE */
  /* Not all machines have MNT2_GEN_OPT_NEWTYPE (HP-UX 9.01) */
  flags = 0;
#endif /* not MNT2_GEN_OPT_NEWTYPE */

#if 0 /* redundant? */
#if defined(MNT2_GEN_OPT_OVERLAY) && defined(MNTTAB_OPT_OVERLAY)
  /*
   * Overlay this amd mount (presumably on another amd which died
   * before and left the machine hung).  This will allow a new amd or
   * hlfsd to be remounted on top of another one.
   */
  if (hasmntopt(mntp, MNTTAB_OPT_OVERLAY)) {
    flags |= MNT2_GEN_OPT_OVERLAY;
    plog(XLOG_INFO, "using an overlay mount");
  }
#endif /* defined(MNT2_GEN_OVERLAY) && defined(MNTOPT_OVERLAY) */
#endif

#ifdef MNT_AUTOMOUNTED
  flags |= MNT_AUTOMOUNTED;
#endif

  /*
   * Crack basic mount options
   */
  for (opt = mnt_flags; opt->opt; opt++) {
    flags |= hasmntopt(mntp, opt->opt) ? opt->flag : 0;
  }

  return flags;
}
Beispiel #21
0
int
VAttachPartitions(void)
{
    int errors = 0;
    struct mnttab mnt;
    FILE *mntfile;

    if (!(mntfile = afs_fopen(MNTTAB, "r"))) {
	Log("Can't open %s\n", MNTTAB);
	perror(MNTTAB);
	exit(-1);
    }
    while (!getmntent(mntfile, &mnt)) {
	/* Ignore non ufs or non read/write partitions */
	/* but allow zfs too if we're in the NAMEI environment */
	if (
#ifdef AFS_NAMEI_ENV
	    (((strcmp(mnt.mnt_fstype, "ufs") &&
		strcmp(mnt.mnt_fstype, "zfs"))))
#else
	    (strcmp(mnt.mnt_fstype, "ufs") != 0)
#endif
	    || (strncmp(mnt.mnt_mntopts, "ro,ignore", 9) == 0))
	    continue;
	
	/* If we're going to always attach this partition, do it later. */
	if (VIsAlwaysAttach(mnt.mnt_mountp))
	    continue;

#ifndef AFS_NAMEI_ENV
	if (hasmntopt(&mnt, "logging") != NULL) {
	    Log("This program is compiled without AFS_NAMEI_ENV, and "
	        "partition %s is mounted with the 'logging' option. "
		"Using the inode fileserver backend with 'logging' UFS "
		"partitions causes volume corruption, so please either "
		"mount the partition without logging, or use the namei "
		"fileserver backend. Aborting...\n", mnt.mnt_mountp);
	    errors++;
	}
#endif /* !AFS_NAMEI_ENV */

	if (VCheckPartition(mnt.mnt_mountp, mnt.mnt_special) < 0)
	    errors++;
    }

    (void)fclose(mntfile);

    /* Process the always-attach partitions, if any. */
    VAttachPartitions2();

    return errors;
}
Beispiel #22
0
/*
 * Determines whether the "logdev" or "rtdev" mount options are
 * present for the given mount point.  If so, the value for each (a
 * device path) is returned in the pointers whose addresses are
 * provided.  The pointers are assigned NULL for an option not
 * present.  Note that the path buffers returned are allocated
 * dynamically and it is the caller's responsibility to free them.
 */
static int
fs_extract_mount_options(
	struct mntent	*mnt,
	char		**logp,
	char		**rtp)
{
	char		*fslog, *fsrt;

	/* Extract log device and realtime device from mount options */
	if ((fslog = hasmntopt(mnt, "logdev=")))
		fslog += 7;
	if ((fsrt = hasmntopt(mnt, "rtdev=")))
		fsrt += 6;

	/* Do this only after we've finished processing mount options */
	if (fslog) {
		fslog = strndup(fslog, strcspn(fslog, " ,"));
		if (!fslog)
			goto out_nomem;
	}
	if (fsrt) {
		fsrt = strndup(fsrt, strcspn(fsrt, " ,"));
		if (!fsrt) {
			free(fslog);
			goto out_nomem;
		}
	}
	*logp = fslog;
	*rtp = fsrt;

	return 0;

out_nomem:
	*logp = NULL;
	*rtp = NULL;
	fprintf(stderr, _("%s: unable to extract mount options for \"%s\"\n"),
		progname, mnt->mnt_dir);
	return ENOMEM;
}
Beispiel #23
0
int
VAttachPartitions(void)
{
    int errors = 0;
    struct mnttab mnt;
    FILE *mntfile;

    if (!(mntfile = afs_fopen(MNTTAB, "r"))) {
	Log("Can't open %s\n", MNTTAB);
	perror(MNTTAB);
	exit(-1);
    }
    while (!getmntent(mntfile, &mnt)) {
	int logging = 0;
	/* Ignore non ufs or non read/write partitions */
	/* but allow zfs too if we're in the NAMEI environment */
	if (
#ifdef AFS_NAMEI_ENV
	    (((strcmp(mnt.mnt_fstype, "ufs") &&
		strcmp(mnt.mnt_fstype, "zfs"))))
#else
	    (strcmp(mnt.mnt_fstype, "ufs") != 0)
#endif
	    || (strncmp(mnt.mnt_mntopts, "ro,ignore", 9) == 0))
	    continue;

	/* Skip this Partition? */
	if (VIsNeverAttach(mnt.mnt_mountp))
	    continue;

	/* If we're going to always attach this partition, do it later. */
	if (VIsAlwaysAttach(mnt.mnt_mountp, NULL))
	    continue;

#ifndef AFS_NAMEI_ENV
	if (hasmntopt(&mnt, "logging") != NULL) {
	    logging = 1;
	}
#endif /* !AFS_NAMEI_ENV */

	if (VCheckPartition(mnt.mnt_mountp, mnt.mnt_special, logging) < 0)
	    errors++;
    }

    (void)fclose(mntfile);

    /* Process the always-attach partitions, if any. */
    VAttachPartitions2();

    return errors;
}
Beispiel #24
0
static int get_cgroup_mount(const char *subsystem, char *mnt)
{
	struct mntent *mntent;
	char initcgroup[MAXPATHLEN];
	FILE *file = NULL;
	int ret, flags, err = -1;

	file = setmntent(MTAB, "r");
	if (!file) {
		SYSERROR("failed to open %s", MTAB);
		return -1;
	}

	while ((mntent = getmntent(file))) {
		if (strcmp(mntent->mnt_type, "cgroup"))
			continue;

		if (subsystem) {
			if (!hasmntopt(mntent, subsystem))
				continue;
		}
		else {
			if (!mount_has_subsystem(mntent))
				continue;
		}

		flags = get_cgroup_flags(mntent);
		ret = snprintf(mnt, MAXPATHLEN, "%s%s%s", mntent->mnt_dir,
			       get_init_cgroup(subsystem, NULL, initcgroup),
		               (flags & CGROUP_NS_CGROUP) ? "" : "/lxc");
		if (ret < 0 || ret >= MAXPATHLEN)
			goto fail;

		DEBUG("using cgroup mounted at '%s'", mnt);
		err = 0;
		goto out;
	};

fail:
	DEBUG("Failed to find cgroup for %s\n",
	      subsystem ? subsystem : "(NULL)");
out:
	endmntent(file);
	return err;
}
Beispiel #25
0
int misc_dev_mounted(const char *device) {
	struct mntent *mnt;
	
	/* Check for the "/" first to avoid any possible problem with 
	   reflecting the root fs info in mtab files. */
	if (misc_root_mounted(device) == 1) {
		return misc_file_ro("/") ? MF_RO : MF_RW;
	}
	
	/* Lookup the mount entry. */
	if ((mnt = misc_mntent(device)) == NULL) {
		return MF_NOT_MOUNTED;
	} else if (mnt == INVAL_PTR) {
		return 0;
	}

	return hasmntopt(mnt, MNTOPT_RO) ? MF_RO : MF_RW;
}
Beispiel #26
0
/*
 * get_init_cgroup: get the cgroup init is in.
 *  dsg: preallocated buffer to put the output in
 *  subsystem: the exact cgroup subsystem to look up
 *  mntent: a mntent (from getmntent) whose mntopts contains the
 *          subsystem to look up.
 *
 * subsystem and mntent can both be NULL, in which case we return
 * the first entry in /proc/1/cgroup.
 *
 * Returns a pointer to the answer, which may be "".
 */
static char *get_init_cgroup(const char *subsystem, struct mntent *mntent,
			     char *dsg)
{
	FILE *f;
	char *c, *c2;
	char line[MAXPATHLEN];

	*dsg = '\0';
	f = fopen("/proc/1/cgroup", "r");
	if (!f)
		return dsg;

	while (fgets(line, MAXPATHLEN, f)) {
		c = index(line, ':');
		if (!c)
			continue;
		c++;
		c2 = index(c, ':');
		if (!c2)
			continue;
		*c2 = '\0';
		c2++;
		if (!subsystem && !mntent)
			goto good;
		if (subsystem && strcmp(c, subsystem) != 0)
			continue;
		if (mntent && !hasmntopt(mntent, c))
			continue;
good:
		DEBUG("get_init_cgroup: found init cgroup for subsys %s at %s\n",
			subsystem, c2);
		strncpy(dsg, c2, MAXPATHLEN);
		c = &dsg[strlen(dsg)-1];
		if (*c == '\n')
			*c = '\0';
		goto found;
	}

found:
	fclose(f);
	return dsg;
}
int main (void)
{
	FILE * fichier;
	struct mntent * mntent;

	fichier = setmntent("/etc/fstab", "r");
	if (fichier == NULL)
		exit(EXIT_FAILURE);
	while (1) {
		mntent = getmntent(fichier);
		if (mntent == NULL)
			break;
		if (hasmntopt(mntent, "mand") != NULL)
			fprintf(stdout, "%s (%s)\n",
				mntent->mnt_fsname,
				mntent->mnt_dir);
	}
	endmntent(fichier);
	return EXIT_SUCCESS;
}
Beispiel #28
0
int main (int argc, char **argv)
{
	FILE *fp;
	struct mnttab mp;
	int ret;

	if (argc != 2)
		err_quit ("Usage: hasmntopt mount_option");

	if ((fp = fopen ("/etc/mnttab", "r")) == NULL)
		err_msg ("Can't open /etc/mnttab");

	while ((ret = getmntent (fp, &mp)) == 0) {
		if (hasmntopt (&mp, argv [1]))
			printf ("%s\n", mp.mnt_mountp);
	}

	if (ret != -1)
		err_quit ("Bad /etc/mnttab file.\n");

	return (0);
}
static int mount_find_pri(struct mntent *me, int *ret) {
        char *end, *pri;
        unsigned long r;

        assert(me);
        assert(ret);

        pri = hasmntopt(me, "pri");
        if (!pri)
                return 0;

        pri += 4;

        errno = 0;
        r = strtoul(pri, &end, 10);
        if (errno > 0)
                return -errno;

        if (end == pri || (*end != ',' && *end != 0))
                return -EINVAL;

        *ret = (int) r;
        return 1;
}
Beispiel #30
0
static void
showquotas(uid_t uid, char *name)
{
	struct mnttab mnt;
	FILE *mtab;
	struct dqblk dqblk;
	uid_t myuid;
	struct failed_srv {
		char *serv_name;
		struct failed_srv *next;
	};
	struct failed_srv *failed_srv_list = NULL;
	int	rc;
	char	my_zonename[ZONENAME_MAX];
	zoneid_t my_zoneid = getzoneid();

	myuid = getuid();
	if (uid != myuid && myuid != 0) {
		printf("quota: %s (uid %d): permission denied\n", name, uid);
		zexit(32);
	}

	memset(my_zonename, '\0', ZONENAME_MAX);
	getzonenamebyid(my_zoneid, my_zonename, ZONENAME_MAX);

	if (vflag)
		heading(uid, name);
	mtab = fopen(MNTTAB, "r");
	while (getmntent(mtab, &mnt) == NULL) {
		if (strcmp(mnt.mnt_fstype, MNTTYPE_ZFS) == 0) {
			bzero(&dqblk, sizeof (dqblk));
			if (getzfsquota(name, mnt.mnt_special, &dqblk))
				continue;
		} else if (strcmp(mnt.mnt_fstype, MNTTYPE_UFS) == 0) {
			if (nolocalquota ||
			    (quotactl(Q_GETQUOTA,
			    mnt.mnt_mountp, uid, &dqblk) != 0 &&
			    !(vflag && getdiskquota(&mnt, uid, &dqblk))))
				continue;
		} else if (strcmp(mnt.mnt_fstype, MNTTYPE_NFS) == 0) {

			struct replica *rl;
			int count;
			char *mntopt = NULL;

			/*
			 * Skip checking quotas for file systems mounted
			 * in other zones. Zone names will be passed in
			 * following format from hasmntopt():
			 * "zone=<zone-name>,<mnt options...>"
			 */
			if ((mntopt = hasmntopt(&mnt, MNTOPT_ZONE)) &&
			    (my_zonename[0] != '\0')) {
				mntopt += strcspn(mntopt, "=") + 1;
				if (strncmp(mntopt, my_zonename,
				    strcspn(mntopt, ",")) != 0)
					continue;
			}

			if (hasopt(MNTOPT_NOQUOTA, mnt.mnt_mntopts))
				continue;

			/*
			 * Skip quota processing if mounted with public
			 * option. We are not likely to be able to pierce
			 * a fire wall to contact the quota server.
			 */
			if (hasopt(MNTOPT_PUBLIC, mnt.mnt_mntopts))
				continue;

			rl = parse_replica(mnt.mnt_special, &count);

			if (rl == NULL) {

				if (count < 0)
					fprintf(stderr, "cannot find hostname "
					    "and/or pathname for %s\n",
					    mnt.mnt_mountp);
				else
					fprintf(stderr, "no memory to parse "
					    "mnttab entry for %s\n",
					    mnt.mnt_mountp);
				continue;
			}

			/*
			 * We skip quota reporting on mounts with replicas
			 * for the following reasons:
			 *
			 * (1) Very little point in reporting quotas on
			 * a set of read-only replicas ... how will the
			 * user correct the problem?
			 *
			 * (2) Which replica would we report the quota
			 * for? If we pick the current replica, what
			 * happens when a fail over event occurs? The
			 * next time quota is run, the quota will look
			 * all different, or there won't even be one.
			 * This has the potential to break scripts.
			 *
			 * If we prnt quouta for all replicas, how do
			 * we present the output without breaking scripts?
			 */

			if (count > 1) {
				free_replica(rl, count);
				continue;
			}

			/*
			 * Skip file systems mounted using public fh.
			 * We are not likely to be able to pierce
			 * a fire wall to contact the quota server.
			 */
			if (strcmp(rl[0].host, "nfs") == 0 &&
			    strncmp(rl[0].path, "//", 2) == 0) {
				free_replica(rl, count);
				continue;
			}

			/*
			 * Skip getting quotas from failing servers
			 */
			if (failed_srv_list != NULL) {
				struct failed_srv *tmp_list;
				int found_failed = 0;
				size_t len = strlen(rl[0].host);

				tmp_list = failed_srv_list;
				do {
					if (strncasecmp(rl[0].host,
					    tmp_list->serv_name, len) == 0) {
						found_failed = 1;
						break;
					}
				} while ((tmp_list = tmp_list->next) != NULL);
				if (found_failed) {
					free_replica(rl, count);
					continue;
				}
			}

			rc = getnfsquota(rl[0].host, rl[0].path, uid, &dqblk);
			if (rc != RPC_SUCCESS) {
				size_t len;
				struct failed_srv *tmp_srv;

				/*
				 * Failed to get quota from this server. Add
				 * this server to failed_srv_list and skip
				 * getting quotas for other mounted filesystems
				 * from this server.
				 */
				if (rc == RPC_TIMEDOUT || rc == RPC_CANTSEND) {
					len = strlen(rl[0].host);
					tmp_srv = (struct failed_srv *)malloc(
					    sizeof (struct failed_srv));
					tmp_srv->serv_name = (char *)malloc(
					    len * sizeof (char) + 1);
					strncpy(tmp_srv->serv_name, rl[0].host,
					    len);
					tmp_srv->serv_name[len] = '\0';

					tmp_srv->next = failed_srv_list;
					failed_srv_list = tmp_srv;
				}

				free_replica(rl, count);
				continue;
			}

			free_replica(rl, count);
		} else {
			continue;
		}
		if (dqblk.dqb_bsoftlimit == 0 && dqblk.dqb_bhardlimit == 0 &&
		    dqblk.dqb_fsoftlimit == 0 && dqblk.dqb_fhardlimit == 0)
			continue;
		if (vflag)
			prquota(&mnt, &dqblk);
		else
			warn(&mnt, &dqblk);
	}

	/*
	 * Free list of failed servers
	 */
	while (failed_srv_list != NULL) {
		struct failed_srv *tmp_srv = failed_srv_list;

		failed_srv_list = failed_srv_list->next;
		free(tmp_srv->serv_name);
		free(tmp_srv);
	}

	fclose(mtab);
}