diff --git a/gating.yaml b/gating.yaml new file mode 100644 index 0000000..db58054 --- /dev/null +++ b/gating.yaml @@ -0,0 +1,6 @@ +--- !Policy +product_versions: + - rhel-8 +decision_context: osci_compose_gate +rules: + - !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional} # this is the testcase identifier, which OSCI pipeline uses diff --git a/tests/scripts/dlm_seq_async.c b/tests/scripts/dlm_seq_async.c new file mode 100644 index 0000000..395efaa --- /dev/null +++ b/tests/scripts/dlm_seq_async.c @@ -0,0 +1,362 @@ +/* + * Copyright (c) 2011 David Teigland + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License V2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* gcc dlm_seq_async.c -ldlm -o dlm_seq_async */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libdlm.h" + +#define DEFAULT_NUM_R 1000 +#define DEFAULT_NUM_LPR 1 + +static dlm_lshandle_t *dh; +static int openclose = 0; +static int quiet = 0; +static int verbose = 0; +static int opt_convert = 0; +static int opt_unlock = 0; +static int opt_async = 0; +static int opt_delay = 0; +static unsigned int num_r = DEFAULT_NUM_R; +static unsigned int num_lpr = DEFAULT_NUM_LPR; +static unsigned int num_iter = 1; +static unsigned int iter = 0; +static uint32_t *lkids; +static struct dlm_lksb lksb; +static unsigned int cb_count; +static int libdlm_fd; + +#define log_debug(fmt, args...) \ +do { \ + if (!quiet) \ + printf(fmt "\n", ##args); \ +} while (0) + +#define log_error(fmt, args...) \ +do { \ + printf("ERROR " fmt "\n", ##args); \ + exit(-1); \ +} while (0) + +static void astfn(void *arg) +{ + int status = lksb.sb_status; + + cb_count++; + + printf("astfn %x status %d count %u\n", lksb.sb_lkid, status, cb_count); + + if (!status) + return; + if (status == EUNLOCK) + return; +} + +static void seq(int acquire, int convert, int unlock, int mode) +{ + char name[DLM_RESNAME_MAXLEN]; + uint32_t lkid; + int i, j, rv; + + for (i = 0; i < num_r; i++) { + snprintf(name, sizeof(name), "seq.%08d", i); + + for (j = 0; j < num_lpr; j++) { + memset(&lksb, 0, sizeof(lksb)); + + if (acquire) { + printf("acquire %s %d\n", name, mode); + + rv = dlm_ls_lockx(dh, mode, &lksb, 0, + name, strlen(name), 0, + astfn, &lksb, NULL, + NULL, NULL); + } + if (convert) { + lksb.sb_lkid = lkids[(i * num_lpr) + j]; + + printf("convert %s %x %d\n", name, lksb.sb_lkid, mode); + + rv = dlm_ls_lockx(dh, mode, &lksb, LKF_CONVERT, + name, strlen(name), 0, + astfn, &lksb, NULL, + NULL, NULL); + } + if (unlock) { + lkid = lkids[(i * num_lpr) + j]; + + printf("unlock %s %x\n", name, lkid); + + rv = dlm_ls_unlock(dh, lkid, 0, &lksb, &lksb); + } + + if (rv) { + log_error("dlm op %d %d %d %d,%d error %d", + acquire, convert, unlock, i, j, rv); + return; + } + + if (acquire && lkids) + lkids[(i * num_lpr) + j] = lksb.sb_lkid; + } + } + + cb_count = 0; + + while (1) { + rv = dlm_dispatch(libdlm_fd); + if (rv < 0) { + printf("dlm_dispatch error %d %d\n", rv, errno); + } + + if (cb_count == (num_r * num_lpr)) + break; + } +} + +static void print_usage(void) +{ + printf("dlm_seq [options]\n"); + printf("Options:\n"); + printf("\n"); + printf(" -i Iterations (0 no limit), default 1)\n"); + printf(" -r The number of resources, default %d\n", DEFAULT_NUM_R); + printf(" -l The number of locks per resource, default %d\n", DEFAULT_NUM_LPR); + printf(" -c Convert locks after acquiring them all\n"); + printf(" -u Unlock locks after acquire/convert\n"); + printf(" -s Same resource names in each iteration\n"); + printf(" -d Delay us between consecutive seq\n"); + printf(" -o Open/close existing lockspace\n"); + printf(" -v Verbose output\n"); + printf(" -q Quiet output\n"); +} + +static void decode_arguments(int argc, char **argv) +{ + int cont = 1; + int optchar; + + while (cont) { + optchar = getopt(argc, argv, "i:r:l:cuvqohad:s"); + + switch (optchar) { + + case 'i': + num_iter = atoi(optarg); + break; + + case 'r': + num_r = atoi(optarg); + break; + + case 'l': + num_lpr = atoi(optarg); + break; + + case 'c': + opt_convert = 1; + break; + + case 'u': + opt_unlock = 1; + break; + + case 'd': + opt_delay = atoi(optarg); + break; + + case 'o': + openclose = 1; + break; + + case 'v': + verbose = 1; + break; + + case 'q': + quiet = 1; + break; + + case 'h': + print_usage(); + exit(EXIT_SUCCESS); + break; + + case 'V': + printf("%s (built %s %s)\n", argv[0], __DATE__, __TIME__); + exit(EXIT_SUCCESS); + break; + + case ':': + case '?': + fprintf(stderr, "Please use '-h' for usage.\n"); + exit(EXIT_FAILURE); + break; + + case EOF: + cont = 0; + break; + + default: + fprintf(stderr, "unknown option: %c\n", optchar); + exit(EXIT_FAILURE); + break; + }; + } +} + +void _acquire(int mode) +{ + seq(1, 0, 0, mode); + + if (opt_delay) + usleep(opt_delay); +} + +void _convert(int mode) +{ + seq(0, 1, 0, mode); + + if (opt_delay) + usleep(opt_delay); +} + +void _unlock(void) +{ + seq(0, 0, 1, 0); + + if (opt_delay) + usleep(opt_delay); +} + +int main(int argc, char *argv[]) +{ + int rv, quit = 0; + + decode_arguments(argc, argv); + + printf("%d resources, %d locks per resource\n", num_r, num_lpr); + + if (openclose) { + log_debug("dlm_open_lockspace..."); + + dh = dlm_open_lockspace("dlm_seq"); + if (!dh) { + log_error("dlm_open_lockspace error %lu %d", + (unsigned long)dh, errno); + return -ENOTCONN; + } + } else { + log_debug("dlm_new_lockspace..."); + + dh = dlm_new_lockspace("dlm_seq", 0600, 0); + if (!dh) { + log_error("dlm_new_lockspace error %lu %d", + (unsigned long)dh, errno); + return -ENOTCONN; + } + } + + libdlm_fd = dlm_ls_get_fd(dh); + if (libdlm_fd < 0) { + log_error("dlm_ls_get fd error %d %d", libdlm_fd, errno); + goto done; + } + + lkids = malloc(sizeof(uint32_t) * (num_r * num_lpr)); + if (!lkids) { + log_error("no mem"); + goto done; + } + + while (1) { + _acquire(LKM_EXMODE); + _convert(LKM_PRMODE); + _unlock(); + _acquire(LKM_EXMODE); + _unlock(); + _acquire(LKM_EXMODE); + _convert(LKM_NLMODE); + _convert(LKM_EXMODE); + _unlock(); + + _acquire(LKM_PRMODE); + _convert(LKM_EXMODE); + _unlock(); + _acquire(LKM_PRMODE); + _unlock(); + _acquire(LKM_PRMODE); + _convert(LKM_NLMODE); + _convert(LKM_PRMODE); + _unlock(); + + _acquire(LKM_NLMODE); + _convert(LKM_PRMODE); + _unlock(); + _acquire(LKM_NLMODE); + _unlock(); + _acquire(LKM_NLMODE); + _convert(LKM_EXMODE); + _convert(LKM_NLMODE); + _unlock(); + + iter++; + + if (!num_iter) + continue; + if (iter == num_iter) + break; + } + + free(lkids); + + done: + if (openclose) { + log_debug("dlm_close_lockspace"); + + rv = dlm_close_lockspace(dh); + if (rv < 0) + log_error("dlm_close_lockspace error %d %d", + rv, errno); + } else { + log_debug("dlm_release_lockspace"); + + rv = dlm_release_lockspace("dlm_seq", dh, 1); + if (rv < 0) + log_error("dlm_release_lockspace error %d %d", + rv, errno); + } + + return 0; +} + diff --git a/tests/scripts/dlm_seq_sync.c b/tests/scripts/dlm_seq_sync.c new file mode 100644 index 0000000..b8faccf --- /dev/null +++ b/tests/scripts/dlm_seq_sync.c @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2011 David Teigland + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License V2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* gcc dlm_seq_sync.c -ldlm_lt -o dlm_seq_sync */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libdlm.h" + +#define DEFAULT_NUM_R 1000 +#define DEFAULT_NUM_LPR 1 + +static dlm_lshandle_t *dh; +static int openclose = 0; +static int quiet = 0; +static int verbose = 0; +static int opt_convert = 0; +static int opt_unlock = 0; +static int opt_delay = 0; +static unsigned int num_r = DEFAULT_NUM_R; +static unsigned int num_lpr = DEFAULT_NUM_LPR; +static unsigned int num_iter = 1; +static unsigned int iter = 0; +static uint32_t *lkids; +static struct dlm_lksb lksb; +static unsigned int cb_count; + +#define log_debug(fmt, args...) \ +do { \ + if (!quiet) \ + printf(fmt "\n", ##args); \ +} while (0) + +#define log_error(fmt, args...) \ +do { \ + printf("ERROR " fmt "\n", ##args); \ + exit(-1); \ +} while (0) + + +static void seq(int acquire, int convert, int unlock, int mode) +{ + char name[DLM_RESNAME_MAXLEN]; + uint32_t lkid; + int i, j, rv; + + for (i = 0; i < num_r; i++) { + snprintf(name, sizeof(name), "seq.%08d", i); + + for (j = 0; j < num_lpr; j++) { + memset(&lksb, 0, sizeof(lksb)); + + if (acquire) { + printf("acquire %s %d\n", name, mode); + rv = dlm_ls_lock_wait(dh, mode, &lksb, 0, + name, strlen(name), + 0, NULL, NULL, NULL); + } + if (convert) { + lksb.sb_lkid = lkids[(i * num_lpr) + j]; + + printf("convert %s %x %d\n", name, lksb.sb_lkid, mode); + + rv = dlm_ls_lock_wait(dh, mode, &lksb, + LKF_CONVERT, + name, strlen(name), + 0, NULL, NULL, NULL); + } + if (unlock) { + lkid = lkids[(i * num_lpr) + j]; + + printf("unlock %s %x\n", name, lkid); + + rv = dlm_ls_unlock_wait(dh, lkid, 0, &lksb); + } + + if (rv) { + log_error("dlm op %d %d %d %d,%d error %d", + acquire, convert, unlock, i, j, rv); + exit(EXIT_FAILURE); + } + + if (acquire && lkids) + lkids[(i * num_lpr) + j] = lksb.sb_lkid; + } + } +} + +static void print_usage(void) +{ + printf("dlm_seq [options]\n"); + printf("Options:\n"); + printf("\n"); + printf(" -i Iterations (0 no limit), default 1)\n"); + printf(" -r The number of resources, default %d\n", DEFAULT_NUM_R); + printf(" -l The number of locks per resource, default %d\n", DEFAULT_NUM_LPR); + printf(" -c Convert locks after acquiring them all\n"); + printf(" -u Unlock locks after acquire/convert\n"); + printf(" -s Same resource names in each iteration\n"); + printf(" -d Delay us between consecutive seq\n"); + printf(" -o Open/close existing lockspace\n"); + printf(" -v Verbose output\n"); + printf(" -q Quiet output\n"); +} + +static void decode_arguments(int argc, char **argv) +{ + int cont = 1; + int optchar; + + while (cont) { + optchar = getopt(argc, argv, "i:r:l:cuvqohad:s"); + + switch (optchar) { + + case 'i': + num_iter = atoi(optarg); + break; + + case 'r': + num_r = atoi(optarg); + break; + + case 'l': + num_lpr = atoi(optarg); + break; + + case 'c': + opt_convert = 1; + break; + + case 'u': + opt_unlock = 1; + break; + + case 'd': + opt_delay = atoi(optarg); + break; + + case 'o': + openclose = 1; + break; + + case 'v': + verbose = 1; + break; + + case 'q': + quiet = 1; + break; + + case 'h': + print_usage(); + exit(EXIT_SUCCESS); + break; + + case 'V': + printf("%s (built %s %s)\n", argv[0], __DATE__, __TIME__); + exit(EXIT_SUCCESS); + break; + + case ':': + case '?': + fprintf(stderr, "Please use '-h' for usage.\n"); + exit(EXIT_FAILURE); + break; + + case EOF: + cont = 0; + break; + + default: + fprintf(stderr, "unknown option: %c\n", optchar); + exit(EXIT_FAILURE); + break; + }; + } +} + +void _acquire(int mode) +{ + seq(1, 0, 0, mode); + + if (opt_delay) + usleep(opt_delay); +} + +void _convert(int mode) +{ + seq(0, 1, 0, mode); + + if (opt_delay) + usleep(opt_delay); +} + +void _unlock(void) +{ + seq(0, 0, 1, 0); + + if (opt_delay) + usleep(opt_delay); +} + +int main(int argc, char *argv[]) +{ + int rv, quit = 0; + + decode_arguments(argc, argv); + + printf("%d resources, %d locks per resource\n", num_r, num_lpr); + + if (openclose) { + log_debug("dlm_open_lockspace..."); + + dh = dlm_open_lockspace("dlm_seq"); + if (!dh) { + log_error("dlm_open_lockspace error %lu %d", + (unsigned long)dh, errno); + return -ENOTCONN; + } + } else { + log_debug("dlm_new_lockspace..."); + + dh = dlm_new_lockspace("dlm_seq", 0600, 0); + if (!dh) { + log_error("dlm_new_lockspace error %lu %d", + (unsigned long)dh, errno); + return -ENOTCONN; + } + } + + lkids = malloc(sizeof(uint32_t) * (num_r * num_lpr)); + if (!lkids) { + log_error("no mem"); + goto done; + } + + while (1) { + _acquire(LKM_EXMODE); + _convert(LKM_PRMODE); + _unlock(); + _acquire(LKM_EXMODE); + _unlock(); + _acquire(LKM_EXMODE); + _convert(LKM_NLMODE); + _convert(LKM_EXMODE); + _unlock(); + + _acquire(LKM_PRMODE); + _convert(LKM_EXMODE); + _unlock(); + _acquire(LKM_PRMODE); + _unlock(); + _acquire(LKM_PRMODE); + _convert(LKM_NLMODE); + _convert(LKM_PRMODE); + _unlock(); + + _acquire(LKM_NLMODE); + _convert(LKM_PRMODE); + _unlock(); + _acquire(LKM_NLMODE); + _unlock(); + _acquire(LKM_NLMODE); + _convert(LKM_EXMODE); + _convert(LKM_NLMODE); + _unlock(); + + iter++; + + if (!num_iter) + continue; + if (iter == num_iter) + break; + } + + free(lkids); + + done: + if (openclose) { + log_debug("dlm_close_lockspace"); + + rv = dlm_close_lockspace(dh); + if (rv < 0) + log_error("dlm_close_lockspace error %d %d", + rv, errno); + } else { + log_debug("dlm_release_lockspace"); + + rv = dlm_release_lockspace("dlm_seq", dh, 1); + if (rv < 0) + log_error("dlm_release_lockspace error %d %d", + rv, errno); + } + + return 0; +} + diff --git a/tests/scripts/run_tests.sh b/tests/scripts/run_tests.sh new file mode 100644 index 0000000..58ed555 --- /dev/null +++ b/tests/scripts/run_tests.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +set -x + +COROSYNC_NODE=$(hostname) + +sed -e "s/@LOCAL_NODE@/$COROSYNC_NODE/" test-corosync-conf > /etc/corosync/corosync.conf + +modprobe configfs +mount -t configfs none /sys/kernel/config + +modprobe dlm + +ls /sys/kernel/config +ls /sys/kernel/config/dlm + +mkdir /var/log/cluster + +systemctl start corosync +sleep 2 +corosync-quorumtool +sleep 2 + +tail -8 /var/log/cluster/corosync.conf + +mkdir /var/log/dlm_controld + +dlm_controld --log_debug --debug_logfile --enable_fencing 0 --enable_quorum_lockspace 0 --enable_quorum_fencing 0 --enable_startup_fencing 0 +sleep 2 + +tail -8 /var/log/dlm_controld/dlm_controld.log + +ls /sys/kernel/config/dlm + +dlm_tool status + +gcc dlm_seq_async.c -ldlm -o dlm_seq_async +gcc dlm_seq_sync.c -ldlm_lt -o dlm_seq_sync + +./dlm_seq_sync -i 100 -d 10000 -c -u -v -r 10 -i 10 + +[ $? -ne 0 ] && echo "dlm_seq_sync error" >&2 && exit 1 + +./dlm_seq_async -i 100 -d 10000 -c -u -v -r 10 -i 10 + +[ $? -ne 0 ] && echo "dlm_seq_async error" >&2 && exit 1 + +pkill dlm_controld +sleep 2 +corosync-cfgtool -H diff --git a/tests/scripts/test-corosync-conf b/tests/scripts/test-corosync-conf new file mode 100644 index 0000000..346c1ec --- /dev/null +++ b/tests/scripts/test-corosync-conf @@ -0,0 +1,20 @@ +totem { + version: 2 + secauth: off + cluster_name: test +} +nodelist { + node { + ring0_addr: @LOCAL_NODE@ + nodeid: 1 + } +} +quorum { + provider: corosync_votequorum +} +logging { + to_logfile: yes + logfile: /var/log/cluster/corosync.log + to_syslog: yes +} + diff --git a/tests/tests.yml b/tests/tests.yml new file mode 100644 index 0000000..6ef0f93 --- /dev/null +++ b/tests/tests.yml @@ -0,0 +1,14 @@ +- hosts: localhost + roles: + - role: standard-test-basic # this is a standard test role, it takes care of the test environment, logging, archiving results.. + tags: + - classic + tests: + - simple: + dir: scripts + run: ./run_tests.sh + required_packages: + - dlm + - dlm-devel + - corosync + - gcc