1 /* libguestfs - the guestfsd daemon
2 * Copyright (C) 2009-2011 Red Hat Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 static const char zero_buf[4096];
34 do_zero (const char *device)
36 char buf[sizeof zero_buf];
40 fd = open (device, O_RDWR);
42 reply_with_perror ("%s", device);
46 for (i = 0; i < 32; ++i) {
47 offset = i * sizeof zero_buf;
49 /* Check if the block is already zero before overwriting it. */
50 if (pread (fd, buf, sizeof buf, offset) != sizeof buf) {
51 reply_with_perror ("pread: %s", device);
56 if (!is_zero (buf, sizeof buf)) {
57 if (pwrite (fd, zero_buf, sizeof zero_buf, offset) != sizeof zero_buf) {
58 reply_with_perror ("pwrite: %s", device);
64 notify_progress ((uint64_t) i, 32);
67 if (close (fd) == -1) {
68 reply_with_perror ("close: %s", device);
76 do_zero_device (const char *device)
78 int64_t ssize = do_blockdev_getsize64 (device);
81 uint64_t size = (uint64_t) ssize;
83 int fd = open (device, O_RDWR);
85 reply_with_perror ("%s", device);
89 char buf[sizeof zero_buf];
94 uint64_t n64 = size - pos;
99 n = (size_t) n64; /* safe because of if condition */
101 /* Check if the block is already zero before overwriting it. */
103 r = pread (fd, buf, n, pos);
105 reply_with_perror ("pread: %s at offset %" PRIu64, device, pos);
110 if (!is_zero (buf, sizeof buf)) {
111 r = pwrite (fd, zero_buf, n, pos);
113 reply_with_perror ("pwrite: %s (with %" PRId64 " bytes left to write)",
123 notify_progress (pos, size);
126 if (close (fd) == -1) {
127 reply_with_perror ("close: %s", device);
135 do_is_zero (const char *path)
142 fd = open (path, O_RDONLY);
146 reply_with_perror ("open: %s", path);
150 while ((r = read (fd, buf, sizeof buf)) > 0) {
151 if (!is_zero (buf, r)) {
158 reply_with_perror ("read: %s", path);
163 if (close (fd) == -1) {
164 reply_with_perror ("close: %s", path);
172 do_is_zero_device (const char *device)
178 fd = open (device, O_RDONLY);
180 reply_with_perror ("open: %s", device);
184 while ((r = read (fd, buf, sizeof buf)) > 0) {
185 if (!is_zero (buf, r)) {
192 reply_with_perror ("read: %s", device);
197 if (close (fd) == -1) {
198 reply_with_perror ("close: %s", device);