/*
 * Migration stress workload
 *
 * Copyright (c) 2016 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include <getopt.h>
#include <sys/reboot.h>
#include <sys/syscall.h>
#include <linux/random.h>
#include <pthread.h>
#include <sys/mount.h>

const char *argv0;

#define RAM_PAGE_SIZE 4096

#ifndef CONFIG_GETTID
static int gettid(void)
{
    return syscall(SYS_gettid);
}
#endif

static __attribute__((noreturn)) void exit_failure(void)
{
    if (getpid() == 1) {
        sync();
        reboot(RB_POWER_OFF);
        fprintf(stderr, "%s (%05d): ERROR: cannot reboot: %s\n",
                argv0, gettid(), strerror(errno));
        abort();
    } else {
        exit(1);
    }
}

static int get_command_arg_str(const char *name,
                               char **val)
{
    static char line[1024];
    FILE *fp = fopen("/proc/cmdline", "r");
    char *start, *end;

    if (fp == NULL) {
        fprintf(stderr, "%s (%05d): ERROR: cannot open /proc/cmdline: %s\n",
                argv0, gettid(), strerror(errno));
        return -1;
    }

    if (!fgets(line, sizeof line, fp)) {
        fprintf(stderr, "%s (%05d): ERROR: cannot read /proc/cmdline: %s\n",
                argv0, gettid(), strerror(errno));
        fclose(fp);
        return -1;
    }
    fclose(fp);

    start = strstr(line, name);
    if (!start)
        return 0;

    start += strlen(name);

    if (*start != '=') {
        fprintf(stderr, "%s (%05d): ERROR: no value provided for '%s' in /proc/cmdline\n",
                argv0, gettid(), name);
    }
    start++;

    end = strstr(start, " ");
    if (!end)
        end = strstr(start, "\n");

    if (end == start) {
        fprintf(stderr, "%s (%05d): ERROR: no value provided for '%s' in /proc/cmdline\n",
                argv0, gettid(), name);
        return -1;
    }

    if (end)
        *val = g_strndup(start, end - start);
    else
        *val = g_strdup(start);
    return 1;
}


static int get_command_arg_ull(const char *name,
                               unsigned long long *val)
{
    char *valstr;
    char *end;

    int ret = get_command_arg_str(name, &valstr);
    if (ret <= 0)
        return ret;

    errno = 0;
    *val = strtoll(valstr, &end, 10);
    if (errno || *end) {
        fprintf(stderr, "%s (%05d): ERROR: cannot parse %s value %s\n",
                argv0, gettid(), name, valstr);
        g_free(valstr);
        return -1;
    }
    g_free(valstr);
    return 0;
}


static int random_bytes(char *buf, size_t len)
{
    int fd;

    fd = open("/dev/urandom", O_RDONLY);
    if (fd < 0) {
        fprintf(stderr, "%s (%05d): ERROR: cannot open /dev/urandom: %s\n",
                argv0, gettid(), strerror(errno));
        return -1;
    }

    if (read(fd, buf, len) != len) {
        fprintf(stderr, "%s (%05d): ERROR: cannot read /dev/urandom: %s\n",
                argv0, gettid(), strerror(errno));
        close(fd);
        return -1;
    }

    close(fd);

    return 0;
}


static unsigned long long now(void)
{
    struct timeval tv;

    gettimeofday(&tv, NULL);

    return (tv.tv_sec * 1000ull) + (tv.tv_usec / 1000ull);
}

static void stressone(unsigned long long ramsizeMB)
{
    size_t pagesPerMB = 1024 * 1024 / RAM_PAGE_SIZE;
    g_autofree char *ram = g_malloc(ramsizeMB * 1024 * 1024);
    char *ramptr;
    size_t i, j, k;
    g_autofree char *data = g_malloc(RAM_PAGE_SIZE);
    char *dataptr;
    size_t nMB = 0;
    unsigned long long before, after;

    /* We don't care about initial state, but we do want
     * to fault it all into RAM, otherwise the first iter
     * of the loop below will be quite slow. We can't use
     * 0x0 as the byte as gcc optimizes that away into a
     * calloc instead :-) */
    memset(ram, 0xfe, ramsizeMB * 1024 * 1024);

    if (random_bytes(data, RAM_PAGE_SIZE) < 0) {
        return;
    }

    before = now();

    while (1) {

        ramptr = ram;
        for (i = 0; i < ramsizeMB; i++, nMB++) {
            for (j = 0; j < pagesPerMB; j++) {
                dataptr = data;
                for (k = 0; k < RAM_PAGE_SIZE; k += sizeof(long long)) {
                    ramptr += sizeof(long long);
                    dataptr += sizeof(long long);
                    *(unsigned long long *)ramptr ^= *(unsigned long long *)dataptr;
                }
            }

            if (nMB == 1024) {
                after = now();
                fprintf(stderr, "%s (%05d): INFO: %06llums copied 1 GB in %05llums\n",
                        argv0, gettid(), after, after - before);
                before = now();
                nMB = 0;
            }
        }
    }
}


static void *stressthread(void *arg)
{
    unsigned long long ramsizeMB = *(unsigned long long *)arg;

    stressone(ramsizeMB);

    return NULL;
}

static void stress(unsigned long long ramsizeGB, int ncpus)
{
    size_t i;
    unsigned long long ramsizeMB = ramsizeGB * 1024 / ncpus;
    ncpus--;

    for (i = 0; i < ncpus; i++) {
        pthread_t thr;
        pthread_create(&thr, NULL,
                       stressthread,   &ramsizeMB);
    }

    stressone(ramsizeMB);
}


static int mount_misc(const char *fstype, const char *dir)
{
    if (mkdir(dir, 0755) < 0 && errno != EEXIST) {
        fprintf(stderr, "%s (%05d): ERROR: cannot create %s: %s\n",
                argv0, gettid(), dir, strerror(errno));
        return -1;
    }

    if (mount("none", dir, fstype, 0, NULL) < 0) {
        fprintf(stderr, "%s (%05d): ERROR: cannot mount %s: %s\n",
                argv0, gettid(), dir, strerror(errno));
        return -1;
    }

    return 0;
}

static int mount_all(void)
{
    if (mount_misc("proc", "/proc") < 0 ||
        mount_misc("sysfs", "/sys") < 0 ||
        mount_misc("tmpfs", "/dev") < 0)
        return -1;

    mknod("/dev/urandom", 0777 | S_IFCHR, makedev(1, 9));
    mknod("/dev/random", 0777 | S_IFCHR, makedev(1, 8));

    return 0;
}

int main(int argc, char **argv)
{
    unsigned long long ramsizeGB = 1;
    char *end;
    int ch;
    int opt_ind = 0;
    const char *sopt = "hr:c:";
    struct option lopt[] = {
        { "help", no_argument, NULL, 'h' },
        { "ramsize", required_argument, NULL, 'r' },
        { "cpus", required_argument, NULL, 'c' },
        { NULL, 0, NULL, 0 }
    };
    int ret;
    int ncpus = 0;

    argv0 = argv[0];

    while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) {
        switch (ch) {
        case 'r':
            errno = 0;
            ramsizeGB = strtoll(optarg, &end, 10);
            if (errno != 0 || *end) {
                fprintf(stderr, "%s (%05d): ERROR: Cannot parse RAM size %s\n",
                        argv0, gettid(), optarg);
                exit_failure();
            }
            break;

        case 'c':
            errno = 0;
            ncpus = strtoll(optarg, &end, 10);
            if (errno != 0 || *end) {
                fprintf(stderr, "%s (%05d): ERROR: Cannot parse CPU count %s\n",
                        argv0, gettid(), optarg);
                exit_failure();
            }
            break;

        case '?':
        case 'h':
            fprintf(stderr, "%s: [--help][--ramsize GB][--cpus N]\n", argv0);
            exit_failure();
        }
    }

    if (getpid() == 1) {
        if (mount_all() < 0)
            exit_failure();

        ret = get_command_arg_ull("ramsize", &ramsizeGB);
        if (ret < 0)
            exit_failure();
    }

    if (ncpus == 0)
        ncpus = sysconf(_SC_NPROCESSORS_ONLN);

    fprintf(stdout, "%s (%05d): INFO: RAM %llu GiB across %d CPUs\n",
            argv0, gettid(), ramsizeGB, ncpus);

    stress(ramsizeGB, ncpus);

    exit_failure();
}
