-
Nathan Rutman authoredNathan Rutman authored
mkdirdeep.c 7.20 KiB
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=8:tabstop=8:
*
* Compile with:
* cc -I../../lnet/include -o mkdirdeep mkdirdeep.c
* -L../../lnet/linux/utils -lptlctl
*/
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/limits.h>
#include <libcfs/lltrace.h>
static int opt_verbose = 0;
static int opt_trace = 0;
void usage(const char *pname)
{
fprintf(stderr, "Usage: %s --depth <d> [--output <outputtracefilename>]"
" [--mknod] [--verbose] [--notrace] <basepath>\n", pname);
exit(1);
}
int do_mkdir(char *path)
{
int rc = mkdir(path, 0755);
if (rc) {
fprintf(stderr, "mkdir(%s) failed: %s\n",
path, strerror(errno));
exit(1);
}
if (opt_verbose)
printf("mkdir %s\n", path);
return rc;
}
int do_mknod(char *path)
{
int rc = mknod(path, 0755, S_IFIFO);
if (rc) {
fprintf(stderr, "mkdir(%s) failed: %s\n",
path, strerror(errno));
exit(1);
}
if (opt_verbose)
printf("mknod %s\n", path);
return rc;
}
int do_chdir(char* path)
{
int rc = chdir(path);
if (rc) {
fprintf(stderr, "chdir(%s) failed: %s\n",
path, strerror(errno));
exit(1);
}
if (opt_verbose)
printf("chdir %s\n", path);
return rc;
}
int do_stat(char *path)
{
char mark_buf[PATH_MAX + 50];
struct stat mystat;
int rc = stat(path, &mystat);
if (rc) {
fprintf(stderr, "stat(%s) failed: %s\n",
path, strerror(errno));
exit(1);
}
if (opt_verbose)
printf("stat %s = inode %lu\n", path,
(unsigned long)mystat.st_ino);
if (opt_trace) {
snprintf(mark_buf, PATH_MAX, "stat %s = inode %lu",
path, (unsigned long)mystat.st_ino);
ltrace_mark(0, mark_buf);
}
return rc;
}
int main(int argc, char** argv)
{
int c, i, mypid;
int opt_depth = 1;
int opt_mknod = 0;
static struct option long_opt[] = {
{"depth", 1, 0, 'd' },
{"help", 0, 0, 'h' },
{"mknod", 0, 0, 'm' },
{"output", 1, 0, 'o' },
{"trace", 1, 0, 't' },
{"verbose", 0, 0, 'v' },
{0,0,0,0}
};
char *outputfilename = NULL;
char *base_pathname;
char pathname[PATH_MAX];
char mark_buf[PATH_MAX + 50];
char mycwd[PATH_MAX];
char *pname = argv[0];
while ((c = getopt_long(argc, argv, "d:mhvo:", long_opt, NULL)) != -1) {
switch (c) {
case 'd':
opt_depth = atoi(optarg);
if ((opt_depth == 0) || (opt_depth > 1100))
usage(pname);
break;
case 'm':
opt_mknod = 1;
break;
case 't':
opt_trace = 1;
break;
case 'v':
opt_verbose = 1;
break;
case 'o':
outputfilename = optarg;
break;
case 'h':
case '?':
case ':':
default:
usage(pname);
break;
}
}
if (optind != (argc - 1))
usage(pname);
base_pathname = argv[optind];
mypid = getpid();
if (!getcwd(&mycwd[0], sizeof(mycwd))) {
fprintf(stderr, "%s: unable to getcwd()\n", pname);
exit(1);
}
printf("%s(pid=%d) depth=%d mknod=%d, basepathname=%s, trace=%d\n",
pname, mypid, opt_depth, opt_mknod, base_pathname, opt_trace);
if (outputfilename)
printf("outputfilename=%s\n", outputfilename);
if (opt_trace) {
ltrace_start();
ltrace_clear();
snprintf(mark_buf, PATH_MAX, "Initialize - mkdir %s; chdir %s",
base_pathname, base_pathname);
ltrace_mark(2, mark_buf);
}
if (do_mkdir(base_pathname)!=0)
exit(1);
if (do_chdir(base_pathname)!=0)
exit(1);
/* Create directory tree with depth level of subdirectories */
if (opt_trace) {
snprintf(mark_buf, PATH_MAX,
"Create Directory Tree (depth %d)", opt_depth);
ltrace_mark(2, mark_buf);
}
for (i = 0; i < opt_depth; i++) {
snprintf(pathname, sizeof(pathname), "%d", i + 1);
if (i == (opt_depth - 1)) {
/* Last Iteration */
if (opt_trace) {
snprintf(mark_buf, PATH_MAX,
"Tree Leaf (%d) %s/stat", i,
(opt_mknod ? "mknod" : "mkdir"));
ltrace_mark(3, mark_buf);
}
if (opt_mknod)
do_mknod(pathname);
else
do_mkdir(pathname);
/* Now stat it */
do_stat(pathname);
} else {
/* Not Leaf */
if (opt_trace) {
snprintf(mark_buf, sizeof(mark_buf),
"Tree Level (%d) mkdir/stat/chdir", i);
ltrace_mark(3, mark_buf);
}
do_mkdir(pathname);
do_stat(pathname);
do_chdir(pathname);
}
}
/* Stat through directory tree with fullpaths */
if (opt_trace) {
snprintf(mark_buf, PATH_MAX, "Walk Directory Tree");
ltrace_mark(2, mark_buf);
}
do_chdir(base_pathname);
strncpy(pathname, base_pathname, sizeof(pathname));
c = strlen(base_pathname);
for (i = 0; i < opt_depth; i++) {
c += snprintf(pathname + c, sizeof(pathname) - c, "/%d", i+1);
if (opt_trace) {
snprintf(mark_buf, PATH_MAX, "stat %s", pathname);
ltrace_mark(2, mark_buf);
}
do_stat(pathname);
}
if (opt_trace && outputfilename) {
ltrace_write_file(outputfilename);
ltrace_add_processnames(outputfilename);
ltrace_stop();
}
do_chdir(base_pathname);
printf("%s (pid=%d) done.\n", pname, mypid);
return 0;
}