1 /*        $NetBSD: lvm_lv.c,v 1.1.1.1 2009/12/02 00:26:15 haad Exp $  */
2 
3 /*
4  * Copyright (C) 2008,2009 Red Hat, Inc. All rights reserved.
5  *
6  * This file is part of LVM2.
7  *
8  * This copyrighted material is made available to anyone wishing to use,
9  * modify, copy, or redistribute it subject to the terms and conditions
10  * of the GNU Lesser General Public License v.2.1.
11  *
12  * You should have received a copy of the GNU Lesser General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15  */
16 
17 #include "lib.h"
18 #include "lvm2app.h"
19 #include "metadata-exported.h"
20 #include "lvm-string.h"
21 #include "defaults.h"
22 #include "segtype.h"
23 #include "locking.h"
24 #include "activate.h"
25 
26 #include <string.h>
27 
28 /* FIXME: have lib/report/report.c _disp function call lv_size()? */
lvm_lv_get_size(const lv_t lv)29 uint64_t lvm_lv_get_size(const lv_t lv)
30 {
31           return lv_size(lv);
32 }
33 
lvm_lv_get_uuid(const lv_t lv)34 char *lvm_lv_get_uuid(const lv_t lv)
35 {
36           char uuid[64] __attribute((aligned(8)));
37 
38           if (!id_write_format(&lv->lvid.id[1], uuid, sizeof(uuid))) {
39                     log_error("Internal error converting uuid");
40                     return NULL;
41           }
42           return strndup((const char *)uuid, 64);
43 }
44 
lvm_lv_get_name(const lv_t lv)45 char *lvm_lv_get_name(const lv_t lv)
46 {
47           char *name;
48 
49           name = dm_malloc(NAME_LEN + 1);
50           strncpy(name, (const char *)lv->name, NAME_LEN);
51           name[NAME_LEN] = '\0';
52           return name;
53 }
54 
lvm_lv_is_active(const lv_t lv)55 uint64_t lvm_lv_is_active(const lv_t lv)
56 {
57           struct lvinfo info;
58           if (lv_info(lv->vg->cmd, lv, &info, 1, 0) &&
59               info.exists && info.live_table)
60                     return 1;
61           return 0;
62 }
63 
lvm_lv_is_suspended(const lv_t lv)64 uint64_t lvm_lv_is_suspended(const lv_t lv)
65 {
66           struct lvinfo info;
67           if (lv_info(lv->vg->cmd, lv, &info, 1, 0) &&
68               info.exists && info.suspended)
69                     return 1;
70           return 0;
71 }
72 
73 /* Set defaults for non-segment specific LV parameters */
_lv_set_default_params(struct lvcreate_params * lp,vg_t vg,const char * lvname,uint64_t extents)74 static void _lv_set_default_params(struct lvcreate_params *lp,
75                                            vg_t vg, const char *lvname,
76                                            uint64_t extents)
77 {
78           lp->zero = 1;
79           lp->major = -1;
80           lp->minor = -1;
81           lp->vg_name = vg->name;
82           lp->lv_name = lvname; /* FIXME: check this for safety */
83           lp->pvh = &vg->pvs;
84 
85           lp->extents = extents;
86           lp->permission = LVM_READ | LVM_WRITE;
87           lp->read_ahead = DM_READ_AHEAD_NONE;
88           lp->alloc = ALLOC_INHERIT;
89           lp->tag = NULL;
90 }
91 
92 /* Set default for linear segment specific LV parameters */
_lv_set_default_linear_params(struct cmd_context * cmd,struct lvcreate_params * lp)93 static void _lv_set_default_linear_params(struct cmd_context *cmd,
94                                                     struct lvcreate_params *lp)
95 {
96           lp->segtype = get_segtype_from_string(cmd, "striped");
97           lp->stripes = 1;
98           lp->stripe_size = DEFAULT_STRIPESIZE * 2;
99 }
100 
101 /*
102  * FIXME: This function should probably not commit to disk but require calling
103  * lvm_vg_write.  However, this appears to be non-trivial change until
104  * lv_create_single is refactored by segtype.
105  */
lvm_vg_create_lv_linear(vg_t vg,const char * name,uint64_t size)106 lv_t lvm_vg_create_lv_linear(vg_t vg, const char *name, uint64_t size)
107 {
108           struct lvcreate_params lp;
109           uint64_t extents;
110           struct lv_list *lvl;
111 
112           if (vg_read_error(vg))
113                     return NULL;
114           if (!vg_check_write_mode(vg))
115                     return NULL;
116           memset(&lp, 0, sizeof(lp));
117           extents = extents_from_size(vg->cmd, size, vg->extent_size);
118           _lv_set_default_params(&lp, vg, name, extents);
119           _lv_set_default_linear_params(vg->cmd, &lp);
120           if (!lv_create_single(vg, &lp))
121                     return NULL;
122           lvl = find_lv_in_vg(vg, name);
123           if (!lvl)
124                     return NULL;
125           return (lv_t) lvl->lv;
126 }
127 
128 /*
129  * FIXME: This function should probably not commit to disk but require calling
130  * lvm_vg_write.
131  */
lvm_vg_remove_lv(lv_t lv)132 int lvm_vg_remove_lv(lv_t lv)
133 {
134           if (!lv || !lv->vg || vg_read_error(lv->vg))
135                     return -1;
136           if (!vg_check_write_mode(lv->vg))
137                     return -1;
138           if (!lv_remove_single(lv->vg->cmd, lv, DONT_PROMPT))
139                     return -1;
140           return 0;
141 }
142 
lvm_lv_activate(lv_t lv)143 int lvm_lv_activate(lv_t lv)
144 {
145           if (!lv || !lv->vg || vg_read_error(lv->vg) || !lv->vg->cmd)
146                     return -1;
147 
148           /* FIXME: handle pvmove stuff later */
149           if (lv->status & LOCKED) {
150                     log_error("Unable to activate locked LV");
151                     return -1;
152           }
153 
154           /* FIXME: handle lvconvert stuff later */
155           if (lv->status & CONVERTING) {
156                     log_error("Unable to activate LV with in-progress lvconvert");
157                     return -1;
158           }
159 
160           if (lv_is_origin(lv)) {
161                     log_verbose("Activating logical volume \"%s\" "
162                                   "exclusively", lv->name);
163                     if (!activate_lv_excl(lv->vg->cmd, lv)) {
164                               log_error("Activate exclusive failed.");
165                               return -1;
166                     }
167           } else {
168                     log_verbose("Activating logical volume \"%s\"",
169                                   lv->name);
170                     if (!activate_lv(lv->vg->cmd, lv)) {
171                               log_error("Activate failed.");
172                               return -1;
173                     }
174           }
175           return 0;
176 }
177 
lvm_lv_deactivate(lv_t lv)178 int lvm_lv_deactivate(lv_t lv)
179 {
180           if (!lv || !lv->vg || vg_read_error(lv->vg) || !lv->vg->cmd)
181                     return -1;
182 
183           log_verbose("Deactivating logical volume \"%s\"", lv->name);
184           if (!deactivate_lv(lv->vg->cmd, lv)) {
185                     log_error("Deactivate failed.");
186                     return -1;
187           }
188           return 0;
189 }
190 
lvm_lv_resize(const lv_t lv,uint64_t new_size)191 int lvm_lv_resize(const lv_t lv, uint64_t new_size)
192 {
193           /* FIXME: add lv resize code here */
194           log_error("NOT IMPLEMENTED YET");
195           return -1;
196 }
197