mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-11 19:00:02 +01:00
* Move device utils code and provide context parameter (for log).
* Keyfile now must be provided by path, only stdin file descriptor is used (api only). * Do not call isatty() on closed keyfile descriptor. Signed-off-by: Milan Broz <mbroz@redhat.com> git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@93 36d66b0a-2a48-0410-832c-cd162a569da5
This commit is contained in:
@@ -5,6 +5,9 @@
|
|||||||
* Add log macros and make logging modre consitent.
|
* Add log macros and make logging modre consitent.
|
||||||
* Move command successful messages to verbose level.
|
* Move command successful messages to verbose level.
|
||||||
* Introduce --debug parameter.
|
* Introduce --debug parameter.
|
||||||
|
* Move device utils code and provide context parameter (for log).
|
||||||
|
* Keyfile now must be provided by path, only stdin file descriptor is used (api only).
|
||||||
|
* Do not call isatty() on closed keyfile descriptor.
|
||||||
|
|
||||||
2009-08-17 Milan Broz <mbroz@redhat.com>
|
2009-08-17 Milan Broz <mbroz@redhat.com>
|
||||||
* Fix PBKDF2 speed calculation for large passhrases.
|
* Fix PBKDF2 speed calculation for large passhrases.
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
#include <libintl.h>
|
#include <libintl.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
@@ -26,6 +27,8 @@
|
|||||||
|
|
||||||
#define CRYPT_FLAG_PRIVATE_MASK ((unsigned int)-1 << 24)
|
#define CRYPT_FLAG_PRIVATE_MASK ((unsigned int)-1 << 24)
|
||||||
|
|
||||||
|
#define at_least_one(a) ({ __typeof__(a) __at_least_one=(a); (__at_least_one)?__at_least_one:1; })
|
||||||
|
|
||||||
struct hash_type {
|
struct hash_type {
|
||||||
char *name;
|
char *name;
|
||||||
void *private;
|
void *private;
|
||||||
@@ -39,6 +42,11 @@ struct hash_backend {
|
|||||||
void (*free_hashes)(struct hash_type *hashes);
|
void (*free_hashes)(struct hash_type *hashes);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct device_infos {
|
||||||
|
uint64_t size;
|
||||||
|
int readonly;
|
||||||
|
};
|
||||||
|
|
||||||
struct crypt_device;
|
struct crypt_device;
|
||||||
|
|
||||||
void set_error_va(const char *fmt, va_list va);
|
void set_error_va(const char *fmt, va_list va);
|
||||||
@@ -82,10 +90,15 @@ int sector_size_for_device(const char *device);
|
|||||||
ssize_t write_blockwise(int fd, const void *buf, size_t count);
|
ssize_t write_blockwise(int fd, const void *buf, size_t count);
|
||||||
ssize_t read_blockwise(int fd, void *_buf, size_t count);
|
ssize_t read_blockwise(int fd, void *_buf, size_t count);
|
||||||
ssize_t write_lseek_blockwise(int fd, const char *buf, size_t count, off_t offset);
|
ssize_t write_lseek_blockwise(int fd, const char *buf, size_t count, off_t offset);
|
||||||
|
int device_ready(struct crypt_device *cd, const char *device, int mode);
|
||||||
|
int get_device_infos(const char *device, struct device_infos *infos, struct crypt_device *cd);
|
||||||
|
int wipe_device_header(const char *device, int sectors);
|
||||||
|
|
||||||
|
void get_key(char *prompt, char **key, unsigned int *passLen, int key_size,
|
||||||
|
const char *key_file, int timeout, int how2verify,
|
||||||
|
struct crypt_device *cd);
|
||||||
|
|
||||||
int get_key(char *prompt, char **key, unsigned int *passLen, int key_size,
|
int parse_into_name_and_mode(const char *nameAndMode, char *name, char *mode);
|
||||||
const char *key_file, int passphrase_fd, int timeout, int how2verify, struct crypt_device *cd);
|
|
||||||
|
|
||||||
void set_default_log(void (*log)(int class, char *msg));
|
void set_default_log(void (*log)(int class, char *msg));
|
||||||
void logger(struct crypt_device *cd, int class, const char *file, int line, const char *format, ...);
|
void logger(struct crypt_device *cd, int class, const char *file, int line, const char *format, ...);
|
||||||
|
|||||||
148
lib/setup.c
148
lib/setup.c
@@ -1,19 +1,11 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <inttypes.h>
|
#include <stdarg.h>
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <signal.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "libcryptsetup.h"
|
#include "libcryptsetup.h"
|
||||||
#include "internal.h"
|
|
||||||
#include "blockdev.h"
|
|
||||||
#include "luks.h"
|
#include "luks.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
@@ -23,13 +15,6 @@ struct crypt_device {
|
|||||||
void *log_usrptr;
|
void *log_usrptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct device_infos {
|
|
||||||
uint64_t size;
|
|
||||||
int readonly;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define at_least_one(a) ({ __typeof__(a) __at_least_one=(a); (__at_least_one)?__at_least_one:1; })
|
|
||||||
|
|
||||||
/* Log helper */
|
/* Log helper */
|
||||||
static void (*_default_log)(int class, char *msg) = NULL;
|
static void (*_default_log)(int class, char *msg) = NULL;
|
||||||
static int _debug_level = 0;
|
static int _debug_level = 0;
|
||||||
@@ -122,107 +107,7 @@ static char *process_key(struct crypt_device *cd,
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_device_infos(const char *device, struct device_infos *infos)
|
int parse_into_name_and_mode(const char *nameAndMode, char *name, char *mode)
|
||||||
{
|
|
||||||
char buf[128];
|
|
||||||
uint64_t size;
|
|
||||||
unsigned long size_small;
|
|
||||||
int readonly = 0;
|
|
||||||
int ret = -1;
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
/* Try to open read-write to check whether it is a read-only device */
|
|
||||||
fd = open(device, O_RDWR);
|
|
||||||
if (fd < 0) {
|
|
||||||
if (errno == EROFS) {
|
|
||||||
readonly = 1;
|
|
||||||
fd = open(device, O_RDONLY);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
close(fd);
|
|
||||||
fd = open(device, O_RDONLY);
|
|
||||||
}
|
|
||||||
if (fd < 0) {
|
|
||||||
set_error("Error opening device: %s",
|
|
||||||
strerror_r(errno, buf, 128));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef BLKROGET
|
|
||||||
/* If the device can be opened read-write, i.e. readonly is still 0, then
|
|
||||||
* check whether BKROGET says that it is read-only. E.g. read-only loop
|
|
||||||
* devices may be openend read-write but are read-only according to BLKROGET
|
|
||||||
*/
|
|
||||||
if (readonly == 0) {
|
|
||||||
if (ioctl(fd, BLKROGET, &readonly) < 0) {
|
|
||||||
set_error("BLKROGET failed on device: %s",
|
|
||||||
strerror_r(errno, buf, 128));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#error BLKROGET not available
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef BLKGETSIZE64
|
|
||||||
if (ioctl(fd, BLKGETSIZE64, &size) >= 0) {
|
|
||||||
size >>= SECTOR_SHIFT;
|
|
||||||
ret = 0;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef BLKGETSIZE
|
|
||||||
if (ioctl(fd, BLKGETSIZE, &size_small) >= 0) {
|
|
||||||
size = (uint64_t)size_small;
|
|
||||||
ret = 0;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
# error Need at least the BLKGETSIZE ioctl!
|
|
||||||
#endif
|
|
||||||
|
|
||||||
set_error("BLKGETSIZE ioctl failed on device: %s",
|
|
||||||
strerror_r(errno, buf, 128));
|
|
||||||
|
|
||||||
out:
|
|
||||||
if (ret == 0) {
|
|
||||||
infos->size = size;
|
|
||||||
infos->readonly = readonly;
|
|
||||||
}
|
|
||||||
close(fd);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int wipe_device_header(const char *device, int sectors)
|
|
||||||
{
|
|
||||||
char *buffer;
|
|
||||||
int size = sectors * SECTOR_SIZE;
|
|
||||||
int r = -1;
|
|
||||||
int devfd;
|
|
||||||
|
|
||||||
devfd = open(device, O_RDWR | O_DIRECT | O_SYNC);
|
|
||||||
if(devfd == -1) {
|
|
||||||
set_error("Can't wipe header on device %s", device);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer = malloc(size);
|
|
||||||
if (!buffer) {
|
|
||||||
close(devfd);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
memset(buffer, 0, size);
|
|
||||||
|
|
||||||
r = write_blockwise(devfd, buffer, size) < size ? -EIO : 0;
|
|
||||||
|
|
||||||
free(buffer);
|
|
||||||
close(devfd);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int parse_into_name_and_mode(const char *nameAndMode, char *name, char *mode)
|
|
||||||
{
|
{
|
||||||
/* Token content stringification, see info cpp/stringification */
|
/* Token content stringification, see info cpp/stringification */
|
||||||
#define str(s) #s
|
#define str(s) #s
|
||||||
@@ -311,7 +196,7 @@ static int create_device_helper(int reload, struct crypt_options *options)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_device_infos(options->device, &infos) < 0)
|
if (get_device_infos(options->device, &infos, cd) < 0)
|
||||||
return -ENOTBLK;
|
return -ENOTBLK;
|
||||||
|
|
||||||
if (!options->size) {
|
if (!options->size) {
|
||||||
@@ -331,7 +216,7 @@ static int create_device_helper(int reload, struct crypt_options *options)
|
|||||||
options->flags |= CRYPT_FLAG_READONLY;
|
options->flags |= CRYPT_FLAG_READONLY;
|
||||||
|
|
||||||
get_key("Enter passphrase: ", &key, &keyLen, options->key_size,
|
get_key("Enter passphrase: ", &key, &keyLen, options->key_size,
|
||||||
options->key_file, options->passphrase_fd, options->timeout, options->flags, NULL);
|
options->key_file, options->timeout, options->flags, NULL);
|
||||||
if (!key) {
|
if (!key) {
|
||||||
log_err(cd, "Key reading error");
|
log_err(cd, "Key reading error");
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
@@ -370,7 +255,7 @@ static int luks_remove_helper(struct crypt_device *cd,
|
|||||||
|
|
||||||
if(supply_it) {
|
if(supply_it) {
|
||||||
get_key("Enter LUKS passphrase to be deleted: ",&password,&passwordLen, 0, options->new_key_file,
|
get_key("Enter LUKS passphrase to be deleted: ",&password,&passwordLen, 0, options->new_key_file,
|
||||||
options->passphrase_fd, options->timeout, options->flags, cd);
|
options->timeout, options->flags, cd);
|
||||||
if(!password) {
|
if(!password) {
|
||||||
r = -EINVAL; goto out;
|
r = -EINVAL; goto out;
|
||||||
}
|
}
|
||||||
@@ -399,7 +284,7 @@ static int luks_remove_helper(struct crypt_device *cd,
|
|||||||
if(options->flags & CRYPT_FLAG_VERIFY_ON_DELKEY) {
|
if(options->flags & CRYPT_FLAG_VERIFY_ON_DELKEY) {
|
||||||
options->flags &= ~CRYPT_FLAG_VERIFY_ON_DELKEY;
|
options->flags &= ~CRYPT_FLAG_VERIFY_ON_DELKEY;
|
||||||
get_key("Enter any remaining LUKS passphrase: ",&password,&passwordLen, 0, options->key_file,
|
get_key("Enter any remaining LUKS passphrase: ",&password,&passwordLen, 0, options->key_file,
|
||||||
options->passphrase_fd, options->timeout, options->flags, cd);
|
options->timeout, options->flags, cd);
|
||||||
if(!password) {
|
if(!password) {
|
||||||
r = -EINVAL; goto out;
|
r = -EINVAL; goto out;
|
||||||
}
|
}
|
||||||
@@ -462,7 +347,7 @@ int crypt_resize_device(struct crypt_options *options)
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (get_device_infos(device, &infos) < 0)
|
if (get_device_infos(device, &infos, cd) < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (!options->size) {
|
if (!options->size) {
|
||||||
@@ -597,7 +482,7 @@ int crypt_luksFormat(struct crypt_options *options)
|
|||||||
logger(options, CRYPT_LOG_ERROR, "pitr %d\n", header.keyblock[0].passwordIterations);
|
logger(options, CRYPT_LOG_ERROR, "pitr %d\n", header.keyblock[0].passwordIterations);
|
||||||
#endif
|
#endif
|
||||||
get_key("Enter LUKS passphrase: ",&password,&passwordLen, 0, options->new_key_file,
|
get_key("Enter LUKS passphrase: ",&password,&passwordLen, 0, options->new_key_file,
|
||||||
options->passphrase_fd, options->timeout, options->flags, NULL);
|
options->timeout, options->flags, NULL);
|
||||||
if(!password) {
|
if(!password) {
|
||||||
r = -EINVAL; goto out;
|
r = -EINVAL; goto out;
|
||||||
}
|
}
|
||||||
@@ -640,7 +525,7 @@ int crypt_luksOpen(struct crypt_options *options)
|
|||||||
if (!LUKS_device_ready(options->device, O_RDONLY | excl))
|
if (!LUKS_device_ready(options->device, O_RDONLY | excl))
|
||||||
return -ENOTBLK;
|
return -ENOTBLK;
|
||||||
|
|
||||||
if (get_device_infos(options->device, &infos) < 0) {
|
if (get_device_infos(options->device, &infos, cd) < 0) {
|
||||||
log_err(cd, "Can't get device information.\n");
|
log_err(cd, "Can't get device information.\n");
|
||||||
return -ENOTBLK;
|
return -ENOTBLK;
|
||||||
}
|
}
|
||||||
@@ -659,11 +544,14 @@ start:
|
|||||||
password = safe_alloc(passwordLen + 1);
|
password = safe_alloc(passwordLen + 1);
|
||||||
strncpy(password, options->passphrase, passwordLen + 1);
|
strncpy(password, options->passphrase, passwordLen + 1);
|
||||||
tries = 0;
|
tries = 0;
|
||||||
} else if(get_key(prompt, &password, &passwordLen, options->key_size, options->key_file,
|
} else {
|
||||||
options->passphrase_fd, options->timeout, options->flags, cd))
|
get_key(prompt, &password, &passwordLen, options->key_size, options->key_file,
|
||||||
tries--;
|
options->timeout, options->flags, cd);
|
||||||
else
|
if (password)
|
||||||
tries = 0;
|
tries--;
|
||||||
|
else
|
||||||
|
tries = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if(!password) {
|
if(!password) {
|
||||||
r = -EINVAL; goto out;
|
r = -EINVAL; goto out;
|
||||||
@@ -761,7 +649,6 @@ int crypt_luksAddKey(struct crypt_options *options)
|
|||||||
&passwordLen,
|
&passwordLen,
|
||||||
0,
|
0,
|
||||||
options->key_file,
|
options->key_file,
|
||||||
options->passphrase_fd,
|
|
||||||
options->timeout,
|
options->timeout,
|
||||||
options->flags & ~(CRYPT_FLAG_VERIFY | CRYPT_FLAG_VERIFY_IF_POSSIBLE), cd);
|
options->flags & ~(CRYPT_FLAG_VERIFY | CRYPT_FLAG_VERIFY_IF_POSSIBLE), cd);
|
||||||
|
|
||||||
@@ -780,7 +667,6 @@ int crypt_luksAddKey(struct crypt_options *options)
|
|||||||
&passwordLen,
|
&passwordLen,
|
||||||
0,
|
0,
|
||||||
options->new_key_file,
|
options->new_key_file,
|
||||||
options->passphrase_fd,
|
|
||||||
options->timeout,
|
options->timeout,
|
||||||
options->flags, cd);
|
options->flags, cd);
|
||||||
if(!password) {
|
if(!password) {
|
||||||
|
|||||||
130
lib/utils.c
130
lib/utils.c
@@ -390,13 +390,11 @@ out_err:
|
|||||||
* Legend: p..prompt, v..can verify, n..newline-stop, h..read horizon
|
* Legend: p..prompt, v..can verify, n..newline-stop, h..read horizon
|
||||||
*
|
*
|
||||||
* Note: --key-file=- is interpreted as a read from a binary file (stdin)
|
* Note: --key-file=- is interpreted as a read from a binary file (stdin)
|
||||||
*
|
|
||||||
* Returns true when more keys are available (that is when password
|
|
||||||
* reading can be retried as for interactive terminals).
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int get_key(char *prompt, char **key, unsigned int *passLen, int key_size,
|
void get_key(char *prompt, char **key, unsigned int *passLen, int key_size,
|
||||||
const char *key_file, int passphrase_fd, int timeout, int how2verify, struct crypt_device *cd)
|
const char *key_file, int timeout, int how2verify,
|
||||||
|
struct crypt_device *cd)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
const int verify = how2verify & CRYPT_FLAG_VERIFY;
|
const int verify = how2verify & CRYPT_FLAG_VERIFY;
|
||||||
@@ -407,7 +405,7 @@ int get_key(char *prompt, char **key, unsigned int *passLen, int key_size,
|
|||||||
|
|
||||||
if(key_file && !strcmp(key_file, "-")) {
|
if(key_file && !strcmp(key_file, "-")) {
|
||||||
/* Allow binary reading from stdin */
|
/* Allow binary reading from stdin */
|
||||||
fd = passphrase_fd;
|
fd = STDIN_FILENO;
|
||||||
newline_stop = 0;
|
newline_stop = 0;
|
||||||
read_horizon = 0;
|
read_horizon = 0;
|
||||||
} else if (key_file) {
|
} else if (key_file) {
|
||||||
@@ -496,15 +494,129 @@ int get_key(char *prompt, char **key, unsigned int *passLen, int key_size,
|
|||||||
*key = pass;
|
*key = pass;
|
||||||
*passLen = i;
|
*passLen = i;
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
return isatty(fd); /* Return true, when password reading can be tried on interactive fds */
|
|
||||||
|
|
||||||
out_err:
|
out_err:
|
||||||
if(pass)
|
if(pass)
|
||||||
safe_free(pass);
|
safe_free(pass);
|
||||||
*key = NULL;
|
*key = NULL;
|
||||||
*passLen = 0;
|
*passLen = 0;
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
|
int device_ready(struct crypt_device *cd, const char *device, int mode)
|
||||||
|
{
|
||||||
|
int devfd;
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if(stat(device, &st) < 0) {
|
||||||
|
log_err(cd, _("Device %s doesn't exist or access denied.\n"), device);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mode)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
devfd = open(device, mode | O_DIRECT | O_SYNC);
|
||||||
|
if(devfd < 0) {
|
||||||
|
log_err(cd, _("Can't open device %s for %s%s access.\n"), device,
|
||||||
|
(mode & O_EXCL) ? _("exclusive ") : "",
|
||||||
|
(mode & O_RDWR) ? _("writable") : _("read-only"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
close(devfd);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_device_infos(const char *device, struct device_infos *infos, struct crypt_device *cd)
|
||||||
|
{
|
||||||
|
uint64_t size;
|
||||||
|
unsigned long size_small;
|
||||||
|
int readonly = 0;
|
||||||
|
int ret = -1;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
/* Try to open read-write to check whether it is a read-only device */
|
||||||
|
fd = open(device, O_RDWR);
|
||||||
|
if (fd < 0) {
|
||||||
|
if (errno == EROFS) {
|
||||||
|
readonly = 1;
|
||||||
|
fd = open(device, O_RDONLY);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
close(fd);
|
||||||
|
fd = open(device, O_RDONLY);
|
||||||
|
}
|
||||||
|
if (fd < 0) {
|
||||||
|
log_err(cd, _("Cannot open device: %s\n"), device);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BLKROGET
|
||||||
|
/* If the device can be opened read-write, i.e. readonly is still 0, then
|
||||||
|
* check whether BKROGET says that it is read-only. E.g. read-only loop
|
||||||
|
* devices may be openend read-write but are read-only according to BLKROGET
|
||||||
|
*/
|
||||||
|
if (readonly == 0 && ioctl(fd, BLKROGET, &readonly) < 0) {
|
||||||
|
log_err(cd, _("BLKROGET failed on device %s.\n"), device);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#error BLKROGET not available
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BLKGETSIZE64
|
||||||
|
if (ioctl(fd, BLKGETSIZE64, &size) >= 0) {
|
||||||
|
size >>= SECTOR_SHIFT;
|
||||||
|
ret = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BLKGETSIZE
|
||||||
|
if (ioctl(fd, BLKGETSIZE, &size_small) >= 0) {
|
||||||
|
size = (uint64_t)size_small;
|
||||||
|
ret = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
# error Need at least the BLKGETSIZE ioctl!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
log_err(cd, _("BLKGETSIZE failed on device %s.\n"), device);
|
||||||
|
out:
|
||||||
|
if (ret == 0) {
|
||||||
|
infos->size = size;
|
||||||
|
infos->readonly = readonly;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int wipe_device_header(const char *device, int sectors)
|
||||||
|
{
|
||||||
|
char *buffer;
|
||||||
|
int size = sectors * SECTOR_SIZE;
|
||||||
|
int r = -1;
|
||||||
|
int devfd;
|
||||||
|
|
||||||
|
devfd = open(device, O_RDWR | O_DIRECT | O_SYNC);
|
||||||
|
if(devfd == -1)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
buffer = malloc(size);
|
||||||
|
if (!buffer) {
|
||||||
|
close(devfd);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
memset(buffer, 0, size);
|
||||||
|
|
||||||
|
r = write_blockwise(devfd, buffer, size) < size ? -EIO : 0;
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
|
close(devfd);
|
||||||
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MEMLOCK */
|
/* MEMLOCK */
|
||||||
|
|||||||
Reference in New Issue
Block a user