4 * Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
5 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
7 * This file is part of LVM2.
9 * This copyrighted material is made available to anyone wishing to use,
10 * modify, copy, or redistribute it subject to the terms and conditions
11 * of the GNU Lesser General Public License v.2.1.
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "toolcontext.h"
26 #include "format_pool.h"
27 #include "pool_label.h"
29 /* Must be called after pvs are imported */
30 static struct user_subpool
*_build_usp(struct dm_list
*pls
, struct dm_pool
*mem
,
34 struct user_subpool
*usp
= NULL
, *cur_sp
= NULL
;
35 struct user_device
*cur_dev
= NULL
;
38 * FIXME: Need to do some checks here - I'm tempted to add a
39 * user_pool structure and build the entire thing to check against.
41 dm_list_iterate_items(pl
, pls
) {
42 *sps
= pl
->pd
.pl_subpools
;
43 if (!usp
&& (!(usp
= dm_pool_zalloc(mem
, sizeof(*usp
) * (*sps
))))) {
44 log_error("Unable to allocate %d subpool structures",
49 if (cur_sp
!= &usp
[pl
->pd
.pl_sp_id
]) {
50 cur_sp
= &usp
[pl
->pd
.pl_sp_id
];
52 cur_sp
->id
= pl
->pd
.pl_sp_id
;
53 cur_sp
->striping
= pl
->pd
.pl_striping
;
54 cur_sp
->num_devs
= pl
->pd
.pl_sp_devs
;
55 cur_sp
->type
= pl
->pd
.pl_sp_type
;
56 cur_sp
->initialized
= 1;
62 sizeof(*usp
->devs
) * pl
->pd
.pl_sp_devs
)))) {
64 log_error("Unable to allocate %d pool_device "
65 "structures", pl
->pd
.pl_sp_devs
);
69 cur_dev
= &cur_sp
->devs
[pl
->pd
.pl_sp_devid
];
70 cur_dev
->sp_id
= cur_sp
->id
;
71 cur_dev
->devid
= pl
->pd
.pl_sp_id
;
72 cur_dev
->blocks
= pl
->pd
.pl_blocks
;
74 cur_dev
->initialized
= 1;
80 static int _check_usp(char *vgname
, struct user_subpool
*usp
, int sp_count
)
85 for (i
= 0; i
< sp_count
; i
++) {
86 if (!usp
[i
].initialized
) {
87 log_error("Missing subpool %d in pool %s", i
, vgname
);
90 for (j
= 0; j
< usp
[i
].num_devs
; j
++) {
91 if (!usp
[i
].devs
[j
].initialized
) {
92 log_error("Missing device %u for subpool %d"
93 " in pool %s", j
, i
, vgname
);
103 static struct volume_group
*_build_vg_from_pds(struct format_instance
104 *fid
, struct dm_pool
*mem
,
107 struct dm_pool
*smem
= fid
->fmt
->cmd
->mem
;
108 struct volume_group
*vg
= NULL
;
109 struct user_subpool
*usp
= NULL
;
112 if (!(vg
= dm_pool_zalloc(smem
, sizeof(*vg
)))) {
113 log_error("Unable to allocate volume group structure");
117 vg
->cmd
= fid
->fmt
->cmd
;
122 vg
->extent_count
= 0;
125 vg
->system_id
= NULL
;
126 dm_list_init(&vg
->pvs
);
127 dm_list_init(&vg
->lvs
);
128 dm_list_init(&vg
->tags
);
129 dm_list_init(&vg
->removed_pvs
);
131 if (!import_pool_vg(vg
, smem
, pds
))
134 if (!import_pool_pvs(fid
->fmt
, vg
, &vg
->pvs
, smem
, pds
))
137 if (!import_pool_lvs(vg
, smem
, pds
))
141 * I need an intermediate subpool structure that contains all the
142 * relevant info for this. Then i can iterate through the subpool
143 * structures for checking, and create the segments
145 if (!(usp
= _build_usp(pds
, mem
, &sp_count
)))
149 * check the subpool structures - we can't handle partial VGs in
150 * the pool format, so this will error out if we're missing PVs
152 if (!_check_usp(vg
->name
, usp
, sp_count
))
155 if (!import_pool_segments(&vg
->lvs
, smem
, usp
, sp_count
))
161 static struct volume_group
*_pool_vg_read(struct format_instance
*fid
,
163 struct metadata_area
*mda
__attribute((unused
)))
165 struct dm_pool
*mem
= dm_pool_create("pool vg_read", VG_MEMPOOL_CHUNK
);
167 struct volume_group
*vg
= NULL
;
171 /* We can safely ignore the mda passed in */
176 /* Strip dev_dir if present */
177 vg_name
= strip_dir(vg_name
, fid
->fmt
->cmd
->dev_dir
);
179 /* Read all the pvs in the vg */
180 if (!read_pool_pds(fid
->fmt
, vg_name
, mem
, &pds
))
183 /* Do the rest of the vg stuff */
184 if (!(vg
= _build_vg_from_pds(fid
, mem
, &pds
)))
189 dm_pool_destroy(mem
);
193 static int _pool_pv_setup(const struct format_type
*fmt
__attribute((unused
)),
194 uint64_t pe_start
__attribute((unused
)),
195 uint32_t extent_count
__attribute((unused
)),
196 uint32_t extent_size
__attribute((unused
)),
197 unsigned long data_alignment
__attribute((unused
)),
198 unsigned long data_alignment_offset
__attribute((unused
)),
199 int pvmetadatacopies
__attribute((unused
)),
200 uint64_t pvmetadatasize
__attribute((unused
)),
201 struct dm_list
*mdas
__attribute((unused
)),
202 struct physical_volume
*pv
__attribute((unused
)),
203 struct volume_group
*vg
__attribute((unused
)))
208 static int _pool_pv_read(const struct format_type
*fmt
, const char *pv_name
,
209 struct physical_volume
*pv
,
210 struct dm_list
*mdas
__attribute((unused
)),
211 int scan_label_only
__attribute((unused
)))
213 struct dm_pool
*mem
= dm_pool_create("pool pv_read", 1024);
214 struct pool_list
*pl
;
218 log_very_verbose("Reading physical volume data %s from disk", pv_name
);
223 if (!(dev
= dev_cache_get(pv_name
, fmt
->cmd
->filter
)))
227 * I need to read the disk and populate a pv structure here
228 * I'll probably need to abstract some of this later for the
231 if (!(pl
= read_pool_disk(fmt
, dev
, mem
, NULL
)))
234 if (!import_pool_pv(fmt
, fmt
->cmd
->mem
, NULL
, pv
, pl
))
242 dm_pool_destroy(mem
);
247 static struct metadata_area_ops _metadata_format_pool_ops
= {
248 .vg_read
= _pool_vg_read
,
252 static struct format_instance
*_pool_create_instance(const struct format_type
*fmt
,
253 const char *vgname
__attribute((unused
)),
254 const char *vgid
__attribute((unused
)),
255 void *private __attribute((unused
)))
257 struct format_instance
*fid
;
258 struct metadata_area
*mda
;
260 if (!(fid
= dm_pool_zalloc(fmt
->cmd
->mem
, sizeof(*fid
)))) {
261 log_error("Unable to allocate format instance structure for "
267 dm_list_init(&fid
->metadata_areas
);
269 /* Define a NULL metadata area */
270 if (!(mda
= dm_pool_zalloc(fmt
->cmd
->mem
, sizeof(*mda
)))) {
271 log_error("Unable to allocate metadata area structure "
273 dm_pool_free(fmt
->cmd
->mem
, fid
);
277 mda
->ops
= &_metadata_format_pool_ops
;
278 mda
->metadata_locn
= NULL
;
279 dm_list_add(&fid
->metadata_areas
, &mda
->list
);
284 static void _pool_destroy_instance(struct format_instance
*fid
__attribute((unused
)))
289 static void _pool_destroy(const struct format_type
*fmt
)
291 dm_free((void *) fmt
);
295 static struct format_handler _format_pool_ops
= {
296 .pv_read
= _pool_pv_read
,
297 .pv_setup
= _pool_pv_setup
,
298 .create_instance
= _pool_create_instance
,
299 .destroy_instance
= _pool_destroy_instance
,
300 .destroy
= _pool_destroy
,
305 struct format_type
*init_pool_format(struct cmd_context
*cmd
)
307 struct format_type
*init_format(struct cmd_context
*cmd
);
308 struct format_type
*init_format(struct cmd_context
*cmd
)
311 struct format_type
*fmt
= dm_malloc(sizeof(*fmt
));
314 log_error("Unable to allocate format type structure for pool "
320 fmt
->ops
= &_format_pool_ops
;
321 fmt
->name
= FMT_POOL_NAME
;
323 fmt
->orphan_vg_name
= FMT_POOL_ORPHAN_VG_NAME
;
327 if (!(fmt
->labeller
= pool_labeller_create(fmt
))) {
328 log_error("Couldn't create pool label handler.");
332 if (!(label_register_handler(FMT_POOL_NAME
, fmt
->labeller
))) {
333 log_error("Couldn't register pool label handler.");
337 log_very_verbose("Initialised format: %s", fmt
->name
);