]>
Commit | Line | Data |
---|---|---|
f0bef3ca HT |
1 | /* |
2 | * fsfreeze.c -- Filesystem freeze/unfreeze IO for Linux | |
3 | * | |
4 | * Copyright (C) 2010 Hajime Taira <htaira@redhat.com> | |
5 | * Masatake Yamato <yamato@redhat.com> | |
6 | * | |
7 | * This program is free software. You can redistribute it and/or | |
8 | * modify it under the terms of the GNU General Public License as | |
9 | * published by the Free Software Foundation: either version 1 or | |
10 | * (at your option) any later version. | |
11 | */ | |
12 | ||
13 | #include <stdio.h> | |
14 | #include <stdlib.h> | |
15 | #include <errno.h> | |
16 | #include <string.h> | |
17 | #include <fcntl.h> | |
18 | #include <linux/fs.h> | |
19 | #include <sys/ioctl.h> | |
20 | #include <sys/types.h> | |
21 | #include <sys/stat.h> | |
22 | #include <getopt.h> | |
f0bef3ca HT |
23 | |
24 | #include "blkdev.h" | |
25 | #include "nls.h" | |
26 | #include "c.h" | |
27 | ||
28 | static int freeze_f(int fd) | |
29 | { | |
30 | return ioctl(fd, FIFREEZE, 0); | |
31 | } | |
32 | ||
33 | static int unfreeze_f(int fd) | |
34 | { | |
35 | return ioctl(fd, FITHAW, 0); | |
36 | } | |
37 | ||
38 | static void __attribute__((__noreturn__)) usage(FILE *out) | |
39 | { | |
40 | fprintf(out, _("Usage: %s [options] <mount point>\n\nOptions:\n"), | |
41 | program_invocation_short_name); | |
42 | ||
43 | fprintf(out, _( | |
44 | " -h, --help this help\n" | |
45 | " -f, --freeze freeze the filesystem\n" | |
46 | " -u, --unfreeze unfreeze the filesystem\n")); | |
47 | ||
48 | fprintf(out, _("\nFor more information see fsfreeze(8).\n")); | |
49 | ||
50 | exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS); | |
51 | } | |
52 | ||
53 | int main(int argc, char **argv) | |
54 | { | |
55 | int fd = -1, c; | |
56 | int freeze = -1, rc = EXIT_FAILURE; | |
57 | char *path; | |
58 | struct stat sb; | |
59 | ||
60 | struct option longopts[] = { | |
61 | { "help", 0, 0, 'h' }, | |
62 | { "freeze", 0, 0, 'f' }, | |
63 | { "unfreeze", 0, 0, 'u' }, | |
64 | { NULL, 0, 0, 0 } | |
65 | }; | |
66 | ||
67 | setlocale(LC_ALL, ""); | |
68 | bindtextdomain(PACKAGE, LOCALEDIR); | |
69 | textdomain(PACKAGE); | |
70 | ||
71 | while ((c = getopt_long(argc, argv, "hfu", longopts, NULL)) != -1) { | |
72 | switch(c) { | |
73 | case 'h': | |
74 | usage(stdout); | |
75 | break; | |
76 | case 'f': | |
77 | freeze = TRUE; | |
78 | break; | |
79 | case 'u': | |
80 | freeze = FALSE; | |
81 | break; | |
82 | default: | |
83 | usage(stderr); | |
84 | break; | |
85 | } | |
86 | } | |
87 | ||
88 | if (freeze == -1) | |
89 | errx(EXIT_FAILURE, _("no action specified")); | |
90 | if (optind == argc) | |
91 | errx(EXIT_FAILURE, _("no filename specified")); | |
92 | path = argv[optind++]; | |
93 | ||
94 | if (optind != argc) { | |
95 | warnx(_("unexpected number of arguments")); | |
96 | usage(stderr); | |
97 | } | |
98 | ||
99 | fd = open(path, O_RDONLY); | |
100 | if (fd < 0) | |
101 | err(EXIT_FAILURE, _("%s: open failed"), path); | |
102 | ||
103 | if (fstat(fd, &sb) == -1) { | |
104 | warn(_("%s: fstat failed"), path); | |
105 | goto done; | |
106 | } | |
107 | ||
108 | if (!S_ISDIR(sb.st_mode)) { | |
109 | warnx(_("%s: is not a directory"), path); | |
110 | goto done; | |
111 | } | |
112 | ||
113 | if (freeze) { | |
114 | if (freeze_f(fd)) { | |
115 | warn(_("%s: freeze failed"), path); | |
116 | goto done; | |
117 | } | |
118 | } else { | |
119 | if (unfreeze_f(fd)) { | |
120 | warn(_("%s: unfreeze failed"), path); | |
121 | goto done; | |
122 | } | |
123 | } | |
124 | ||
125 | rc = EXIT_SUCCESS; | |
126 | done: | |
127 | if (fd >= 0) | |
128 | close(fd); | |
129 | return rc; | |
130 | } | |
131 |