/* * Copyright (c) 2007 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. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "libdlm.h" #define die(fmt, args...) \ do \ { \ fprintf(stderr, "%s: ", prog_name); \ fprintf(stderr, fmt, ##args); \ exit(EXIT_FAILURE); \ } \ while (0) static char *prog_name; static dlm_lshandle_t *dh; static int verbose; static struct dlm_lksb lksb; static char lvb[32]; int main(int argc, char *argv[]) { unsigned long long offset; unsigned long long num, last_num = 0; unsigned int id, clients, sleeptime = 0; unsigned long long skip = 0; char *name; int rv; prog_name = argv[0]; verbose = 0; if (argc < 5) die("name offset id clients [sleep]\n"); name = argv[1]; offset = atoll(argv[2]); id = atoi(argv[3]); clients = atoi(argv[4]); if (argc > 5) sleeptime = atoi(argv[5]); printf("Joining \"alternate\" lockspace...\n"); dh = dlm_create_lockspace("alternate", 0600); if (!dh) { printf("dlm_create_lockspace error %p %d\n",dh, errno); return -ENOTCONN; } rv = dlm_ls_pthread_init(dh); if (rv < 0) { printf("dlm_ls_pthread_init error %d %d\n", rv, errno); dlm_release_lockspace("alternate", dh, 1); return rv; } memset(&lksb, 0, sizeof(lksb)); memset(&lvb, 0, sizeof(lvb)); lksb.sb_lvbptr = lvb; if (verbose) printf("request NL\n"); rv = dlm_ls_lock_wait(dh, LKM_NLMODE, &lksb, LKF_VALBLK, name, strlen(name), 0, NULL, NULL, NULL); while (1) { if (verbose) printf("convert NL->PR\n"); rv = dlm_ls_lock_wait(dh, LKM_PRMODE, &lksb, LKF_VALBLK | LKF_CONVERT, name, strlen(name), 0, NULL, NULL, NULL); if (rv) printf("lock1 error: %d %d\n", rv, lksb.sb_status); memcpy(&num, &lvb, sizeof(num)); if (verbose) printf("read lvb %llu\n", num); /* it's our turn */ if (num % clients == id) { if (last_num && last_num + clients != num + 1) die("bad: num %llu last_num %llu\n", num, last_num); if (verbose) printf("convert PR->EX\n"); rv = dlm_ls_lock_wait(dh, LKM_EXMODE, &lksb, LKF_VALBLK | LKF_CONVERT, name, strlen(name), 0, NULL, NULL, NULL); if (rv) printf("lock2 error: %d %d\n", rv, lksb.sb_status); memcpy(&num, &lvb, sizeof(num)); if (num % clients != id) die("bad2: num %llu\n", num); num++; memcpy(&lvb, &num, sizeof(num)); printf("%llu %llu\n", num, skip); if (verbose) printf("convert EX->NL\n"); rv = dlm_ls_lock_wait(dh, LKM_NLMODE, &lksb, LKF_VALBLK | LKF_CONVERT, name, strlen(name), 0, NULL, NULL, NULL); if (rv) printf("lock3 error: %d %d\n", rv, lksb.sb_status); last_num = num; skip = 0; } else { skip++; if (verbose) printf("convert PR->NL, skip %llu\n", skip); rv = dlm_ls_lock_wait(dh, LKM_NLMODE, &lksb, LKF_VALBLK | LKF_CONVERT, name, strlen(name), 0, NULL, NULL, NULL); if (rv) printf("lock4 error: %d %d\n", rv, lksb.sb_status); } if (sleeptime) usleep(sleeptime); } dlm_ls_unlock_wait(dh, lksb.sb_lkid, 0, &lksb); dlm_release_lockspace("alternate", dh, 1); exit(EXIT_SUCCESS); }