Implemented lock mechanism for hard disk images (fixes SF bug #605).
- Create a file with image name plus extension ".lock" if an image is opened in read/write mode. This file will be deleted after closing the image. - Check for a lock file before opening an image and fail if it exists. - Check for a lock file before creating a undoable/volatile redolog file and fail if it exists.
This commit is contained in:
parent
124f521797
commit
7fd9194d81
@ -178,12 +178,30 @@ int bx_write_image(int fd, Bit64s offset, void *buf, int count)
|
|||||||
return write(fd, buf, count);
|
return write(fd, buf, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int bx_close_image(int fd, const char *pathname)
|
||||||
|
{
|
||||||
|
#ifndef BXIMAGE
|
||||||
|
char lockfn[BX_PATHNAME_LEN];
|
||||||
|
|
||||||
|
sprintf(lockfn, "%s.lock", pathname);
|
||||||
|
if (access(lockfn, F_OK) == 0) {
|
||||||
|
unlink(lockfn);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return ::close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
int hdimage_open_file(const char *pathname, int flags, Bit64u *fsize, time_t *mtime)
|
int hdimage_open_file(const char *pathname, int flags, Bit64u *fsize, time_t *mtime)
|
||||||
#else
|
#else
|
||||||
int hdimage_open_file(const char *pathname, int flags, Bit64u *fsize, FILETIME *mtime)
|
int hdimage_open_file(const char *pathname, int flags, Bit64u *fsize, FILETIME *mtime)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
#ifndef BXIMAGE
|
||||||
|
char lockfn[BX_PATHNAME_LEN];
|
||||||
|
int lockfd;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
if (fsize != NULL) {
|
if (fsize != NULL) {
|
||||||
HANDLE hFile = CreateFile(pathname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL);
|
HANDLE hFile = CreateFile(pathname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL);
|
||||||
@ -205,6 +223,17 @@ int hdimage_open_file(const char *pathname, int flags, Bit64u *fsize, FILETIME *
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef BXIMAGE
|
||||||
|
sprintf(lockfn, "%s.lock", pathname);
|
||||||
|
lockfd = ::open(lockfn, O_RDONLY);
|
||||||
|
if (lockfd >= 0) {
|
||||||
|
// Opening image must fail if lock file exists.
|
||||||
|
::close(lockfd);
|
||||||
|
BX_ERROR(("image locked: '%s'", pathname));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int fd = ::open(pathname, flags
|
int fd = ::open(pathname, flags
|
||||||
#ifdef O_BINARY
|
#ifdef O_BINARY
|
||||||
| O_BINARY
|
| O_BINARY
|
||||||
@ -235,6 +264,19 @@ int hdimage_open_file(const char *pathname, int flags, Bit64u *fsize, FILETIME *
|
|||||||
*mtime = stat_buf.st_mtime;
|
*mtime = stat_buf.st_mtime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifndef BXIMAGE
|
||||||
|
if ((flags & O_ACCMODE) != O_RDONLY) {
|
||||||
|
lockfd = ::open(lockfn, O_CREAT | O_RDWR
|
||||||
|
#ifdef O_BINARY
|
||||||
|
| O_BINARY
|
||||||
|
#endif
|
||||||
|
, S_IWUSR | S_IRUSR | S_IRGRP | S_IWGRP);
|
||||||
|
if (lockfd >= 0) {
|
||||||
|
// lock this image
|
||||||
|
::close(lockfd);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
@ -488,7 +530,7 @@ int flat_image_t::open(const char* _pathname, int flags)
|
|||||||
void flat_image_t::close()
|
void flat_image_t::close()
|
||||||
{
|
{
|
||||||
if (fd > -1) {
|
if (fd > -1) {
|
||||||
::close(fd);
|
bx_close_image(fd, pathname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -569,11 +611,11 @@ int concat_image_t::open(const char* _pathname0, int flags)
|
|||||||
{
|
{
|
||||||
UNUSED(flags);
|
UNUSED(flags);
|
||||||
pathname0 = _pathname0;
|
pathname0 = _pathname0;
|
||||||
char *pathname = strdup(pathname0);
|
char *pathname1 = strdup(pathname0);
|
||||||
BX_DEBUG(("concat_image_t::open"));
|
BX_DEBUG(("concat_image_t::open"));
|
||||||
Bit64s start_offset = 0;
|
Bit64s start_offset = 0;
|
||||||
for (int i=0; i<BX_CONCAT_MAX_IMAGES; i++) {
|
for (int i=0; i<BX_CONCAT_MAX_IMAGES; i++) {
|
||||||
fd_table[i] = hdimage_open_file(pathname, flags, &length_table[i], NULL);
|
fd_table[i] = hdimage_open_file(pathname1, flags, &length_table[i], NULL);
|
||||||
if (fd_table[i] < 0) {
|
if (fd_table[i] < 0) {
|
||||||
// open failed.
|
// open failed.
|
||||||
// if no FD was opened successfully, return -1 (fail).
|
// if no FD was opened successfully, return -1 (fail).
|
||||||
@ -583,7 +625,7 @@ int concat_image_t::open(const char* _pathname0, int flags)
|
|||||||
maxfd = i;
|
maxfd = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
BX_INFO(("concat_image: open image #%d: '%s', (" FMT_LL "u bytes)", i, pathname, length_table[i]));
|
BX_INFO(("concat_image: open image #%d: '%s', (" FMT_LL "u bytes)", i, pathname1, length_table[i]));
|
||||||
struct stat stat_buf;
|
struct stat stat_buf;
|
||||||
int ret = fstat(fd_table[i], &stat_buf);
|
int ret = fstat(fd_table[i], &stat_buf);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@ -599,9 +641,9 @@ int concat_image_t::open(const char* _pathname0, int flags)
|
|||||||
}
|
}
|
||||||
start_offset_table[i] = start_offset;
|
start_offset_table[i] = start_offset;
|
||||||
start_offset += length_table[i];
|
start_offset += length_table[i];
|
||||||
increment_string(pathname);
|
increment_string(pathname1);
|
||||||
}
|
}
|
||||||
free(pathname);
|
free(pathname1);
|
||||||
// start up with first image selected
|
// start up with first image selected
|
||||||
total_offset = 0;
|
total_offset = 0;
|
||||||
index = 0;
|
index = 0;
|
||||||
@ -616,11 +658,14 @@ int concat_image_t::open(const char* _pathname0, int flags)
|
|||||||
void concat_image_t::close()
|
void concat_image_t::close()
|
||||||
{
|
{
|
||||||
BX_DEBUG(("concat_image_t.close"));
|
BX_DEBUG(("concat_image_t.close"));
|
||||||
|
char *pathname1 = strdup(pathname0);
|
||||||
for (int index = 0; index < maxfd; index++) {
|
for (int index = 0; index < maxfd; index++) {
|
||||||
if (fd_table[index] > -1) {
|
if (fd_table[index] > -1) {
|
||||||
::close(fd_table[index]);
|
bx_close_image(fd_table[index], pathname1);
|
||||||
}
|
}
|
||||||
|
increment_string(pathname1);
|
||||||
}
|
}
|
||||||
|
free(pathname1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Bit64s concat_image_t::lseek(Bit64s offset, int whence)
|
Bit64s concat_image_t::lseek(Bit64s offset, int whence)
|
||||||
@ -914,13 +959,8 @@ int sparse_image_t::open(const char* pathname0, int flags)
|
|||||||
void sparse_image_t::close()
|
void sparse_image_t::close()
|
||||||
{
|
{
|
||||||
BX_DEBUG(("concat_image_t.close"));
|
BX_DEBUG(("concat_image_t.close"));
|
||||||
if (pathname != NULL)
|
|
||||||
{
|
|
||||||
free(pathname);
|
|
||||||
}
|
|
||||||
#ifdef _POSIX_MAPPED_FILES
|
#ifdef _POSIX_MAPPED_FILES
|
||||||
if (mmap_header != NULL)
|
if (mmap_header != NULL) {
|
||||||
{
|
|
||||||
int ret = munmap(mmap_header, mmap_length);
|
int ret = munmap(mmap_header, mmap_length);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
BX_INFO(("failed to un-memory map sparse disk file"));
|
BX_INFO(("failed to un-memory map sparse disk file"));
|
||||||
@ -928,14 +968,15 @@ void sparse_image_t::close()
|
|||||||
pagetable = NULL; // We didn't malloc it
|
pagetable = NULL; // We didn't malloc it
|
||||||
#endif
|
#endif
|
||||||
if (fd > -1) {
|
if (fd > -1) {
|
||||||
::close(fd);
|
bx_close_image(fd, pathname);
|
||||||
}
|
}
|
||||||
if (pagetable != NULL)
|
if (pathname != NULL) {
|
||||||
{
|
free(pathname);
|
||||||
|
}
|
||||||
|
if (pagetable != NULL) {
|
||||||
delete [] pagetable;
|
delete [] pagetable;
|
||||||
}
|
}
|
||||||
if (parent_image != NULL)
|
if (parent_image != NULL) {
|
||||||
{
|
|
||||||
delete parent_image;
|
delete parent_image;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1492,6 +1533,15 @@ int redolog_t::make_header(const char* type, Bit64u size)
|
|||||||
|
|
||||||
int redolog_t::create(const char* filename, const char* type, Bit64u size)
|
int redolog_t::create(const char* filename, const char* type, Bit64u size)
|
||||||
{
|
{
|
||||||
|
#ifndef BXIMAGE
|
||||||
|
char lockfn[BX_PATHNAME_LEN];
|
||||||
|
|
||||||
|
sprintf(lockfn, "%s.lock", filename);
|
||||||
|
if (access(lockfn, F_OK) == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
BX_INFO(("redolog : creating redolog %s", filename));
|
BX_INFO(("redolog : creating redolog %s", filename));
|
||||||
|
|
||||||
int filedes = ::open(filename, O_RDWR | O_CREAT | O_TRUNC
|
int filedes = ::open(filename, O_RDWR | O_CREAT | O_TRUNC
|
||||||
@ -1541,6 +1591,7 @@ int redolog_t::open(const char* filename, const char *type, int flags)
|
|||||||
FILETIME mtime;
|
FILETIME mtime;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
pathname = strdup(filename);
|
||||||
fd = hdimage_open_file(filename, flags, &imgsize, &mtime);
|
fd = hdimage_open_file(filename, flags, &imgsize, &mtime);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
BX_INFO(("redolog : could not open image %s", filename));
|
BX_INFO(("redolog : could not open image %s", filename));
|
||||||
@ -1624,7 +1675,10 @@ int redolog_t::open(const char* filename, const char *type, int flags)
|
|||||||
void redolog_t::close()
|
void redolog_t::close()
|
||||||
{
|
{
|
||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
::close(fd);
|
bx_close_image(fd, pathname);
|
||||||
|
|
||||||
|
if (pathname != NULL)
|
||||||
|
free(pathname);
|
||||||
|
|
||||||
if (catalog != NULL)
|
if (catalog != NULL)
|
||||||
free(catalog);
|
free(catalog);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// $Id$
|
// $Id$
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Copyright (C) 2005-2015 The Bochs Project
|
// Copyright (C) 2005-2017 The Bochs Project
|
||||||
//
|
//
|
||||||
// This library is free software; you can redistribute it and/or
|
// This library is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU Lesser General Public
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
@ -143,6 +143,7 @@ class redolog_t;
|
|||||||
|
|
||||||
int bx_read_image(int fd, Bit64s offset, void *buf, int count);
|
int bx_read_image(int fd, Bit64s offset, void *buf, int count);
|
||||||
int bx_write_image(int fd, Bit64s offset, void *buf, int count);
|
int bx_write_image(int fd, Bit64s offset, void *buf, int count);
|
||||||
|
int bx_close_image(int fd, const char *pathname);
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
int hdimage_open_file(const char *pathname, int flags, Bit64u *fsize, time_t *mtime);
|
int hdimage_open_file(const char *pathname, int flags, Bit64u *fsize, time_t *mtime);
|
||||||
#else
|
#else
|
||||||
@ -452,6 +453,7 @@ class redolog_t
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void print_header();
|
void print_header();
|
||||||
|
char *pathname;
|
||||||
int fd;
|
int fd;
|
||||||
redolog_header_t header; // Header is kept in x86 (little) endianness
|
redolog_header_t header; // Header is kept in x86 (little) endianness
|
||||||
Bit32u *catalog;
|
Bit32u *catalog;
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
* Contact: fys [at] fysnet [dot] net
|
* Contact: fys [at] fysnet [dot] net
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015 Benjamin D Lunt.
|
* Copyright (C) 2015 Benjamin D Lunt.
|
||||||
* Copyright (C) 2006-2016 The Bochs Project
|
* Copyright (C) 2006-2017 The Bochs Project
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@ -167,7 +167,7 @@ void vbox_image_t::close()
|
|||||||
delete [] mtlb; mtlb = 0;
|
delete [] mtlb; mtlb = 0;
|
||||||
delete [] block_data; block_data = 0;
|
delete [] block_data; block_data = 0;
|
||||||
|
|
||||||
::close(file_descriptor);
|
bx_close_image(file_descriptor, pathname);
|
||||||
file_descriptor = -1;
|
file_descriptor = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
* Contact: snrrrub@yahoo.com
|
* Contact: snrrrub@yahoo.com
|
||||||
*
|
*
|
||||||
* Copyright (C) 2003 Net Integration Technologies, Inc.
|
* Copyright (C) 2003 Net Integration Technologies, Inc.
|
||||||
* Copyright (C) 2003-2015 The Bochs Project
|
* Copyright (C) 2003-2017 The Bochs Project
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@ -224,7 +224,7 @@ int vmware3_image_t::open(const char* _pathname, int flags)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
::close(file);
|
bx_close_image(file, pathname);
|
||||||
|
|
||||||
tlb_size = header.tlb_size_sectors * 512;
|
tlb_size = header.tlb_size_sectors * 512;
|
||||||
slb_count = (1 << FL_SHIFT) / tlb_size;
|
slb_count = (1 << FL_SHIFT) / tlb_size;
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
* Contact: snrrrub@gmail.com
|
* Contact: snrrrub@gmail.com
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006 Sharvil Nanavati.
|
* Copyright (C) 2006 Sharvil Nanavati.
|
||||||
* Copyright (C) 2006-2016 The Bochs Project
|
* Copyright (C) 2006-2017 The Bochs Project
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@ -112,7 +112,7 @@ void vmware4_image_t::close()
|
|||||||
flush();
|
flush();
|
||||||
delete [] tlb; tlb = 0;
|
delete [] tlb; tlb = 0;
|
||||||
|
|
||||||
::close(file_descriptor);
|
bx_close_image(file_descriptor, pathname);
|
||||||
file_descriptor = -1;
|
file_descriptor = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 2005 Alex Beregszaszi
|
// Copyright (c) 2005 Alex Beregszaszi
|
||||||
// Copyright (c) 2009 Kevin Wolf <kwolf@suse.de>
|
// Copyright (c) 2009 Kevin Wolf <kwolf@suse.de>
|
||||||
// Copyright (C) 2012-2013 The Bochs Project
|
// Copyright (C) 2012-2017 The Bochs Project
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -138,20 +138,20 @@ int vpc_image_t::open(const char* _pathname, int flags)
|
|||||||
hd_size = sector_count * 512;
|
hd_size = sector_count * 512;
|
||||||
|
|
||||||
if (sector_count >= 65535 * 16 * 255) {
|
if (sector_count >= 65535 * 16 * 255) {
|
||||||
::close(fd);
|
bx_close_image(fd, pathname);
|
||||||
return -EFBIG;
|
return -EFBIG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (disk_type == VHD_DYNAMIC) {
|
if (disk_type == VHD_DYNAMIC) {
|
||||||
if (bx_read_image(fd, be64_to_cpu(footer->data_offset), buf, HEADER_SIZE) != HEADER_SIZE) {
|
if (bx_read_image(fd, be64_to_cpu(footer->data_offset), buf, HEADER_SIZE) != HEADER_SIZE) {
|
||||||
::close(fd);
|
bx_close_image(fd, pathname);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dyndisk_header = (vhd_dyndisk_header_t*)buf;
|
dyndisk_header = (vhd_dyndisk_header_t*)buf;
|
||||||
|
|
||||||
if (strncmp((char*)dyndisk_header->magic, "cxsparse", 8)) {
|
if (strncmp((char*)dyndisk_header->magic, "cxsparse", 8)) {
|
||||||
::close(fd);
|
bx_close_image(fd, pathname);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,7 +163,7 @@ int vpc_image_t::open(const char* _pathname, int flags)
|
|||||||
|
|
||||||
bat_offset = be64_to_cpu(dyndisk_header->table_offset);
|
bat_offset = be64_to_cpu(dyndisk_header->table_offset);
|
||||||
if (bx_read_image(fd, bat_offset, (void*)pagetable, max_table_entries * 4) != (max_table_entries * 4)) {
|
if (bx_read_image(fd, bat_offset, (void*)pagetable, max_table_entries * 4) != (max_table_entries * 4)) {
|
||||||
::close(fd);
|
bx_close_image(fd, pathname);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,7 +193,7 @@ void vpc_image_t::close(void)
|
|||||||
{
|
{
|
||||||
if (fd > -1) {
|
if (fd > -1) {
|
||||||
delete [] pagetable;
|
delete [] pagetable;
|
||||||
::close(fd);
|
bx_close_image(fd, pathname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user