/*
 * Copyright (c) 2013-2022 Douglas Gilbert.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#include <iostream>
#include <vector>
#include <system_error>
#include <thread>
#include <mutex>
#include <chrono>

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "sg_lib.h"
#include "sg_pt.h"
#include "sg_unaligned.h"

static const char * version_str = "1.11 20220425";
static const char * util_name = "sg_tst_excl2";

/* This is a test program for checking O_EXCL on open() works. It uses
 * multiple threads and can be run as multiple processes and attempts
 * to "break" O_EXCL. The strategy is to open a device O_EXCL|O_NONBLOCK
 * and do a double increment on a LB then close it. Prior to the first
 * increment, the value is checked for even or odd. Assuming the count
 * starts as an even (typically 0) then it should remain even. Odd instances
 * are counted and reported at the end of the program, after all threads
 * have completed.
 *
 * This is C++ code with some things from C++11 (e.g. threads) and was
 * only just able to compile (when some things were reverted) with gcc/g++
 * version 4.7.3 found in Ubuntu 13.04 . C++11 "feature complete" support
 * was not available until g++ version 4.8.1 and that is only currently
 * found in Fedora 19 .
 *
 * The build uses various object files from the <sg3_utils>/lib directory
 * which is assumed to be a sibling of this examples directory. Those
 * object files in the lib directory can be built with:
 *   cd <sg3_utils> ; ./configure ; cd lib; make
 * Then:
 *   cd ../testing
 *   make sg_tst_excl2
 *
 * BEWARE: this utility modifies a logical block (default LBA 1000) on the
 * given device.
 *
 */

using namespace std;
using namespace std::chrono;

#define DEF_NUM_PER_THREAD 200
#define DEF_NUM_THREADS 4
#define DEF_WAIT_MS 0          /* 0: yield; -1: don't wait; -2: sleep(0) */

#define DEF_LBA 1000

#define EBUFF_SZ 256


static mutex odd_count_mutex;
static mutex console_mutex;
static unsigned int odd_count;
static unsigned int ebusy_count;


static void
usage(void)
{
    printf("Usage: %s [-b] [-f] [-h] [-l <lba>] [-n <n_per_thr>] "
           "[-t <num_thrs>]\n"
           "                    [-V] [-w <wait_ms>] [-x] "
           "<disk_device>\n", util_name);
    printf("  where\n");
    printf("    -b                block on open (def: O_NONBLOCK)\n");
    printf("    -f                force: any SCSI disk (def: only "
           "scsi_debug)\n");
    printf("                      WARNING: <lba> written to\n");
    printf("    -h                print this usage message then exit\n");
    printf("    -l <lba>          logical block to increment (def: %u)\n",
           DEF_LBA);
    printf("    -n <n_per_thr>    number of loops per thread "
           "(def: %d)\n", DEF_NUM_PER_THREAD);
    printf("    -t <num_thrs>     number of threads (def: %d)\n",
           DEF_NUM_THREADS);
    printf("    -V                print version number then exit\n");
    printf("    -w <wait_ms>      >0: sleep_for(<wait_ms>); =0: "
           "yield(); -1: no\n"
           "                      wait; -2: sleep(0)  (def: %d)\n",
           DEF_WAIT_MS);
    printf("    -x                don't use O_EXCL on first thread "
           "(def: use\n"
           "                      O_EXCL on all threads)\n\n");
    printf("Test O_EXCL open flag with pass-through drivers. Each "
           "open/close cycle with\nthe O_EXCL flag does a double increment "
           "on lba (using its first 4 bytes).\n");
}

/* Assumed a lock (mutex) held when pt_err() is called */
static int
pt_err(int res)
{
    if (res < 0)
        fprintf(stderr, "  pass through os error: %s\n", safe_strerror(-res));
    else if (SCSI_PT_DO_BAD_PARAMS == res)
        fprintf(stderr, "  bad pass through setup\n");
    else if (SCSI_PT_DO_TIMEOUT == res)
        fprintf(stderr, "  pass through timeout\n");
    else
        fprintf(stderr, "  do_scsi_pt error=%d\n", res);
    return -1;
}

/* Assumed a lock (mutex) held when pt_cat_no_good() is called */
static int
pt_cat_no_good(int cat, struct sg_pt_base * ptp, const unsigned char * sbp)
{
    int slen;
    char b[256];
    const int bl = (int)sizeof(b);

    switch (cat) {
    case SCSI_PT_RESULT_STATUS: /* other than GOOD and CHECK CONDITION */
        sg_get_scsi_status_str(get_scsi_pt_status_response(ptp), bl, b);
        fprintf(stderr, "  scsi status: %s\n", b);
        break;
    case SCSI_PT_RESULT_SENSE:
        slen = get_scsi_pt_sense_len(ptp);
        sg_get_sense_str("", sbp, slen, 1, bl, b);
        fprintf(stderr, "%s", b);
        break;
    case SCSI_PT_RESULT_TRANSPORT_ERR:
        get_scsi_pt_transport_err_str(ptp, bl, b);
        fprintf(stderr, "  transport: %s", b);
        break;
    case SCSI_PT_RESULT_OS_ERR:
        get_scsi_pt_os_err_str(ptp, bl, b);
        fprintf(stderr, "  os: %s", b);
        break;
    default:
        fprintf(stderr, "  unknown pt result category (%d)\n", cat);
        break;
    }
    return -1;
}

#define READ16_REPLY_LEN 512
#define READ16_CMD_LEN 16
#define WRITE16_REPLY_LEN 512
#define WRITE16_CMD_LEN 16

/* Opens dev_name and spins if busy (i.e. gets EBUSY), sleeping for
 * wait_ms milliseconds if wait_ms is positive. Reads lba and treats the
 * first 4 bytes as an int (SCSI endian), increments it and writes it back.
 * Repeats so that happens twice. Then closes dev_name. If an error occurs
 * returns -1 else returns 0 if first int read is even otherwise returns 1. */
static int
do_rd_inc_wr_twice(const char * dev_name, unsigned int lba, int block,
                   int excl, int wait_ms, unsigned int & ebusys)
{
    int k, sg_fd, res, cat;
    int odd = 0;
    unsigned int u = 0;
    struct sg_pt_base * ptp = NULL;
    unsigned char r16CmdBlk [READ16_CMD_LEN] =
                {0x88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0};
    unsigned char w16CmdBlk [WRITE16_CMD_LEN] =
                {0x8a, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0};
    unsigned char sense_buffer[64] SG_C_CPP_ZERO_INIT;
    unsigned char lb[READ16_REPLY_LEN];
    char ebuff[EBUFF_SZ];
    int open_flags = O_RDWR;

    sg_put_unaligned_be64(lba, r16CmdBlk + 2);
    sg_put_unaligned_be64(lba, w16CmdBlk + 2);
    if (! block)
        open_flags |= O_NONBLOCK;
    if (excl)
        open_flags |= O_EXCL;

    while (((sg_fd = scsi_pt_open_flags(dev_name, open_flags, 0)) < 0) &&
           (-EBUSY == sg_fd)) {
        ++ebusys;
        if (wait_ms > 0)
            this_thread::sleep_for(milliseconds{wait_ms});
        else if (0 == wait_ms)
            this_thread::yield();       // thread yield
        else if (-2 == wait_ms)
            sleep(0);                   // process yield ??
    }
    if (sg_fd < 0) {
        snprintf(ebuff, EBUFF_SZ,
                 "do_rd_inc_wr_twice: error opening file: %s", dev_name);
        {
            lock_guard<mutex> lg(console_mutex);

            perror(ebuff);
        }
        return -1;
    }

    ptp = construct_scsi_pt_obj();
    for (k = 0; k < 2; ++k) {
        /* Prepare READ_16 command */
        clear_scsi_pt_obj(ptp);
        set_scsi_pt_cdb(ptp, r16CmdBlk, sizeof(r16CmdBlk));
        set_scsi_pt_sense(ptp, sense_buffer, sizeof(sense_buffer));
        set_scsi_pt_data_in(ptp, lb, READ16_REPLY_LEN);
        res = do_scsi_pt(ptp, sg_fd, 20 /* secs timeout */, 1);
        if (res) {
            {
                lock_guard<mutex> lg(console_mutex);

                fprintf(stderr, "READ_16 do_scsi_pt() submission error\n");
                res = pt_err(res);
            }
            goto err;
        }
        cat = get_scsi_pt_result_category(ptp);
        if (SCSI_PT_RESULT_GOOD != cat) {
            {
                lock_guard<mutex> lg(console_mutex);

                fprintf(stderr, "READ_16 do_scsi_pt() category problem\n");
                res = pt_cat_no_good(cat, ptp, sense_buffer);
            }
            goto err;
        }

        u = sg_get_unaligned_be32(lb);
        // Assuming u starts test as even (probably 0), expect it to stay even
        if (0 == k)
            odd = (1 == (u % 2));
        ++u;
        sg_put_unaligned_be32(u, lb);

        if (wait_ms > 0)       /* allow daylight for bad things ... */
            this_thread::sleep_for(milliseconds{wait_ms});
        else if (0 == wait_ms)
            this_thread::yield();       // thread yield
        else if (-2 == wait_ms)
            sleep(0);                   // process yield ??

        /* Prepare WRITE_16 command */
        clear_scsi_pt_obj(ptp);
        set_scsi_pt_cdb(ptp, w16CmdBlk, sizeof(w16CmdBlk));
        set_scsi_pt_sense(ptp, sense_buffer, sizeof(sense_buffer));
        set_scsi_pt_data_out(ptp, lb, WRITE16_REPLY_LEN);
        res = do_scsi_pt(ptp, sg_fd, 20 /* secs timeout */, 1);
        if (res) {
            {
                lock_guard<mutex> lg(console_mutex);

                fprintf(stderr, "WRITE_16 do_scsi_pt() submission error\n");
                res = pt_err(res);
            }
            goto err;
        }
        cat = get_scsi_pt_result_category(ptp);
        if (SCSI_PT_RESULT_GOOD != cat) {
            {
                lock_guard<mutex> lg(console_mutex);

                fprintf(stderr, "WRITE_16 do_scsi_pt() category problem\n");
                res = pt_cat_no_good(cat, ptp, sense_buffer);
            }
            goto err;
        }
    }
err:
    if (ptp)
        destruct_scsi_pt_obj(ptp);
    scsi_pt_close_device(sg_fd);
    return odd;
}



#define INQ_REPLY_LEN 96
#define INQ_CMD_LEN 6

/* Send INQUIRY and fetches response. If okay puts PRODUCT ID field
 * in b (up to m_blen bytes). Does not use O_EXCL flag. Returns 0 on success,
 * else -1 . */
static int
do_inquiry_prod_id(const char * dev_name, int block, int wait_ms,
                   unsigned int & ebusys, char * b, int b_mlen)
{
    int sg_fd, res, cat;
    struct sg_pt_base * ptp = NULL;
    unsigned char inqCmdBlk [INQ_CMD_LEN] =
                                {0x12, 0, 0, 0, INQ_REPLY_LEN, 0};
    unsigned char inqBuff[INQ_REPLY_LEN];
    unsigned char sense_buffer[64] SG_C_CPP_ZERO_INIT;
    char ebuff[EBUFF_SZ];
    int open_flags = O_RDWR;    /* since O_EXCL | O_RDONLY gives EPERM */

    if (! block)
        open_flags |= O_NONBLOCK;
    while (((sg_fd = scsi_pt_open_flags(dev_name, open_flags, 0)) < 0) &&
           (-EBUSY == sg_fd)) {
        ++ebusys;
        if (wait_ms > 0)
            this_thread::sleep_for(milliseconds{wait_ms});
        else if (0 == wait_ms)
            this_thread::yield();       // thread yield
        else if (-2 == wait_ms)
            sleep(0);                   // process yield ??
    }
    if (sg_fd < 0) {
        snprintf(ebuff, EBUFF_SZ,
                 "do_inquiry_prod_id: error opening file: %s", dev_name);
        perror(ebuff);
        return -1;
    }
    /* Prepare INQUIRY command */
    ptp = construct_scsi_pt_obj();
    clear_scsi_pt_obj(ptp);
    set_scsi_pt_cdb(ptp, inqCmdBlk, sizeof(inqCmdBlk));
    set_scsi_pt_sense(ptp, sense_buffer, sizeof(sense_buffer));
    set_scsi_pt_data_in(ptp, inqBuff, INQ_REPLY_LEN);
    res = do_scsi_pt(ptp, sg_fd, 20 /* secs timeout */, 1);
    if (res) {
        {
            lock_guard<mutex> lg(console_mutex);

            fprintf(stderr, "INQUIRY do_scsi_pt() submission error\n");
            res = pt_err(res);
        }
        goto err;
    }
    cat = get_scsi_pt_result_category(ptp);
    if (SCSI_PT_RESULT_GOOD != cat) {
        {
            lock_guard<mutex> lg(console_mutex);

            fprintf(stderr, "INQUIRY do_scsi_pt() category problem\n");
            res = pt_cat_no_good(cat, ptp, sense_buffer);
        }
        goto err;
    }

    /* Good, so fetch Product ID from response, copy to 'b' */
    if (b_mlen > 0) {
        if (b_mlen > 16) {
            memcpy(b, inqBuff + 16, 16);
            b[16] = '\0';
        } else {
            memcpy(b, inqBuff + 16, b_mlen - 1);
            b[b_mlen - 1] = '\0';
        }
    }
err:
    if (ptp)
        destruct_scsi_pt_obj(ptp);
    close(sg_fd);
    return 0;
}

static void
work_thread(const char * dev_name, unsigned int lba, int id, int block,
            int excl, int num, int wait_ms)
{
    unsigned int thr_odd_count = 0;
    unsigned int thr_ebusy_count = 0;
    int k, res;

    {
        lock_guard<mutex> lg(console_mutex);

        cerr << "Enter work_thread id=" << id << " excl=" << excl << " block="
             << block << endl;
    }
    for (k = 0; k < num; ++k) {
        res = do_rd_inc_wr_twice(dev_name, lba, block, excl, wait_ms,
                                 thr_ebusy_count);
        if (res < 0)
            break;
        if (res)
            ++thr_odd_count;
    }
    {
        lock_guard<mutex> lg(console_mutex);

        if (k < num)
            cerr << "thread id=" << id << " FAILed at iteration: " << k <<
                    '\n';
        else
            cerr << "thread id=" << id << " normal exit" << '\n';
    }

    {
        lock_guard<mutex> lg(odd_count_mutex);

        odd_count += thr_odd_count;
        ebusy_count += thr_ebusy_count;
    }
}


int
main(int argc, char * argv[])
{
    int k, res;
    int block = 0;
    int force = 0;
    unsigned int lba = DEF_LBA;
    int num_per_thread = DEF_NUM_PER_THREAD;
    int num_threads = DEF_NUM_THREADS;
    int wait_ms = DEF_WAIT_MS;
    int exclude_o_excl = 0;
    char * dev_name = NULL;
    char b[64];

    for (k = 1; k < argc; ++k) {
        if (0 == memcmp("-b", argv[k], 2))
            ++block;
        else if (0 == memcmp("-f", argv[k], 2))
            ++force;
        else if (0 == memcmp("-h", argv[k], 2)) {
            usage();
            return 0;
        } else if (0 == memcmp("-l", argv[k], 2)) {
            ++k;
            if ((k < argc) && isdigit(*argv[k]))
                lba = (unsigned int)atoi(argv[k]);
            else
                break;
        } else if (0 == memcmp("-n", argv[k], 2)) {
            ++k;
            if ((k < argc) && isdigit(*argv[k]))
                num_per_thread = atoi(argv[k]);
            else
                break;
        } else if (0 == memcmp("-t", argv[k], 2)) {
            ++k;
            if ((k < argc) && isdigit(*argv[k]))
                num_threads = atoi(argv[k]);
            else
                break;
        } else if (0 == memcmp("-V", argv[k], 2)) {
            printf("%s version: %s\n", util_name, version_str);
            return 0;
        } else if (0 == memcmp("-w", argv[k], 2)) {
            ++k;
            if ((k < argc) && (isdigit(*argv[k]) || ('-' == *argv[k]))) {
                if ('-' == *argv[k])
                    wait_ms = - atoi(argv[k] + 1);
                else
                    wait_ms = atoi(argv[k]);
            } else
                break;
        } else if (0 == memcmp("-x", argv[k], 2))
            ++exclude_o_excl;
        else if (*argv[k] == '-') {
            printf("Unrecognized switch: %s\n", argv[k]);
            dev_name = NULL;
            break;
        }
        else if (! dev_name)
            dev_name = argv[k];
        else {
            printf("too many arguments\n");
            dev_name = 0;
            break;
        }
    }
    if (0 == dev_name) {
        usage();
        return 1;
    }
    try {

        if (! force) {
            res = do_inquiry_prod_id(dev_name, block, wait_ms, ebusy_count,
                                     b, sizeof(b));
            if (res) {
                fprintf(stderr, "INQUIRY failed on %s\n", dev_name);
                return 1;
            }
            // For safety, since <lba> written to, only permit scsi_debug
            // devices. Bypass this with '-f' option.
            if (0 != memcmp("scsi_debug", b, 10)) {
                fprintf(stderr, "Since this utility writes to LBA %d, only "
                        "devices with scsi_debug\nproduct ID accepted.\n",
                        lba);
                return 2;
            }
        }

        vector<thread *> vt;

        for (k = 0; k < num_threads; ++k) {
            int excl = ((0 == k) && exclude_o_excl) ? 0 : 1;

            thread * tp = new thread {work_thread, dev_name, lba, k, block,
                                      excl, num_per_thread, wait_ms};
            vt.push_back(tp);
        }

        for (k = 0; k < (int)vt.size(); ++k)
            vt[k]->join();

        for (k = 0; k < (int)vt.size(); ++k)
            delete vt[k];

        cout << "Expecting odd count of 0, got " << odd_count << endl;
        cout << "Number of EBUSYs: " << ebusy_count << endl;

    }
    catch(system_error& e)  {
        cerr << "got a system_error exception: " << e.what() << '\n';
        auto ec = e.code();
        cerr << "category: " << ec.category().name() << '\n';
        cerr << "value: " << ec.value() << '\n';
        cerr << "message: " << ec.message() << '\n';
        cerr << "\nNote: if g++ may need '-pthread' or similar in "
                "compile/link line" << '\n';
    }
    catch(...) {
        cerr << "got another exception: " << '\n';
    }
    return 0;
}
