]>
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 | 23 | |
d4543f84 | 24 | #include "c.h" |
f0bef3ca HT |
25 | #include "blkdev.h" |
26 | #include "nls.h" | |
efb8854f | 27 | #include "closestream.h" |
d4543f84 | 28 | #include "optutils.h" |
f0bef3ca | 29 | |
5543aaad SK |
30 | enum fs_operation { |
31 | NOOP, | |
32 | FREEZE, | |
33 | UNFREEZE | |
34 | }; | |
35 | ||
6e1eda6f | 36 | static void __attribute__((__noreturn__)) usage(void) |
f0bef3ca | 37 | { |
6e1eda6f RM |
38 | FILE *out = stdout; |
39 | fputs(USAGE_HEADER, out); | |
a2aef6d9 | 40 | fprintf(out, |
7de20424 | 41 | _(" %s [options] <mountpoint>\n"), program_invocation_short_name); |
451dbcfa BS |
42 | |
43 | fputs(USAGE_SEPARATOR, out); | |
8d42631e | 44 | fputs(_("Suspend access to a filesystem.\n"), out); |
451dbcfa | 45 | |
7de20424 KZ |
46 | fputs(USAGE_OPTIONS, out); |
47 | fputs(_(" -f, --freeze freeze the filesystem\n"), out); | |
48 | fputs(_(" -u, --unfreeze unfreeze the filesystem\n"), out); | |
6e1eda6f RM |
49 | fputs(USAGE_SEPARATOR, out); |
50 | fputs(USAGE_HELP, out); | |
51 | fputs(USAGE_VERSION, out); | |
7de20424 | 52 | fprintf(out, USAGE_MAN_TAIL("fsfreeze(8)")); |
f0bef3ca | 53 | |
6e1eda6f | 54 | exit(EXIT_SUCCESS); |
f0bef3ca HT |
55 | } |
56 | ||
57 | int main(int argc, char **argv) | |
58 | { | |
59 | int fd = -1, c; | |
5543aaad | 60 | int action = NOOP, rc = EXIT_FAILURE; |
f0bef3ca HT |
61 | char *path; |
62 | struct stat sb; | |
63 | ||
6c7d5ae9 | 64 | static const struct option longopts[] = { |
87918040 SK |
65 | { "help", no_argument, NULL, 'h' }, |
66 | { "freeze", no_argument, NULL, 'f' }, | |
67 | { "unfreeze", no_argument, NULL, 'u' }, | |
68 | { "version", no_argument, NULL, 'V' }, | |
69 | { NULL, 0, NULL, 0 } | |
f0bef3ca HT |
70 | }; |
71 | ||
a7349ee3 | 72 | static const ul_excl_t excl[] = { /* rows and cols in ASCII order */ |
d4543f84 KZ |
73 | { 'f','u' }, /* freeze, unfreeze */ |
74 | { 0 } | |
75 | }; | |
76 | int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT; | |
77 | ||
f0bef3ca HT |
78 | setlocale(LC_ALL, ""); |
79 | bindtextdomain(PACKAGE, LOCALEDIR); | |
80 | textdomain(PACKAGE); | |
efb8854f | 81 | atexit(close_stdout); |
f0bef3ca | 82 | |
7de20424 | 83 | while ((c = getopt_long(argc, argv, "hfuV", longopts, NULL)) != -1) { |
d4543f84 KZ |
84 | |
85 | err_exclusive_options(c, longopts, excl, excl_st); | |
86 | ||
f0bef3ca HT |
87 | switch(c) { |
88 | case 'h': | |
6e1eda6f | 89 | usage(); |
f0bef3ca HT |
90 | break; |
91 | case 'f': | |
5543aaad | 92 | action = FREEZE; |
f0bef3ca HT |
93 | break; |
94 | case 'u': | |
5543aaad | 95 | action = UNFREEZE; |
f0bef3ca | 96 | break; |
7de20424 KZ |
97 | case 'V': |
98 | printf(UTIL_LINUX_VERSION); | |
99 | exit(EXIT_SUCCESS); | |
f0bef3ca | 100 | default: |
677ec86c | 101 | errtryhelp(EXIT_FAILURE); |
f0bef3ca HT |
102 | } |
103 | } | |
104 | ||
5543aaad SK |
105 | if (action == NOOP) |
106 | errx(EXIT_FAILURE, _("neither --freeze or --unfreeze specified")); | |
f0bef3ca HT |
107 | if (optind == argc) |
108 | errx(EXIT_FAILURE, _("no filename specified")); | |
109 | path = argv[optind++]; | |
110 | ||
111 | if (optind != argc) { | |
112 | warnx(_("unexpected number of arguments")); | |
6e1eda6f | 113 | errtryhelp(EXIT_FAILURE); |
f0bef3ca HT |
114 | } |
115 | ||
116 | fd = open(path, O_RDONLY); | |
117 | if (fd < 0) | |
289dcc90 | 118 | err(EXIT_FAILURE, _("cannot open %s"), path); |
f0bef3ca HT |
119 | |
120 | if (fstat(fd, &sb) == -1) { | |
fc14ceba | 121 | warn(_("stat of %s failed"), path); |
f0bef3ca HT |
122 | goto done; |
123 | } | |
124 | ||
125 | if (!S_ISDIR(sb.st_mode)) { | |
126 | warnx(_("%s: is not a directory"), path); | |
127 | goto done; | |
128 | } | |
129 | ||
5543aaad SK |
130 | switch (action) { |
131 | case FREEZE: | |
6690ceed | 132 | if (ioctl(fd, FIFREEZE, 0)) { |
f0bef3ca HT |
133 | warn(_("%s: freeze failed"), path); |
134 | goto done; | |
135 | } | |
5543aaad SK |
136 | break; |
137 | case UNFREEZE: | |
6690ceed | 138 | if (ioctl(fd, FITHAW, 0)) { |
f0bef3ca HT |
139 | warn(_("%s: unfreeze failed"), path); |
140 | goto done; | |
141 | } | |
5543aaad SK |
142 | break; |
143 | default: | |
144 | abort(); | |
f0bef3ca HT |
145 | } |
146 | ||
147 | rc = EXIT_SUCCESS; | |
148 | done: | |
149 | if (fd >= 0) | |
150 | close(fd); | |
151 | return rc; | |
152 | } | |
153 |