summaryrefslogtreecommitdiffstats
path: root/lib/format1/disk-rep.h
blob: 66d688460d16e2e772966052e5d10a86c63c03e9 (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 Sistina Software (UK) Limited.
 *
 * This file is released under the GPL.
 */

#ifndef DISK_REP_FORMAT1_H
#define DISK_REP_FORMAT1_H

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


#define SECTOR_SIZE 512

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

#define MAX_PV_SIZE	((uint32_t) -1) /* 2TB in sectors - 1 */
#define MIN_PE_SIZE	(8192L / SECTOR_SIZE)     /* 8 KB in sectors */
#define MAX_PE_SIZE	(16L * 1024L * 1024L / SECTOR_SIZE * 1024)
#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;
};

struct pv_disk {
        uint8_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;
        uint8_t pv_uuid[NAME_LEN];
        uint8_t vg_name[NAME_LEN];
        uint8_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;
};

struct lv_disk {
        uint8_t lv_name[NAME_LEN];
        uint8_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;
};

struct vg_disk {
        uint8_t vg_uuid[ID_LEN]; /* volume group UUID */
        uint8_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 */
};

struct pe_disk {
	uint16_t lv_num;
	uint16_t le_num;
};


struct uuid_list {
	struct list list;
	char uuid[NAME_LEN];
};

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

struct disk_list {
	struct list list;
	struct pool *mem;
	struct device *dev;

	struct pv_disk pvd;
	struct vg_disk vgd;
	struct list uuids;
	struct list lvds;
	struct pe_disk *extents;
};


/*
 * Layout constants.
 */
#define METADATA_ALIGN 4096UL
#define	PE_ALIGN (65536UL / SECTOR_SIZE)

#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);


/*
 * Low level io routines which read/write
 * disk_lists.
 */
int read_pvd(struct device *dev, struct pv_disk *pvd);

struct disk_list *read_disk(struct device *dev, struct pool *mem,
			    const char *vg_name);

int read_pvs_in_vg(const char *vg_name, struct dev_filter *filter,
		   struct pool *mem, struct list *results);

int write_disks(struct list *pvds);


/*
 * Functions to translate to between disk and in
 * core structures.
 */
int import_pv(struct pool *mem, struct device *dev,
	      struct volume_group *vg,
	      struct physical_volume *pv, struct pv_disk *pvd);
int export_pv(struct pool *mem, struct volume_group *vg,
	      struct pv_disk *pvd, struct physical_volume *pv);

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

int import_lv(struct pool *mem, struct logical_volume *lv,
	      struct lv_disk *lvd);
void export_lv(struct lv_disk *lvd, struct volume_group *vg,
	       struct logical_volume *lv, const char *dev_dir);

int import_extents(struct pool *mem, struct volume_group *vg,
		   struct list *pvds);
int export_extents(struct disk_list *dl, int lv_num,
		   struct logical_volume *lv,
		   struct physical_volume *pv);

int import_pvs(struct pool *mem, struct volume_group *vg,
	       struct list *pvds, struct list *results, int *count);

int import_lvs(struct pool *mem, struct volume_group *vg,
	       struct 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 pool *mem, struct volume_group *vg,
		     struct list *pvds);

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

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

void export_pv_act(struct list *pvds);

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


#endif