X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=cgroup.c;h=86d4d5ea3b4331c1758561249b8583bce1e2ecc8;hp=29d89dd3e316c4ec8c6dfc385488129beb6f193a;hb=521da527743088a9bd2ab882f8b64799d49d5848;hpb=ed81ee199ec8f3cdfcdc78ff067a0397c3b02f5f diff --git a/cgroup.c b/cgroup.c index 29d89dd3..86d4d5ea 100644 --- a/cgroup.c +++ b/cgroup.c @@ -3,6 +3,9 @@ */ #include #include +#include +#include +#include #include "fio.h" #include "flist.h" #include "cgroup.h" @@ -13,16 +16,47 @@ static struct fio_mutex *lock; struct cgroup_member { struct flist_head list; char *root; + unsigned int cgroup_nodelete; }; -static void add_cgroup(const char *name, struct flist_head *clist) +static char *find_cgroup_mnt(struct thread_data *td) +{ + char *mntpoint = NULL; + struct mntent *mnt, dummy; + char buf[256] = {0}; + FILE *f; + + f = setmntent("/proc/mounts", "r"); + if (!f) { + td_verror(td, errno, "setmntent /proc/mounts"); + return NULL; + } + + while ((mnt = getmntent_r(f, &dummy, buf, sizeof(buf))) != NULL) { + if (!strcmp(mnt->mnt_type, "cgroup") && + strstr(mnt->mnt_opts, "blkio")) + break; + } + + if (mnt) + mntpoint = smalloc_strdup(mnt->mnt_dir); + else + log_err("fio: cgroup blkio does not appear to be mounted\n"); + + endmntent(f); + return mntpoint; +} + +static void add_cgroup(struct thread_data *td, const char *name, + struct flist_head *clist) { struct cgroup_member *cm; cm = smalloc(sizeof(*cm)); INIT_FLIST_HEAD(&cm->list); cm->root = smalloc_strdup(name); - + if (td->o.cgroup_nodelete) + cm->cgroup_nodelete = 1; fio_mutex_down(lock); flist_add_tail(&cm->list, clist); fio_mutex_up(lock); @@ -37,7 +71,8 @@ void cgroup_kill(struct flist_head *clist) flist_for_each_safe(n, tmp, clist) { cm = flist_entry(n, struct cgroup_member, list); - rmdir(cm->root); + if (!cm->cgroup_nodelete) + rmdir(cm->root); flist_del(&cm->list); sfree(cm->root); sfree(cm); @@ -46,26 +81,14 @@ void cgroup_kill(struct flist_head *clist) fio_mutex_up(lock); } -/* - * Check if the given root appears valid - */ -static int cgroup_check_fs(struct thread_data *td) -{ - struct stat sb; - char tmp[256]; - - sprintf(tmp, "%s/tasks", td->o.cgroup_root); - return stat(tmp, &sb); -} - -static char *get_cgroup_root(struct thread_data *td) +static char *get_cgroup_root(struct thread_data *td, char *mnt) { char *str = malloc(64); if (td->o.cgroup) - sprintf(str, "%s/%s", td->o.cgroup_root, td->o.cgroup); + sprintf(str, "%s%s%s", mnt, FIO_OS_PATH_SEPARATOR, td->o.cgroup); else - sprintf(str, "%s/%s", td->o.cgroup_root, td->o.name); + sprintf(str, "%s%s%s", mnt, FIO_OS_PATH_SEPARATOR, td->o.name); return str; } @@ -76,8 +99,8 @@ static int write_int_to_file(struct thread_data *td, const char *path, { char tmp[256]; FILE *f; - - sprintf(tmp, "%s/%s", path, filename); + + sprintf(tmp, "%s%s%s", path, FIO_OS_PATH_SEPARATOR, filename); f = fopen(tmp, "w"); if (!f) { td_verror(td, errno, onerr); @@ -100,34 +123,35 @@ static int cgroup_write_pid(struct thread_data *td, const char *root) /* * Move pid to root class */ -static int cgroup_del_pid(struct thread_data *td) +static int cgroup_del_pid(struct thread_data *td, char *mnt) { - return cgroup_write_pid(td, td->o.cgroup_root); + return cgroup_write_pid(td, mnt); } -int cgroup_setup(struct thread_data *td, struct flist_head *clist) +int cgroup_setup(struct thread_data *td, struct flist_head *clist, char **mnt) { char *root; - if (cgroup_check_fs(td)) { - log_err("fio: blkio cgroup mount point %s not valid\n", - td->o.cgroup_root); - return 1; + if (!*mnt) { + *mnt = find_cgroup_mnt(td); + if (!*mnt) + return 1; } /* * Create container, if it doesn't exist */ - root = get_cgroup_root(td); + root = get_cgroup_root(td, *mnt); if (mkdir(root, 0755) < 0) { int __e = errno; if (__e != EEXIST) { td_verror(td, __e, "cgroup mkdir"); + log_err("fio: path %s\n", root); goto err; } } else - add_cgroup(root, clist); + add_cgroup(td, root, clist); if (td->o.cgroup_weight) { if (write_int_to_file(td, root, "blkio.weight", @@ -146,19 +170,19 @@ err: return 1; } -void cgroup_shutdown(struct thread_data *td) +void cgroup_shutdown(struct thread_data *td, char **mnt) { - if (cgroup_check_fs(td)) + if (*mnt == NULL) return; if (!td->o.cgroup_weight && !td->o.cgroup) return; - cgroup_del_pid(td); + cgroup_del_pid(td, *mnt); } static void fio_init cgroup_init(void) { - lock = fio_mutex_init(1); + lock = fio_mutex_init(FIO_MUTEX_UNLOCKED); } static void fio_exit cgroup_exit(void)