ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/vhd_unix.cpp
Revision: 1.1
Committed: 2010-10-19T03:21:52Z (14 years, 1 month ago) by asvitkine
Branch: MAIN
CVS Tags: HEAD
Log Message:
[Geoffrey Brown]
For my work on digital preservation it's important to have "golden"
disk images that are not corrupted by user action.  In order to enable
this, I've added support for VHD virtual disks (especially snapshots !)
to the Linux and OS X versions of BasiliskII and SheepShaver.

The support uses the open source libvhd library which is part of xen,
available here:
  http://www.xen.org/products/xen_source.html

The piece that's needed is libvhd which is in tools/blktap2 and it can
be separately compiled.
The vhd-util enables creation of vhd disks and snapshots.

Compiling libvhd for OS X is non-trivial and required  1) a new config
and 2) a number of small changes to the include files and c files.
Compiling for linux is a snap.

I use this as follows.

1) create my "golden image"  gold.dsk in the usual way
2) create a snapshot:  vhd-util snapshot -n gold.vhd -p gold.dsk -m
3) use the snapshot in my prefs file

In my work the golden images are in an AFS system which means the golden
images can reside at "universal" addresses.   The snapshots are initially
tiny, so a complete virtual machine configuration -- prefs + snapshot is
quick to download for the end user.

The snapshots are copy on write which has the pleasant side effect of
letting the end user keep any changes.

File Contents

# Content
1 /*
2 * vhd_unix.cpp -- support for disk images in vhd format
3 *
4 * (C) 2010 Geoffrey Brown
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include "sysdeps.h"
22 #include "vhd_unix.h"
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <string.h>
27 extern "C" {
28 #include <libvhd.h>
29 }
30 // libvhd.h defines DEBUG
31 #undef DEBUG
32 #define DEBUG 0
33 #include "debug.h"
34
35 void *vhd_unix_open(const char *name, int *size, bool read_only)
36 {
37 int amode = read_only ? R_OK : (R_OK | W_OK);
38 int fid;
39 vhd_context_t *vhd;
40
41 D(bug("vhd open %s\n", name));
42
43 if (access(name, amode)) {
44 D(bug("vhd open -- incorrect permissions %s\n", name));
45 return NULL;
46 }
47
48 if (! (fid = open(name, O_RDONLY))) {
49 D(bug("vhd open -- couldn't open file %s\n", name));
50 return NULL;
51 }
52 else {
53 char buf[9];
54 read(fid, buf, sizeof(buf)-1);
55 buf[8] = 0;
56 close(fid);
57 if (strcmp("conectix", buf) != 0) {
58 D(bug("vhd open -- not vhd magic = %s\n", buf));
59 return NULL;
60 }
61 if (vhd = (vhd_context_t *) malloc(sizeof(vhd_context_t))) {
62 int err;
63 if (err = vhd_open(vhd, name, read_only ?
64 VHD_OPEN_RDONLY : VHD_OPEN_RDWR)) {
65 D(bug("vhd_open failed (%d)\n", err));
66 free(vhd);
67 return NULL;
68 }
69 else {
70 *size = (int) vhd->footer.curr_size;
71 printf("VHD Open %s\n", name);
72 return (void *) vhd;
73 }
74 }
75 else {
76 D(bug("vhd open -- malloc failed\n"));
77 return NULL;
78 }
79 }
80 }
81
82 int vhd_unix_read(void *arg, void *buffer, loff_t offset, size_t length)
83 {
84 vhd_context_t *ctx = (vhd_context_t *) arg;
85 int err;
86 if ((offset % VHD_SECTOR_SIZE) || (length % VHD_SECTOR_SIZE)) {
87 printf("vhd read only supported on sector boundaries (%d)\n",
88 VHD_SECTOR_SIZE);
89 return 0;
90 }
91 if (err = vhd_io_read(ctx, (char *) buffer, offset / VHD_SECTOR_SIZE,
92 length / VHD_SECTOR_SIZE)){
93 D(bug("vhd read error %d\n", err));
94 return err;
95 }
96 else
97 return length;
98 }
99
100 int vhd_unix_write(void *arg, void *buffer, loff_t offset, size_t length)
101 {
102 int err;
103 vhd_context_t *ctx = (vhd_context_t *) arg;
104
105 if ((offset % VHD_SECTOR_SIZE) || (length % VHD_SECTOR_SIZE)) {
106 printf("vhd write only supported on sector boundaries (%d)\n",
107 VHD_SECTOR_SIZE);
108 return 0;
109 }
110 if (err = vhd_io_write(ctx, (char *) buffer, offset/VHD_SECTOR_SIZE,
111 length/VHD_SECTOR_SIZE)) {
112 D(bug("vhd write error %d\n", err));
113 return err;
114 }
115 else
116 return length;
117 }
118
119 void vhd_unix_close(void *arg)
120 {
121 D(bug("vhd close\n"));
122 vhd_close((vhd_context_t *) arg);
123 free(arg);
124 }