On Tue, Jan 13, 2009 at 01:37:02PM +0000, Eric B Munson wrote: > The --create-mounts switch builds a mount point for each available > huge page size under /var/lib/hugetlbfs. These mounts points are > owned by root:root and are set to 770 and are named pagesize-<size>. > > Signed-off-by: Eric B Munson <ebmun...@us.ibm.com> > --- > Changes from V2: > Make sure the base directory is readable by the world > > Changes from V1: > Fixed usage message for --create-mounts > > hugeadm.c | 91 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- > 1 files changed, 90 insertions(+), 1 deletions(-) > > diff --git a/hugeadm.c b/hugeadm.c > index 81c53d9..9a98e7d 100644 > --- a/hugeadm.c > +++ b/hugeadm.c > @@ -29,6 +29,11 @@ > #include <string.h> > #include <limits.h> > #include <mntent.h> > +#include <unistd.h> > + > +#include <sys/stat.h> > +#include <sys/types.h> > +#include <sys/mount.h> > > #define _GNU_SOURCE /* for getopt_long */ > #include <unistd.h> > @@ -44,6 +49,9 @@ extern char *optarg; > #define OPTION(opts, text) fprintf(stderr, " %-25s %s\n", opts, text) > #define CONT(text) fprintf(stderr, " %-25s %s\n", "", text) > > +#define MOUNT_DIR "/var/lib/hugetlbfs" > +#define ARG_MAX 4096 > +
Why do you add ARG_MAX? I get a warning about redefinitions. > #define PROCMOUNTS "/proc/mounts" > #define FS_NAME "hugetlbfs" > #define MIN_COL 20 > @@ -61,6 +69,8 @@ void print_usage() > CONT("Adjust pool 'size' lower bound"); > OPTION("--pool-pages-max <size>:[+|-]<count>", ""); > CONT("Adjust pool 'size' upper bound"); > + OPTION("--create-mounts", "Creates a mount point for each available"); > + CONT("huge page size on this system under /var/lib/hugetlbfs"); > > OPTION("--page-sizes", "Display page sizes that a configured pool"); > OPTION("--page-sizes-all", > @@ -75,7 +85,6 @@ int opt_dry_run = 0; > * getopts return values for options which are long only. > */ > #define LONG_POOL ('p' << 8) > -#define LONG_LIST_ALL_MOUNTS (LONG_POOL|'A') > #define LONG_POOL_LIST (LONG_POOL|'l') > #define LONG_POOL_MIN_ADJ (LONG_POOL|'m') > #define LONG_POOL_MAX_ADJ (LONG_POOL|'M') > @@ -84,6 +93,10 @@ int opt_dry_run = 0; > #define LONG_PAGE_SIZES (LONG_PAGE|'s') > #define LONG_PAGE_AVAIL (LONG_PAGE|'a') > > +#define LONG_MOUNTS ('m' << 8) > +#define LONG_CREATE_MOUNTS (LONG_MOUNTS|'C') > +#define LONG_LIST_ALL_MOUNTS (LONG_MOUNTS|'A') > + > #define MAX_POOLS 32 > > static int cmpsizes(const void *p1, const void *p2) > @@ -195,6 +208,73 @@ void mounts_list_all(void) > } > } > > +int ensure_dir(char *path) > +{ ensure_dir what? Put a one-line comment describing what you are doing here. It looks like the equivalent of mkdir -p. If so, say so. > + char *idx, local_path[PATH_MAX]; > + int ret; > + As this function is called recursively, this potentially consumes a *lot* of stack and might hit stack ulimits even though we do not create deep directories. Can it be done iteratively? > + if (!path || strlen(path) == 0) > + return 0; > + > + strncpy(local_path, path, PATH_MAX); > + > + idx = strrchr(local_path, '/'); > + if (!idx) > + return 0; > + > + *idx = '\0'; > + if ((ret = ensure_dir(local_path))) > + return ret; > + if (strlen(local_path) == 0) > + return 0; > + > + if (mkdir(path, S_IRUSR | S_IWUSR | S_IXUSR | > + S_IRGRP | S_IWGRP | S_IXGRP) != 0) > + if (errno != EEXIST) > + return 1; > + > + return 0; > +} > + > +void create_mounts(void) > +{ > + struct hpage_pool pools[MAX_POOLS]; > + char path[PATH_MAX]; > + char options[ARG_MAX]; > + int cnt, pos; > + > + if (geteuid() != 0) { > + ERROR("mounts can only be created by root"); > + exit(EXIT_FAILURE); > + } Conceivably, the fstab will allow the mounts to be mounted and the directories will already exist. Maybe you should only check this in the event mount fails and then report root is required. > + > + cnt = hpool_sizes(pools, MAX_POOLS); > + if (cnt < 0) { > + ERROR("unable to obtain pools list"); > + exit(EXIT_FAILURE); > + } > + > + qsort(pools, cnt, sizeof(pools[0]), cmpsizes); > + Why do you care about the order pools are created in? > + for (pos = 0; cnt--; pos++) { > + snprintf(path, PATH_MAX, "%s/pagesize-%ld", > + MOUNT_DIR, pools[pos].pagesize); > + snprintf(options, ARG_MAX, "pagesize=%ld", > + pools[pos].pagesize); > + if (ensure_dir(path)) { > + ERROR("unable to create dir '%s', error: %s\n", > + path, strerror(errno)); > + exit(EXIT_FAILURE); > + } > + > + if (mount("none", path, FS_NAME, 0, options)) { > + ERROR("unable to mount %s, error: %s", > + path, strerror(errno)); > + exit(EXIT_FAILURE); > + } You didn't update mtab here. On systems that do not symlink /etc/mtab to /proc/mounts, it would appear invisible. Check the source of mount to see how mtab should be updated. The default permissions for the mounts created are rwxr-xr-x . Should this be rwxr-x---? > + } > +} > + > enum { > POOL_MIN, > POOL_MAX, > @@ -350,6 +430,7 @@ int main(int argc, char** argv) > {"pool-list", no_argument, NULL, LONG_POOL_LIST}, > {"pool-pages-min", required_argument, NULL, LONG_POOL_MIN_ADJ}, > {"pool-pages-max", required_argument, NULL, LONG_POOL_MAX_ADJ}, > + {"create-mounts", no_argument, NULL, LONG_CREATE_MOUNTS}, > > {"page-sizes", no_argument, NULL, LONG_PAGE_SIZES}, > {"page-sizes-all", no_argument, NULL, LONG_PAGE_AVAIL}, > @@ -410,6 +491,14 @@ int main(int argc, char** argv) > pool_adjust(optarg, POOL_MAX); > break; > > + case LONG_CREATE_MOUNTS: > + ensure_dir(MOUNT_DIR); > + chmod(MOUNT_DIR, S_IRUSR | S_IWUSR | S_IXUSR | > + S_IRGRP | S_IWGRP | S_IXGRP | > + S_IROTH | S_IWOTH | S_IXOTH); > + create_mounts(); > + break; > + > case LONG_PAGE_SIZES: > page_sizes(0); > break; -- Mel Gorman Part-time Phd Student Linux Technology Center University of Limerick IBM Dublin Software Lab ------------------------------------------------------------------------------ This SF.net email is sponsored by: SourcForge Community SourceForge wants to tell your story. http://p.sf.net/sfu/sf-spreadtheword _______________________________________________ Libhugetlbfs-devel mailing list Libhugetlbfs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libhugetlbfs-devel