]>
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 | 49 | fputs(USAGE_SEPARATOR, out); |
f45f3ec3 RM |
50 | printf(USAGE_HELP_OPTIONS(19)); |
51 | printf(USAGE_MAN_TAIL("fsfreeze(8)")); | |
f0bef3ca | 52 | |
6e1eda6f | 53 | exit(EXIT_SUCCESS); |
f0bef3ca HT |
54 | } |
55 | ||
56 | int main(int argc, char **argv) | |
57 | { | |
58 | int fd = -1, c; | |
5543aaad | 59 | int action = NOOP, rc = EXIT_FAILURE; |
f0bef3ca HT |
60 | char *path; |
61 | struct stat sb; | |
62 | ||
6c7d5ae9 | 63 | static const struct option longopts[] = { |
87918040 SK |
64 | { "help", no_argument, NULL, 'h' }, |
65 | { "freeze", no_argument, NULL, 'f' }, | |
66 | { "unfreeze", no_argument, NULL, 'u' }, | |
67 | { "version", no_argument, NULL, 'V' }, | |
68 | { NULL, 0, NULL, 0 } | |
f0bef3ca HT |
69 | }; |
70 | ||
a7349ee3 | 71 | static const ul_excl_t excl[] = { /* rows and cols in ASCII order */ |
d4543f84 KZ |
72 | { 'f','u' }, /* freeze, unfreeze */ |
73 | { 0 } | |
74 | }; | |
75 | int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT; | |
76 | ||
f0bef3ca HT |
77 | setlocale(LC_ALL, ""); |
78 | bindtextdomain(PACKAGE, LOCALEDIR); | |
79 | textdomain(PACKAGE); | |
25b7045e | 80 | close_stdout_atexit(); |
f0bef3ca | 81 | |
7de20424 | 82 | while ((c = getopt_long(argc, argv, "hfuV", longopts, NULL)) != -1) { |
d4543f84 KZ |
83 | |
84 | err_exclusive_options(c, longopts, excl, excl_st); | |
85 | ||
f0bef3ca | 86 | switch(c) { |
f0bef3ca | 87 | case 'f': |
5543aaad | 88 | action = FREEZE; |
f0bef3ca HT |
89 | break; |
90 | case 'u': | |
5543aaad | 91 | action = UNFREEZE; |
f0bef3ca | 92 | break; |
2c308875 KZ |
93 | |
94 | case 'h': | |
95 | usage(); | |
7de20424 | 96 | case 'V': |
2c308875 | 97 | print_version(EXIT_SUCCESS); |
f0bef3ca | 98 | default: |
677ec86c | 99 | errtryhelp(EXIT_FAILURE); |
f0bef3ca HT |
100 | } |
101 | } | |
102 | ||
5543aaad SK |
103 | if (action == NOOP) |
104 | errx(EXIT_FAILURE, _("neither --freeze or --unfreeze specified")); | |
f0bef3ca HT |
105 | if (optind == argc) |
106 | errx(EXIT_FAILURE, _("no filename specified")); | |
107 | path = argv[optind++]; | |
108 | ||
109 | if (optind != argc) { | |
110 | warnx(_("unexpected number of arguments")); | |
6e1eda6f | 111 | errtryhelp(EXIT_FAILURE); |
f0bef3ca HT |
112 | } |
113 | ||
114 | fd = open(path, O_RDONLY); | |
115 | if (fd < 0) | |
289dcc90 | 116 | err(EXIT_FAILURE, _("cannot open %s"), path); |
f0bef3ca HT |
117 | |
118 | if (fstat(fd, &sb) == -1) { | |
fc14ceba | 119 | warn(_("stat of %s failed"), path); |
f0bef3ca HT |
120 | goto done; |
121 | } | |
122 | ||
123 | if (!S_ISDIR(sb.st_mode)) { | |
124 | warnx(_("%s: is not a directory"), path); | |
125 | goto done; | |
126 | } | |
127 | ||
5543aaad SK |
128 | switch (action) { |
129 | case FREEZE: | |
6690ceed | 130 | if (ioctl(fd, FIFREEZE, 0)) { |
f0bef3ca HT |
131 | warn(_("%s: freeze failed"), path); |
132 | goto done; | |
133 | } | |
5543aaad SK |
134 | break; |
135 | case UNFREEZE: | |
6690ceed | 136 | if (ioctl(fd, FITHAW, 0)) { |
f0bef3ca HT |
137 | warn(_("%s: unfreeze failed"), path); |
138 | goto done; | |
139 | } | |
5543aaad SK |
140 | break; |
141 | default: | |
142 | abort(); | |
f0bef3ca HT |
143 | } |
144 | ||
145 | rc = EXIT_SUCCESS; | |
146 | done: | |
8e76d28d | 147 | close(fd); |
f0bef3ca HT |
148 | return rc; |
149 | } | |
150 |