From 26b3b3e368a79ce29df732ea04e72a4c002ae2ce Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Tue, 6 Mar 2018 17:38:59 +0000 Subject: rename into ioriot --- ioreplay/src/mounts.c | 400 -------------------------------------------------- 1 file changed, 400 deletions(-) delete mode 100644 ioreplay/src/mounts.c (limited to 'ioreplay/src/mounts.c') diff --git a/ioreplay/src/mounts.c b/ioreplay/src/mounts.c deleted file mode 100644 index afa8376..0000000 --- a/ioreplay/src/mounts.c +++ /dev/null @@ -1,400 +0,0 @@ -// Copyright 2018 Mimecast Ltd. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "mounts.h" - -#include "utils/futils.h" - -#define _PATH_INSERT "/.ioreplay/" -#define _PATH_INSERT_LEN 11 // strlen of _PATH_INSERT - -void mounts_read(mounts_s *m) -{ - char *mounts = "/proc/mounts"; - size_t len = 0; - char *line = NULL; - char *saveptr = NULL; - - Put("Reading '%s'", mounts); - - FILE *fp = Fopen(mounts, "r"); - Out("Adding supported file systems to replay paths:"); - - while (getline(&line, &len, fp) != -1) { - bool ignore = true; - - char *dev = strtok_r(line, " ", &saveptr); - if (dev == NULL) { - Error("Could not parse device from %s", mounts); - } - - char *mp = strtok_r(NULL, " ", &saveptr); - if (mp == NULL) { - Error("Could not parse mountpoint from %s", mounts); - } - - char *fs = strtok_r(NULL, " ", &saveptr); - if (fs == NULL) { - Error("Could not parse file system from %s", mounts); - } -#ifdef MP_DEBUG - Debug("fs:%s", fs); -#endif - // TODO: Make file system types configurable - if (Eq(fs, "ext2")) { - ignore = false; - } else if (Eq(fs, "ext5")) { - ignore = false; - } else if (Eq(fs, "ext4")) { - ignore = false; - } else if (Eq(fs, "xfs")) { - ignore = false; - } else if (Eq(fs, "zfs")) { - ignore = false; - } else if (Eq(fs, "btrfs")) { - ignore = false; - } - - if (ignore) { - if (strcmp(mp, "/") != 0) { - m->ignore_mps[m->ignore_count] = Clone(mp); - m->ignore_count++; - } - - } else if (m->count >= MAX_MOUNTPOINTS) { - Error("Exceeded max mount points: %d\n", m->count); - - } else { - Out(" %s (%s)", mp, fs); - m->mps[m->count] = Clone(mp); - m->lengths[m->count] = strlen(mp); - m->count++; - } - } - - fclose(fp); - Out("\n"); -} - -mounts_s *mounts_new(options_s *opts) -{ - mounts_s *m = Malloc(mounts_s); - - m->opts = opts; - m->count = 0; - m->ignore_count = 0; - mounts_read(m); - - return m; -} - -void mounts_destroy(mounts_s *m) -{ - if (!m) - return; - for (int i = 0; i < m->count; i++) - free(m->mps[i]); - free(m); -} - -void mounts_trash(mounts_s *m) -{ - options_s *opts = m->opts; - set_limits_drop_root(opts->user); - Put("Moving all old files to trash (of previous tests)..."); - - struct timeval tv; - gettimeofday(&tv, NULL); - - char *wd_path = NULL; - asprintf(&wd_path, "%s/%s", opts->wd_base, opts->name); - - char *trash_path = NULL; - asprintf(&trash_path, "%s/.trash/%ld", opts->wd_base, tv.tv_sec); - - if (is_dir(wd_path)) { - ensure_dir_exists(trash_path); - chown_path(opts->user, trash_path); - if (rename(wd_path, trash_path)) { - Errno("Could not move '%s' to '%s'", wd_path, trash_path); - } - } - free(wd_path); - free(trash_path); - - for (int i = 0; i < m->count; i++) { - char *mp = m->mps[i]; - char *path = NULL; - asprintf(&path, "%s/%s/%s", mp, _PATH_INSERT, opts->name); - asprintf(&trash_path, "%s/%s/.trash/%ld", - mp, _PATH_INSERT, tv.tv_sec); - - if (is_dir(path)) { - ensure_dir_exists(trash_path); - chown_path(opts->user, trash_path); - if (rename(path, trash_path)) { - Errno("Could not move '%s' to '%s'", path, trash_path); - } - } - - free(path); - free(trash_path); - } - - Put("Done trashing!"); - Put("Once the drives fill up you may want to purge old data (-P)"); -} - -void mounts_purge(mounts_s *m) -{ - options_s *opts = m->opts; - set_limits_drop_root(opts->user); - - Out("Purging all data from the following directories:"); - - int active_purgers = 0, max_purgers = 16; - if (opts->num_workers > max_purgers) - max_purgers = opts->num_workers; - - char *purge_path = NULL; - asprintf(&purge_path, "%s", opts->wd_base); - if (is_dir(purge_path)) { - Out(" %s", purge_path); - pid_t pid = fork(); - - if (pid == 0) { - ensure_dir_empty(purge_path); - free(purge_path); - exit(0); - - } else if (pid < 0) { - Errno("\nUnable to create cleaner process! :'-("); - } - active_purgers++; - } - free(purge_path); - - int cleaner_status = SUCCESS; - - for (int i = 0; i < m->count; i++) { - char *mp = m->mps[i]; - char *purge_path = NULL; - asprintf(&purge_path, "%s/%s", mp, _PATH_INSERT); - - if (is_dir(purge_path)) { - if (active_purgers+1 >= max_purgers) { - wait(&cleaner_status); - active_purgers--; - } - - // TODO: Use threading model same way as in init/init.c - pid_t pid = fork(); - if (pid == 0) { - Out(" %s", purge_path); - ensure_dir_empty(purge_path); - free(purge_path); - exit(0); - } else if (pid < 0) { - Errno("Unable to create cleaner process! :'-("); - } - active_purgers++; - } - free(purge_path); - } - - while (wait(&cleaner_status) > 0) - active_purgers--; - Put("\nCleaning done!"); -} - -void mounts_init(mounts_s *m) -{ - options_s *opts = m->opts; - char *wd_path = NULL; - asprintf(&wd_path, "%s/%s", opts->wd_base, opts->name); - ensure_dir_exists(wd_path); - chown_path(opts->user, opts->wd_base); - chown_path(opts->user, wd_path); - - if (chdir(wd_path)) { - Errno("Could not chdir into '%s'!", wd_path); - - } else { - Put("Chdir into '%s'", wd_path); - } - - free(wd_path); - - for (int i = 0; i < m->count; i++) { - char *mp = m->mps[i]; - char *path = NULL; - - // Create .ioreplay/ directory on MP - asprintf(&path, "%s/%s", mp, _PATH_INSERT); - ensure_dir_exists(path); - chown_path(m->opts->user, path); - free(path); - path = NULL; - - // Create .ioreplay/NAME directory on MP - asprintf(&path, "%s/%s/%s", mp, _PATH_INSERT, opts->name); - ensure_dir_exists(path); - chown_path(m->opts->user, path); - free(path); - } -} - -bool mounts_ignore_path(mounts_s *m, const char *path) -{ - // CentOS 7 specific, ignore temp namespace mounts! - char *pos = strstr(path, "/tmp/namespace-"); - if (pos == path) - return true; - - // iterate backwards through all mount points. - for (int i = m->ignore_count-1; i >= 0; --i) { - char *mountpoint = m->ignore_mps[i]; - pos = strstr(path, mountpoint); - // Ignore this path as it is in the ignore mp list - if (pos == path) - return true; - } - - return false; -} - -bool mounts_transform_path(mounts_s *m, const char *name, - char *path, char **path_r) -{ - char *tmp = NULL; -#ifdef DEBUG_TRANSFORM_PATH - char *original_path = path; -#endif - bool line_ok = true; - - // First figure out whether there are '..' in any paths. If so we have to - // tokenize the path and remove '..'. Example: - // transform '/foo/bar/../' into '/foo/'. - // Also remove double '/' from paths. - - if (strstr(path, "..") || strstr(path, "//")) { - // tmp will be freed under label 'cleanup' at end of function. - tmp = Calloc(strlen(path)+1, char); - - // stack to put the tokens on - stack_s *s = stack_new(); - - // we need a copy of the path, so we can tokenize it into the stack - char* clone = Clone(path); - - char *saveptr = NULL; - char *tok = strtok_r(clone, "/", &saveptr); - - // Add each part of the path to the stack. - while (tok) { - if (strcmp(tok, "..") == 0) { - stack_pop(s); - } else { - stack_push(s, tok); - } - tok = strtok_r(NULL, "/", &saveptr); - } - - if (stack_is_empty(s)) { - strcpy(tmp, "."); - - } else { - s = stack_new_reverse_from(s); - strcpy(tmp, "/"); - strcat(tmp, (char*)stack_pop(s)); - - while(!stack_is_empty(s)) { - strcat(tmp, "/"); - strcat(tmp, (char*)stack_pop(s)); - } - } - - stack_destroy(s); - free(clone); - - // This is the path without '..' and '//' (and '///' ... etc') - path = tmp; - } - - // Now heck whether the path is on a supported file system. If not, ignore! - if (mounts_ignore_path(m, path)) { - line_ok = false; - goto cleanup; - } - - // So the path is on a valid mount point! Now we need to insert - // .ioreplay/NAME to each mount point, e.g. /usr/local/.ioreplay/NAME/... - - // Iterate backwards through all mount points. - for (int i = m->count-1; i >= 0; --i) { - char *mountpoint = m->mps[i]; - int mp_len = m->lengths[i]; - - if (strncmp(path, mountpoint, mp_len) == 0) { - // Found a path to replace - // Now insert .ioreplay/NAME/ into the file path. - *path_r = Calloc(strlen(path) + strlen(name)+1 - + _PATH_INSERT_LEN+1, char); - - if (strcmp(mountpoint, "/") == 0) { - // Root path - strcpy(*path_r, _PATH_INSERT); - strcat(*path_r, name); - strcat(*path_r, path); - - } else { - strcpy(*path_r, mountpoint); - strcat(*path_r, _PATH_INSERT); - strcat(*path_r, name); - char *pos = path; - pos += mp_len * (int) sizeof(char); - strcat(*path_r, pos); - } - - goto cleanup; - } - } - - if (tmp) - free(tmp); - - return line_ok; - -cleanup: -#ifdef DEBUG_TRANSFORM_PATH - Debug("Transform path '%s' -> '%s' -> '%s'", original_path, path, *path_r); -#endif - if (tmp) - free(tmp); - - return line_ok; -} - -int mounts_get_mountnumber(mounts_s *m, const char *path) -{ - for (int i = m->count-1; i >= 0; --i) { - char *mountpoint = m->mps[i]; - int mp_len = m->lengths[i]; - - if (strncmp(path, mountpoint, mp_len) == 0) - return i; - } - - return 0; -} -- cgit v1.2.3