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]
22 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
30 * user interface to lockfs functionality
32 #include <sys/types.h>
37 #include <sys/mntent.h>
38 #include <sys/mnttab.h>
40 #include <sys/lockfs.h>
41 #include <sys/filio.h>
43 #define bzero(s, n) memset(s, 0, n);
46 * command line processing
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);
81 struct filename
*fn_next
;
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
109 int no_unlocks_printed
= 0;
112 * file system was modified during hlock/wlock/elock
114 #define LOCKWARN(FN, S) \
117 printf("WARNING: %s was modified while %s locked\n", FN, S); \
127 main(int argc
, char *argv
[])
130 struct filename
*fnp
;
135 * process command line
140 while ((c
= getopt(argc
, argv
, "vfwnduheac:")) != -1)
177 comlen
= strlen(optarg
)+1;
186 no_unlocks_printed
= 1;
199 getcmdnames(argc
, argv
, optind
);
202 * for each filename, doit
204 for (fnp
= fnanchor
; fnp
; fnp
= fnp
->fn_next
) {
207 printstatus(fnp
->fn_name
);
210 lockfs(fnp
->fn_name
);
213 flushfs(fnp
->fn_name
);
227 * bad command line, give hint
232 printf("usage: lockfs [-dfhnuw] [-c string] [-a] [file system ...]\n");
237 * prettyprint the status line
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
);
248 * get and prettyprint file system lock status
251 printstatus(char *fn
)
256 char commentbuffer
[LOCKFS_MAXCOMMENTLEN
+1];
259 fd
= open64(fn
, O_RDONLY
);
262 printstatusline(fn
, "EIO", "May be hard locked");
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) {
281 switch (lf
.lf_lock
) {
283 if (no_unlocks_printed
)
285 if (LOCKFS_IS_BUSY(&lf
))
286 locktype
= "(unlock)";
291 if (LOCKFS_IS_BUSY(&lf
))
292 locktype
= "(write)";
295 fsmod
= LOCKFS_IS_MOD(&lf
);
299 if (LOCKFS_IS_BUSY(&lf
))
306 if (LOCKFS_IS_BUSY(&lf
))
307 locktype
= "(delete)";
312 if (LOCKFS_IS_BUSY(&lf
))
316 fsmod
= LOCKFS_IS_MOD(&lf
);
320 if (LOCKFS_IS_BUSY(&lf
))
321 locktype
= "(error)";
324 fsmod
= LOCKFS_IS_MOD(&lf
);
328 if (LOCKFS_IS_BUSY(&lf
))
329 locktype
= "(unknown)";
331 locktype
= "unknown";
334 lf
.lf_comment
[lf
.lf_comlen
] = '\0';
335 printstatusline(fn
, locktype
, lf
.lf_comment
);
337 LOCKWARN(fn
, locktype
);
343 * push and invalidate at least the data that is *currently* dirty
350 fd
= open64(fn
, O_RDONLY
);
357 if (ioctl(fd
, _FIOFFS
, NULL
) == -1) {
367 * lock the file system
375 fd
= open64(fn
, O_RDONLY
);
382 bzero((caddr_t
)&lf
, sizeof (struct lockfs
));
384 lf
.lf_flags
= LOCKFS_MOD
;
385 if (ioctl(fd
, _FIOLFSS
, &lf
) == -1) {
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");
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) {
417 * file names from /etc/mtab
423 struct filename
*fnp
;
424 struct filename
*fnpc
;
426 struct mnttab mnt
, *mntp
= &mnt
;
430 if ((mnttab
= fopen(MNTTAB
, "r")) == NULL
) {
431 fprintf(stderr
, "Can't open %s\n", MNTTAB
);
435 while ((getmntent(mnttab
, mntp
)) == 0) {
436 if (strcmp(mntp
->mnt_fstype
, MNTTYPE_UFS
) != 0)
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
);
453 * file names from command line
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
);