From: Arkadiusz Miśkiewicz Date: Thu, 29 Jan 2009 21:57:34 +0000 (+0100) Subject: xfs_quota: add support for passing project paths on cmdline X-Git-Tag: v3.0.0~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=02b26a6db7be0b36609214391d1b9d6d6f6a11a8;p=thirdparty%2Fxfsprogs-dev.git xfs_quota: add support for passing project paths on cmdline /etc/project is currently required for using project quota. This patch adds ability to specify paths at command line. fs_table_insert_project_path() introduced in libxcmd. Allows to insert arbitrary path to fs_* iterating engine. We insert our paths with -1 as project id (because we know no "original" id for this path and generally this knowledge is not needed). New option introduced for paths passing - project -p . Example: $ sudo rm -f /etc/projects /etc/projid $ sudo ./xfs_quota -x -c "project -p /tmp/xx -s 60" Setting up project 60 (path /tmp/xx)... Processed 1 (/etc/projects and cmdline) paths for project 60 with recursion depth infinite (-1). $ sudo ./xfs_quota -x -c "project -p /tmp/xx -c 60" Checking project 60 (path /tmp/xx)... Processed 1 (/etc/projects and cmdline) paths for project 60 with recursion depth infinite (-1). $ sudo ./xfs_quota -x -c "project -p /tmp/xx -c 70" Checking project 70 (path /tmp/xx)... /tmp/xx - project identifier is not set (inode=60, tree=70) /tmp/xx/file1 - project identifier is not set (inode=60, tree=70) /tmp/xx/file2 - project identifier is not set (inode=60, tree=70) /tmp/xx/file3 - project identifier is not set (inode=60, tree=70) /tmp/xx/dir1 - project identifier is not set (inode=60, tree=70) /tmp/xx/dir2 - project identifier is not set (inode=60, tree=70) Processed 1 (/etc/projects and cmdline) paths for project 70 with recursion depth infinite (-1). $ sudo ./xfs_quota -x -c "project -p /tmp/xx -s 70" Setting up project 70 (path /tmp/xx)... Processed 1 (/etc/projects and cmdline) paths for project 70 with recursion depth infinite (-1). $ sudo ./xfs_quota -x -c "project -p /tmp/xx -c 70" Checking project 70 (path /tmp/xx)... Processed 1 (/etc/projects and cmdline) paths for project 70 with recursion depth infinite (-1). Signed-off-by: Arkadiusz Miśkiewicz Reviewed-by: Donald Douwsma Reviewed-by: Christoph Hellwig --- diff --git a/include/path.h b/include/path.h index 6bf7338f0..b8c8b3158 100644 --- a/include/path.h +++ b/include/path.h @@ -52,6 +52,8 @@ extern void fs_table_destroy(void); extern void fs_table_insert_mount(char *__mount); extern void fs_table_insert_project(char *__project); +extern void fs_table_insert_project_path(char *__dir, uint __projid); + extern fs_path_t *fs_table_lookup(const char *__dir, uint __flags); diff --git a/libxcmd/paths.c b/libxcmd/paths.c index b84720a8c..369c071fd 100644 --- a/libxcmd/paths.c +++ b/libxcmd/paths.c @@ -402,6 +402,36 @@ fs_table_insert_project( } } +void +fs_table_insert_project_path( + char *udir, + prid_t prid) +{ + fs_path_t *fs; + char *dir = NULL, *fsname = NULL; + int error = 0; + + if ((fs = fs_mount_point_from_path(udir)) != NULL) { + dir = strdup(udir); + fsname = strdup(fs->fs_name); + if (dir && fsname) + error = fs_table_insert(dir, prid, + FS_PROJECT_PATH, fsname, NULL, NULL); + else + error = ENOMEM; + } else + error = ENOENT; + + if (error) { + if (dir) + free(dir); + if (fsname) + free(fsname); + fprintf(stderr, _("%s: cannot setup path for project dir %s: %s\n"), + progname, udir, strerror(error)); + exit(1); + } +} /* * Table iteration (cursor-based) interfaces */ diff --git a/quota/project.c b/quota/project.c index f2ff19be4..151016c48 100644 --- a/quota/project.c +++ b/quota/project.c @@ -76,6 +76,11 @@ project_help(void) " which do not have the project ID of the rest of the tree, or if the inode\n" " flag is not set.\n" "\n" +" The -p option can be used to manually specify project path without\n" +" need to create /etc/projects file. This option can be used multiple times\n" +" to specify multiple paths. When using this option only one projid/name can\n" +" be specified at command line. Note that /etc/projects is also used if exists.\n" +"\n" " The -d option allows to descend at most levels of directories\n" " below the command line arguments. -d 0 means only apply the actions\n" " to the top level of the projects. -d -1 means no recursion limit (default).\n" @@ -257,13 +262,13 @@ project( fs_cursor_initialise(NULL, FS_PROJECT_PATH, &cursor); while ((path = fs_cursor_next_entry(&cursor))) { - if (prid != path->fs_prid) + if (prid != path->fs_prid && path->fs_prid != -1) continue; project_operations(project, path->fs_dir, type); count++; } - printf(_("Processed %d %s paths for project %s with recursion depth %s (%d)\n"), + printf(_("Processed %d (%s and cmdline) paths for project %s with recursion depth %s (%d).\n"), count, projects_file, project, recurse_depth < 0 ? _("infinite") : _("limited"), recurse_depth); } @@ -273,9 +278,9 @@ project_f( int argc, char **argv) { - int c, type = 0; + int c, type = 0, ispath = 0; - while ((c = getopt(argc, argv, "cd:sC")) != EOF) { + while ((c = getopt(argc, argv, "cd:p:sC")) != EOF) { switch (c) { case 'c': type = CHECK_PROJECT; @@ -285,6 +290,10 @@ project_f( if (recurse_depth < 0) recurse_depth = -1; break; + case 'p': + ispath = 1; + fs_table_insert_project_path(optarg, -1); + break; case 's': type = SETUP_PROJECT; break; @@ -304,13 +313,20 @@ project_f( type = CHECK_PROJECT; setprfiles(); - if (access(projects_file, F_OK) != 0) { + if (!ispath && access(projects_file, F_OK) != 0) { exitcode = 1; fprintf(stderr, _("projects file \"%s\" doesn't exist\n"), projects_file); return 0; } + if (ispath && argc - optind > 1) { + exitcode = 1; + fprintf(stderr, _("%s: only one projid/name can be specified when using -p , %d found.\n"), + progname, argc - optind); + return 0; + } + while (argc > optind) { prid = prid_from_string(argv[optind]); if (prid == -1) { @@ -331,7 +347,7 @@ project_init(void) project_cmd.name = _("project"); project_cmd.altname = _("tree"); project_cmd.cfunc = project_f; - project_cmd.args = _("[-c|-s|-C|-d ] project ..."); + project_cmd.args = _("[-c|-s|-C|-d |-p ] project ..."); project_cmd.argmin = 1; project_cmd.argmax = -1; project_cmd.oneline = _("check, setup or clear project quota trees");