summaryrefslogtreecommitdiffstats
path: root/lib/format1/disk-rep.h
blob: 0d54438a92957252e4af31cfdaad09ebbdc0ec3f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
/*
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
 *
 * This file is part of LVM2.
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU Lesser General Public License v.2.1.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef DISK_REP_FORMAT1_H
#define DISK_REP_FORMAT1_H

#include "lvm-types.h"
#include "metadata.h"
#include "toolcontext.h"

#define MAX_PV 256
#define MAX_LV 256
#define MAX_VG 99

#define LVM_BLK_MAJOR 58

#define MAX_PV_SIZE	((uint32_t) -1)	/* 2TB in sectors - 1 */
#define MIN_PE_SIZE	(8192L >> SECTOR_SHIFT)	/* 8 KB in sectors */
#define MAX_PE_SIZE	(16L * 1024L * (1024L >> SECTOR_SHIFT) * 1024L)
#define PE_SIZE_PV_SIZE_REL 5	/* PV size must be at least 5 times PE size */
#define	MAX_LE_TOTAL	65534	/* 2^16 - 2 */
#define	MAX_PE_TOTAL	((uint32_t) -2)

#define UNMAPPED_EXTENT 0

/* volume group */
#define	VG_ACTIVE            0x01	/* vg_status */
#define	VG_EXPORTED          0x02	/*     "     */
#define	VG_EXTENDABLE        0x04	/*     "     */

#define	VG_READ              0x01	/* vg_access */
#define	VG_WRITE             0x02	/*     "     */
#define	VG_CLUSTERED         0x04	/*     "     */
#define	VG_SHARED            0x08	/*     "     */

/* logical volume */
#define	LV_ACTIVE            0x01	/* lv_status */
#define	LV_SPINDOWN          0x02	/*     "     */
#define LV_PERSISTENT_MINOR  0x04	/*     "     */

#define	LV_READ              0x01	/* lv_access */
#define	LV_WRITE             0x02	/*     "     */
#define	LV_SNAPSHOT          0x04	/*     "     */
#define	LV_SNAPSHOT_ORG      0x08	/*     "     */

#define	LV_BADBLOCK_ON       0x01	/* lv_badblock */

#define	LV_STRICT            0x01	/* lv_allocation */
#define	LV_CONTIGUOUS        0x02	/*       "       */

/* physical volume */
#define	PV_ACTIVE            0x01	/* pv_status */
#define	PV_ALLOCATABLE       0x02	/* pv_allocatable */

#define EXPORTED_TAG "PV_EXP"	/* Identifier for exported PV */
#define IMPORTED_TAG "PV_IMP"	/* Identifier for imported PV */

struct data_area {
	uint32_t base;
	uint32_t size;
} __attribute__ ((packed));

struct pv_disk {
	int8_t id[2];
	uint16_t version;	/* lvm version */
	struct data_area pv_on_disk;
	struct data_area vg_on_disk;
	struct data_area pv_uuidlist_on_disk;
	struct data_area lv_on_disk;
	struct data_area pe_on_disk;
	int8_t pv_uuid[NAME_LEN];
	int8_t vg_name[NAME_LEN];
	int8_t system_id[NAME_LEN];	/* for vgexport/vgimport */
	uint32_t pv_major;
	uint32_t pv_number;
	uint32_t pv_status;
	uint32_t pv_allocatable;
	uint32_t pv_size;
	uint32_t lv_cur;
	uint32_t pe_size;
	uint32_t pe_total;
	uint32_t pe_allocated;

	/* only present on version == 2 pv's */
	uint32_t pe_start;
} __attribute__ ((packed));

struct lv_disk {
	int8_t lv_name[NAME_LEN];
	int8_t vg_name[NAME_LEN];
	uint32_t lv_access;
	uint32_t lv_status;
	uint32_t lv_open;
	uint32_t lv_dev;
	uint32_t lv_number;
	uint32_t lv_mirror_copies;	/* for future use */
	uint32_t lv_recovery;	/*       "        */
	uint32_t lv_schedule;	/*       "        */
	uint32_t lv_size;
	uint32_t lv_snapshot_minor;	/* minor number of original */
	uint16_t lv_chunk_size;	/* chunk size of snapshot */
	uint16_t dummy;
	uint32_t lv_allocated_le;
	uint32_t lv_stripes;
	uint32_t lv_stripesize;
	uint32_t lv_badblock;	/* for future use */
	uint32_t lv_allocation;
	uint32_t lv_io_timeout;	/* for future use */
	uint32_t lv_read_ahead;
} __attribute__ ((packed));

struct vg_disk {
	int8_t vg_uuid[ID_LEN];	/* volume group UUID */
	int8_t vg_name_dummy[NAME_LEN - ID_LEN];	/* rest of v1 VG name */
	uint32_t vg_number;	/* volume group number */
	uint32_t vg_access;	/* read/write */
	uint32_t vg_status;	/* active or not */
	uint32_t lv_max;	/* maximum logical volumes */
	uint32_t lv_cur;	/* current logical volumes */
	uint32_t lv_open;	/* open logical volumes */
	uint32_t pv_max;	/* maximum physical volumes */
	uint32_t pv_cur;	/* current physical volumes FU */
	uint32_t pv_act;	/* active physical volumes */
	uint32_t dummy;
	uint32_t vgda;		/* volume group descriptor arrays FU */
	uint32_t pe_size;	/* physical extent size in sectors */
	uint32_t pe_total;	/* total of physical extents */
	uint32_t pe_allocated;	/* allocated physical extents */
	uint32_t pvg_total;	/* physical volume groups FU */
} __attribute__ ((packed));

struct pe_disk {
	uint16_t lv_num;
	uint16_t le_num;
} __attribute__ ((packed));

struct uuid_list {
	struct dm_list list;
	char uuid[NAME_LEN] __attribute__((aligned(8)));
};

struct lvd_list {
	struct dm_list list;
	struct lv_disk lvd;
};

struct disk_list {
	struct dm_list list;
	struct dm_pool *mem;
	struct device *dev;

	struct pv_disk pvd __attribute__((aligned(8)));
	struct vg_disk vgd __attribute__((aligned(8)));
	struct dm_list uuids __attribute__((aligned(8)));
	struct dm_list lvds __attribute__((aligned(8)));
	struct pe_disk *extents __attribute__((aligned(8)));
};

/*
 * Layout constants.
 */
#define METADATA_ALIGN 4096UL
#define LVM1_PE_ALIGN (65536UL >> SECTOR_SHIFT)      /* PE alignment */

#define	METADATA_BASE 0UL
#define	PV_SIZE 1024UL
#define	VG_SIZE 4096UL

/*
 * Functions to calculate layout info.
 */
int calculate_layout(struct disk_list *dl);
int calculate_extent_count(struct physical_volume *pv, uint32_t extent_size,
			   uint32_t max_extent_count, uint64_t pe_start);

/*
 * Low level io routines which read/write
 * disk_lists.
 */

struct disk_list *read_disk(const struct format_type *fmt, struct device *dev,
			    struct dm_pool *mem, const char *vg_name);

int read_pvs_in_vg(const struct format_type *fmt, const char *vg_name,
		   struct dev_filter *filter,
		   struct dm_pool *mem, struct dm_list *results);

int write_disks(const struct format_type *fmt, struct dm_list *pvds);

/*
 * Functions to translate to between disk and in
 * core structures.
 */
int import_pv(const struct format_type *fmt, struct dm_pool *mem,
	      struct device *dev, struct volume_group *vg,
	      struct physical_volume *pv, struct pv_disk *pvd,
	      struct vg_disk *vgd);
int export_pv(struct cmd_context *cmd, struct dm_pool *mem,
	      struct volume_group *vg,
	      struct pv_disk *pvd, struct physical_volume *pv);

int import_vg(struct dm_pool *mem,
	      struct volume_group *vg, struct disk_list *dl);
int export_vg(struct vg_disk *vgd, struct volume_group *vg);

int import_lv(struct cmd_context *cmd, struct dm_pool *mem,
	      struct logical_volume *lv, struct lv_disk *lvd);

int import_extents(struct cmd_context *cmd, struct volume_group *vg,
		   struct dm_list *pvds);
int export_extents(struct disk_list *dl, uint32_t lv_num,
		   struct logical_volume *lv, struct physical_volume *pv);

int import_pvs(const struct format_type *fmt, struct dm_pool *mem,
	       struct volume_group *vg, struct dm_list *pvds);

int import_lvs(struct dm_pool *mem, struct volume_group *vg, struct dm_list *pvds);
int export_lvs(struct disk_list *dl, struct volume_group *vg,
	       struct physical_volume *pv, const char *dev_dir);

int import_snapshots(struct dm_pool *mem, struct volume_group *vg,
		     struct dm_list *pvds);

int export_uuids(struct disk_list *dl, struct volume_group *vg);

void export_numbers(struct dm_list *pvds, struct volume_group *vg);

void export_pv_act(struct dm_list *pvds);
int munge_pvd(struct device *dev, struct pv_disk *pvd);
int read_vgd(struct device *dev, struct vg_disk *vgd, struct pv_disk *pvd);

/* blech */
int get_free_vg_number(struct format_instance *fid, struct dev_filter *filter,
		       const char *candidate_vg, int *result);
int export_vg_number(struct format_instance *fid, struct dm_list *pvds,
		     const char *vg_name, struct dev_filter *filter);

#endif