Skip to content

Instantly share code, notes, and snippets.

@ToroNZ
Created January 23, 2019 01:54
Show Gist options
  • Select an option

  • Save ToroNZ/e6f6257f2ce4e339ee49d63dd0c58e5c to your computer and use it in GitHub Desktop.

Select an option

Save ToroNZ/e6f6257f2ce4e339ee49d63dd0c58e5c to your computer and use it in GitHub Desktop.
Lockfile test to see NFS CB_NOTIFY_LOCK behaviour between Linux/BSD NFS server implementations.
/*
* locktest.c
*
* Lock a file (block until we have a lock), write a message to the file, and
* sleep for a while. If we run multiple of these at once in a loop, we can show
* that file system locking is working correctly.
*
* USAGE:
* locktest.exe FILENAME SECONDS MESSAGE NUMRUNS
*
* PARAMETERS:
* FILENAME: This program will attempt to lock FILENAME.lck, and once completed
* will write the parameter MESSAGE to FILENAME.
* SECONDS: Period to sleep for after obtaining a lock and writing a message
* to FILENAME. We use this to show clearly that other process is
* waiting.
* MESSAGE: Message to write to FILENAME on each loop. A good value to use
* is $HOSTNAME, so if we run from multiple PODs, it will show how many
* successful writes there have been, and if the locking is really
* working properly - if it isn't we won't see a full set of entries in
* the file.
* NUMRUNS: Run this many executions of our full process. Useful when wanting to
* show that locking behaves over many executions.
*
* DESCRIPTION:
*
* Created on: Jan 23, 2019
*
*/
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <iostream>
#include <string.h>
#include <string>
#include <sstream>
#include <stdlib.h>
using namespace std;
int main(int argc, const char *argv[])
{
if (argc != 5)
{
cerr << "Usage:" << argv[0] << " FILENAME SECONDS MESSAGE NUMRUNS" << endl;
exit(1);
}
const char *filename = argv[1];
int seconds;
stringstream ss1(argv[2]);
ss1 >> seconds;
const char *message = argv[3];
int numruns;
stringstream ss2(argv[4]);
ss2 >> numruns;
if ( !filename || !strcmp(filename,"") )
{
filename = "lock.txt";
cout << "Using default value for file (" << filename << ")" << endl;
}
for (int i=1; i<=numruns; i++)
{
if (numruns > 0)
{
cout << "Execution #" << i << endl;
}
char lockfilename[100];
sprintf(lockfilename, "%s.lck", filename);
cout << "Opening " << lockfilename << endl;
int lockfd = open(lockfilename, O_WRONLY | O_CREAT, 0664);
if (lockfd < 0)
{
cerr << "ERROR: Could not open " << lockfilename << " (" << strerror(errno) << ")" << endl;
exit(1);
}
cout << "Locking " << lockfilename << endl;
if (lockf(lockfd, F_LOCK, 0) != 0)
{
cerr << "ERROR: Could not lock " << lockfilename << " (" << strerror(errno) << ")" << endl;
close(lockfd);
exit(1);
}
cout << "Locked " << lockfilename << std::endl;
cout << "Opening " << filename << endl;
FILE *fp = fopen(filename, "a");
if (!fp)
{
cerr << "ERROR: Could not open " << filename << " (" << strerror(errno) << ")" << endl;
exit(1);
}
cout << "Writing message to " << filename << endl;
fprintf(fp, "%s\n", message);
fflush(fp);
if (seconds)
{
cout << "Sleeping for " << seconds << " seconds..." << endl;
sleep(seconds);
}
cout << "Closing " << filename << std::endl;
fclose(fp);
cout << "Closing " << lockfilename << std::endl;
close(lockfd);
}
exit(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment