Revision 249069a1 lib/cmdlib.py
b/lib/cmdlib.py | ||
---|---|---|
3203 | 3203 |
return cmd[0], cmd |
3204 | 3204 |
|
3205 | 3205 |
|
3206 |
class LUAddMDDRBDComponent(LogicalUnit): |
|
3207 |
"""Adda new mirror member to an instance's disk. |
|
3208 |
|
|
3209 |
""" |
|
3210 |
HPATH = "mirror-add" |
|
3211 |
HTYPE = constants.HTYPE_INSTANCE |
|
3212 |
_OP_REQP = ["instance_name", "remote_node", "disk_name"] |
|
3213 |
|
|
3214 |
def BuildHooksEnv(self): |
|
3215 |
"""Build hooks env. |
|
3216 |
|
|
3217 |
This runs on the master, the primary and all the secondaries. |
|
3218 |
|
|
3219 |
""" |
|
3220 |
env = { |
|
3221 |
"NEW_SECONDARY": self.op.remote_node, |
|
3222 |
"DISK_NAME": self.op.disk_name, |
|
3223 |
} |
|
3224 |
env.update(_BuildInstanceHookEnvByObject(self.instance)) |
|
3225 |
nl = [self.sstore.GetMasterNode(), self.instance.primary_node, |
|
3226 |
self.op.remote_node,] + list(self.instance.secondary_nodes) |
|
3227 |
return env, nl, nl |
|
3228 |
|
|
3229 |
def CheckPrereq(self): |
|
3230 |
"""Check prerequisites. |
|
3231 |
|
|
3232 |
This checks that the instance is in the cluster. |
|
3233 |
|
|
3234 |
""" |
|
3235 |
instance = self.cfg.GetInstanceInfo( |
|
3236 |
self.cfg.ExpandInstanceName(self.op.instance_name)) |
|
3237 |
if instance is None: |
|
3238 |
raise errors.OpPrereqError("Instance '%s' not known" % |
|
3239 |
self.op.instance_name) |
|
3240 |
self.instance = instance |
|
3241 |
|
|
3242 |
remote_node = self.cfg.ExpandNodeName(self.op.remote_node) |
|
3243 |
if remote_node is None: |
|
3244 |
raise errors.OpPrereqError("Node '%s' not known" % self.op.remote_node) |
|
3245 |
self.remote_node = remote_node |
|
3246 |
|
|
3247 |
if remote_node == instance.primary_node: |
|
3248 |
raise errors.OpPrereqError("The specified node is the primary node of" |
|
3249 |
" the instance.") |
|
3250 |
|
|
3251 |
if instance.disk_template != constants.DT_REMOTE_RAID1: |
|
3252 |
raise errors.OpPrereqError("Instance's disk layout is not" |
|
3253 |
" remote_raid1.") |
|
3254 |
for disk in instance.disks: |
|
3255 |
if disk.iv_name == self.op.disk_name: |
|
3256 |
break |
|
3257 |
else: |
|
3258 |
raise errors.OpPrereqError("Can't find this device ('%s') in the" |
|
3259 |
" instance." % self.op.disk_name) |
|
3260 |
if len(disk.children) > 1: |
|
3261 |
raise errors.OpPrereqError("The device already has two slave devices." |
|
3262 |
" This would create a 3-disk raid1 which we" |
|
3263 |
" don't allow.") |
|
3264 |
self.disk = disk |
|
3265 |
|
|
3266 |
def Exec(self, feedback_fn): |
|
3267 |
"""Add the mirror component |
|
3268 |
|
|
3269 |
""" |
|
3270 |
disk = self.disk |
|
3271 |
instance = self.instance |
|
3272 |
|
|
3273 |
remote_node = self.remote_node |
|
3274 |
lv_names = [".%s_%s" % (disk.iv_name, suf) for suf in ["data", "meta"]] |
|
3275 |
names = _GenerateUniqueNames(self.cfg, lv_names) |
|
3276 |
new_drbd = _GenerateMDDRBDBranch(self.cfg, instance.primary_node, |
|
3277 |
remote_node, disk.size, names) |
|
3278 |
|
|
3279 |
logger.Info("adding new mirror component on secondary") |
|
3280 |
#HARDCODE |
|
3281 |
if not _CreateBlockDevOnSecondary(self.cfg, remote_node, instance, |
|
3282 |
new_drbd, False, |
|
3283 |
_GetInstanceInfoText(instance)): |
|
3284 |
raise errors.OpExecError("Failed to create new component on secondary" |
|
3285 |
" node %s" % remote_node) |
|
3286 |
|
|
3287 |
logger.Info("adding new mirror component on primary") |
|
3288 |
#HARDCODE |
|
3289 |
if not _CreateBlockDevOnPrimary(self.cfg, instance.primary_node, |
|
3290 |
instance, new_drbd, |
|
3291 |
_GetInstanceInfoText(instance)): |
|
3292 |
# remove secondary dev |
|
3293 |
self.cfg.SetDiskID(new_drbd, remote_node) |
|
3294 |
rpc.call_blockdev_remove(remote_node, new_drbd) |
|
3295 |
raise errors.OpExecError("Failed to create volume on primary") |
|
3296 |
|
|
3297 |
# the device exists now |
|
3298 |
# call the primary node to add the mirror to md |
|
3299 |
logger.Info("adding new mirror component to md") |
|
3300 |
if not rpc.call_blockdev_addchildren(instance.primary_node, |
|
3301 |
disk, [new_drbd]): |
|
3302 |
logger.Error("Can't add mirror compoment to md!") |
|
3303 |
self.cfg.SetDiskID(new_drbd, remote_node) |
|
3304 |
if not rpc.call_blockdev_remove(remote_node, new_drbd): |
|
3305 |
logger.Error("Can't rollback on secondary") |
|
3306 |
self.cfg.SetDiskID(new_drbd, instance.primary_node) |
|
3307 |
if not rpc.call_blockdev_remove(instance.primary_node, new_drbd): |
|
3308 |
logger.Error("Can't rollback on primary") |
|
3309 |
raise errors.OpExecError("Can't add mirror component to md array") |
|
3310 |
|
|
3311 |
disk.children.append(new_drbd) |
|
3312 |
|
|
3313 |
self.cfg.AddInstance(instance) |
|
3314 |
|
|
3315 |
_WaitForSync(self.cfg, instance, self.proc) |
|
3316 |
|
|
3317 |
return 0 |
|
3318 |
|
|
3319 |
|
|
3320 |
class LURemoveMDDRBDComponent(LogicalUnit): |
|
3321 |
"""Remove a component from a remote_raid1 disk. |
|
3322 |
|
|
3323 |
""" |
|
3324 |
HPATH = "mirror-remove" |
|
3325 |
HTYPE = constants.HTYPE_INSTANCE |
|
3326 |
_OP_REQP = ["instance_name", "disk_name", "disk_id"] |
|
3327 |
|
|
3328 |
def BuildHooksEnv(self): |
|
3329 |
"""Build hooks env. |
|
3330 |
|
|
3331 |
This runs on the master, the primary and all the secondaries. |
|
3332 |
|
|
3333 |
""" |
|
3334 |
env = { |
|
3335 |
"DISK_NAME": self.op.disk_name, |
|
3336 |
"DISK_ID": self.op.disk_id, |
|
3337 |
"OLD_SECONDARY": self.old_secondary, |
|
3338 |
} |
|
3339 |
env.update(_BuildInstanceHookEnvByObject(self.instance)) |
|
3340 |
nl = [self.sstore.GetMasterNode(), |
|
3341 |
self.instance.primary_node] + list(self.instance.secondary_nodes) |
|
3342 |
return env, nl, nl |
|
3343 |
|
|
3344 |
def CheckPrereq(self): |
|
3345 |
"""Check prerequisites. |
|
3346 |
|
|
3347 |
This checks that the instance is in the cluster. |
|
3348 |
|
|
3349 |
""" |
|
3350 |
instance = self.cfg.GetInstanceInfo( |
|
3351 |
self.cfg.ExpandInstanceName(self.op.instance_name)) |
|
3352 |
if instance is None: |
|
3353 |
raise errors.OpPrereqError("Instance '%s' not known" % |
|
3354 |
self.op.instance_name) |
|
3355 |
self.instance = instance |
|
3356 |
|
|
3357 |
if instance.disk_template != constants.DT_REMOTE_RAID1: |
|
3358 |
raise errors.OpPrereqError("Instance's disk layout is not" |
|
3359 |
" remote_raid1.") |
|
3360 |
for disk in instance.disks: |
|
3361 |
if disk.iv_name == self.op.disk_name: |
|
3362 |
break |
|
3363 |
else: |
|
3364 |
raise errors.OpPrereqError("Can't find this device ('%s') in the" |
|
3365 |
" instance." % self.op.disk_name) |
|
3366 |
for child in disk.children: |
|
3367 |
if (child.dev_type == constants.LD_DRBD7 and |
|
3368 |
child.logical_id[2] == self.op.disk_id): |
|
3369 |
break |
|
3370 |
else: |
|
3371 |
raise errors.OpPrereqError("Can't find the device with this port.") |
|
3372 |
|
|
3373 |
if len(disk.children) < 2: |
|
3374 |
raise errors.OpPrereqError("Cannot remove the last component from" |
|
3375 |
" a mirror.") |
|
3376 |
self.disk = disk |
|
3377 |
self.child = child |
|
3378 |
if self.child.logical_id[0] == instance.primary_node: |
|
3379 |
oid = 1 |
|
3380 |
else: |
|
3381 |
oid = 0 |
|
3382 |
self.old_secondary = self.child.logical_id[oid] |
|
3383 |
|
|
3384 |
def Exec(self, feedback_fn): |
|
3385 |
"""Remove the mirror component |
|
3386 |
|
|
3387 |
""" |
|
3388 |
instance = self.instance |
|
3389 |
disk = self.disk |
|
3390 |
child = self.child |
|
3391 |
logger.Info("remove mirror component") |
|
3392 |
self.cfg.SetDiskID(disk, instance.primary_node) |
|
3393 |
if not rpc.call_blockdev_removechildren(instance.primary_node, |
|
3394 |
disk, [child]): |
|
3395 |
raise errors.OpExecError("Can't remove child from mirror.") |
|
3396 |
|
|
3397 |
for node in child.logical_id[:2]: |
|
3398 |
self.cfg.SetDiskID(child, node) |
|
3399 |
if not rpc.call_blockdev_remove(node, child): |
|
3400 |
logger.Error("Warning: failed to remove device from node %s," |
|
3401 |
" continuing operation." % node) |
|
3402 |
|
|
3403 |
disk.children.remove(child) |
|
3404 |
self.cfg.AddInstance(instance) |
|
3405 |
|
|
3406 |
|
|
3407 | 3206 |
class LUReplaceDisks(LogicalUnit): |
3408 | 3207 |
"""Replace the disks of an instance. |
3409 | 3208 |
|
Also available in: Unified diff