added sparse test
[tridge/junkcode.git] / tsmread.c
1 /*
2   example program to read a file in the same way that Samba does. This
3   demonstrates the problem with GPFS share modes and leases and TSM
4   migrated files
5
6   Andrew Tridgell January 2008
7
8   compile with:
9
10      gcc -Wall -o tsmread{,.c} -lgpfs_gpl
11
12   then to run you must symlink tsmread to smbd
13
14      ln -s tsmread smbd
15
16   and run like this:
17
18     ./smbd /gpfs/data/tsmtest/test.dat 
19     ./smbd /gpfs/data/tsmtest/test.dat -S
20     ./smbd /gpfs/data/tsmtest/test.dat -L
21     ./smbd /gpfs/data/tsmtest/test.dat -L -S
22
23  */
24
25 #define _XOPEN_SOURCE 500
26
27 #include <stdio.h>
28 #include <unistd.h>
29 #include <stdlib.h>
30 #include <errno.h>
31 #include <sys/stat.h>
32 #include <fcntl.h>
33 #include <string.h>
34 #include <getopt.h>
35 #include <signal.h>
36 #include <stdbool.h>
37 #include "gpfs_gpl.h"
38
39
40 static void sigio_handler(int sig)
41 {
42         printf("Got SIGIO\n");
43 }
44
45 static int read_file(const char *fname, bool use_lease, bool use_sharemode, bool do_write)
46 {
47         int fd;
48         char c = 42;
49         struct stat st;
50
51         printf("Reading '%s' with use_lease=%s use_sharemode=%s\n",
52                fname, use_lease?"yes":"no", use_sharemode?"yes":"no");
53
54         signal(SIGIO, sigio_handler);
55
56         fd = open(fname, do_write?O_RDWR:O_RDONLY);
57         if (fd == -1) {
58                 perror(fname);
59                 return -1;
60         }
61
62         if (fstat(fd, &st) != 0 || st.st_blocks != 0 || st.st_size == 0) {
63                 printf("WARNING: file is not offline - test INVALID\n");
64         }
65
66         if (use_lease && gpfs_set_lease(fd, do_write?GPFS_LEASE_WRITE:GPFS_LEASE_READ) != 0) {
67                 perror("gpfs_set_lease");
68                 close(fd);
69                 return -1;
70         }
71
72         if (use_sharemode && gpfs_set_share(fd, 1, 2) != 0) {
73                 perror("gpfs_set_share");
74                 close(fd);
75                 return -1;
76         }
77
78         if (do_write && pwrite(fd, &c, 1, 0) != 1) {
79                 perror("pwrite");
80                 close(fd);
81                 return -1;              
82         }
83
84         if (pread(fd, &c, 1, 0) != 1) {
85                 perror("pread");
86                 close(fd);
87                 return -1;              
88         }
89
90         printf("read OK\n");
91         
92         close(fd);
93         return 0;       
94 }
95
96 static void usage(void)
97 {
98         printf("Usage: (note, must run as 'smbd')\n");
99         printf("ln -sf tesmread smbd\n");
100         printf("./smbd [options] <files>\n");
101         printf("Options:\n");
102         printf("  -L    use gpfs leases\n");
103         printf("  -S    use gpfs sharemodes\n");
104         printf("  -W    do a write before a read\n");
105         exit(0);
106 }
107
108 int main(int argc, char * const argv[])
109 {
110         int opt, i;
111         bool use_lease = false, use_sharemode = false, do_write=false;
112         const char *progname = argv[0];
113
114         if (strstr(progname, "smbd") == NULL) {
115                 printf("WARNING: you should invoke as smbd - use a symlink\n");
116         }
117         
118         /* parse command-line options */
119         while ((opt = getopt(argc, argv, "LSWh")) != -1) {
120                 switch (opt){
121                 case 'L':
122                         use_lease = true;
123                         break;
124                 case 'S':
125                         use_sharemode = true;
126                         break;
127                 case 'W':
128                         do_write = true;
129                         break;
130                 default:
131                         usage();
132                         break;
133                 }
134         }
135
136         argv += optind;
137         argc -= optind;
138
139         if (argc == 0) {
140                 usage();
141         }
142
143         for (i=0;i<argc;i++) {
144                 const char *fname = argv[i];
145                 if (read_file(fname, use_lease, use_sharemode, do_write) != 0) {
146                         printf("Failed to read '%s'\n", fname);
147                 }
148         }
149
150         return 0;
151 }