8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / fs.d / ufs / lockfs / lockfs.c
blobb10bdae5225d0b54b69ebc2140019ef316bcdef0
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
29 * lockfs
30 * user interface to lockfs functionality
32 #include <sys/types.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <unistd.h>
36 #include <fcntl.h>
37 #include <sys/mntent.h>
38 #include <sys/mnttab.h>
39 #include <errno.h>
40 #include <sys/lockfs.h>
41 #include <sys/filio.h>
43 #define bzero(s, n) memset(s, 0, n);
46 * command line processing
48 extern char *optarg;
49 extern int optind;
50 extern int opterr;
52 extern void exit();
54 static void exitusage();
55 static void printstatusline(char *, char *, char *);
56 static void printstatus(char *);
57 static void flushfs(char *);
58 static void lockfs(char *);
59 static void getmntnames();
60 static void getcmdnames(int, char **, int);
63 * -a = all
64 * -v = verbose
66 int all = 0;
67 int verbose = 0;
70 * exitstatus
71 * 0 all ok
72 * 1 internal error
73 * 2 system call error
75 int exitstatus = 0;
78 * list of filenames
80 struct filename {
81 struct filename *fn_next;
82 char *fn_name;
84 struct filename *fnanchor = 0;
87 * default request is `file system lock status'
88 * default lock type is `unlock'
89 * -wnduhfe changes them
91 int request = _FIOLFSS;
92 ushort_t lock = LOCKFS_ULOCK;
95 * default comment is null
96 * -c changes it
98 caddr_t comment = 0;
99 ulong_t comlen = 0;
102 * for prettyprint
104 int firsttime = 0;
107 * no unlocks printed
109 int no_unlocks_printed = 0;
112 * file system was modified during hlock/wlock/elock
114 #define LOCKWARN(FN, S) \
116 if (verbose) \
117 printf("WARNING: %s was modified while %s locked\n", FN, S); \
118 exitstatus = 2; \
122 * forward reference
124 char *malloc();
127 main(int argc, char *argv[])
129 int c;
130 struct filename *fnp;
132 exitstatus = 0;
135 * process command line
137 opterr = 0;
138 optarg = 0;
140 while ((c = getopt(argc, argv, "vfwnduheac:")) != -1)
141 switch (c) {
142 case 'v':
143 verbose = 1;
144 break;
145 case 'f':
146 request = _FIOFFS;
147 break;
148 case 'w':
149 lock = LOCKFS_WLOCK;
150 request = _FIOLFS;
151 break;
152 case 'n':
153 lock = LOCKFS_NLOCK;
154 request = _FIOLFS;
155 break;
156 case 'd':
157 lock = LOCKFS_DLOCK;
158 request = _FIOLFS;
159 break;
160 case 'h':
161 lock = LOCKFS_HLOCK;
162 request = _FIOLFS;
163 break;
164 case 'e':
165 lock = LOCKFS_ELOCK;
166 request = _FIOLFS;
167 break;
168 case 'u':
169 lock = LOCKFS_ULOCK;
170 request = _FIOLFS;
171 break;
172 case 'a':
173 all = 1;
174 break;
175 case 'c':
176 comment = optarg;
177 comlen = strlen(optarg)+1;
178 request = _FIOLFS;
179 break;
180 default:
181 exitusage();
182 break;
185 if (argc == 1) {
186 no_unlocks_printed = 1;
187 all = 1;
190 if (all)
192 * use /etc/mtab
194 getmntnames();
195 else
197 * use command line
199 getcmdnames(argc, argv, optind);
202 * for each filename, doit
204 for (fnp = fnanchor; fnp; fnp = fnp->fn_next) {
205 switch (request) {
206 case _FIOLFSS:
207 printstatus(fnp->fn_name);
208 break;
209 case _FIOLFS:
210 lockfs(fnp->fn_name);
211 break;
212 case _FIOFFS:
213 flushfs(fnp->fn_name);
214 break;
215 default:
216 break;
221 * all done
223 return (exitstatus);
226 * exitusage
227 * bad command line, give hint
229 void
230 exitusage()
232 printf("usage: lockfs [-dfhnuw] [-c string] [-a] [file system ...]\n");
233 exit(1);
236 * printstatusline
237 * prettyprint the status line
239 void
240 printstatusline(char *fn, char *locktype, char *comment)
242 if (firsttime++ == 0)
243 printf("%-20s %-10s %s\n", "Filesystem", "Locktype", "Comment");
244 printf("%-20s %-10s %s\n", fn, locktype, comment);
247 * printstatus
248 * get and prettyprint file system lock status
250 void
251 printstatus(char *fn)
253 int fd;
254 int fsmod = 0;
255 char *locktype;
256 char commentbuffer[LOCKFS_MAXCOMMENTLEN+1];
257 struct lockfs lf;
259 fd = open64(fn, O_RDONLY);
260 if (fd == -1) {
261 if (errno == EIO)
262 printstatusline(fn, "EIO", "May be hard locked");
263 else
264 perror(fn);
265 exitstatus = 2;
266 return;
269 bzero((caddr_t)&lf, sizeof (struct lockfs));
271 lf.lf_flags = LOCKFS_MOD;
272 lf.lf_comlen = LOCKFS_MAXCOMMENTLEN;
273 lf.lf_comment = commentbuffer;
275 if (ioctl(fd, _FIOLFSS, &lf) == -1) {
276 perror(fn);
277 close(fd);
278 exitstatus = 2;
279 return;
281 switch (lf.lf_lock) {
282 case LOCKFS_ULOCK:
283 if (no_unlocks_printed)
284 goto out;
285 if (LOCKFS_IS_BUSY(&lf))
286 locktype = "(unlock)";
287 else
288 locktype = "unlock";
289 break;
290 case LOCKFS_WLOCK:
291 if (LOCKFS_IS_BUSY(&lf))
292 locktype = "(write)";
293 else {
294 locktype = "write";
295 fsmod = LOCKFS_IS_MOD(&lf);
297 break;
298 case LOCKFS_NLOCK:
299 if (LOCKFS_IS_BUSY(&lf))
300 locktype = "(name)";
301 else
302 locktype = "name";
303 break;
304 case LOCKFS_DLOCK:
305 locktype = "delete";
306 if (LOCKFS_IS_BUSY(&lf))
307 locktype = "(delete)";
308 else
309 locktype = "delete";
310 break;
311 case LOCKFS_HLOCK:
312 if (LOCKFS_IS_BUSY(&lf))
313 locktype = "(hard)";
314 else {
315 locktype = "hard";
316 fsmod = LOCKFS_IS_MOD(&lf);
318 break;
319 case LOCKFS_ELOCK:
320 if (LOCKFS_IS_BUSY(&lf))
321 locktype = "(error)";
322 else {
323 locktype = "error";
324 fsmod = LOCKFS_IS_MOD(&lf);
326 break;
327 default:
328 if (LOCKFS_IS_BUSY(&lf))
329 locktype = "(unknown)";
330 else
331 locktype = "unknown";
332 break;
334 lf.lf_comment[lf.lf_comlen] = '\0';
335 printstatusline(fn, locktype, lf.lf_comment);
336 if (fsmod)
337 LOCKWARN(fn, locktype);
338 out:
339 close(fd);
342 * flushfs
343 * push and invalidate at least the data that is *currently* dirty
345 void
346 flushfs(char *fn)
348 int fd;
350 fd = open64(fn, O_RDONLY);
351 if (fd == -1) {
352 perror(fn);
353 exitstatus = 2;
354 return;
357 if (ioctl(fd, _FIOFFS, NULL) == -1) {
358 perror(fn);
359 close(fd);
360 exitstatus = 2;
361 return;
363 close(fd);
366 * lockfs
367 * lock the file system
369 void
370 lockfs(char *fn)
372 int fd;
373 struct lockfs lf;
375 fd = open64(fn, O_RDONLY);
376 if (fd == -1) {
377 perror(fn);
378 exitstatus = 2;
379 return;
382 bzero((caddr_t)&lf, sizeof (struct lockfs));
384 lf.lf_flags = LOCKFS_MOD;
385 if (ioctl(fd, _FIOLFSS, &lf) == -1) {
386 perror(fn);
387 close(fd);
388 exitstatus = 2;
389 return;
392 if (!LOCKFS_IS_BUSY(&lf) && LOCKFS_IS_MOD(&lf)) {
393 if (LOCKFS_IS_HLOCK(&lf))
394 LOCKWARN(fn, "hard");
395 if (LOCKFS_IS_ELOCK(&lf))
396 LOCKWARN(fn, "error");
397 if (LOCKFS_IS_WLOCK(&lf))
398 LOCKWARN(fn, "write");
401 lf.lf_lock = lock;
402 lf.lf_flags = 0;
403 lf.lf_key = lf.lf_key;
404 lf.lf_comment = comment;
405 lf.lf_comlen = (comment) ? strlen(comment)+1 : 0;
407 if (ioctl(fd, _FIOLFS, &lf) == -1) {
408 perror(fn);
409 close(fd);
410 exitstatus = 2;
411 return;
413 close(fd);
416 * getmntnames
417 * file names from /etc/mtab
419 void
420 getmntnames()
422 int fnlen;
423 struct filename *fnp;
424 struct filename *fnpc;
425 FILE *mnttab;
426 struct mnttab mnt, *mntp = &mnt;
428 fnpc = fnanchor;
430 if ((mnttab = fopen(MNTTAB, "r")) == NULL) {
431 fprintf(stderr, "Can't open %s\n", MNTTAB);
432 perror(MNTTAB);
433 exit(32);
435 while ((getmntent(mnttab, mntp)) == 0) {
436 if (strcmp(mntp->mnt_fstype, MNTTYPE_UFS) != 0)
437 continue;
438 fnlen = strlen(mntp->mnt_mountp) + 1;
439 fnp = (struct filename *)malloc(sizeof (struct filename));
440 fnp->fn_name = malloc((uint_t)fnlen);
441 strcpy(fnp->fn_name, mntp->mnt_mountp);
442 fnp->fn_next = NULL;
443 if (fnpc)
444 fnpc->fn_next = fnp;
445 else
446 fnanchor = fnp;
447 fnpc = fnp;
449 fclose(mnttab);
452 * getcmdnames
453 * file names from command line
455 void
456 getcmdnames(int argc, char **argv, int i)
458 struct filename *fnp;
459 struct filename *fnpc;
461 for (fnpc = fnanchor; i < argc; ++i) {
462 fnp = (struct filename *)malloc(sizeof (struct filename));
463 fnp->fn_name = *(argv+i);
464 fnp->fn_next = NULL;
465 if (fnpc)
466 fnpc->fn_next = fnp;
467 else
468 fnanchor = fnp;
469 fnpc = fnp;